1 2/* 3 * Copyright 2014 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9// This test only works with the GPU backend. 10 11#include "gm.h" 12 13#if SK_SUPPORT_GPU 14 15#include "GrDrawContext.h" 16#include "GrContext.h" 17#include "SkBitmap.h" 18#include "SkGr.h" 19#include "SkGradientShader.h" 20#include "batches/GrDrawBatch.h" 21#include "batches/GrRectBatchFactory.h" 22#include "effects/GrTextureDomain.h" 23 24namespace skiagm { 25/** 26 * This GM directly exercises GrTextureDomainEffect. 27 */ 28class TextureDomainEffect : public GM { 29public: 30 TextureDomainEffect() { 31 this->setBGColor(0xFFFFFFFF); 32 } 33 34protected: 35 SkString onShortName() override { 36 return SkString("texture_domain_effect"); 37 } 38 39 SkISize onISize() override { 40 const SkScalar canvasWidth = kDrawPad + 41 (kTargetWidth + 2 * kDrawPad) * GrTextureDomain::kModeCount + 42 kTestPad * GrTextureDomain::kModeCount; 43 return SkISize::Make(SkScalarCeilToInt(canvasWidth), 800); 44 } 45 46 void onOnceBeforeDraw() override { 47 fBmp.allocN32Pixels(kTargetWidth, kTargetHeight); 48 SkCanvas canvas(fBmp); 49 canvas.clear(0x00000000); 50 SkPaint paint; 51 52 SkColor colors1[] = { SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGRAY }; 53 paint.setShader(SkGradientShader::CreateSweep(65.f, 75.f, colors1, 54 nullptr, SK_ARRAY_COUNT(colors1)))->unref(); 55 canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, 56 fBmp.width() + 10.f, fBmp.height() + 10.f), paint); 57 58 SkColor colors2[] = { SK_ColorMAGENTA, SK_ColorLTGRAY, SK_ColorYELLOW }; 59 paint.setShader(SkGradientShader::CreateSweep(45.f, 55.f, colors2, nullptr, 60 SK_ARRAY_COUNT(colors2)))->unref(); 61 paint.setXfermodeMode(SkXfermode::kDarken_Mode); 62 canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, 63 fBmp.width() + 10.f, fBmp.height() + 10.f), paint); 64 65 SkColor colors3[] = { SK_ColorBLUE, SK_ColorLTGRAY, SK_ColorGREEN }; 66 paint.setShader(SkGradientShader::CreateSweep(25.f, 35.f, colors3, nullptr, 67 SK_ARRAY_COUNT(colors3)))->unref(); 68 paint.setXfermodeMode(SkXfermode::kLighten_Mode); 69 canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, 70 fBmp.width() + 10.f, fBmp.height() + 10.f), paint); 71 } 72 73 void onDraw(SkCanvas* canvas) override { 74 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); 75 if (nullptr == rt) { 76 return; 77 } 78 GrContext* context = rt->getContext(); 79 if (nullptr == context) { 80 skiagm::GM::DrawGpuOnlyMessage(canvas); 81 return; 82 } 83 84 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(rt)); 85 if (!drawContext) { 86 return; 87 } 88 89 SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, fBmp, 90 GrTextureParams::ClampNoFilter())); 91 if (!texture) { 92 return; 93 } 94 95 SkTArray<SkMatrix> textureMatrices; 96 textureMatrices.push_back().setIDiv(texture->width(), texture->height()); 97 textureMatrices.push_back() = textureMatrices[0]; 98 textureMatrices.back().postScale(1.5f, 0.85f); 99 textureMatrices.push_back() = textureMatrices[0]; 100 textureMatrices.back().preRotate(45.f, texture->width() / 2.f, texture->height() / 2.f); 101 102 const SkIRect texelDomains[] = { 103 fBmp.bounds(), 104 SkIRect::MakeXYWH(fBmp.width() / 4, 105 fBmp.height() / 4, 106 fBmp.width() / 2, 107 fBmp.height() / 2), 108 }; 109 110 SkRect renderRect = SkRect::Make(fBmp.bounds()); 111 renderRect.outset(kDrawPad, kDrawPad); 112 113 SkScalar y = kDrawPad + kTestPad; 114 for (int tm = 0; tm < textureMatrices.count(); ++tm) { 115 for (size_t d = 0; d < SK_ARRAY_COUNT(texelDomains); ++d) { 116 SkScalar x = kDrawPad + kTestPad; 117 for (int m = 0; m < GrTextureDomain::kModeCount; ++m) { 118 GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m; 119 GrPipelineBuilder pipelineBuilder; 120 pipelineBuilder.setXPFactory( 121 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref(); 122 SkAutoTUnref<const GrFragmentProcessor> fp( 123 GrTextureDomainEffect::Create(texture, textureMatrices[tm], 124 GrTextureDomain::MakeTexelDomain(texture, 125 texelDomains[d]), 126 mode, GrTextureParams::kNone_FilterMode)); 127 128 if (!fp) { 129 continue; 130 } 131 const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y); 132 pipelineBuilder.setRenderTarget(rt); 133 pipelineBuilder.addColorFragmentProcessor(fp); 134 135 SkAutoTUnref<GrDrawBatch> batch( 136 GrRectBatchFactory::CreateNonAAFill(GrColor_WHITE, viewMatrix, 137 renderRect, nullptr, nullptr)); 138 drawContext->internal_drawBatch(pipelineBuilder, batch); 139 x += renderRect.width() + kTestPad; 140 } 141 y += renderRect.height() + kTestPad; 142 } 143 } 144 } 145 146private: 147 static const SkScalar kDrawPad; 148 static const SkScalar kTestPad; 149 static const int kTargetWidth = 100; 150 static const int kTargetHeight = 100; 151 SkBitmap fBmp; 152 153 typedef GM INHERITED; 154}; 155 156// Windows builds did not like SkScalar initialization in class :( 157const SkScalar TextureDomainEffect::kDrawPad = 10.f; 158const SkScalar TextureDomainEffect::kTestPad = 10.f; 159 160DEF_GM(return new TextureDomainEffect;) 161} 162 163#endif 164