Home | History | Annotate | Download | only in gm
      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:
     35     YUVtoRGBEffect() {
     36         this->setBGColor(0xFFFFFFFF);
     37     }
     38 
     39 protected:
     40     SkString onShortName() override {
     41         return SkString("yuv_to_rgb_effect");
     42     }
     43 
     44     SkISize onISize() override {
     45         return SkISize::Make(238, 120);
     46     }
     47 
     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 
     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