• 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 // This test only works with the GPU backend.
9 
10 #include "gm.h"
11 
12 #if SK_SUPPORT_GPU
13 
14 #include "GrContext.h"
15 #include "GrContextPriv.h"
16 #include "GrProxyProvider.h"
17 #include "GrRenderTargetContextPriv.h"
18 #include "SkBitmap.h"
19 #include "SkGr.h"
20 #include "SkGradientShader.h"
21 #include "effects/GrTextureDomain.h"
22 #include "ops/GrDrawOp.h"
23 #include "ops/GrRectOpFactory.h"
24 
25 namespace skiagm {
26 /**
27  * This GM directly exercises GrTextureDomainEffect.
28  */
29 class TextureDomainEffect : public GM {
30 public:
TextureDomainEffect()31     TextureDomainEffect() {
32         this->setBGColor(0xFFFFFFFF);
33     }
34 
35 protected:
onShortName()36     SkString onShortName() override {
37         return SkString("texture_domain_effect");
38     }
39 
onISize()40     SkISize onISize() override {
41         const SkScalar canvasWidth = kDrawPad +
42                 (kTargetWidth + 2 * kDrawPad) * GrTextureDomain::kModeCount +
43                 kTestPad * GrTextureDomain::kModeCount;
44         return SkISize::Make(SkScalarCeilToInt(canvasWidth), 800);
45     }
46 
onOnceBeforeDraw()47     void onOnceBeforeDraw() override {
48         // TODO: do this with surfaces & images and gpu backend
49         SkImageInfo ii = SkImageInfo::Make(kTargetWidth, kTargetHeight, kN32_SkColorType,
50                                            kPremul_SkAlphaType);
51         fBmp.allocPixels(ii);
52         SkCanvas canvas(fBmp);
53         canvas.clear(0x00000000);
54         SkPaint paint;
55 
56         SkColor colors1[] = { SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGRAY };
57         paint.setShader(SkGradientShader::MakeSweep(65.f, 75.f, colors1, nullptr,
58                                                     SK_ARRAY_COUNT(colors1)));
59         canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
60                         paint);
61 
62         SkColor colors2[] = { SK_ColorMAGENTA, SK_ColorLTGRAY, SK_ColorYELLOW };
63         paint.setShader(SkGradientShader::MakeSweep(45.f, 55.f, colors2, nullptr,
64                                                     SK_ARRAY_COUNT(colors2)));
65         paint.setBlendMode(SkBlendMode::kDarken);
66         canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
67                         paint);
68 
69         SkColor colors3[] = { SK_ColorBLUE, SK_ColorLTGRAY, SK_ColorGREEN };
70         paint.setShader(SkGradientShader::MakeSweep(25.f, 35.f, colors3, nullptr,
71                                                     SK_ARRAY_COUNT(colors3)));
72         paint.setBlendMode(SkBlendMode::kLighten);
73         canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
74                         paint);
75     }
76 
onDraw(SkCanvas * canvas)77     void onDraw(SkCanvas* canvas) override {
78         GrRenderTargetContext* renderTargetContext =
79             canvas->internal_private_accessTopLayerRenderTargetContext();
80         if (!renderTargetContext) {
81             skiagm::GM::DrawGpuOnlyMessage(canvas);
82             return;
83         }
84 
85         GrContext* context = canvas->getGrContext();
86         if (!context) {
87             return;
88         }
89 
90         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
91         GrSurfaceDesc desc;
92         desc.fOrigin = kTopLeft_GrSurfaceOrigin;
93         desc.fWidth = fBmp.width();
94         desc.fHeight = fBmp.height();
95         desc.fConfig = SkImageInfo2GrPixelConfig(fBmp.info(), *context->caps());
96         SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
97 
98         sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
99                                                                         fBmp.getPixels(),
100                                                                         fBmp.rowBytes());
101         if (!proxy) {
102             return;
103         }
104 
105         SkTArray<SkMatrix> textureMatrices;
106         textureMatrices.push_back() = SkMatrix::I();
107         textureMatrices.push_back() = SkMatrix::MakeScale(1.5f, 0.85f);
108         textureMatrices.push_back();
109         textureMatrices.back().setRotate(45.f, proxy->width() / 2.f, proxy->height() / 2.f);
110 
111         const SkIRect texelDomains[] = {
112             fBmp.bounds(),
113             SkIRect::MakeXYWH(fBmp.width() / 4, fBmp.height() / 4,
114                               fBmp.width() / 2, fBmp.height() / 2),
115         };
116 
117         SkRect renderRect = SkRect::Make(fBmp.bounds());
118         renderRect.outset(kDrawPad, kDrawPad);
119 
120         SkScalar y = kDrawPad + kTestPad;
121         for (int tm = 0; tm < textureMatrices.count(); ++tm) {
122             for (size_t d = 0; d < SK_ARRAY_COUNT(texelDomains); ++d) {
123                 SkScalar x = kDrawPad + kTestPad;
124                 for (int m = 0; m < GrTextureDomain::kModeCount; ++m) {
125                     GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m;
126                     GrPaint grPaint;
127                     grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
128                     auto fp = GrTextureDomainEffect::Make(
129                             proxy, textureMatrices[tm],
130                             GrTextureDomain::MakeTexelDomainForMode(texelDomains[d], mode), mode,
131                             GrSamplerState::Filter::kNearest);
132 
133                     if (!fp) {
134                         continue;
135                     }
136                     const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
137                     grPaint.addColorFragmentProcessor(std::move(fp));
138                     renderTargetContext->priv().testingOnly_addDrawOp(
139                             GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix,
140                                                            renderRect, GrAAType::kNone));
141                     x += renderRect.width() + kTestPad;
142                 }
143                 y += renderRect.height() + kTestPad;
144             }
145         }
146     }
147 
148 private:
149     static constexpr SkScalar kDrawPad = 10.f;
150     static constexpr SkScalar kTestPad = 10.f;;
151     static constexpr int      kTargetWidth = 100;
152     static constexpr int      kTargetHeight = 100;
153     SkBitmap fBmp;
154 
155     typedef GM INHERITED;
156 };
157 
158 DEF_GM(return new TextureDomainEffect;)
159 }
160 
161 #endif
162