blob: 9171f2d3983b6c1523943ea7666f8e8b0550675a [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "gm/gm.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkBitmap.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040012#include "include/core/SkBlendMode.h"
13#include "include/core/SkCanvas.h"
14#include "include/core/SkColor.h"
15#include "include/core/SkMatrix.h"
16#include "include/core/SkPaint.h"
17#include "include/core/SkRect.h"
18#include "include/core/SkRefCnt.h"
19#include "include/core/SkScalar.h"
20#include "include/core/SkShader.h"
21#include "include/core/SkSize.h"
22#include "include/core/SkString.h"
23#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/effects/SkGradientShader.h"
25#include "include/gpu/GrContext.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040026#include "include/gpu/GrSamplerState.h"
27#include "include/gpu/GrTypes.h"
28#include "include/private/GrTextureProxy.h"
29#include "include/private/GrTypesPriv.h"
30#include "include/private/SkTArray.h"
31#include "src/gpu/GrCaps.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050032#include "src/gpu/GrContextPriv.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040033#include "src/gpu/GrFragmentProcessor.h"
34#include "src/gpu/GrPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050035#include "src/gpu/GrProxyProvider.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040036#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050037#include "src/gpu/GrRenderTargetContextPriv.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040038#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050039#include "src/gpu/effects/GrTextureDomain.h"
40#include "src/gpu/ops/GrDrawOp.h"
41#include "src/gpu/ops/GrFillRectOp.h"
commit-bot@chromium.org26632632014-03-25 15:13:18 +000042
Ben Wagner7fde8e12019-05-01 17:28:53 -040043#include <memory>
44#include <utility>
45
commit-bot@chromium.org26632632014-03-25 15:13:18 +000046namespace skiagm {
47/**
48 * This GM directly exercises GrTextureDomainEffect.
49 */
Chris Dalton3a778372019-02-07 15:23:36 -070050class TextureDomainEffect : public GpuGM {
commit-bot@chromium.org26632632014-03-25 15:13:18 +000051public:
Michael Ludwigbe315a22018-12-17 09:50:51 -050052 TextureDomainEffect(GrSamplerState::Filter filter)
53 : fFilter(filter) {
commit-bot@chromium.org26632632014-03-25 15:13:18 +000054 this->setBGColor(0xFFFFFFFF);
55 }
56
57protected:
mtklein36352bf2015-03-25 18:17:31 -070058 SkString onShortName() override {
Michael Ludwigbe315a22018-12-17 09:50:51 -050059 SkString name("texture_domain_effect");
60 if (fFilter == GrSamplerState::Filter::kBilerp) {
61 name.append("_bilerp");
62 } else if (fFilter == GrSamplerState::Filter::kMipMap) {
63 name.append("_mipmap");
64 }
65 return name;
commit-bot@chromium.org26632632014-03-25 15:13:18 +000066 }
67
mtklein36352bf2015-03-25 18:17:31 -070068 SkISize onISize() override {
joshualitt5ae5fc52014-07-29 12:59:27 -070069 const SkScalar canvasWidth = kDrawPad +
70 (kTargetWidth + 2 * kDrawPad) * GrTextureDomain::kModeCount +
71 kTestPad * GrTextureDomain::kModeCount;
72 return SkISize::Make(SkScalarCeilToInt(canvasWidth), 800);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000073 }
74
mtklein36352bf2015-03-25 18:17:31 -070075 void onOnceBeforeDraw() override {
Brian Osman65f33442019-03-25 13:42:35 -040076 fBitmap.allocN32Pixels(kTargetWidth, kTargetHeight);
77 SkCanvas canvas(fBitmap);
78 canvas.clear(0x00000000);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000079 SkPaint paint;
80
81 SkColor colors1[] = { SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGRAY };
reed1a9b9642016-03-13 14:13:58 -070082 paint.setShader(SkGradientShader::MakeSweep(65.f, 75.f, colors1, nullptr,
83 SK_ARRAY_COUNT(colors1)));
Brian Osman65f33442019-03-25 13:42:35 -040084 canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, kTargetWidth + 10.f, kTargetHeight + 10.f),
85 paint);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000086
87 SkColor colors2[] = { SK_ColorMAGENTA, SK_ColorLTGRAY, SK_ColorYELLOW };
reed1a9b9642016-03-13 14:13:58 -070088 paint.setShader(SkGradientShader::MakeSweep(45.f, 55.f, colors2, nullptr,
89 SK_ARRAY_COUNT(colors2)));
reed374772b2016-10-05 17:33:02 -070090 paint.setBlendMode(SkBlendMode::kDarken);
Brian Osman65f33442019-03-25 13:42:35 -040091 canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, kTargetWidth + 10.f, kTargetHeight + 10.f),
92 paint);
commit-bot@chromium.org26632632014-03-25 15:13:18 +000093
94 SkColor colors3[] = { SK_ColorBLUE, SK_ColorLTGRAY, SK_ColorGREEN };
reed1a9b9642016-03-13 14:13:58 -070095 paint.setShader(SkGradientShader::MakeSweep(25.f, 35.f, colors3, nullptr,
96 SK_ARRAY_COUNT(colors3)));
reed374772b2016-10-05 17:33:02 -070097 paint.setBlendMode(SkBlendMode::kLighten);
Brian Osman65f33442019-03-25 13:42:35 -040098 canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, kTargetWidth + 10.f, kTargetHeight + 10.f),
99 paint);
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000100 }
101
Chris Dalton50e24d72019-02-07 16:20:09 -0700102 DrawResult onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
103 SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips9da87e02019-02-04 13:26:26 -0500104 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Michael Ludwigbe315a22018-12-17 09:50:51 -0500105 sk_sp<GrTextureProxy> proxy;
Brian Osman65f33442019-03-25 13:42:35 -0400106 GrMipMapped mipMapped = fFilter == GrSamplerState::Filter::kMipMap &&
107 context->priv().caps()->mipMapSupport()
108 ? GrMipMapped::kYes : GrMipMapped::kNo;
109 proxy = proxyProvider->createProxyFromBitmap(fBitmap, mipMapped);
Robert Phillips2f493142017-03-02 18:18:38 -0500110 if (!proxy) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700111 *errorMsg = "Failed to create proxy.";
112 return DrawResult::kFail;
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000113 }
114
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000115 SkTArray<SkMatrix> textureMatrices;
Robert Phillips67c18d62017-01-20 12:44:06 -0500116 textureMatrices.push_back() = SkMatrix::I();
117 textureMatrices.push_back() = SkMatrix::MakeScale(1.5f, 0.85f);
118 textureMatrices.push_back();
Robert Phillips40fd7c92017-01-30 08:06:27 -0500119 textureMatrices.back().setRotate(45.f, proxy->width() / 2.f, proxy->height() / 2.f);
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000120
121 const SkIRect texelDomains[] = {
Brian Osman65f33442019-03-25 13:42:35 -0400122 fBitmap.bounds(),
123 SkIRect::MakeXYWH(fBitmap.width() / 4 - 1, fBitmap.height() / 4 - 1,
124 fBitmap.width() / 2 + 2, fBitmap.height() / 2 + 2),
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000125 };
126
Brian Osman65f33442019-03-25 13:42:35 -0400127 SkRect renderRect = SkRect::Make(fBitmap.bounds());
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000128 renderRect.outset(kDrawPad, kDrawPad);
129
130 SkScalar y = kDrawPad + kTestPad;
131 for (int tm = 0; tm < textureMatrices.count(); ++tm) {
132 for (size_t d = 0; d < SK_ARRAY_COUNT(texelDomains); ++d) {
133 SkScalar x = kDrawPad + kTestPad;
134 for (int m = 0; m < GrTextureDomain::kModeCount; ++m) {
135 GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m;
Michael Ludwigbe315a22018-12-17 09:50:51 -0500136 if (fFilter != GrSamplerState::Filter::kNearest &&
137 mode == GrTextureDomain::kRepeat_Mode) {
138 // Repeat mode doesn't produce correct results with bilerp filtering
139 continue;
140 }
141
robertphillips28a838e2016-06-23 14:07:00 -0700142 GrPaint grPaint;
Brian Salomona1633922017-01-09 11:46:10 -0500143 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonaff329b2017-08-11 09:40:37 -0400144 auto fp = GrTextureDomainEffect::Make(
Brian Osman2240be92017-10-18 13:15:13 -0400145 proxy, textureMatrices[tm],
Michael Ludwigbe315a22018-12-17 09:50:51 -0500146 GrTextureDomain::MakeTexelDomain(texelDomains[d], mode),
147 mode, fFilter);
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000148
joshualittb0a8a372014-09-23 09:50:21 -0700149 if (!fp) {
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000150 continue;
151 }
robertphillips1d24b8d2015-03-26 19:57:08 -0700152 const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
robertphillips28a838e2016-06-23 14:07:00 -0700153 grPaint.addColorFragmentProcessor(std::move(fp));
Brian Salomonac70f842017-05-08 10:43:33 -0400154 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400155 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
156 viewMatrix, renderRect));
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000157 x += renderRect.width() + kTestPad;
158 }
159 y += renderRect.height() + kTestPad;
160 }
161 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700162 return DrawResult::kOk;
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000163 }
164
165private:
mtkleindbfd7ab2016-09-01 11:24:54 -0700166 static constexpr SkScalar kDrawPad = 10.f;
Kevin Lubick48ce5432019-01-04 08:54:32 -0500167 static constexpr SkScalar kTestPad = 10.f;
mtkleindbfd7ab2016-09-01 11:24:54 -0700168 static constexpr int kTargetWidth = 100;
169 static constexpr int kTargetHeight = 100;
Brian Osman65f33442019-03-25 13:42:35 -0400170 SkBitmap fBitmap;
Michael Ludwigbe315a22018-12-17 09:50:51 -0500171 GrSamplerState::Filter fFilter;
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000172
173 typedef GM INHERITED;
174};
175
Michael Ludwigbe315a22018-12-17 09:50:51 -0500176DEF_GM(return new TextureDomainEffect(GrSamplerState::Filter::kNearest);)
177DEF_GM(return new TextureDomainEffect(GrSamplerState::Filter::kBilerp);)
178DEF_GM(return new TextureDomainEffect(GrSamplerState::Filter::kMipMap);)
179
commit-bot@chromium.org26632632014-03-25 15:13:18 +0000180}