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