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#include "gl/builders/GrGLProgramBuilder.h" 9#include "GrYUVtoRGBEffect.h" 10 11#include "GrCoordTransform.h" 12#include "GrProcessor.h" 13#include "gl/GrGLProcessor.h" 14#include "GrTBackendProcessorFactory.h" 15 16namespace { 17 18class YUVtoRGBEffect : public GrFragmentProcessor { 19public: 20 static GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture, 21 GrTexture* vTexture, SkYUVColorSpace colorSpace) { 22 return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace)); 23 } 24 25 static const char* Name() { return "YUV to RGB"; } 26 27 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE { 28 return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::getInstance(); 29 } 30 31 virtual void getConstantColorComponents(GrColor* color, 32 uint32_t* validFlags) const SK_OVERRIDE { 33 // YUV is opaque 34 *color = 0xFF; 35 *validFlags = kA_GrColorComponentFlag; 36 } 37 38 SkYUVColorSpace getColorSpace() const { 39 return fColorSpace; 40 } 41 42 class GLProcessor : public GrGLFragmentProcessor { 43 public: 44 static const GrGLfloat kJPEGConversionMatrix[16]; 45 static const GrGLfloat kRec601ConversionMatrix[16]; 46 47 // this class always generates the same code. 48 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {} 49 50 GLProcessor(const GrBackendProcessorFactory& factory, 51 const GrProcessor&) 52 : INHERITED(factory) { 53 } 54 55 virtual void emitCode(GrGLProgramBuilder* builder, 56 const GrFragmentProcessor&, 57 const GrProcessorKey&, 58 const char* outputColor, 59 const char* inputColor, 60 const TransformedCoordsArray& coords, 61 const TextureSamplerArray& samplers) SK_OVERRIDE { 62 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 63 64 const char* yuvMatrix = NULL; 65 fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 66 kMat44f_GrSLType, "YUVMatrix", 67 &yuvMatrix); 68 fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor); 69 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType()); 70 fsBuilder->codeAppend(".r,\n\t\t"); 71 fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType()); 72 fsBuilder->codeAppend(".r,\n\t\t"); 73 fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType()); 74 fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix); 75 } 76 77 virtual void setData(const GrGLProgramDataManager& pdman, 78 const GrProcessor& processor) SK_OVERRIDE { 79 const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>(); 80 switch (yuvEffect.getColorSpace()) { 81 case kJPEG_SkYUVColorSpace: 82 pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix); 83 break; 84 case kRec601_SkYUVColorSpace: 85 pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix); 86 break; 87 } 88 } 89 90 private: 91 GrGLProgramDataManager::UniformHandle fMatrixUni; 92 93 typedef GrGLFragmentProcessor INHERITED; 94 }; 95 96private: 97 YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, 98 SkYUVColorSpace colorSpace) 99 : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture), 100 yTexture) 101 , fYAccess(yTexture) 102 , fUAccess(uTexture) 103 , fVAccess(vTexture) 104 , fColorSpace(colorSpace) { 105 this->addCoordTransform(&fCoordTransform); 106 this->addTextureAccess(&fYAccess); 107 this->addTextureAccess(&fUAccess); 108 this->addTextureAccess(&fVAccess); 109 this->setWillNotUseInputColor(); 110 } 111 112 virtual bool onIsEqual(const GrProcessor& sBase) const { 113 const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>(); 114 return fYAccess.getTexture() == s.fYAccess.getTexture() && 115 fUAccess.getTexture() == s.fUAccess.getTexture() && 116 fVAccess.getTexture() == s.fVAccess.getTexture() && 117 fColorSpace == s.getColorSpace(); 118 } 119 120 GrCoordTransform fCoordTransform; 121 GrTextureAccess fYAccess; 122 GrTextureAccess fUAccess; 123 GrTextureAccess fVAccess; 124 SkYUVColorSpace fColorSpace; 125 126 typedef GrFragmentProcessor INHERITED; 127}; 128 129const GrGLfloat YUVtoRGBEffect::GLProcessor::kJPEGConversionMatrix[16] = { 130 1.0f, 0.0f, 1.402f, -0.701f, 131 1.0f, -0.34414f, -0.71414f, 0.529f, 132 1.0f, 1.772f, 0.0f, -0.886f, 133 0.0f, 0.0f, 0.0f, 1.0}; 134const GrGLfloat YUVtoRGBEffect::GLProcessor::kRec601ConversionMatrix[16] = { 135 1.164f, 0.0f, 1.596f, -0.87075f, 136 1.164f, -0.391f, -0.813f, 0.52925f, 137 1.164f, 2.018f, 0.0f, -1.08175f, 138 0.0f, 0.0f, 0.0f, 1.0}; 139} 140 141////////////////////////////////////////////////////////////////////////////// 142 143GrFragmentProcessor* 144GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, 145 SkYUVColorSpace colorSpace) { 146 return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace); 147} 148