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