blob: deb5cb791df483d78981ebd69000d96a1e27a3c6 [file] [log] [blame]
sugoi24dcac22014-07-07 15:09:48 -07001/*
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/SkColor.h"
14#include "include/core/SkImage.h"
15#include "include/core/SkImageInfo.h"
16#include "include/core/SkMatrix.h"
17#include "include/core/SkRect.h"
18#include "include/core/SkRefCnt.h"
19#include "include/core/SkScalar.h"
20#include "include/core/SkSize.h"
21#include "include/core/SkString.h"
22#include "include/core/SkTypes.h"
23#include "include/core/SkYUVAIndex.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/gpu/GrContext.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040025#include "include/private/GrTypesPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/GrClip.h"
27#include "src/gpu/GrContextPriv.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040028#include "src/gpu/GrFragmentProcessor.h"
29#include "src/gpu/GrPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "src/gpu/GrProxyProvider.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040031#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050032#include "src/gpu/GrRenderTargetContextPriv.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040033#include "src/gpu/GrSamplerState.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040034#include "src/gpu/GrTextureProxy.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040035#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050036#include "src/gpu/effects/GrYUVtoRGBEffect.h"
37#include "src/gpu/ops/GrDrawOp.h"
38#include "src/gpu/ops/GrFillRectOp.h"
sugoi24dcac22014-07-07 15:09:48 -070039
Ben Wagner7fde8e12019-05-01 17:28:53 -040040#include <memory>
41#include <utility>
42
43class SkCanvas;
44
sugoi4ccce7e2015-02-13 13:57:09 -080045#define YSIZE 8
46#define USIZE 4
47#define VSIZE 4
48
sugoi24dcac22014-07-07 15:09:48 -070049namespace skiagm {
50/**
51 * This GM directly exercises GrYUVtoRGBEffect.
52 */
Chris Dalton3a778372019-02-07 15:23:36 -070053class YUVtoRGBEffect : public GpuGM {
sugoi24dcac22014-07-07 15:09:48 -070054public:
55 YUVtoRGBEffect() {
56 this->setBGColor(0xFFFFFFFF);
57 }
58
59protected:
mtklein36352bf2015-03-25 18:17:31 -070060 SkString onShortName() override {
sugoi24dcac22014-07-07 15:09:48 -070061 return SkString("yuv_to_rgb_effect");
62 }
63
mtklein36352bf2015-03-25 18:17:31 -070064 SkISize onISize() override {
Robert Phillips0a22ba82019-03-06 12:36:47 -050065 int numRows = kLastEnum_SkYUVColorSpace + 1;
66 return SkISize::Make(238, kDrawPad + numRows * kColorSpaceOffset);
sugoi24dcac22014-07-07 15:09:48 -070067 }
68
mtklein36352bf2015-03-25 18:17:31 -070069 void onOnceBeforeDraw() override {
Brian Osman2700abc2018-09-12 10:19:41 -040070 SkBitmap bmp[3];
sugoi4ccce7e2015-02-13 13:57:09 -080071 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Brian Osman2700abc2018-09-12 10:19:41 -040072 bmp[0].allocPixels(yinfo);
sugoi4ccce7e2015-02-13 13:57:09 -080073 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
Brian Osman2700abc2018-09-12 10:19:41 -040074 bmp[1].allocPixels(uinfo);
sugoi4ccce7e2015-02-13 13:57:09 -080075 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
Brian Osman2700abc2018-09-12 10:19:41 -040076 bmp[2].allocPixels(vinfo);
sugoi24dcac22014-07-07 15:09:48 -070077 unsigned char* pixels[3];
78 for (int i = 0; i < 3; ++i) {
Brian Osman2700abc2018-09-12 10:19:41 -040079 pixels[i] = (unsigned char*)bmp[i].getPixels();
sugoi24dcac22014-07-07 15:09:48 -070080 }
81 int color[] = {0, 85, 170};
82 const int limit[] = {255, 0, 255};
83 const int invl[] = {0, 255, 0};
84 const int inc[] = {1, -1, 1};
sugoi4ccce7e2015-02-13 13:57:09 -080085 for (int i = 0; i < 3; ++i) {
Brian Osman2700abc2018-09-12 10:19:41 -040086 const size_t nbBytes = bmp[i].rowBytes() * bmp[i].height();
sugoi4ccce7e2015-02-13 13:57:09 -080087 for (size_t j = 0; j < nbBytes; ++j) {
sugoi24dcac22014-07-07 15:09:48 -070088 pixels[i][j] = (unsigned char)color[i];
89 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
90 }
91 }
Brian Osman2700abc2018-09-12 10:19:41 -040092 for (int i = 0; i < 3; ++i) {
93 fImage[i] = SkImage::MakeFromBitmap(bmp[i]);
94 }
sugoi24dcac22014-07-07 15:09:48 -070095 }
96
Chris Dalton50e24d72019-02-07 16:20:09 -070097 DrawResult onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
98 SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips9da87e02019-02-04 13:26:26 -050099 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Robert Phillips94ade752018-10-09 12:32:31 -0400100 sk_sp<GrTextureProxy> proxies[3];
bsalomonbcf0a522014-10-08 08:40:09 -0700101
Brian Salomon2a4f9832018-03-03 22:43:43 -0500102 for (int i = 0; i < 3; ++i) {
Brian Salomon96b383a2019-08-13 16:55:41 -0400103 proxies[i] = proxyProvider->createTextureProxy(fImage[i], 1, SkBudgeted::kYes,
104 SkBackingFit::kExact);
Robert Phillips94ade752018-10-09 12:32:31 -0400105 if (!proxies[i]) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700106 *errorMsg = "Failed to create proxy";
107 return DrawResult::kFail;
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500108 }
sugoi24dcac22014-07-07 15:09:48 -0700109 }
110
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500111 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
Brian Osman2700abc2018-09-12 10:19:41 -0400112 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fImage[0]->width()),
113 SkIntToScalar(fImage[0]->height()));
bsalomonbcf0a522014-10-08 08:40:09 -0700114 renderRect.outset(kDrawPad, kDrawPad);
sugoi24dcac22014-07-07 15:09:48 -0700115
bsalomonbcf0a522014-10-08 08:40:09 -0700116 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
117 SkScalar x = kDrawPad + kTestPad;
sugoi24dcac22014-07-07 15:09:48 -0700118
bsalomonbcf0a522014-10-08 08:40:09 -0700119 const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
120 {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
sugoi24dcac22014-07-07 15:09:48 -0700121
bsalomonbcf0a522014-10-08 08:40:09 -0700122 for (int i = 0; i < 6; ++i) {
Robert Phillips94ade752018-10-09 12:32:31 -0400123 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips6ba8c832018-10-10 11:43:01 -0400124 { indices[i][0], SkColorChannel::kR },
125 { indices[i][1], SkColorChannel::kR },
126 { indices[i][2], SkColorChannel::kR },
Robert Phillips94ade752018-10-09 12:32:31 -0400127 { -1, SkColorChannel::kA }
128 };
Brian Salomonca6b2f42020-01-24 11:31:21 -0500129 const auto& caps = *context->priv().caps();
130 std::unique_ptr<GrFragmentProcessor> fp(GrYUVtoRGBEffect::Make(
131 proxies, yuvaIndices, static_cast<SkYUVColorSpace>(space),
132 GrSamplerState::Filter::kNearest, caps));
bsalomonbcf0a522014-10-08 08:40:09 -0700133 if (fp) {
Brian Salomon82f44312017-01-11 13:42:54 -0500134 GrPaint grPaint;
135 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
136 grPaint.addColorFragmentProcessor(std::move(fp));
bsalomonbcf0a522014-10-08 08:40:09 -0700137 SkMatrix viewMatrix;
138 viewMatrix.setTranslate(x, y);
Brian Salomonac70f842017-05-08 10:43:33 -0400139 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400140 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
141 viewMatrix, renderRect));
bsalomonbcf0a522014-10-08 08:40:09 -0700142 }
143 x += renderRect.width() + kTestPad;
144 }
sugoi24dcac22014-07-07 15:09:48 -0700145 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700146 return DrawResult::kOk;
bsalomonbcf0a522014-10-08 08:40:09 -0700147 }
sugoi24dcac22014-07-07 15:09:48 -0700148
149private:
Brian Osman2700abc2018-09-12 10:19:41 -0400150 sk_sp<SkImage> fImage[3];
sugoi24dcac22014-07-07 15:09:48 -0700151
Robert Phillips0a22ba82019-03-06 12:36:47 -0500152 static constexpr SkScalar kDrawPad = 10.f;
153 static constexpr SkScalar kTestPad = 10.f;
154 static constexpr SkScalar kColorSpaceOffset = 36.f;
155
sugoi24dcac22014-07-07 15:09:48 -0700156 typedef GM INHERITED;
157};
158
halcanary385fe4d2015-08-26 13:07:48 -0700159DEF_GM(return new YUVtoRGBEffect;)
jbaumanb445a572016-06-09 13:24:48 -0700160
161//////////////////////////////////////////////////////////////////////////////
162
Chris Dalton3a778372019-02-07 15:23:36 -0700163class YUVNV12toRGBEffect : public GpuGM {
jbaumanb445a572016-06-09 13:24:48 -0700164public:
165 YUVNV12toRGBEffect() {
166 this->setBGColor(0xFFFFFFFF);
167 }
168
169protected:
170 SkString onShortName() override {
171 return SkString("yuv_nv12_to_rgb_effect");
172 }
173
174 SkISize onISize() override {
Robert Phillips0a22ba82019-03-06 12:36:47 -0500175 int numRows = kLastEnum_SkYUVColorSpace + 1;
176 return SkISize::Make(48, kDrawPad + numRows * kColorSpaceOffset);
jbaumanb445a572016-06-09 13:24:48 -0700177 }
178
179 void onOnceBeforeDraw() override {
Brian Osman2700abc2018-09-12 10:19:41 -0400180 SkBitmap bmp[2];
jbaumanb445a572016-06-09 13:24:48 -0700181 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Brian Osman2700abc2018-09-12 10:19:41 -0400182 bmp[0].allocPixels(yinfo);
jbaumanb445a572016-06-09 13:24:48 -0700183 SkImageInfo uvinfo = SkImageInfo::MakeN32Premul(USIZE, USIZE);
Brian Osman2700abc2018-09-12 10:19:41 -0400184 bmp[1].allocPixels(uvinfo);
jbaumanb445a572016-06-09 13:24:48 -0700185 int color[] = {0, 85, 170};
186 const int limit[] = {255, 0, 255};
187 const int invl[] = {0, 255, 0};
188 const int inc[] = {1, -1, 1};
189
190 {
Brian Osman2700abc2018-09-12 10:19:41 -0400191 unsigned char* pixels = (unsigned char*)bmp[0].getPixels();
192 const size_t nbBytes = bmp[0].rowBytes() * bmp[0].height();
jbaumanb445a572016-06-09 13:24:48 -0700193 for (size_t j = 0; j < nbBytes; ++j) {
194 pixels[j] = (unsigned char)color[0];
195 color[0] = (color[0] == limit[0]) ? invl[0] : color[0] + inc[0];
196 }
197 }
198
199 {
Brian Osman2700abc2018-09-12 10:19:41 -0400200 for (int y = 0; y < bmp[1].height(); ++y) {
201 uint32_t* pixels = bmp[1].getAddr32(0, y);
202 for (int j = 0; j < bmp[1].width(); ++j) {
jbaumanb445a572016-06-09 13:24:48 -0700203 pixels[j] = SkColorSetARGB(0, color[1], color[2], 0);
204 color[1] = (color[1] == limit[1]) ? invl[1] : color[1] + inc[1];
205 color[2] = (color[2] == limit[2]) ? invl[2] : color[2] + inc[2];
206 }
207 }
208 }
Brian Osman2700abc2018-09-12 10:19:41 -0400209
210 for (int i = 0; i < 2; ++i) {
211 fImage[i] = SkImage::MakeFromBitmap(bmp[i]);
212 }
jbaumanb445a572016-06-09 13:24:48 -0700213 }
214
Chris Dalton50e24d72019-02-07 16:20:09 -0700215 DrawResult onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
216 SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips9da87e02019-02-04 13:26:26 -0500217 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Robert Phillips94ade752018-10-09 12:32:31 -0400218 sk_sp<GrTextureProxy> proxies[2];
jbaumanb445a572016-06-09 13:24:48 -0700219
Robert Phillips94ade752018-10-09 12:32:31 -0400220 for (int i = 0; i < 2; ++i) {
Brian Salomon96b383a2019-08-13 16:55:41 -0400221 proxies[i] = proxyProvider->createTextureProxy(fImage[i], 1, SkBudgeted::kYes,
222 SkBackingFit::kExact);
Robert Phillips94ade752018-10-09 12:32:31 -0400223 if (!proxies[i]) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700224 *errorMsg = "Failed to create proxy";
225 return DrawResult::kFail;
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500226 }
jbaumanb445a572016-06-09 13:24:48 -0700227 }
228
Robert Phillips94ade752018-10-09 12:32:31 -0400229 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips6ba8c832018-10-10 11:43:01 -0400230 { 0, SkColorChannel::kR },
Robert Phillips94ade752018-10-09 12:32:31 -0400231 { 1, SkColorChannel::kR },
232 { 1, SkColorChannel::kG },
233 { -1, SkColorChannel::kA }
234 };
235
jbaumanb445a572016-06-09 13:24:48 -0700236 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
Brian Osman2700abc2018-09-12 10:19:41 -0400237 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fImage[0]->width()),
238 SkIntToScalar(fImage[0]->height()));
jbaumanb445a572016-06-09 13:24:48 -0700239 renderRect.outset(kDrawPad, kDrawPad);
240
241 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
242 SkScalar x = kDrawPad + kTestPad;
243
robertphillips28a838e2016-06-23 14:07:00 -0700244 GrPaint grPaint;
Brian Salomona1633922017-01-09 11:46:10 -0500245 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonca6b2f42020-01-24 11:31:21 -0500246 const auto& caps = *context->priv().caps();
Robert Phillips94ade752018-10-09 12:32:31 -0400247 auto fp = GrYUVtoRGBEffect::Make(proxies, yuvaIndices,
Jim Van Verth30e0d7f2018-11-02 13:36:42 -0400248 static_cast<SkYUVColorSpace>(space),
Brian Salomonca6b2f42020-01-24 11:31:21 -0500249 GrSamplerState::Filter::kNearest, caps);
jbaumanb445a572016-06-09 13:24:48 -0700250 if (fp) {
251 SkMatrix viewMatrix;
252 viewMatrix.setTranslate(x, y);
Brian Salomonaff329b2017-08-11 09:40:37 -0400253 grPaint.addColorFragmentProcessor(std::move(fp));
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400254 std::unique_ptr<GrDrawOp> op(GrFillRectOp::MakeNonAARect(
255 context, std::move(grPaint), viewMatrix, renderRect));
Robert Phillips09dfc472017-09-13 15:25:47 -0400256 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
jbaumanb445a572016-06-09 13:24:48 -0700257 }
258 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700259 return DrawResult::kOk;
jbaumanb445a572016-06-09 13:24:48 -0700260 }
261
262private:
Brian Osman2700abc2018-09-12 10:19:41 -0400263 sk_sp<SkImage> fImage[2];
jbaumanb445a572016-06-09 13:24:48 -0700264
Robert Phillips0a22ba82019-03-06 12:36:47 -0500265 static constexpr SkScalar kDrawPad = 10.f;
266 static constexpr SkScalar kTestPad = 10.f;
267 static constexpr SkScalar kColorSpaceOffset = 36.f;
268
jbaumanb445a572016-06-09 13:24:48 -0700269 typedef GM INHERITED;
270};
271
272DEF_GM(return new YUVNV12toRGBEffect;)
Michael Ludwiga6a84002019-04-12 15:03:02 -0400273
274//////////////////////////////////////////////////////////////////////////////
275
276// This GM tests domain clamping on YUV multiplanar images where the U and V
277// planes have different resolution from Y. See skbug:8959
278
279class YUVtoRGBDomainEffect : public GpuGM {
280public:
281 YUVtoRGBDomainEffect() {
282 this->setBGColor(0xFFFFFFFF);
283 }
284
285protected:
286 SkString onShortName() override {
287 return SkString("yuv_to_rgb_domain_effect");
288 }
289
290 SkISize onISize() override {
291 return SkISize::Make((YSIZE + kTestPad) * 3 + kDrawPad, (YSIZE + kTestPad) * 2 + kDrawPad);
292 }
293
294 void onOnceBeforeDraw() override {
295 SkBitmap bmp[3];
296 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
297 bmp[0].allocPixels(yinfo);
298 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
299 bmp[1].allocPixels(uinfo);
300 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
301 bmp[2].allocPixels(vinfo);
302
303 int innerColor[] = {149, 43, 21};
304 int outerColor[] = {128, 128, 128};
305 for (int i = 0; i < 3; ++i) {
306 bmp[i].eraseColor(SkColorSetARGB(outerColor[i], 0, 0, 0));
307 SkIRect innerRect = i == 0 ? SkIRect::MakeLTRB(2, 2, 6, 6) : SkIRect::MakeLTRB(1, 1, 3, 3);
308 bmp[i].erase(SkColorSetARGB(innerColor[i], 0, 0, 0), innerRect);
309 fImage[i] = SkImage::MakeFromBitmap(bmp[i]);
310 }
311 }
312
313 DrawResult onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
314 SkCanvas* canvas, SkString* errorMsg) override {
315 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
316 sk_sp<GrTextureProxy> proxies[3];
317
318 for (int i = 0; i < 3; ++i) {
Brian Salomon96b383a2019-08-13 16:55:41 -0400319 proxies[i] = proxyProvider->createTextureProxy(fImage[i], 1, SkBudgeted::kYes,
320 SkBackingFit::kExact);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400321 if (!proxies[i]) {
322 *errorMsg = "Failed to create proxy";
323 return DrawResult::kFail;
324 }
325 }
326
327 // Draw a 2x2 grid of the YUV images.
328 // Rows = kNearest, kBilerp, Cols = No clamp, clamp
329 static const GrSamplerState::Filter kFilters[] = {
330 GrSamplerState::Filter::kNearest, GrSamplerState::Filter::kBilerp };
331 static const SkRect kGreenRect = SkRect::MakeLTRB(2.f, 2.f, 6.f, 6.f);
332
333 SkYUVAIndex yuvaIndices[4] = {
334 { SkYUVAIndex::kY_Index, SkColorChannel::kR },
335 { SkYUVAIndex::kU_Index, SkColorChannel::kR },
336 { SkYUVAIndex::kV_Index, SkColorChannel::kR },
337 { -1, SkColorChannel::kA }
338 };
339 SkRect rect = SkRect::MakeWH(YSIZE, YSIZE);
340
341 SkScalar y = kDrawPad + kTestPad;
342 for (uint32_t i = 0; i < SK_ARRAY_COUNT(kFilters); ++i) {
343 SkScalar x = kDrawPad + kTestPad;
344
345 for (uint32_t j = 0; j < 2; ++j) {
346 SkMatrix ctm = SkMatrix::MakeTrans(x, y);
347 ctm.postScale(10.f, 10.f);
348
349 SkRect domain = kGreenRect;
350 if (kFilters[i] == GrSamplerState::Filter::kNearest) {
351 // Make a very small inset for nearest-neighbor filtering so that 0.5px
352 // centers don't round out beyond the green pixels.
353 domain.inset(0.01f, 0.01f);
354 }
355
356 const SkRect* domainPtr = j > 0 ? &domain : nullptr;
Brian Salomonca6b2f42020-01-24 11:31:21 -0500357 const auto& caps = *context->priv().caps();
358 std::unique_ptr<GrFragmentProcessor> fp(
359 GrYUVtoRGBEffect::Make(proxies, yuvaIndices, kJPEG_SkYUVColorSpace,
360 kFilters[i], caps, SkMatrix::I(), domainPtr));
Michael Ludwiga6a84002019-04-12 15:03:02 -0400361 if (fp) {
362 GrPaint grPaint;
363 grPaint.addColorFragmentProcessor(std::move(fp));
364 renderTargetContext->drawRect(
365 GrNoClip(), std::move(grPaint), GrAA::kYes, ctm, rect);
366 }
367 x += rect.width() + kTestPad;
368 }
369
370 y += rect.height() + kTestPad;
371 }
372
373 return DrawResult::kOk;
374 }
375
376private:
377 sk_sp<SkImage> fImage[3];
378
379 static constexpr SkScalar kDrawPad = 10.f;
380 static constexpr SkScalar kTestPad = 10.f;
381
382 typedef GM INHERITED;
383};
384
385DEF_GM(return new YUVtoRGBDomainEffect;)
sugoi24dcac22014-07-07 15:09:48 -0700386}