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