xref: /third_party/skia/gm/discard.cpp (revision cb93a386)
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
24namespace 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 */
30class DiscardGM : public GM {
31
32public:
33    DiscardGM() {}
34
35protected:
36    SkString onShortName() override {
37        return SkString("discard");
38    }
39
40    SkISize onISize() override {
41        return SkISize::Make(100, 100);
42    }
43
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
90private:
91    using INHERITED = GM;
92};
93
94//////////////////////////////////////////////////////////////////////////////
95
96DEF_GM(return new DiscardGM;)
97
98}  // namespace skiagm
99