2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 // This test only works with the GPU backend.
14 #include "GrContext.h"
15 #include "GrRenderTargetContextPriv.h"
18 #include "SkGradientShader.h"
19 #include "batches/GrDrawOp.h"
20 #include "batches/GrRectBatchFactory.h"
21 #include "effects/GrYUVEffect.h"
29 * This GM directly exercises GrYUVtoRGBEffect.
31 class YUVtoRGBEffect : public GM {
34 this->setBGColor(0xFFFFFFFF);
38 SkString onShortName() override {
39 return SkString("yuv_to_rgb_effect");
42 SkISize onISize() override {
43 return SkISize::Make(238, 120);
46 void onOnceBeforeDraw() override {
47 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
48 fBmp[0].allocPixels(yinfo);
49 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
50 fBmp[1].allocPixels(uinfo);
51 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
52 fBmp[2].allocPixels(vinfo);
53 unsigned char* pixels[3];
54 for (int i = 0; i < 3; ++i) {
55 pixels[i] = (unsigned char*)fBmp[i].getPixels();
57 int color[] = {0, 85, 170};
58 const int limit[] = {255, 0, 255};
59 const int invl[] = {0, 255, 0};
60 const int inc[] = {1, -1, 1};
61 for (int i = 0; i < 3; ++i) {
62 const size_t nbBytes = fBmp[i].rowBytes() * fBmp[i].height();
63 for (size_t j = 0; j < nbBytes; ++j) {
64 pixels[i][j] = (unsigned char)color[i];
65 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
70 void onDraw(SkCanvas* canvas) override {
71 GrRenderTargetContext* renderTargetContext =
72 canvas->internal_private_accessTopLayerRenderTargetContext();
73 if (!renderTargetContext) {
74 skiagm::GM::DrawGpuOnlyMessage(canvas);
78 GrContext* context = canvas->getGrContext();
83 sk_sp<GrTexture> texture[3];
85 GrRefCachedBitmapTexture(context, fBmp[0], GrSamplerParams::ClampBilerp()));
87 GrRefCachedBitmapTexture(context, fBmp[1], GrSamplerParams::ClampBilerp()));
89 GrRefCachedBitmapTexture(context, fBmp[2], GrSamplerParams::ClampBilerp()));
91 if (!texture[0] || !texture[1] || !texture[2]) {
95 constexpr SkScalar kDrawPad = 10.f;
96 constexpr SkScalar kTestPad = 10.f;
97 constexpr SkScalar kColorSpaceOffset = 36.f;
98 SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
100 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace;
102 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
103 SkIntToScalar(fBmp[0].height()));
104 renderRect.outset(kDrawPad, kDrawPad);
106 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
107 SkScalar x = kDrawPad + kTestPad;
109 const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
110 {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
112 for (int i = 0; i < 6; ++i) {
114 grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc));
115 sk_sp<GrFragmentProcessor> fp(
116 GrYUVEffect::MakeYUVToRGB(texture[indices[i][0]].get(),
117 texture[indices[i][1]].get(),
118 texture[indices[i][2]].get(),
120 static_cast<SkYUVColorSpace>(space),
124 viewMatrix.setTranslate(x, y);
125 grPaint.addColorFragmentProcessor(std::move(fp));
126 sk_sp<GrDrawOp> batch(
127 GrRectBatchFactory::CreateNonAAFill(GrColor_WHITE, viewMatrix,
128 renderRect, nullptr, nullptr));
129 renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
131 x += renderRect.width() + kTestPad;
139 typedef GM INHERITED;
142 DEF_GM(return new YUVtoRGBEffect;)
144 //////////////////////////////////////////////////////////////////////////////
146 class YUVNV12toRGBEffect : public GM {
148 YUVNV12toRGBEffect() {
149 this->setBGColor(0xFFFFFFFF);
153 SkString onShortName() override {
154 return SkString("yuv_nv12_to_rgb_effect");
157 SkISize onISize() override {
158 return SkISize::Make(48, 120);
161 void onOnceBeforeDraw() override {
162 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
163 fBmp[0].allocPixels(yinfo);
164 SkImageInfo uvinfo = SkImageInfo::MakeN32Premul(USIZE, USIZE);
165 fBmp[1].allocPixels(uvinfo);
166 int color[] = {0, 85, 170};
167 const int limit[] = {255, 0, 255};
168 const int invl[] = {0, 255, 0};
169 const int inc[] = {1, -1, 1};
172 unsigned char* pixels = (unsigned char*)fBmp[0].getPixels();
173 const size_t nbBytes = fBmp[0].rowBytes() * fBmp[0].height();
174 for (size_t j = 0; j < nbBytes; ++j) {
175 pixels[j] = (unsigned char)color[0];
176 color[0] = (color[0] == limit[0]) ? invl[0] : color[0] + inc[0];
181 for (int y = 0; y < fBmp[1].height(); ++y) {
182 uint32_t* pixels = fBmp[1].getAddr32(0, y);
183 for (int j = 0; j < fBmp[1].width(); ++j) {
184 pixels[j] = SkColorSetARGB(0, color[1], color[2], 0);
185 color[1] = (color[1] == limit[1]) ? invl[1] : color[1] + inc[1];
186 color[2] = (color[2] == limit[2]) ? invl[2] : color[2] + inc[2];
192 void onDraw(SkCanvas* canvas) override {
193 GrRenderTargetContext* renderTargetContext =
194 canvas->internal_private_accessTopLayerRenderTargetContext();
195 if (!renderTargetContext) {
196 skiagm::GM::DrawGpuOnlyMessage(canvas);
200 GrContext* context = canvas->getGrContext();
205 sk_sp<GrTexture> texture[3];
207 GrRefCachedBitmapTexture(context, fBmp[0], GrSamplerParams::ClampBilerp()));
209 GrRefCachedBitmapTexture(context, fBmp[1], GrSamplerParams::ClampBilerp()));
211 GrRefCachedBitmapTexture(context, fBmp[1], GrSamplerParams::ClampBilerp()));
213 if (!texture[0] || !texture[1] || !texture[2]) {
217 constexpr SkScalar kDrawPad = 10.f;
218 constexpr SkScalar kTestPad = 10.f;
219 constexpr SkScalar kColorSpaceOffset = 36.f;
220 SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
222 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
224 SkRect::MakeWH(SkIntToScalar(fBmp[0].width()), SkIntToScalar(fBmp[0].height()));
225 renderRect.outset(kDrawPad, kDrawPad);
227 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
228 SkScalar x = kDrawPad + kTestPad;
231 grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc));
232 sk_sp<GrFragmentProcessor> fp(
233 GrYUVEffect::MakeYUVToRGB(texture[0].get(), texture[1].get(), texture[2].get(),
234 sizes, static_cast<SkYUVColorSpace>(space), true));
237 viewMatrix.setTranslate(x, y);
238 grPaint.addColorFragmentProcessor(fp);
239 sk_sp<GrDrawOp> batch(GrRectBatchFactory::CreateNonAAFill(
240 GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
241 renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
249 typedef GM INHERITED;
252 DEF_GM(return new YUVNV12toRGBEffect;)