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