• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
10 #include "gm.h"
11 
12 #if SK_SUPPORT_GPU
13 
14 #include "GrContext.h"
15 #include "GrContextPriv.h"
16 #include "GrProxyProvider.h"
17 #include "GrRenderTargetContextPriv.h"
18 #include "GrTextureProxy.h"
19 #include "SkBitmap.h"
20 #include "SkGr.h"
21 #include "SkGradientShader.h"
22 #include "effects/GrYUVtoRGBEffect.h"
23 #include "ops/GrDrawOp.h"
24 #include "ops/GrRectOpFactory.h"
25 
26 #define YSIZE 8
27 #define USIZE 4
28 #define VSIZE 4
29 
30 namespace skiagm {
31 /**
32  * This GM directly exercises GrYUVtoRGBEffect.
33  */
34 class YUVtoRGBEffect : public GM {
35 public:
YUVtoRGBEffect()36     YUVtoRGBEffect() {
37         this->setBGColor(0xFFFFFFFF);
38     }
39 
40 protected:
onShortName()41     SkString onShortName() override {
42         return SkString("yuv_to_rgb_effect");
43     }
44 
onISize()45     SkISize onISize() override {
46         return SkISize::Make(238, 120);
47     }
48 
onOnceBeforeDraw()49     void onOnceBeforeDraw() override {
50         SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
51         fBmp[0].allocPixels(yinfo);
52         SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
53         fBmp[1].allocPixels(uinfo);
54         SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
55         fBmp[2].allocPixels(vinfo);
56         unsigned char* pixels[3];
57         for (int i = 0; i < 3; ++i) {
58             pixels[i] = (unsigned char*)fBmp[i].getPixels();
59         }
60         int color[] = {0, 85, 170};
61         const int limit[] = {255, 0, 255};
62         const int invl[]  = {0, 255, 0};
63         const int inc[]   = {1, -1, 1};
64         for (int i = 0; i < 3; ++i) {
65             const size_t nbBytes = fBmp[i].rowBytes() * fBmp[i].height();
66             for (size_t j = 0; j < nbBytes; ++j) {
67                 pixels[i][j] = (unsigned char)color[i];
68                 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
69             }
70         }
71     }
72 
onDraw(SkCanvas * canvas)73     void onDraw(SkCanvas* canvas) override {
74         GrRenderTargetContext* renderTargetContext =
75             canvas->internal_private_accessTopLayerRenderTargetContext();
76         if (!renderTargetContext) {
77             skiagm::GM::DrawGpuOnlyMessage(canvas);
78             return;
79         }
80 
81         GrContext* context = canvas->getGrContext();
82         if (!context) {
83             return;
84         }
85 
86         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
87         sk_sp<GrTextureProxy> proxy[3];
88 
89         {
90             GrSurfaceDesc desc;
91             desc.fOrigin = kTopLeft_GrSurfaceOrigin;
92 
93             for (int i = 0; i < 3; ++i) {
94                 desc.fWidth = fBmp[i].width();
95                 desc.fHeight = fBmp[i].height();
96                 desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[i].info(), *context->caps());
97                 SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
98 
99                 proxy[i] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
100                                                              fBmp[i].getPixels(),
101                                                              fBmp[i].rowBytes());
102                 if (!proxy[i]) {
103                     return;
104                 }
105             }
106         }
107 
108         constexpr SkScalar kDrawPad = 10.f;
109         constexpr SkScalar kTestPad = 10.f;
110         constexpr SkScalar kColorSpaceOffset = 36.f;
111         SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
112 
113         for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
114             SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
115                                                SkIntToScalar(fBmp[0].height()));
116             renderRect.outset(kDrawPad, kDrawPad);
117 
118             SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
119             SkScalar x = kDrawPad + kTestPad;
120 
121             const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
122                                        {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
123 
124             for (int i = 0; i < 6; ++i) {
125                 std::unique_ptr<GrFragmentProcessor> fp(
126                         GrYUVtoRGBEffect::Make(proxy[indices[i][0]],
127                                                proxy[indices[i][1]],
128                                                proxy[indices[i][2]],
129                                                sizes,
130                                                static_cast<SkYUVColorSpace>(space),
131                                                false));
132                 if (fp) {
133                     GrPaint grPaint;
134                     grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
135                     grPaint.addColorFragmentProcessor(std::move(fp));
136                     SkMatrix viewMatrix;
137                     viewMatrix.setTranslate(x, y);
138                     renderTargetContext->priv().testingOnly_addDrawOp(
139                             GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix,
140                                                            renderRect, GrAAType::kNone));
141                 }
142                 x += renderRect.width() + kTestPad;
143             }
144         }
145      }
146 
147 private:
148     SkBitmap fBmp[3];
149 
150     typedef GM INHERITED;
151 };
152 
153 DEF_GM(return new YUVtoRGBEffect;)
154 
155 //////////////////////////////////////////////////////////////////////////////
156 
157 class YUVNV12toRGBEffect : public GM {
158 public:
YUVNV12toRGBEffect()159     YUVNV12toRGBEffect() {
160         this->setBGColor(0xFFFFFFFF);
161     }
162 
163 protected:
onShortName()164     SkString onShortName() override {
165         return SkString("yuv_nv12_to_rgb_effect");
166     }
167 
onISize()168     SkISize onISize() override {
169         return SkISize::Make(48, 120);
170     }
171 
onOnceBeforeDraw()172     void onOnceBeforeDraw() override {
173         SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
174         fBmp[0].allocPixels(yinfo);
175         SkImageInfo uvinfo = SkImageInfo::MakeN32Premul(USIZE, USIZE);
176         fBmp[1].allocPixels(uvinfo);
177         int color[] = {0, 85, 170};
178         const int limit[] = {255, 0, 255};
179         const int invl[] = {0, 255, 0};
180         const int inc[] = {1, -1, 1};
181 
182         {
183             unsigned char* pixels = (unsigned char*)fBmp[0].getPixels();
184             const size_t nbBytes = fBmp[0].rowBytes() * fBmp[0].height();
185             for (size_t j = 0; j < nbBytes; ++j) {
186                 pixels[j] = (unsigned char)color[0];
187                 color[0] = (color[0] == limit[0]) ? invl[0] : color[0] + inc[0];
188             }
189         }
190 
191         {
192             for (int y = 0; y < fBmp[1].height(); ++y) {
193                 uint32_t* pixels = fBmp[1].getAddr32(0, y);
194                 for (int j = 0; j < fBmp[1].width(); ++j) {
195                     pixels[j] = SkColorSetARGB(0, color[1], color[2], 0);
196                     color[1] = (color[1] == limit[1]) ? invl[1] : color[1] + inc[1];
197                     color[2] = (color[2] == limit[2]) ? invl[2] : color[2] + inc[2];
198                 }
199             }
200         }
201     }
202 
onDraw(SkCanvas * canvas)203     void onDraw(SkCanvas* canvas) override {
204         GrRenderTargetContext* renderTargetContext =
205             canvas->internal_private_accessTopLayerRenderTargetContext();
206         if (!renderTargetContext) {
207             skiagm::GM::DrawGpuOnlyMessage(canvas);
208             return;
209         }
210 
211         GrContext* context = canvas->getGrContext();
212         if (!context) {
213             return;
214         }
215 
216         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
217         sk_sp<GrTextureProxy> proxy[3];
218 
219         {
220             GrSurfaceDesc desc;
221             desc.fOrigin = kTopLeft_GrSurfaceOrigin;
222 
223             for (int i = 0; i < 3; ++i) {
224                 int index = (0 == i) ? 0 : 1;
225 
226                 desc.fWidth = fBmp[index].width();
227                 desc.fHeight = fBmp[index].height();
228                 desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[index].info(), *context->caps());
229                 SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
230 
231                 proxy[i] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
232                                                              fBmp[index].getPixels(),
233                                                              fBmp[index].rowBytes());
234                 if (!proxy[i]) {
235                     return;
236                 }
237             }
238         }
239 
240         constexpr SkScalar kDrawPad = 10.f;
241         constexpr SkScalar kTestPad = 10.f;
242         constexpr SkScalar kColorSpaceOffset = 36.f;
243         SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
244 
245         for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
246             SkRect renderRect =
247                 SkRect::MakeWH(SkIntToScalar(fBmp[0].width()), SkIntToScalar(fBmp[0].height()));
248             renderRect.outset(kDrawPad, kDrawPad);
249 
250             SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
251             SkScalar x = kDrawPad + kTestPad;
252 
253             GrPaint grPaint;
254             grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
255             auto fp = GrYUVtoRGBEffect::Make(proxy[0], proxy[1], proxy[2], sizes,
256                                              static_cast<SkYUVColorSpace>(space), true);
257             if (fp) {
258                 SkMatrix viewMatrix;
259                 viewMatrix.setTranslate(x, y);
260                 grPaint.addColorFragmentProcessor(std::move(fp));
261                 std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
262                                 std::move(grPaint), viewMatrix, renderRect, GrAAType::kNone));
263                 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
264             }
265         }
266     }
267 
268 private:
269     SkBitmap fBmp[2];
270 
271     typedef GM INHERITED;
272 };
273 
274 DEF_GM(return new YUVNV12toRGBEffect;)
275 }
276 
277 #endif
278