blob: 9133fca4e04c705a252604b5ea0f5ab8faf14a9c [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"
Greg Daniel6f5441a2020-01-28 17:02:49 -050026#include "src/gpu/GrBitmapTextureMaker.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "src/gpu/GrContextPriv.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040028#include "src/gpu/GrFragmentProcessor.h"
29#include "src/gpu/GrPaint.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040030#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050031#include "src/gpu/GrRenderTargetContextPriv.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040032#include "src/gpu/GrSamplerState.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040033#include "src/gpu/GrTextureProxy.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040034#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050035#include "src/gpu/effects/GrYUVtoRGBEffect.h"
36#include "src/gpu/ops/GrDrawOp.h"
37#include "src/gpu/ops/GrFillRectOp.h"
sugoi24dcac22014-07-07 15:09:48 -070038
Ben Wagner7fde8e12019-05-01 17:28:53 -040039#include <memory>
40#include <utility>
41
42class SkCanvas;
43
sugoi4ccce7e2015-02-13 13:57:09 -080044#define YSIZE 8
45#define USIZE 4
46#define VSIZE 4
47
sugoi24dcac22014-07-07 15:09:48 -070048namespace skiagm {
49/**
50 * This GM directly exercises GrYUVtoRGBEffect.
51 */
Chris Dalton3a778372019-02-07 15:23:36 -070052class YUVtoRGBEffect : public GpuGM {
sugoi24dcac22014-07-07 15:09:48 -070053public:
54 YUVtoRGBEffect() {
55 this->setBGColor(0xFFFFFFFF);
56 }
57
58protected:
mtklein36352bf2015-03-25 18:17:31 -070059 SkString onShortName() override {
sugoi24dcac22014-07-07 15:09:48 -070060 return SkString("yuv_to_rgb_effect");
61 }
62
mtklein36352bf2015-03-25 18:17:31 -070063 SkISize onISize() override {
Robert Phillips0a22ba82019-03-06 12:36:47 -050064 int numRows = kLastEnum_SkYUVColorSpace + 1;
65 return SkISize::Make(238, kDrawPad + numRows * kColorSpaceOffset);
sugoi24dcac22014-07-07 15:09:48 -070066 }
67
mtklein36352bf2015-03-25 18:17:31 -070068 void onOnceBeforeDraw() override {
sugoi4ccce7e2015-02-13 13:57:09 -080069 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -050070 fBitmaps[0].allocPixels(yinfo);
sugoi4ccce7e2015-02-13 13:57:09 -080071 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -050072 fBitmaps[1].allocPixels(uinfo);
sugoi4ccce7e2015-02-13 13:57:09 -080073 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -050074 fBitmaps[2].allocPixels(vinfo);
sugoi24dcac22014-07-07 15:09:48 -070075 unsigned char* pixels[3];
76 for (int i = 0; i < 3; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -050077 pixels[i] = (unsigned char*)fBitmaps[i].getPixels();
sugoi24dcac22014-07-07 15:09:48 -070078 }
79 int color[] = {0, 85, 170};
80 const int limit[] = {255, 0, 255};
81 const int invl[] = {0, 255, 0};
82 const int inc[] = {1, -1, 1};
sugoi4ccce7e2015-02-13 13:57:09 -080083 for (int i = 0; i < 3; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -050084 const size_t nbBytes = fBitmaps[i].rowBytes() * fBitmaps[i].height();
sugoi4ccce7e2015-02-13 13:57:09 -080085 for (size_t j = 0; j < nbBytes; ++j) {
sugoi24dcac22014-07-07 15:09:48 -070086 pixels[i][j] = (unsigned char)color[i];
87 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
88 }
89 }
Brian Osman2700abc2018-09-12 10:19:41 -040090 for (int i = 0; i < 3; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -050091 fBitmaps[i].setImmutable();
Brian Osman2700abc2018-09-12 10:19:41 -040092 }
sugoi24dcac22014-07-07 15:09:48 -070093 }
94
Robert Phillips95c250c2020-06-29 15:36:12 -040095 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Chris Dalton50e24d72019-02-07 16:20:09 -070096 SkCanvas* canvas, SkString* errorMsg) override {
Greg Danielc7672092020-02-06 14:32:54 -050097 GrSurfaceProxyView views[3];
bsalomonbcf0a522014-10-08 08:40:09 -070098
Brian Salomon2a4f9832018-03-03 22:43:43 -050099 for (int i = 0; i < 3; ++i) {
Brian Salomonbc074a62020-03-18 10:06:13 -0400100 GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500101 views[i] = maker.view(GrMipMapped::kNo);
Greg Danielc7672092020-02-06 14:32:54 -0500102 if (!views[i]) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700103 *errorMsg = "Failed to create proxy";
104 return DrawResult::kFail;
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500105 }
sugoi24dcac22014-07-07 15:09:48 -0700106 }
107
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500108 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500109 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBitmaps[0].width()),
110 SkIntToScalar(fBitmaps[0].height()));
bsalomonbcf0a522014-10-08 08:40:09 -0700111 renderRect.outset(kDrawPad, kDrawPad);
sugoi24dcac22014-07-07 15:09:48 -0700112
bsalomonbcf0a522014-10-08 08:40:09 -0700113 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
114 SkScalar x = kDrawPad + kTestPad;
sugoi24dcac22014-07-07 15:09:48 -0700115
bsalomonbcf0a522014-10-08 08:40:09 -0700116 const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
117 {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
sugoi24dcac22014-07-07 15:09:48 -0700118
bsalomonbcf0a522014-10-08 08:40:09 -0700119 for (int i = 0; i < 6; ++i) {
Robert Phillips94ade752018-10-09 12:32:31 -0400120 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips6ba8c832018-10-10 11:43:01 -0400121 { indices[i][0], SkColorChannel::kR },
122 { indices[i][1], SkColorChannel::kR },
123 { indices[i][2], SkColorChannel::kR },
Robert Phillips94ade752018-10-09 12:32:31 -0400124 { -1, SkColorChannel::kA }
125 };
Brian Salomonca6b2f42020-01-24 11:31:21 -0500126 const auto& caps = *context->priv().caps();
127 std::unique_ptr<GrFragmentProcessor> fp(GrYUVtoRGBEffect::Make(
Greg Danielc7672092020-02-06 14:32:54 -0500128 views, yuvaIndices, static_cast<SkYUVColorSpace>(space),
Brian Salomonca6b2f42020-01-24 11:31:21 -0500129 GrSamplerState::Filter::kNearest, caps));
bsalomonbcf0a522014-10-08 08:40:09 -0700130 if (fp) {
Brian Salomon82f44312017-01-11 13:42:54 -0500131 GrPaint grPaint;
132 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
133 grPaint.addColorFragmentProcessor(std::move(fp));
bsalomonbcf0a522014-10-08 08:40:09 -0700134 SkMatrix viewMatrix;
135 viewMatrix.setTranslate(x, y);
Brian Salomonac70f842017-05-08 10:43:33 -0400136 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400137 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
138 viewMatrix, renderRect));
bsalomonbcf0a522014-10-08 08:40:09 -0700139 }
140 x += renderRect.width() + kTestPad;
141 }
sugoi24dcac22014-07-07 15:09:48 -0700142 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700143 return DrawResult::kOk;
bsalomonbcf0a522014-10-08 08:40:09 -0700144 }
sugoi24dcac22014-07-07 15:09:48 -0700145
146private:
Greg Daniel6f5441a2020-01-28 17:02:49 -0500147 SkBitmap fBitmaps[3];
sugoi24dcac22014-07-07 15:09:48 -0700148
Robert Phillips0a22ba82019-03-06 12:36:47 -0500149 static constexpr SkScalar kDrawPad = 10.f;
150 static constexpr SkScalar kTestPad = 10.f;
151 static constexpr SkScalar kColorSpaceOffset = 36.f;
152
sugoi24dcac22014-07-07 15:09:48 -0700153 typedef GM INHERITED;
154};
155
halcanary385fe4d2015-08-26 13:07:48 -0700156DEF_GM(return new YUVtoRGBEffect;)
jbaumanb445a572016-06-09 13:24:48 -0700157
158//////////////////////////////////////////////////////////////////////////////
159
Chris Dalton3a778372019-02-07 15:23:36 -0700160class YUVNV12toRGBEffect : public GpuGM {
jbaumanb445a572016-06-09 13:24:48 -0700161public:
162 YUVNV12toRGBEffect() {
163 this->setBGColor(0xFFFFFFFF);
164 }
165
166protected:
167 SkString onShortName() override {
168 return SkString("yuv_nv12_to_rgb_effect");
169 }
170
171 SkISize onISize() override {
Robert Phillips0a22ba82019-03-06 12:36:47 -0500172 int numRows = kLastEnum_SkYUVColorSpace + 1;
173 return SkISize::Make(48, kDrawPad + numRows * kColorSpaceOffset);
jbaumanb445a572016-06-09 13:24:48 -0700174 }
175
176 void onOnceBeforeDraw() override {
177 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500178 fBitmaps[0].allocPixels(yinfo);
jbaumanb445a572016-06-09 13:24:48 -0700179 SkImageInfo uvinfo = SkImageInfo::MakeN32Premul(USIZE, USIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500180 fBitmaps[1].allocPixels(uvinfo);
jbaumanb445a572016-06-09 13:24:48 -0700181 int color[] = {0, 85, 170};
182 const int limit[] = {255, 0, 255};
183 const int invl[] = {0, 255, 0};
184 const int inc[] = {1, -1, 1};
185
186 {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500187 unsigned char* pixels = (unsigned char*)fBitmaps[0].getPixels();
188 const size_t nbBytes = fBitmaps[0].rowBytes() * fBitmaps[0].height();
jbaumanb445a572016-06-09 13:24:48 -0700189 for (size_t j = 0; j < nbBytes; ++j) {
190 pixels[j] = (unsigned char)color[0];
191 color[0] = (color[0] == limit[0]) ? invl[0] : color[0] + inc[0];
192 }
193 }
194
195 {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500196 for (int y = 0; y < fBitmaps[1].height(); ++y) {
197 uint32_t* pixels = fBitmaps[1].getAddr32(0, y);
198 for (int j = 0; j < fBitmaps[1].width(); ++j) {
jbaumanb445a572016-06-09 13:24:48 -0700199 pixels[j] = SkColorSetARGB(0, color[1], color[2], 0);
200 color[1] = (color[1] == limit[1]) ? invl[1] : color[1] + inc[1];
201 color[2] = (color[2] == limit[2]) ? invl[2] : color[2] + inc[2];
202 }
203 }
204 }
Brian Osman2700abc2018-09-12 10:19:41 -0400205
206 for (int i = 0; i < 2; ++i) {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500207 fBitmaps[i].setImmutable();
Brian Osman2700abc2018-09-12 10:19:41 -0400208 }
jbaumanb445a572016-06-09 13:24:48 -0700209 }
210
Robert Phillips95c250c2020-06-29 15:36:12 -0400211 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Chris Dalton50e24d72019-02-07 16:20:09 -0700212 SkCanvas* canvas, SkString* errorMsg) override {
Greg Danielc7672092020-02-06 14:32:54 -0500213 GrSurfaceProxyView views[2];
jbaumanb445a572016-06-09 13:24:48 -0700214
Robert Phillips94ade752018-10-09 12:32:31 -0400215 for (int i = 0; i < 2; ++i) {
Brian Salomonbc074a62020-03-18 10:06:13 -0400216 GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500217 views[i] = maker.view(GrMipMapped::kNo);
Greg Danielc7672092020-02-06 14:32:54 -0500218 if (!views[i]) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700219 *errorMsg = "Failed to create proxy";
220 return DrawResult::kFail;
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500221 }
jbaumanb445a572016-06-09 13:24:48 -0700222 }
223
Robert Phillips94ade752018-10-09 12:32:31 -0400224 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips6ba8c832018-10-10 11:43:01 -0400225 { 0, SkColorChannel::kR },
Robert Phillips94ade752018-10-09 12:32:31 -0400226 { 1, SkColorChannel::kR },
227 { 1, SkColorChannel::kG },
228 { -1, SkColorChannel::kA }
229 };
230
jbaumanb445a572016-06-09 13:24:48 -0700231 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
Greg Daniel6f5441a2020-01-28 17:02:49 -0500232 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBitmaps[0].width()),
233 SkIntToScalar(fBitmaps[0].height()));
jbaumanb445a572016-06-09 13:24:48 -0700234 renderRect.outset(kDrawPad, kDrawPad);
235
236 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
237 SkScalar x = kDrawPad + kTestPad;
238
robertphillips28a838e2016-06-23 14:07:00 -0700239 GrPaint grPaint;
Brian Salomona1633922017-01-09 11:46:10 -0500240 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonca6b2f42020-01-24 11:31:21 -0500241 const auto& caps = *context->priv().caps();
Greg Danielc7672092020-02-06 14:32:54 -0500242 auto fp = GrYUVtoRGBEffect::Make(views, yuvaIndices,
Jim Van Verth30e0d7f2018-11-02 13:36:42 -0400243 static_cast<SkYUVColorSpace>(space),
Brian Salomonca6b2f42020-01-24 11:31:21 -0500244 GrSamplerState::Filter::kNearest, caps);
jbaumanb445a572016-06-09 13:24:48 -0700245 if (fp) {
246 SkMatrix viewMatrix;
247 viewMatrix.setTranslate(x, y);
Brian Salomonaff329b2017-08-11 09:40:37 -0400248 grPaint.addColorFragmentProcessor(std::move(fp));
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400249 std::unique_ptr<GrDrawOp> op(GrFillRectOp::MakeNonAARect(
250 context, std::move(grPaint), viewMatrix, renderRect));
Robert Phillips09dfc472017-09-13 15:25:47 -0400251 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
jbaumanb445a572016-06-09 13:24:48 -0700252 }
253 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700254 return DrawResult::kOk;
jbaumanb445a572016-06-09 13:24:48 -0700255 }
256
257private:
Greg Daniel6f5441a2020-01-28 17:02:49 -0500258 SkBitmap fBitmaps[2];
jbaumanb445a572016-06-09 13:24:48 -0700259
Robert Phillips0a22ba82019-03-06 12:36:47 -0500260 static constexpr SkScalar kDrawPad = 10.f;
261 static constexpr SkScalar kTestPad = 10.f;
262 static constexpr SkScalar kColorSpaceOffset = 36.f;
263
jbaumanb445a572016-06-09 13:24:48 -0700264 typedef GM INHERITED;
265};
266
267DEF_GM(return new YUVNV12toRGBEffect;)
Michael Ludwiga6a84002019-04-12 15:03:02 -0400268
269//////////////////////////////////////////////////////////////////////////////
270
Brian Salomond71548a2020-02-29 19:43:30 -0500271// This GM tests subsetting YUV multiplanar images where the U and V
Michael Ludwiga6a84002019-04-12 15:03:02 -0400272// planes have different resolution from Y. See skbug:8959
273
Brian Salomond71548a2020-02-29 19:43:30 -0500274class YUVtoRGBSubsetEffect : public GpuGM {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400275public:
Brian Salomond71548a2020-02-29 19:43:30 -0500276 YUVtoRGBSubsetEffect() {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400277 this->setBGColor(0xFFFFFFFF);
278 }
279
280protected:
281 SkString onShortName() override {
Brian Salomond71548a2020-02-29 19:43:30 -0500282 return SkString("yuv_to_rgb_subset_effect");
Michael Ludwiga6a84002019-04-12 15:03:02 -0400283 }
284
Brian Salomond71548a2020-02-29 19:43:30 -0500285 SkISize onISize() override { return {1310, 540}; }
Michael Ludwiga6a84002019-04-12 15:03:02 -0400286
287 void onOnceBeforeDraw() override {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400288 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500289 fBitmaps[0].allocPixels(yinfo);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400290 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500291 fBitmaps[1].allocPixels(uinfo);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400292 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
Greg Daniel6f5441a2020-01-28 17:02:49 -0500293 fBitmaps[2].allocPixels(vinfo);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400294
Brian Salomonb9b13732020-06-25 11:13:49 -0400295 unsigned char innerY[16] = {149, 160, 130, 105,
296 160, 130, 105, 149,
297 130, 105, 149, 160,
298 105, 149, 160, 130};
Brian Salomond71548a2020-02-29 19:43:30 -0500299 unsigned char innerU[4] = {43, 75, 145, 200};
300 unsigned char innerV[4] = {88, 180, 200, 43};
301 int outerYUV[] = {128, 128, 128};
Michael Ludwiga6a84002019-04-12 15:03:02 -0400302 for (int i = 0; i < 3; ++i) {
Brian Salomond71548a2020-02-29 19:43:30 -0500303 fBitmaps[i].eraseColor(SkColorSetARGB(outerYUV[i], 0, 0, 0));
304 }
Brian Salomonb9b13732020-06-25 11:13:49 -0400305 SkPixmap innerYPM(SkImageInfo::MakeA8(4, 4), innerY, 4);
Brian Salomond71548a2020-02-29 19:43:30 -0500306 SkPixmap innerUPM(SkImageInfo::MakeA8(2, 2), innerU, 2);
307 SkPixmap innerVPM(SkImageInfo::MakeA8(2, 2), innerV, 2);
Brian Salomonb9b13732020-06-25 11:13:49 -0400308 fBitmaps[0].writePixels(innerYPM, 2, 2);
Brian Salomond71548a2020-02-29 19:43:30 -0500309 fBitmaps[1].writePixels(innerUPM, 1, 1);
310 fBitmaps[2].writePixels(innerVPM, 1, 1);
311 for (auto& fBitmap : fBitmaps) {
312 fBitmap.setImmutable();
Michael Ludwiga6a84002019-04-12 15:03:02 -0400313 }
314 }
315
Robert Phillips95c250c2020-06-29 15:36:12 -0400316 DrawResult onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Michael Ludwiga6a84002019-04-12 15:03:02 -0400317 SkCanvas* canvas, SkString* errorMsg) override {
Greg Danielc7672092020-02-06 14:32:54 -0500318 GrSurfaceProxyView views[3];
Michael Ludwiga6a84002019-04-12 15:03:02 -0400319
320 for (int i = 0; i < 3; ++i) {
Brian Salomonbc074a62020-03-18 10:06:13 -0400321 GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500322 views[i] = maker.view(GrMipMapped::kNo);
Greg Danielc7672092020-02-06 14:32:54 -0500323 if (!views[i]) {
Michael Ludwiga6a84002019-04-12 15:03:02 -0400324 *errorMsg = "Failed to create proxy";
325 return DrawResult::kFail;
326 }
327 }
328
Michael Ludwiga6a84002019-04-12 15:03:02 -0400329 static const GrSamplerState::Filter kFilters[] = {
330 GrSamplerState::Filter::kNearest, GrSamplerState::Filter::kBilerp };
Brian Salomond71548a2020-02-29 19:43:30 -0500331 static const SkRect kColorRect = SkRect::MakeLTRB(2.f, 2.f, 6.f, 6.f);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400332
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 };
Brian Salomond71548a2020-02-29 19:43:30 -0500339 // Outset to visualize wrap modes.
340 SkRect rect = SkRect::MakeWH(YSIZE, YSIZE).makeOutset(YSIZE/2, YSIZE/2);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400341
Brian Salomond71548a2020-02-29 19:43:30 -0500342 SkScalar y = kTestPad;
343 // Rows are filter modes.
Michael Ludwiga6a84002019-04-12 15:03:02 -0400344 for (uint32_t i = 0; i < SK_ARRAY_COUNT(kFilters); ++i) {
Brian Salomond71548a2020-02-29 19:43:30 -0500345 SkScalar x = kTestPad;
346 // Columns are non-subsetted followed by subsetted with each WrapMode in a row
347 for (uint32_t j = 0; j < GrSamplerState::kWrapModeCount + 1; ++j) {
Mike Reed1f607332020-05-21 12:11:27 -0400348 SkMatrix ctm = SkMatrix::Translate(x, y);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400349 ctm.postScale(10.f, 10.f);
350
Brian Salomond71548a2020-02-29 19:43:30 -0500351 const SkRect* subset = j > 0 ? &kColorRect : nullptr;
Michael Ludwiga6a84002019-04-12 15:03:02 -0400352
Brian Salomond71548a2020-02-29 19:43:30 -0500353 GrSamplerState samplerState;
354 samplerState.setFilterMode(kFilters[i]);
355 if (j > 0) {
356 auto wm = static_cast<GrSamplerState::WrapMode>(j - 1);
357 samplerState.setWrapModeX(wm);
358 samplerState.setWrapModeY(wm);
359 }
Brian Salomonca6b2f42020-01-24 11:31:21 -0500360 const auto& caps = *context->priv().caps();
361 std::unique_ptr<GrFragmentProcessor> fp(
Greg Danielc7672092020-02-06 14:32:54 -0500362 GrYUVtoRGBEffect::Make(views, yuvaIndices, kJPEG_SkYUVColorSpace,
Brian Salomond71548a2020-02-29 19:43:30 -0500363 samplerState, caps, SkMatrix::I(), subset));
Michael Ludwiga6a84002019-04-12 15:03:02 -0400364 if (fp) {
365 GrPaint grPaint;
366 grPaint.addColorFragmentProcessor(std::move(fp));
367 renderTargetContext->drawRect(
Michael Ludwig7c12e282020-05-29 09:54:07 -0400368 nullptr, std::move(grPaint), GrAA::kYes, ctm, rect);
Michael Ludwiga6a84002019-04-12 15:03:02 -0400369 }
370 x += rect.width() + kTestPad;
371 }
372
373 y += rect.height() + kTestPad;
374 }
375
376 return DrawResult::kOk;
377 }
378
379private:
Greg Daniel6f5441a2020-01-28 17:02:49 -0500380 SkBitmap fBitmaps[3];
Michael Ludwiga6a84002019-04-12 15:03:02 -0400381
Michael Ludwiga6a84002019-04-12 15:03:02 -0400382 static constexpr SkScalar kTestPad = 10.f;
383
384 typedef GM INHERITED;
385};
386
Brian Salomond71548a2020-02-29 19:43:30 -0500387DEF_GM(return new YUVtoRGBSubsetEffect;)
sugoi24dcac22014-07-07 15:09:48 -0700388}