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