1 /* 2 * Copyright 2019 Google LLC. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "gm/gm.h" 9 10 #include "include/core/SkPath.h" 11 #include "include/gpu/ganesh/GrContextOptions.h" 12 #include "include/gpu/ganesh/GrRecordingContext.h" 13 #include "src/gpu/ganesh/GrDirectContextPriv.h" 14 #include "src/gpu/ganesh/GrDrawingManager.h" 15 #include "src/gpu/ganesh/GrRecordingContextPriv.h" 16 #include "tools/ToolUtils.h" 17 18 #if defined(SK_GRAPHITE) 19 #include "include/gpu/graphite/ContextOptions.h" 20 #include "src/gpu/graphite/ContextOptionsPriv.h" 21 #endif 22 23 namespace skiagm { 24 25 /** 26 * This test originally ensured that the ccpr path cache preserved fill rules properly. CCPR is gone 27 * now, but we decided to keep the test. 28 */ 29 class ManyPathAtlasesGM : public GM { 30 public: ManyPathAtlasesGM(int maxAtlasSize)31 ManyPathAtlasesGM(int maxAtlasSize) : fMaxAtlasSize(maxAtlasSize) {} 32 private: getName() const33 SkString getName() const override { 34 return SkStringPrintf("manypathatlases_%i", fMaxAtlasSize); 35 } getISize()36 SkISize getISize() override { return SkISize::Make(128, 128); } 37 modifyGrContextOptions(GrContextOptions * ctxOptions)38 void modifyGrContextOptions(GrContextOptions* ctxOptions) override { 39 // This will test the case where the atlas runs out of room if fMaxAtlasSize is small. 40 ctxOptions->fMaxTextureAtlasSize = fMaxAtlasSize; 41 } 42 43 #if defined(SK_GRAPHITE) modifyGraphiteContextOptions(skgpu::graphite::ContextOptions * options) const44 void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions* options) const override { 45 SkASSERT(options->fOptionsPriv); 46 options->fOptionsPriv->fMaxTextureAtlasSize = fMaxAtlasSize; 47 } 48 #endif 49 onDraw(SkCanvas * canvas)50 void onDraw(SkCanvas* canvas) override { 51 canvas->clear(SkColors::kYellow); 52 53 // Flush the context to make the DAG empty. This will test the case where we try to add an 54 // atlas task to an empty DAG. 55 auto dContext = GrAsDirectContext(canvas->recordingContext()); 56 if (dContext) { 57 dContext->flush(); 58 } 59 60 SkPath clip = SkPath().moveTo(-50, 20) 61 .cubicTo(-50, -20, 50, -20, 50, 40) 62 .cubicTo(20, 0, -20, 0, -50, 20); 63 clip.transform(SkMatrix::Translate(64, 70)); 64 for (int i = 0; i < 4; ++i) { 65 SkPath rotatedClip = clip; 66 rotatedClip.transform(SkMatrix::RotateDeg(30 * i + 128, {64, 70})); 67 rotatedClip.setIsVolatile(true); 68 canvas->clipPath(rotatedClip, SkClipOp::kDifference, true); 69 } 70 SkPath path = SkPath().moveTo(20, 0) 71 .lineTo(108, 0).cubicTo(108, 20, 108, 20, 128, 20) 72 .lineTo(128, 108).cubicTo(108, 108, 108, 108, 108, 128) 73 .lineTo(20, 128).cubicTo(20, 108, 20, 108, 0, 108) 74 .lineTo(0, 20).cubicTo(20, 20, 20, 20, 20, 0); 75 path.setIsVolatile(true); 76 SkPaint teal; 77 teal.setColor4f({.03f, .91f, .87f, 1}); 78 teal.setAntiAlias(true); 79 canvas->drawPath(path, teal); 80 } 81 82 const int fMaxAtlasSize; 83 }; 84 85 DEF_GM( return new ManyPathAtlasesGM(128); ) // Atlas runs out of room. 86 DEF_GM( return new ManyPathAtlasesGM(2048); ) // Atlas does not run out of room. 87 88 } // namespace skiagm 89