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/GrDirectContext.h" 20 #include "include/gpu/GrRecordingContext.h" 21 #include "include/utils/SkRandom.h" 22 #include "tools/ToolUtils.h" 23 24 class GrRenderTargetContext; 25 26 namespace skiagm { 27 28 /* 29 * This GM exercises SkCanvas::discard() by creating an offscreen SkSurface and repeatedly 30 * discarding it, drawing to it, and then drawing it to the main canvas. 31 */ 32 class DiscardGM : public GpuGM { 33 34 public: DiscardGM()35 DiscardGM() {} 36 37 protected: onShortName()38 SkString onShortName() override { 39 return SkString("discard"); 40 } 41 onISize()42 SkISize onISize() override { 43 return SkISize::Make(100, 100); 44 } 45 onDraw(GrRecordingContext * context,GrRenderTargetContext *,SkCanvas * canvas,SkString * errorMsg)46 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext*, SkCanvas* canvas, 47 SkString* errorMsg) override { 48 auto direct = context->asDirectContext(); 49 if (!direct) { 50 *errorMsg = "GM relies on having access to a live direct context."; 51 return DrawResult::kSkip; 52 } 53 54 SkISize size = this->getISize(); 55 size.fWidth /= 10; 56 size.fHeight /= 10; 57 SkImageInfo info = SkImageInfo::MakeN32Premul(size); 58 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(direct, SkBudgeted::kNo, info); 59 if (nullptr == surface) { 60 *errorMsg = "Could not create render target."; 61 return DrawResult::kFail; 62 } 63 64 canvas->clear(SK_ColorBLACK); 65 66 SkRandom rand; 67 for (int x = 0; x < 10; ++x) { 68 for (int y = 0; y < 10; ++y) { 69 surface->getCanvas()->discard(); 70 // Make something that isn't too close to the background color, black. 71 SkColor color = ToolUtils::color_to_565(rand.nextU() | 0xFF404040); 72 switch (rand.nextULessThan(3)) { 73 case 0: 74 surface->getCanvas()->drawColor(color); 75 break; 76 case 1: 77 surface->getCanvas()->clear(color); 78 break; 79 case 2: 80 SkPaint paint; 81 paint.setShader(SkShaders::Color(color)); 82 surface->getCanvas()->drawPaint(paint); 83 break; 84 } 85 surface->draw(canvas, 10.f*x, 10.f*y, nullptr); 86 } 87 } 88 89 surface->getCanvas()->discard(); 90 return DrawResult::kOk; 91 } 92 93 private: 94 using INHERITED = GM; 95 }; 96 97 ////////////////////////////////////////////////////////////////////////////// 98 99 DEF_GM(return new DiscardGM;) 100 101 } // namespace skiagm 102