blob: 166f12c872f2930801ec6f9e14ae50c4193d3004 [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"
Ben Wagner7fde8e12019-05-01 17:28:53 -040024#include "include/private/GrTypesPriv.h"
Greg Daniel6f5441a2020-01-28 17:02:49 -050025#include "src/gpu/GrBitmapTextureMaker.h"
Adlai Hollera0693042020-10-14 11:23:11 -040026#include "src/gpu/GrDirectContextPriv.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040027#include "src/gpu/GrFragmentProcessor.h"
28#include "src/gpu/GrPaint.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040029#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "src/gpu/GrRenderTargetContextPriv.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040031#include "src/gpu/GrSamplerState.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040032#include "src/gpu/GrTextureProxy.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040033#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050034#include "src/gpu/effects/GrYUVtoRGBEffect.h"
35#include "src/gpu/ops/GrDrawOp.h"
36#include "src/gpu/ops/GrFillRectOp.h"
sugoi24dcac22014-07-07 15:09:48 -070037
Ben Wagner7fde8e12019-05-01 17:28:53 -040038#include <memory>
39#include <utility>
40
41class SkCanvas;
42
sugoi4ccce7e2015-02-13 13:57:09 -080043#define YSIZE 8
44#define USIZE 4
45#define VSIZE 4
46
sugoi24dcac22014-07-07 15:09:48 -070047namespace skiagm {
48/**
49 * This GM directly exercises GrYUVtoRGBEffect.
50 */
Chris Dalton3a778372019-02-07 15:23:36 -070051class YUVtoRGBEffect : public GpuGM {
sugoi24dcac22014-07-07 15:09:48 -070052public:
53 YUVtoRGBEffect() {
54 this->setBGColor(0xFFFFFFFF);
55 }
56
57protected:
mtklein36352bf2015-03-25 18:17:31 -070058 SkString onShortName() override {
sugoi24dcac22014-07-07 15:09:48 -070059 return SkString("yuv_to_rgb_effect");
60 }
61
mtklein36352bf2015-03-25 18:17:31 -070062 SkISize onISize() override {
Robert Phillips0a22ba82019-03-06 12:36:47 -050063 int numRows = kLastEnum_SkYUVColorSpace + 1;
64 return SkISize::Make(238, kDrawPad + numRows * kColorSpaceOffset);
sugoi24dcac22014-07-07 15:09:48 -070065 }
66
mtklein36352bf2015-03-25 18:17:31 -070067 void onOnceBeforeDraw() override {
sugoi4ccce7e2015-02-13 13:57:09 -080068 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -050069 fBitmaps[0].allocPixels(yinfo);
sugoi4ccce7e2015-02-13 13:57:09 -080070 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -050071 fBitmaps[1].allocPixels(uinfo);
sugoi4ccce7e2015-02-13 13:57:09 -080072 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -050073 fBitmaps[2].allocPixels(vinfo);
sugoi24dcac22014-07-07 15:09:48 -070074 unsigned char* pixels[3];
75 for (int i = 0; i < 3; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -050076 pixels[i] = (unsigned char*)fBitmaps[i].getPixels();
sugoi24dcac22014-07-07 15:09:48 -070077 }
78 int color[] = {0, 85, 170};
79 const int limit[] = {255, 0, 255};
80 const int invl[] = {0, 255, 0};
81 const int inc[] = {1, -1, 1};
sugoi4ccce7e2015-02-13 13:57:09 -080082 for (int i = 0; i < 3; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -050083 const size_t nbBytes = fBitmaps[i].rowBytes() * fBitmaps[i].height();
sugoi4ccce7e2015-02-13 13:57:09 -080084 for (size_t j = 0; j < nbBytes; ++j) {
sugoi24dcac22014-07-07 15:09:48 -070085 pixels[i][j] = (unsigned char)color[i];
86 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
87 }
88 }
Brian Osman2700abc2018-09-12 10:19:41 -040089 for (int i = 0; i < 3; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -050090 fBitmaps[i].setImmutable();
Brian Osman2700abc2018-09-12 10:19:41 -040091 }
sugoi24dcac22014-07-07 15:09:48 -070092 }
93
Robert Phillips95c250c2020-06-29 15:36:12 -040094 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Chris Dalton50e24d72019-02-07 16:20:09 -070095 SkCanvas* canvas, SkString* errorMsg) override {
Greg Danielc7672092020-02-06 14:32:54 -050096 GrSurfaceProxyView views[3];
bsalomonbcf0a522014-10-08 08:40:09 -070097
Brian Salomon2a4f9832018-03-03 22:43:43 -050098 for (int i = 0; i < 3; ++i) {
Brian Salomonbc074a62020-03-18 10:06:13 -040099 GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
Brian Salomon7e67dca2020-07-21 09:27:25 -0400100 views[i] = maker.view(GrMipmapped::kNo);
Greg Danielc7672092020-02-06 14:32:54 -0500101 if (!views[i]) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700102 *errorMsg = "Failed to create proxy";
103 return DrawResult::kFail;
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500104 }
sugoi24dcac22014-07-07 15:09:48 -0700105 }
106
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500107 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500108 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBitmaps[0].width()),
109 SkIntToScalar(fBitmaps[0].height()));
bsalomonbcf0a522014-10-08 08:40:09 -0700110 renderRect.outset(kDrawPad, kDrawPad);
sugoi24dcac22014-07-07 15:09:48 -0700111
bsalomonbcf0a522014-10-08 08:40:09 -0700112 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
113 SkScalar x = kDrawPad + kTestPad;
sugoi24dcac22014-07-07 15:09:48 -0700114
bsalomonbcf0a522014-10-08 08:40:09 -0700115 const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
116 {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
sugoi24dcac22014-07-07 15:09:48 -0700117
bsalomonbcf0a522014-10-08 08:40:09 -0700118 for (int i = 0; i < 6; ++i) {
Robert Phillips94ade752018-10-09 12:32:31 -0400119 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips6ba8c832018-10-10 11:43:01 -0400120 { indices[i][0], SkColorChannel::kR },
121 { indices[i][1], SkColorChannel::kR },
122 { indices[i][2], SkColorChannel::kR },
Robert Phillips94ade752018-10-09 12:32:31 -0400123 { -1, SkColorChannel::kA }
124 };
Brian Salomonca6b2f42020-01-24 11:31:21 -0500125 const auto& caps = *context->priv().caps();
126 std::unique_ptr<GrFragmentProcessor> fp(GrYUVtoRGBEffect::Make(
Greg Danielc7672092020-02-06 14:32:54 -0500127 views, yuvaIndices, static_cast<SkYUVColorSpace>(space),
Brian Salomonca6b2f42020-01-24 11:31:21 -0500128 GrSamplerState::Filter::kNearest, caps));
bsalomonbcf0a522014-10-08 08:40:09 -0700129 if (fp) {
Brian Salomon82f44312017-01-11 13:42:54 -0500130 GrPaint grPaint;
131 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
John Stiles5933d7d2020-07-21 12:28:35 -0400132 grPaint.setColorFragmentProcessor(std::move(fp));
bsalomonbcf0a522014-10-08 08:40:09 -0700133 SkMatrix viewMatrix;
134 viewMatrix.setTranslate(x, y);
Brian Salomonac70f842017-05-08 10:43:33 -0400135 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400136 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
137 viewMatrix, renderRect));
bsalomonbcf0a522014-10-08 08:40:09 -0700138 }
139 x += renderRect.width() + kTestPad;
140 }
sugoi24dcac22014-07-07 15:09:48 -0700141 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700142 return DrawResult::kOk;
bsalomonbcf0a522014-10-08 08:40:09 -0700143 }
sugoi24dcac22014-07-07 15:09:48 -0700144
145private:
Greg Daniel6f5441a2020-01-28 17:02:49 -0500146 SkBitmap fBitmaps[3];
sugoi24dcac22014-07-07 15:09:48 -0700147
Robert Phillips0a22ba82019-03-06 12:36:47 -0500148 static constexpr SkScalar kDrawPad = 10.f;
149 static constexpr SkScalar kTestPad = 10.f;
150 static constexpr SkScalar kColorSpaceOffset = 36.f;
151
John Stiles7571f9e2020-09-02 22:42:33 -0400152 using INHERITED = GM;
sugoi24dcac22014-07-07 15:09:48 -0700153};
154
halcanary385fe4d2015-08-26 13:07:48 -0700155DEF_GM(return new YUVtoRGBEffect;)
jbaumanb445a572016-06-09 13:24:48 -0700156
157//////////////////////////////////////////////////////////////////////////////
158
Chris Dalton3a778372019-02-07 15:23:36 -0700159class YUVNV12toRGBEffect : public GpuGM {
jbaumanb445a572016-06-09 13:24:48 -0700160public:
161 YUVNV12toRGBEffect() {
162 this->setBGColor(0xFFFFFFFF);
163 }
164
165protected:
166 SkString onShortName() override {
167 return SkString("yuv_nv12_to_rgb_effect");
168 }
169
170 SkISize onISize() override {
Robert Phillips0a22ba82019-03-06 12:36:47 -0500171 int numRows = kLastEnum_SkYUVColorSpace + 1;
172 return SkISize::Make(48, kDrawPad + numRows * kColorSpaceOffset);
jbaumanb445a572016-06-09 13:24:48 -0700173 }
174
175 void onOnceBeforeDraw() override {
176 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500177 fBitmaps[0].allocPixels(yinfo);
jbaumanb445a572016-06-09 13:24:48 -0700178 SkImageInfo uvinfo = SkImageInfo::MakeN32Premul(USIZE, USIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500179 fBitmaps[1].allocPixels(uvinfo);
jbaumanb445a572016-06-09 13:24:48 -0700180 int color[] = {0, 85, 170};
181 const int limit[] = {255, 0, 255};
182 const int invl[] = {0, 255, 0};
183 const int inc[] = {1, -1, 1};
184
185 {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500186 unsigned char* pixels = (unsigned char*)fBitmaps[0].getPixels();
187 const size_t nbBytes = fBitmaps[0].rowBytes() * fBitmaps[0].height();
jbaumanb445a572016-06-09 13:24:48 -0700188 for (size_t j = 0; j < nbBytes; ++j) {
189 pixels[j] = (unsigned char)color[0];
190 color[0] = (color[0] == limit[0]) ? invl[0] : color[0] + inc[0];
191 }
192 }
193
194 {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500195 for (int y = 0; y < fBitmaps[1].height(); ++y) {
196 uint32_t* pixels = fBitmaps[1].getAddr32(0, y);
197 for (int j = 0; j < fBitmaps[1].width(); ++j) {
jbaumanb445a572016-06-09 13:24:48 -0700198 pixels[j] = SkColorSetARGB(0, color[1], color[2], 0);
199 color[1] = (color[1] == limit[1]) ? invl[1] : color[1] + inc[1];
200 color[2] = (color[2] == limit[2]) ? invl[2] : color[2] + inc[2];
201 }
202 }
203 }
Brian Osman2700abc2018-09-12 10:19:41 -0400204
205 for (int i = 0; i < 2; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500206 fBitmaps[i].setImmutable();
Brian Osman2700abc2018-09-12 10:19:41 -0400207 }
jbaumanb445a572016-06-09 13:24:48 -0700208 }
209
Robert Phillips95c250c2020-06-29 15:36:12 -0400210 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Chris Dalton50e24d72019-02-07 16:20:09 -0700211 SkCanvas* canvas, SkString* errorMsg) override {
Greg Danielc7672092020-02-06 14:32:54 -0500212 GrSurfaceProxyView views[2];
jbaumanb445a572016-06-09 13:24:48 -0700213
Robert Phillips94ade752018-10-09 12:32:31 -0400214 for (int i = 0; i < 2; ++i) {
Brian Salomonbc074a62020-03-18 10:06:13 -0400215 GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
Brian Salomon7e67dca2020-07-21 09:27:25 -0400216 views[i] = maker.view(GrMipmapped::kNo);
Greg Danielc7672092020-02-06 14:32:54 -0500217 if (!views[i]) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700218 *errorMsg = "Failed to create proxy";
219 return DrawResult::kFail;
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500220 }
jbaumanb445a572016-06-09 13:24:48 -0700221 }
222
Robert Phillips94ade752018-10-09 12:32:31 -0400223 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips6ba8c832018-10-10 11:43:01 -0400224 { 0, SkColorChannel::kR },
Robert Phillips94ade752018-10-09 12:32:31 -0400225 { 1, SkColorChannel::kR },
226 { 1, SkColorChannel::kG },
227 { -1, SkColorChannel::kA }
228 };
229
jbaumanb445a572016-06-09 13:24:48 -0700230 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500231 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBitmaps[0].width()),
232 SkIntToScalar(fBitmaps[0].height()));
jbaumanb445a572016-06-09 13:24:48 -0700233 renderRect.outset(kDrawPad, kDrawPad);
234
235 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
236 SkScalar x = kDrawPad + kTestPad;
237
robertphillips28a838e2016-06-23 14:07:00 -0700238 GrPaint grPaint;
Brian Salomona1633922017-01-09 11:46:10 -0500239 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonca6b2f42020-01-24 11:31:21 -0500240 const auto& caps = *context->priv().caps();
Greg Danielc7672092020-02-06 14:32:54 -0500241 auto fp = GrYUVtoRGBEffect::Make(views, yuvaIndices,
Jim Van Verth30e0d7f2018-11-02 13:36:42 -0400242 static_cast<SkYUVColorSpace>(space),
Brian Salomonca6b2f42020-01-24 11:31:21 -0500243 GrSamplerState::Filter::kNearest, caps);
jbaumanb445a572016-06-09 13:24:48 -0700244 if (fp) {
245 SkMatrix viewMatrix;
246 viewMatrix.setTranslate(x, y);
John Stiles5933d7d2020-07-21 12:28:35 -0400247 grPaint.setColorFragmentProcessor(std::move(fp));
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400248 std::unique_ptr<GrDrawOp> op(GrFillRectOp::MakeNonAARect(
249 context, std::move(grPaint), viewMatrix, renderRect));
Robert Phillips09dfc472017-09-13 15:25:47 -0400250 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
jbaumanb445a572016-06-09 13:24:48 -0700251 }
252 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700253 return DrawResult::kOk;
jbaumanb445a572016-06-09 13:24:48 -0700254 }
255
256private:
Greg Daniel6f5441a2020-01-28 17:02:49 -0500257 SkBitmap fBitmaps[2];
jbaumanb445a572016-06-09 13:24:48 -0700258
Robert Phillips0a22ba82019-03-06 12:36:47 -0500259 static constexpr SkScalar kDrawPad = 10.f;
260 static constexpr SkScalar kTestPad = 10.f;
261 static constexpr SkScalar kColorSpaceOffset = 36.f;
262
John Stiles7571f9e2020-09-02 22:42:33 -0400263 using INHERITED = GM;
jbaumanb445a572016-06-09 13:24:48 -0700264};
265
266DEF_GM(return new YUVNV12toRGBEffect;)
Michael Ludwiga6a84002019-04-12 15:03:02 -0400267
268//////////////////////////////////////////////////////////////////////////////
269
Brian Salomond71548a2020-02-29 19:43:30 -0500270// This GM tests subsetting YUV multiplanar images where the U and V
Michael Ludwiga6a84002019-04-12 15:03:02 -0400271// planes have different resolution from Y. See skbug:8959
272
Brian Salomond71548a2020-02-29 19:43:30 -0500273class YUVtoRGBSubsetEffect : public GpuGM {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400274public:
Brian Salomond71548a2020-02-29 19:43:30 -0500275 YUVtoRGBSubsetEffect() {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400276 this->setBGColor(0xFFFFFFFF);
277 }
278
279protected:
280 SkString onShortName() override {
Brian Salomond71548a2020-02-29 19:43:30 -0500281 return SkString("yuv_to_rgb_subset_effect");
Michael Ludwiga6a84002019-04-12 15:03:02 -0400282 }
283
Brian Salomond71548a2020-02-29 19:43:30 -0500284 SkISize onISize() override { return {1310, 540}; }
Michael Ludwiga6a84002019-04-12 15:03:02 -0400285
286 void onOnceBeforeDraw() override {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400287 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500288 fBitmaps[0].allocPixels(yinfo);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400289 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500290 fBitmaps[1].allocPixels(uinfo);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400291 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500292 fBitmaps[2].allocPixels(vinfo);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400293
Brian Salomonb9b13732020-06-25 11:13:49 -0400294 unsigned char innerY[16] = {149, 160, 130, 105,
295 160, 130, 105, 149,
296 130, 105, 149, 160,
297 105, 149, 160, 130};
Brian Salomond71548a2020-02-29 19:43:30 -0500298 unsigned char innerU[4] = {43, 75, 145, 200};
299 unsigned char innerV[4] = {88, 180, 200, 43};
300 int outerYUV[] = {128, 128, 128};
Michael Ludwiga6a84002019-04-12 15:03:02 -0400301 for (int i = 0; i < 3; ++i) {
Brian Salomond71548a2020-02-29 19:43:30 -0500302 fBitmaps[i].eraseColor(SkColorSetARGB(outerYUV[i], 0, 0, 0));
303 }
Brian Salomonb9b13732020-06-25 11:13:49 -0400304 SkPixmap innerYPM(SkImageInfo::MakeA8(4, 4), innerY, 4);
Brian Salomond71548a2020-02-29 19:43:30 -0500305 SkPixmap innerUPM(SkImageInfo::MakeA8(2, 2), innerU, 2);
306 SkPixmap innerVPM(SkImageInfo::MakeA8(2, 2), innerV, 2);
Brian Salomonb9b13732020-06-25 11:13:49 -0400307 fBitmaps[0].writePixels(innerYPM, 2, 2);
Brian Salomond71548a2020-02-29 19:43:30 -0500308 fBitmaps[1].writePixels(innerUPM, 1, 1);
309 fBitmaps[2].writePixels(innerVPM, 1, 1);
310 for (auto& fBitmap : fBitmaps) {
311 fBitmap.setImmutable();
Michael Ludwiga6a84002019-04-12 15:03:02 -0400312 }
313 }
314
Robert Phillips95c250c2020-06-29 15:36:12 -0400315 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Michael Ludwiga6a84002019-04-12 15:03:02 -0400316 SkCanvas* canvas, SkString* errorMsg) override {
Greg Danielc7672092020-02-06 14:32:54 -0500317 GrSurfaceProxyView views[3];
Michael Ludwiga6a84002019-04-12 15:03:02 -0400318
319 for (int i = 0; i < 3; ++i) {
Brian Salomonbc074a62020-03-18 10:06:13 -0400320 GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
Brian Salomon7e67dca2020-07-21 09:27:25 -0400321 views[i] = maker.view(GrMipmapped::kNo);
Greg Danielc7672092020-02-06 14:32:54 -0500322 if (!views[i]) {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400323 *errorMsg = "Failed to create proxy";
324 return DrawResult::kFail;
325 }
326 }
327
Brian Salomona3b02f52020-07-15 16:02:01 -0400328 static const GrSamplerState::Filter kFilters[] = {GrSamplerState::Filter::kNearest,
329 GrSamplerState::Filter::kLinear};
Brian Salomond71548a2020-02-29 19:43:30 -0500330 static const SkRect kColorRect = SkRect::MakeLTRB(2.f, 2.f, 6.f, 6.f);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400331
332 SkYUVAIndex yuvaIndices[4] = {
333 { SkYUVAIndex::kY_Index, SkColorChannel::kR },
334 { SkYUVAIndex::kU_Index, SkColorChannel::kR },
335 { SkYUVAIndex::kV_Index, SkColorChannel::kR },
336 { -1, SkColorChannel::kA }
337 };
Brian Salomond71548a2020-02-29 19:43:30 -0500338 // Outset to visualize wrap modes.
339 SkRect rect = SkRect::MakeWH(YSIZE, YSIZE).makeOutset(YSIZE/2, YSIZE/2);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400340
Brian Salomond71548a2020-02-29 19:43:30 -0500341 SkScalar y = kTestPad;
342 // Rows are filter modes.
Michael Ludwiga6a84002019-04-12 15:03:02 -0400343 for (uint32_t i = 0; i < SK_ARRAY_COUNT(kFilters); ++i) {
Brian Salomond71548a2020-02-29 19:43:30 -0500344 SkScalar x = kTestPad;
345 // Columns are non-subsetted followed by subsetted with each WrapMode in a row
346 for (uint32_t j = 0; j < GrSamplerState::kWrapModeCount + 1; ++j) {
Mike Reed1f607332020-05-21 12:11:27 -0400347 SkMatrix ctm = SkMatrix::Translate(x, y);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400348 ctm.postScale(10.f, 10.f);
349
Brian Salomond71548a2020-02-29 19:43:30 -0500350 const SkRect* subset = j > 0 ? &kColorRect : nullptr;
Michael Ludwiga6a84002019-04-12 15:03:02 -0400351
Brian Salomond71548a2020-02-29 19:43:30 -0500352 GrSamplerState samplerState;
353 samplerState.setFilterMode(kFilters[i]);
354 if (j > 0) {
355 auto wm = static_cast<GrSamplerState::WrapMode>(j - 1);
356 samplerState.setWrapModeX(wm);
357 samplerState.setWrapModeY(wm);
358 }
Brian Salomonca6b2f42020-01-24 11:31:21 -0500359 const auto& caps = *context->priv().caps();
360 std::unique_ptr<GrFragmentProcessor> fp(
Greg Danielc7672092020-02-06 14:32:54 -0500361 GrYUVtoRGBEffect::Make(views, yuvaIndices, kJPEG_SkYUVColorSpace,
Brian Salomond71548a2020-02-29 19:43:30 -0500362 samplerState, caps, SkMatrix::I(), subset));
Michael Ludwiga6a84002019-04-12 15:03:02 -0400363 if (fp) {
364 GrPaint grPaint;
John Stiles5933d7d2020-07-21 12:28:35 -0400365 grPaint.setColorFragmentProcessor(std::move(fp));
Michael Ludwiga6a84002019-04-12 15:03:02 -0400366 renderTargetContext->drawRect(
Michael Ludwig7c12e282020-05-29 09:54:07 -0400367 nullptr, std::move(grPaint), GrAA::kYes, ctm, rect);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400368 }
369 x += rect.width() + kTestPad;
370 }
371
372 y += rect.height() + kTestPad;
373 }
374
375 return DrawResult::kOk;
376 }
377
378private:
Greg Daniel6f5441a2020-01-28 17:02:49 -0500379 SkBitmap fBitmaps[3];
Michael Ludwiga6a84002019-04-12 15:03:02 -0400380
Michael Ludwiga6a84002019-04-12 15:03:02 -0400381 static constexpr SkScalar kTestPad = 10.f;
382
John Stiles7571f9e2020-09-02 22:42:33 -0400383 using INHERITED = GM;
Michael Ludwiga6a84002019-04-12 15:03:02 -0400384};
385
Brian Salomond71548a2020-02-29 19:43:30 -0500386DEF_GM(return new YUVtoRGBSubsetEffect;)
John Stilesa6841be2020-08-06 14:11:56 -0400387} // namespace skiagm