• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2014 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 // This test only works with the GPU backend.
10 
11 #include "gm.h"
12 
13 #if SK_SUPPORT_GPU
14 
15 #include "GrContext.h"
16 #include "GrDrawContext.h"
17 #include "GrPipelineBuilder.h"
18 #include "SkBitmap.h"
19 #include "SkGr.h"
20 #include "SkGradientShader.h"
21 #include "batches/GrDrawBatch.h"
22 #include "batches/GrRectBatchFactory.h"
23 #include "effects/GrYUVEffect.h"
24 
25 #define YSIZE 8
26 #define USIZE 4
27 #define VSIZE 4
28 
29 namespace skiagm {
30 /**
31  * This GM directly exercises GrYUVtoRGBEffect.
32  */
33 class YUVtoRGBEffect : public GM {
34 public:
YUVtoRGBEffect()35     YUVtoRGBEffect() {
36         this->setBGColor(0xFFFFFFFF);
37     }
38 
39 protected:
onShortName()40     SkString onShortName() override {
41         return SkString("yuv_to_rgb_effect");
42     }
43 
onISize()44     SkISize onISize() override {
45         return SkISize::Make(238, 120);
46     }
47 
onOnceBeforeDraw()48     void onOnceBeforeDraw() override {
49         SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
50         fBmp[0].allocPixels(yinfo);
51         SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
52         fBmp[1].allocPixels(uinfo);
53         SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
54         fBmp[2].allocPixels(vinfo);
55         unsigned char* pixels[3];
56         for (int i = 0; i < 3; ++i) {
57             pixels[i] = (unsigned char*)fBmp[i].getPixels();
58         }
59         int color[] = {0, 85, 170};
60         const int limit[] = {255, 0, 255};
61         const int invl[]  = {0, 255, 0};
62         const int inc[]   = {1, -1, 1};
63         for (int i = 0; i < 3; ++i) {
64             const size_t nbBytes = fBmp[i].rowBytes() * fBmp[i].height();
65             for (size_t j = 0; j < nbBytes; ++j) {
66                 pixels[i][j] = (unsigned char)color[i];
67                 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
68             }
69         }
70     }
71 
onDraw(SkCanvas * canvas)72     void onDraw(SkCanvas* canvas) override {
73         GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
74         if (nullptr == rt) {
75             return;
76         }
77         GrContext* context = rt->getContext();
78         if (nullptr == context) {
79             skiagm::GM::DrawGpuOnlyMessage(canvas);
80             return;
81         }
82 
83         SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(rt));
84         if (!drawContext) {
85             return;
86         }
87 
88         SkAutoTUnref<GrTexture> texture[3];
89         texture[0].reset(GrRefCachedBitmapTexture(context, fBmp[0],
90                                                   GrTextureParams::ClampBilerp()));
91         texture[1].reset(GrRefCachedBitmapTexture(context, fBmp[1],
92                                                   GrTextureParams::ClampBilerp()));
93         texture[2].reset(GrRefCachedBitmapTexture(context, fBmp[2],
94                                                   GrTextureParams::ClampBilerp()));
95 
96         if (!texture[0] || !texture[1] || !texture[2]) {
97             return;
98         }
99 
100         static const SkScalar kDrawPad = 10.f;
101         static const SkScalar kTestPad = 10.f;
102         static const SkScalar kColorSpaceOffset = 36.f;
103         SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
104 
105         for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace;
106              ++space) {
107             SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
108                                                SkIntToScalar(fBmp[0].height()));
109             renderRect.outset(kDrawPad, kDrawPad);
110 
111             SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
112             SkScalar x = kDrawPad + kTestPad;
113 
114             const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
115                                        {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
116 
117             for (int i = 0; i < 6; ++i) {
118                 GrPipelineBuilder pipelineBuilder;
119                 pipelineBuilder.setXPFactory(
120                     GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
121                 SkAutoTUnref<const GrFragmentProcessor> fp(
122                             GrYUVEffect::CreateYUVToRGB(texture[indices[i][0]],
123                                                         texture[indices[i][1]],
124                                                         texture[indices[i][2]],
125                                                         sizes,
126                                                         static_cast<SkYUVColorSpace>(space)));
127                 if (fp) {
128                     SkMatrix viewMatrix;
129                     viewMatrix.setTranslate(x, y);
130                     pipelineBuilder.setRenderTarget(rt);
131                     pipelineBuilder.addColorFragmentProcessor(fp);
132                     SkAutoTUnref<GrDrawBatch> batch(
133                             GrRectBatchFactory::CreateNonAAFill(GrColor_WHITE, viewMatrix,
134                                                                 renderRect, nullptr, nullptr));
135                     drawContext->internal_drawBatch(pipelineBuilder, batch);
136                 }
137                 x += renderRect.width() + kTestPad;
138             }
139         }
140      }
141 
142 private:
143     SkBitmap fBmp[3];
144 
145     typedef GM INHERITED;
146 };
147 
148 DEF_GM(return new YUVtoRGBEffect;)
149 }
150 
151 #endif
152