1 /* 2 * Copyright 2014 Google Inc. 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 #include "include/core/SkCanvas.h" 10 #include "include/core/SkColor.h" 11 #include "include/core/SkImageInfo.h" 12 #include "include/core/SkPaint.h" 13 #include "include/core/SkRefCnt.h" 14 #include "include/core/SkShader.h" 15 #include "include/core/SkSize.h" 16 #include "include/core/SkString.h" 17 #include "include/core/SkSurface.h" 18 #include "include/core/SkTypes.h" 19 #include "include/gpu/ganesh/GrDirectContext.h" 20 #include "include/gpu/ganesh/GrRecordingContext.h" 21 #include "include/gpu/ganesh/SkSurfaceGanesh.h" 22 #include "src/base/SkRandom.h" 23 #include "tools/ToolUtils.h" 24 25 #if defined(SK_GRAPHITE) 26 #include "include/gpu/graphite/Surface.h" 27 #endif 28 29 namespace skiagm { 30 31 /* 32 * This GM exercises SkCanvas::discard() by creating an offscreen SkSurface and repeatedly 33 * discarding it, drawing to it, and then drawing it to the main canvas. 34 */ 35 class DiscardGM : public GM { 36 37 public: DiscardGM()38 DiscardGM() {} 39 40 protected: getName() const41 SkString getName() const override { return SkString("discard"); } 42 getISize()43 SkISize getISize() override { return SkISize::Make(100, 100); } 44 onDraw(SkCanvas * canvas,SkString * errorMsg)45 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override { 46 47 SkISize size = this->getISize(); 48 size.fWidth /= 10; 49 size.fHeight /= 10; 50 SkImageInfo info = SkImageInfo::MakeN32Premul(size); 51 sk_sp<SkSurface> surface; 52 53 auto dContext = GrAsDirectContext(canvas->recordingContext()); 54 if (dContext && !dContext->abandoned()) { 55 surface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, info); 56 } 57 58 #if defined(SK_GRAPHITE) 59 auto recorder = canvas->recorder(); 60 if (recorder) { 61 surface = SkSurfaces::RenderTarget(recorder, info); 62 } 63 #endif 64 65 if (!surface) { 66 surface = SkSurfaces::Raster(info); 67 } 68 if (!surface) { 69 *errorMsg = "Could not create surface."; 70 return DrawResult::kFail; 71 } 72 73 canvas->clear(SK_ColorBLACK); 74 75 SkRandom rand; 76 for (int x = 0; x < 10; ++x) { 77 for (int y = 0; y < 10; ++y) { 78 surface->getCanvas()->discard(); 79 // Make something that isn't too close to the background color, black. 80 SkColor color = ToolUtils::color_to_565(rand.nextU() | 0xFF404040); 81 switch (rand.nextULessThan(3)) { 82 case 0: 83 surface->getCanvas()->drawColor(color); 84 break; 85 case 1: 86 surface->getCanvas()->clear(color); 87 break; 88 case 2: 89 SkPaint paint; 90 paint.setShader(SkShaders::Color(color)); 91 surface->getCanvas()->drawPaint(paint); 92 break; 93 } 94 surface->draw(canvas, 10.f*x, 10.f*y); 95 } 96 } 97 98 surface->getCanvas()->discard(); 99 return DrawResult::kOk; 100 } 101 }; 102 103 ////////////////////////////////////////////////////////////////////////////// 104 105 DEF_GM(return new DiscardGM;) 106 107 } // namespace skiagm 108