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 "GrTest.h" 17 #include "effects/GrYUVtoRGBEffect.h" 18 #include "SkBitmap.h" 19 #include "SkGr.h" 20 #include "SkGradientShader.h" 21 22 #define YSIZE 8 23 #define USIZE 4 24 #define VSIZE 4 25 26 namespace skiagm { 27 /** 28 * This GM directly exercises GrYUVtoRGBEffect. 29 */ 30 class YUVtoRGBEffect : public GM { 31 public: YUVtoRGBEffect()32 YUVtoRGBEffect() { 33 this->setBGColor(0xFFFFFFFF); 34 } 35 36 protected: onShortName()37 SkString onShortName() override { 38 return SkString("yuv_to_rgb_effect"); 39 } 40 onISize()41 SkISize onISize() override { 42 return SkISize::Make(238, 84); 43 } 44 onOnceBeforeDraw()45 void onOnceBeforeDraw() override { 46 SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE); 47 fBmp[0].allocPixels(yinfo); 48 SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE); 49 fBmp[1].allocPixels(uinfo); 50 SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE); 51 fBmp[2].allocPixels(vinfo); 52 unsigned char* pixels[3]; 53 for (int i = 0; i < 3; ++i) { 54 pixels[i] = (unsigned char*)fBmp[i].getPixels(); 55 } 56 int color[] = {0, 85, 170}; 57 const int limit[] = {255, 0, 255}; 58 const int invl[] = {0, 255, 0}; 59 const int inc[] = {1, -1, 1}; 60 for (int i = 0; i < 3; ++i) { 61 const size_t nbBytes = fBmp[i].rowBytes() * fBmp[i].height(); 62 for (size_t j = 0; j < nbBytes; ++j) { 63 pixels[i][j] = (unsigned char)color[i]; 64 color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i]; 65 } 66 } 67 } 68 onDraw(SkCanvas * canvas)69 void onDraw(SkCanvas* canvas) override { 70 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); 71 if (NULL == rt) { 72 return; 73 } 74 GrContext* context = rt->getContext(); 75 if (NULL == context) { 76 this->drawGpuOnlyMessage(canvas); 77 return; 78 } 79 80 GrTestTarget tt; 81 context->getTestTarget(&tt); 82 if (NULL == tt.target()) { 83 SkDEBUGFAIL("Couldn't get Gr test target."); 84 return; 85 } 86 87 SkAutoTUnref<GrTexture> texture[3]; 88 texture[0].reset(GrRefCachedBitmapTexture(context, fBmp[0], NULL)); 89 texture[1].reset(GrRefCachedBitmapTexture(context, fBmp[1], NULL)); 90 texture[2].reset(GrRefCachedBitmapTexture(context, fBmp[2], NULL)); 91 92 if (!texture[0] || !texture[1] || !texture[2]) { 93 return; 94 } 95 96 static const SkScalar kDrawPad = 10.f; 97 static const SkScalar kTestPad = 10.f; 98 static const SkScalar kColorSpaceOffset = 36.f; 99 SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}}; 100 101 for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; 102 ++space) { 103 SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()), 104 SkIntToScalar(fBmp[0].height())); 105 renderRect.outset(kDrawPad, kDrawPad); 106 107 SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset; 108 SkScalar x = kDrawPad + kTestPad; 109 110 const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, 111 {1, 2, 0}, {2, 0, 1}, {2, 1, 0}}; 112 113 for (int i = 0; i < 6; ++i) { 114 SkAutoTUnref<GrFragmentProcessor> fp( 115 GrYUVtoRGBEffect::Create(texture[indices[i][0]], 116 texture[indices[i][1]], 117 texture[indices[i][2]], 118 sizes, 119 static_cast<SkYUVColorSpace>(space))); 120 if (fp) { 121 SkMatrix viewMatrix; 122 viewMatrix.setTranslate(x, y); 123 GrPipelineBuilder pipelineBuilder; 124 pipelineBuilder.setRenderTarget(rt); 125 pipelineBuilder.addColorProcessor(fp); 126 tt.target()->drawSimpleRect(&pipelineBuilder, 127 GrColor_WHITE, 128 viewMatrix, 129 renderRect); 130 } 131 x += renderRect.width() + kTestPad; 132 } 133 } 134 } 135 136 private: 137 SkBitmap fBmp[3]; 138 139 typedef GM INHERITED; 140 }; 141 142 DEF_GM( return SkNEW(YUVtoRGBEffect); ) 143 } 144 145 #endif 146