• 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 
98                 proxy[i] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
99                                                              fBmp[i].getPixels(),
100                                                              fBmp[i].rowBytes());
101                 if (!proxy[i]) {
102                     return;
103                 }
104             }
105         }
106 
107         constexpr SkScalar kDrawPad = 10.f;
108         constexpr SkScalar kTestPad = 10.f;
109         constexpr SkScalar kColorSpaceOffset = 36.f;
110         SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
111 
112         for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
113             SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
114                                                SkIntToScalar(fBmp[0].height()));
115             renderRect.outset(kDrawPad, kDrawPad);
116 
117             SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
118             SkScalar x = kDrawPad + kTestPad;
119 
120             const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
121                                        {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
122 
123             for (int i = 0; i < 6; ++i) {
124                 std::unique_ptr<GrFragmentProcessor> fp(
125                         GrYUVtoRGBEffect::Make(proxy[indices[i][0]],
126                                                proxy[indices[i][1]],
127                                                proxy[indices[i][2]],
128                                                sizes,
129                                                static_cast<SkYUVColorSpace>(space),
130                                                false));
131                 if (fp) {
132                     GrPaint grPaint;
133                     grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
134                     grPaint.addColorFragmentProcessor(std::move(fp));
135                     SkMatrix viewMatrix;
136                     viewMatrix.setTranslate(x, y);
137                     renderTargetContext->priv().testingOnly_addDrawOp(
138                             GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix,
139                                                            renderRect, GrAAType::kNone));
140                 }
141                 x += renderRect.width() + kTestPad;
142             }
143         }
144      }
145 
146 private:
147     SkBitmap fBmp[3];
148 
149     typedef GM INHERITED;
150 };
151 
152 DEF_GM(return new YUVtoRGBEffect;)
153 
154 //////////////////////////////////////////////////////////////////////////////
155 
156 class YUVNV12toRGBEffect : public GM {
157 public:
YUVNV12toRGBEffect()158     YUVNV12toRGBEffect() {
159         this->setBGColor(0xFFFFFFFF);
160     }
161 
162 protected:
onShortName()163     SkString onShortName() override {
164         return SkString("yuv_nv12_to_rgb_effect");
165     }
166 
onISize()167     SkISize onISize() override {
168         return SkISize::Make(48, 120);
169     }
170 
onOnceBeforeDraw()171     void onOnceBeforeDraw() override {
172         SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
173         fBmp[0].allocPixels(yinfo);
174         SkImageInfo uvinfo = SkImageInfo::MakeN32Premul(USIZE, USIZE);
175         fBmp[1].allocPixels(uvinfo);
176         int color[] = {0, 85, 170};
177         const int limit[] = {255, 0, 255};
178         const int invl[] = {0, 255, 0};
179         const int inc[] = {1, -1, 1};
180 
181         {
182             unsigned char* pixels = (unsigned char*)fBmp[0].getPixels();
183             const size_t nbBytes = fBmp[0].rowBytes() * fBmp[0].height();
184             for (size_t j = 0; j < nbBytes; ++j) {
185                 pixels[j] = (unsigned char)color[0];
186                 color[0] = (color[0] == limit[0]) ? invl[0] : color[0] + inc[0];
187             }
188         }
189 
190         {
191             for (int y = 0; y < fBmp[1].height(); ++y) {
192                 uint32_t* pixels = fBmp[1].getAddr32(0, y);
193                 for (int j = 0; j < fBmp[1].width(); ++j) {
194                     pixels[j] = SkColorSetARGB(0, color[1], color[2], 0);
195                     color[1] = (color[1] == limit[1]) ? invl[1] : color[1] + inc[1];
196                     color[2] = (color[2] == limit[2]) ? invl[2] : color[2] + inc[2];
197                 }
198             }
199         }
200     }
201 
onDraw(SkCanvas * canvas)202     void onDraw(SkCanvas* canvas) override {
203         GrRenderTargetContext* renderTargetContext =
204             canvas->internal_private_accessTopLayerRenderTargetContext();
205         if (!renderTargetContext) {
206             skiagm::GM::DrawGpuOnlyMessage(canvas);
207             return;
208         }
209 
210         GrContext* context = canvas->getGrContext();
211         if (!context) {
212             return;
213         }
214 
215         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
216         sk_sp<GrTextureProxy> proxy[3];
217 
218         {
219             GrSurfaceDesc desc;
220             desc.fOrigin = kTopLeft_GrSurfaceOrigin;
221 
222             for (int i = 0; i < 3; ++i) {
223                 int index = (0 == i) ? 0 : 1;
224 
225                 desc.fWidth = fBmp[index].width();
226                 desc.fHeight = fBmp[index].height();
227                 desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[index].info(), *context->caps());
228 
229                 proxy[i] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
230                                                              fBmp[index].getPixels(),
231                                                              fBmp[index].rowBytes());
232                 if (!proxy[i]) {
233                     return;
234                 }
235             }
236         }
237 
238         constexpr SkScalar kDrawPad = 10.f;
239         constexpr SkScalar kTestPad = 10.f;
240         constexpr SkScalar kColorSpaceOffset = 36.f;
241         SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
242 
243         for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
244             SkRect renderRect =
245                 SkRect::MakeWH(SkIntToScalar(fBmp[0].width()), SkIntToScalar(fBmp[0].height()));
246             renderRect.outset(kDrawPad, kDrawPad);
247 
248             SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
249             SkScalar x = kDrawPad + kTestPad;
250 
251             GrPaint grPaint;
252             grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
253             auto fp = GrYUVtoRGBEffect::Make(proxy[0], proxy[1], proxy[2], sizes,
254                                              static_cast<SkYUVColorSpace>(space), true);
255             if (fp) {
256                 SkMatrix viewMatrix;
257                 viewMatrix.setTranslate(x, y);
258                 grPaint.addColorFragmentProcessor(std::move(fp));
259                 std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
260                                 std::move(grPaint), viewMatrix, renderRect, GrAAType::kNone));
261                 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
262             }
263         }
264     }
265 
266 private:
267     SkBitmap fBmp[2];
268 
269     typedef GM INHERITED;
270 };
271 
272 DEF_GM(return new YUVNV12toRGBEffect;)
273 }
274 
275 #endif
276