blob: cd49fefe501788df337ff80c0a9f35a6d3785b78 [file] [log] [blame]
commit-bot@chromium.org26632632014-03-25 15:13:18 +00001/*
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
commit-bot@chromium.org26632632014-03-25 15:13:18 +000012#include "GrContext.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050013#include "GrContextPriv.h"
Robert Phillips0bd24dc2018-01-16 08:06:32 -050014#include "GrProxyProvider.h"
Brian Salomon6a639042016-12-14 11:08:17 -050015#include "GrRenderTargetContextPriv.h"
commit-bot@chromium.org26632632014-03-25 15:13:18 +000016#include "SkGradientShader.h"
Brian Osman2700abc2018-09-12 10:19:41 -040017#include "SkImage.h"
Michael Ludwigbe315a22018-12-17 09:50:51 -050018#include "SkImage_Base.h"
Brian Osman2700abc2018-09-12 10:19:41 -040019#include "SkSurface.h"
joshualitt04194f32016-01-13 10:08:27 -080020#include "effects/GrTextureDomain.h"
Brian Salomon89527432016-12-16 09:52:16 -050021#include "ops/GrDrawOp.h"
Michael Ludwig72ab3462018-12-10 12:43:36 -050022#include "ops/GrFillRectOp.h"
commit-bot@chromium.org26632632014-03-25 15:13:18 +000023
24namespace skiagm {
25/**
26 * This GM directly exercises GrTextureDomainEffect.
27 */
Chris Dalton3a778372019-02-07 15:23:36 -070028class TextureDomainEffect : public GpuGM {
commit-bot@chromium.org26632632014-03-25 15:13:18 +000029public:
Michael Ludwigbe315a22018-12-17 09:50:51 -050030 TextureDomainEffect(GrSamplerState::Filter filter)
31 : fFilter(filter) {
commit-bot@chromium.org26632632014-03-25 15:13:18 +000032 this->setBGColor(0xFFFFFFFF);
33 }
34
35protected:
mtklein36352bf2015-03-25 18:17:31 -070036 SkString onShortName() override {
Michael Ludwigbe315a22018-12-17 09:50:51 -050037 SkString name("texture_domain_effect");
38 if (fFilter == GrSamplerState::Filter::kBilerp) {
39 name.append("_bilerp");
40 } else if (fFilter == GrSamplerState::Filter::kMipMap) {
41 name.append("_mipmap");
42 }
43 return name;
commit-bot@chromium.org26632632014-03-25 15:13:18 +000044 }
45
mtklein36352bf2015-03-25 18:17:31 -070046 SkISize onISize() override {
joshualitt5ae5fc52014-07-29 12:59:27 -070047 const SkScalar canvasWidth = kDrawPad +
48 (kTargetWidth + 2 * kDrawPad) * GrTextureDomain::kModeCount +
49 kTestPad * GrTextureDomain::kModeCount;
50 return SkISize::Make(SkScalarCeilToInt(canvasWidth), 800);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000051 }
52
mtklein36352bf2015-03-25 18:17:31 -070053 void onOnceBeforeDraw() override {
Brian Osman2700abc2018-09-12 10:19:41 -040054 // TODO: do this with gpu backend
Robert Phillips40fd7c92017-01-30 08:06:27 -050055 SkImageInfo ii = SkImageInfo::Make(kTargetWidth, kTargetHeight, kN32_SkColorType,
56 kPremul_SkAlphaType);
Brian Osman2700abc2018-09-12 10:19:41 -040057 auto surface = SkSurface::MakeRaster(ii);
58 SkCanvas* canvas = surface->getCanvas();
59 canvas->clear(0x00000000);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000060 SkPaint paint;
61
62 SkColor colors1[] = { SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGRAY };
reed1a9b9642016-03-13 14:13:58 -070063 paint.setShader(SkGradientShader::MakeSweep(65.f, 75.f, colors1, nullptr,
64 SK_ARRAY_COUNT(colors1)));
Brian Osman2700abc2018-09-12 10:19:41 -040065 canvas->drawOval(SkRect::MakeXYWH(-5.f, -5.f, kTargetWidth + 10.f, kTargetHeight + 10.f),
66 paint);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000067
68 SkColor colors2[] = { SK_ColorMAGENTA, SK_ColorLTGRAY, SK_ColorYELLOW };
reed1a9b9642016-03-13 14:13:58 -070069 paint.setShader(SkGradientShader::MakeSweep(45.f, 55.f, colors2, nullptr,
70 SK_ARRAY_COUNT(colors2)));
reed374772b2016-10-05 17:33:02 -070071 paint.setBlendMode(SkBlendMode::kDarken);
Brian Osman2700abc2018-09-12 10:19:41 -040072 canvas->drawOval(SkRect::MakeXYWH(-5.f, -5.f, kTargetWidth + 10.f, kTargetHeight + 10.f),
73 paint);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000074
75 SkColor colors3[] = { SK_ColorBLUE, SK_ColorLTGRAY, SK_ColorGREEN };
reed1a9b9642016-03-13 14:13:58 -070076 paint.setShader(SkGradientShader::MakeSweep(25.f, 35.f, colors3, nullptr,
77 SK_ARRAY_COUNT(colors3)));
reed374772b2016-10-05 17:33:02 -070078 paint.setBlendMode(SkBlendMode::kLighten);
Brian Osman2700abc2018-09-12 10:19:41 -040079 canvas->drawOval(SkRect::MakeXYWH(-5.f, -5.f, kTargetWidth + 10.f, kTargetHeight + 10.f),
80 paint);
81
82 fImage = surface->makeImageSnapshot();
commit-bot@chromium.org26632632014-03-25 15:13:18 +000083 }
84
Chris Dalton50e24d72019-02-07 16:20:09 -070085 DrawResult onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
86 SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips9da87e02019-02-04 13:26:26 -050087 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Michael Ludwigbe315a22018-12-17 09:50:51 -050088 sk_sp<GrTextureProxy> proxy;
89 if (fFilter == GrSamplerState::Filter::kMipMap) {
90 SkBitmap copy;
91 SkImageInfo info = as_IB(fImage)->onImageInfo().makeColorType(kN32_SkColorType);
92 if (!copy.tryAllocPixels(info) || !fImage->readPixels(copy.pixmap(), 0, 0)) {
Chris Dalton50e24d72019-02-07 16:20:09 -070093 *errorMsg = "Failed to read pixels.";
94 return DrawResult::kFail;
Michael Ludwigbe315a22018-12-17 09:50:51 -050095 }
96 proxy = proxyProvider->createMipMapProxyFromBitmap(copy);
97 } else {
98 proxy = proxyProvider->createTextureProxy(
Brian Osman2700abc2018-09-12 10:19:41 -040099 fImage, kNone_GrSurfaceFlags, 1, SkBudgeted::kYes, SkBackingFit::kExact);
Michael Ludwigbe315a22018-12-17 09:50:51 -0500100 }
Robert Phillips2f493142017-03-02 18:18:38 -0500101 if (!proxy) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700102 *errorMsg = "Failed to create proxy.";
103 return DrawResult::kFail;
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000104 }
105
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000106 SkTArray<SkMatrix> textureMatrices;
Robert Phillips67c18d62017-01-20 12:44:06 -0500107 textureMatrices.push_back() = SkMatrix::I();
108 textureMatrices.push_back() = SkMatrix::MakeScale(1.5f, 0.85f);
109 textureMatrices.push_back();
Robert Phillips40fd7c92017-01-30 08:06:27 -0500110 textureMatrices.back().setRotate(45.f, proxy->width() / 2.f, proxy->height() / 2.f);
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000111
112 const SkIRect texelDomains[] = {
Brian Osman2700abc2018-09-12 10:19:41 -0400113 fImage->bounds(),
Michael Ludwigbe315a22018-12-17 09:50:51 -0500114 SkIRect::MakeXYWH(fImage->width() / 4 - 1, fImage->height() / 4 - 1,
115 fImage->width() / 2 + 2, fImage->height() / 2 + 2),
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000116 };
117
Brian Osman2700abc2018-09-12 10:19:41 -0400118 SkRect renderRect = SkRect::Make(fImage->bounds());
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000119 renderRect.outset(kDrawPad, kDrawPad);
120
121 SkScalar y = kDrawPad + kTestPad;
122 for (int tm = 0; tm < textureMatrices.count(); ++tm) {
123 for (size_t d = 0; d < SK_ARRAY_COUNT(texelDomains); ++d) {
124 SkScalar x = kDrawPad + kTestPad;
125 for (int m = 0; m < GrTextureDomain::kModeCount; ++m) {
126 GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m;
Michael Ludwigbe315a22018-12-17 09:50:51 -0500127 if (fFilter != GrSamplerState::Filter::kNearest &&
128 mode == GrTextureDomain::kRepeat_Mode) {
129 // Repeat mode doesn't produce correct results with bilerp filtering
130 continue;
131 }
132
robertphillips28a838e2016-06-23 14:07:00 -0700133 GrPaint grPaint;
Brian Salomona1633922017-01-09 11:46:10 -0500134 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonaff329b2017-08-11 09:40:37 -0400135 auto fp = GrTextureDomainEffect::Make(
Brian Osman2240be92017-10-18 13:15:13 -0400136 proxy, textureMatrices[tm],
Michael Ludwigbe315a22018-12-17 09:50:51 -0500137 GrTextureDomain::MakeTexelDomain(texelDomains[d], mode),
138 mode, fFilter);
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000139
joshualittb0a8a372014-09-23 09:50:21 -0700140 if (!fp) {
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000141 continue;
142 }
robertphillips1d24b8d2015-03-26 19:57:08 -0700143 const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
robertphillips28a838e2016-06-23 14:07:00 -0700144 grPaint.addColorFragmentProcessor(std::move(fp));
Brian Salomonac70f842017-05-08 10:43:33 -0400145 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwig72ab3462018-12-10 12:43:36 -0500146 GrFillRectOp::Make(context, std::move(grPaint), GrAAType::kNone,
147 viewMatrix, renderRect));
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000148 x += renderRect.width() + kTestPad;
149 }
150 y += renderRect.height() + kTestPad;
151 }
152 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700153 return DrawResult::kOk;
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000154 }
155
156private:
mtkleindbfd7ab2016-09-01 11:24:54 -0700157 static constexpr SkScalar kDrawPad = 10.f;
Kevin Lubick48ce5432019-01-04 08:54:32 -0500158 static constexpr SkScalar kTestPad = 10.f;
mtkleindbfd7ab2016-09-01 11:24:54 -0700159 static constexpr int kTargetWidth = 100;
160 static constexpr int kTargetHeight = 100;
Brian Osman2700abc2018-09-12 10:19:41 -0400161 sk_sp<SkImage> fImage;
Michael Ludwigbe315a22018-12-17 09:50:51 -0500162 GrSamplerState::Filter fFilter;
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000163
164 typedef GM INHERITED;
165};
166
Michael Ludwigbe315a22018-12-17 09:50:51 -0500167DEF_GM(return new TextureDomainEffect(GrSamplerState::Filter::kNearest);)
168DEF_GM(return new TextureDomainEffect(GrSamplerState::Filter::kBilerp);)
169DEF_GM(return new TextureDomainEffect(GrSamplerState::Filter::kMipMap);)
170
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000171}