Home | History | Annotate | Download | only in gm
      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