| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrYUVEffect.h" | 8 #include "GrYUVEffect.h" |
| 9 | 9 |
| 10 #include "GrCoordTransform.h" | 10 #include "GrCoordTransform.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 0.182663f, 0.614473f, 0.061971f, 0.0625f, | 57 0.182663f, 0.614473f, 0.061971f, 0.0625f, |
| 58 -0.100672f, -0.338658f, 0.43933f, 0.5f, | 58 -0.100672f, -0.338658f, 0.43933f, 0.5f, |
| 59 0.439142f, -0.39891f, -0.040231f, 0.5f, | 59 0.439142f, -0.39891f, -0.040231f, 0.5f, |
| 60 0.f, 0.f, 0.f, 1. | 60 0.f, 0.f, 0.f, 1. |
| 61 }; | 61 }; |
| 62 | 62 |
| 63 class YUVtoRGBEffect : public GrFragmentProcessor { | 63 class YUVtoRGBEffect : public GrFragmentProcessor { |
| 64 public: | 64 public: |
| 65 static sk_sp<GrFragmentProcessor> Make(GrTexture* yTexture, GrTexture* uText
ure, | 65 static sk_sp<GrFragmentProcessor> Make(GrTexture* yTexture, GrTexture* uText
ure, |
| 66 GrTexture* vTexture, const SkISize si
zes[3], | 66 GrTexture* vTexture, const SkISize si
zes[3], |
| 67 SkYUVColorSpace colorSpace) { | 67 SkYUVColorSpace colorSpace, bool nv12
) { |
| 68 SkScalar w[3], h[3]; | 68 SkScalar w[3], h[3]; |
| 69 w[0] = SkIntToScalar(sizes[0].fWidth) / SkIntToScalar(yTexture->width()
); | 69 w[0] = SkIntToScalar(sizes[0].fWidth) / SkIntToScalar(yTexture->width()
); |
| 70 h[0] = SkIntToScalar(sizes[0].fHeight) / SkIntToScalar(yTexture->height(
)); | 70 h[0] = SkIntToScalar(sizes[0].fHeight) / SkIntToScalar(yTexture->height(
)); |
| 71 w[1] = SkIntToScalar(sizes[1].fWidth) / SkIntToScalar(uTexture->width()
); | 71 w[1] = SkIntToScalar(sizes[1].fWidth) / SkIntToScalar(uTexture->width()
); |
| 72 h[1] = SkIntToScalar(sizes[1].fHeight) / SkIntToScalar(uTexture->height(
)); | 72 h[1] = SkIntToScalar(sizes[1].fHeight) / SkIntToScalar(uTexture->height(
)); |
| 73 w[2] = SkIntToScalar(sizes[2].fWidth) / SkIntToScalar(vTexture->width()
); | 73 w[2] = SkIntToScalar(sizes[2].fWidth) / SkIntToScalar(vTexture->width()
); |
| 74 h[2] = SkIntToScalar(sizes[2].fHeight) / SkIntToScalar(vTexture->height(
)); | 74 h[2] = SkIntToScalar(sizes[2].fHeight) / SkIntToScalar(vTexture->height(
)); |
| 75 SkMatrix yuvMatrix[3]; | 75 SkMatrix yuvMatrix[3]; |
| 76 yuvMatrix[0] = GrCoordTransform::MakeDivByTextureWHMatrix(yTexture); | 76 yuvMatrix[0] = GrCoordTransform::MakeDivByTextureWHMatrix(yTexture); |
| 77 yuvMatrix[1] = yuvMatrix[0]; | 77 yuvMatrix[1] = yuvMatrix[0]; |
| 78 yuvMatrix[1].preScale(w[1] / w[0], h[1] / h[0]); | 78 yuvMatrix[1].preScale(w[1] / w[0], h[1] / h[0]); |
| 79 yuvMatrix[2] = yuvMatrix[0]; | 79 yuvMatrix[2] = yuvMatrix[0]; |
| 80 yuvMatrix[2].preScale(w[2] / w[0], h[2] / h[0]); | 80 yuvMatrix[2].preScale(w[2] / w[0], h[2] / h[0]); |
| 81 GrTextureParams::FilterMode uvFilterMode = | 81 GrTextureParams::FilterMode uvFilterMode = |
| 82 ((sizes[1].fWidth != sizes[0].fWidth) || | 82 ((sizes[1].fWidth != sizes[0].fWidth) || |
| 83 (sizes[1].fHeight != sizes[0].fHeight) || | 83 (sizes[1].fHeight != sizes[0].fHeight) || |
| 84 (sizes[2].fWidth != sizes[0].fWidth) || | 84 (sizes[2].fWidth != sizes[0].fWidth) || |
| 85 (sizes[2].fHeight != sizes[0].fHeight)) ? | 85 (sizes[2].fHeight != sizes[0].fHeight)) ? |
| 86 GrTextureParams::kBilerp_FilterMode : | 86 GrTextureParams::kBilerp_FilterMode : |
| 87 GrTextureParams::kNone_FilterMode; | 87 GrTextureParams::kNone_FilterMode; |
| 88 return sk_sp<GrFragmentProcessor>( | 88 return sk_sp<GrFragmentProcessor>(new YUVtoRGBEffect( |
| 89 new YUVtoRGBEffect(yTexture, uTexture, vTexture, yuvMatrix, uvFilter
Mode, colorSpace)); | 89 yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace, n
v12)); |
| 90 } | 90 } |
| 91 | 91 |
| 92 const char* name() const override { return "YUV to RGB"; } | 92 const char* name() const override { return "YUV to RGB"; } |
| 93 | 93 |
| 94 SkYUVColorSpace getColorSpace() const { return fColorSpace; } | 94 SkYUVColorSpace getColorSpace() const { return fColorSpace; } |
| 95 | 95 |
| 96 bool isNV12() const { |
| 97 return fNV12; |
| 98 } |
| 99 |
| 96 class GLSLProcessor : public GrGLSLFragmentProcessor { | 100 class GLSLProcessor : public GrGLSLFragmentProcessor { |
| 97 public: | 101 public: |
| 98 // this class always generates the same code. | |
| 99 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKey
Builder*) {} | |
| 100 | |
| 101 void emitCode(EmitArgs& args) override { | 102 void emitCode(EmitArgs& args) override { |
| 102 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; | 103 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 104 const YUVtoRGBEffect& effect = args.fFp.cast<YUVtoRGBEffect>(); |
| 103 | 105 |
| 104 const char* colorSpaceMatrix = nullptr; | 106 const char* colorSpaceMatrix = nullptr; |
| 105 fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag
, | 107 fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag
, |
| 106 kMat44f_GrSLType, kDef
ault_GrSLPrecision, | 108 kMat44f_GrSLType, kDef
ault_GrSLPrecision, |
| 107 "ColorSpaceMatrix", &c
olorSpaceMatrix); | 109 "ColorSpaceMatrix", &c
olorSpaceMatrix); |
| 108 fragBuilder->codeAppendf("%s = vec4(", args.fOutputColor); | 110 fragBuilder->codeAppendf("%s = vec4(", args.fOutputColor); |
| 109 fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fCoords[
0].c_str(), | 111 fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fCoords[
0].c_str(), |
| 110 args.fCoords[0].getType()); | 112 args.fCoords[0].getType()); |
| 111 fragBuilder->codeAppend(".r,"); | 113 fragBuilder->codeAppend(".r,"); |
| 112 fragBuilder->appendTextureLookup(args.fTexSamplers[1], args.fCoords[
1].c_str(), | 114 fragBuilder->appendTextureLookup(args.fTexSamplers[1], args.fCoords[
1].c_str(), |
| 113 args.fCoords[1].getType()); | 115 args.fCoords[1].getType()); |
| 114 fragBuilder->codeAppend(".r,"); | 116 if (effect.fNV12) { |
| 115 fragBuilder->appendTextureLookup(args.fTexSamplers[2], args.fCoords[
2].c_str(), | 117 fragBuilder->codeAppendf(".rg,"); |
| 116 args.fCoords[2].getType()); | 118 } else { |
| 117 fragBuilder->codeAppendf(".r, 1.0) * %s;", colorSpaceMatrix); | 119 fragBuilder->codeAppend(".r,"); |
| 120 fragBuilder->appendTextureLookup(args.fTexSamplers[2], args.fCoo
rds[2].c_str(), |
| 121 args.fCoords[2].getType()); |
| 122 fragBuilder->codeAppendf(".g,"); |
| 123 } |
| 124 fragBuilder->codeAppendf("1.0) * %s;", colorSpaceMatrix); |
| 118 } | 125 } |
| 119 | 126 |
| 120 protected: | 127 protected: |
| 121 void onSetData(const GrGLSLProgramDataManager& pdman, | 128 void onSetData(const GrGLSLProgramDataManager& pdman, |
| 122 const GrProcessor& processor) override { | 129 const GrProcessor& processor) override { |
| 123 const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>(); | 130 const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>(); |
| 124 switch (yuvEffect.getColorSpace()) { | 131 switch (yuvEffect.getColorSpace()) { |
| 125 case kJPEG_SkYUVColorSpace: | 132 case kJPEG_SkYUVColorSpace: |
| 126 pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix); | 133 pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix); |
| 127 break; | 134 break; |
| 128 case kRec601_SkYUVColorSpace: | 135 case kRec601_SkYUVColorSpace: |
| 129 pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix); | 136 pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix); |
| 130 break; | 137 break; |
| 131 case kRec709_SkYUVColorSpace: | 138 case kRec709_SkYUVColorSpace: |
| 132 pdman.setMatrix4f(fMatrixUni, kRec709ConversionMatrix); | 139 pdman.setMatrix4f(fMatrixUni, kRec709ConversionMatrix); |
| 133 break; | 140 break; |
| 134 } | 141 } |
| 135 } | 142 } |
| 136 | 143 |
| 137 private: | 144 private: |
| 138 GrGLSLProgramDataManager::UniformHandle fMatrixUni; | 145 GrGLSLProgramDataManager::UniformHandle fMatrixUni; |
| 139 | 146 |
| 140 typedef GrGLSLFragmentProcessor INHERITED; | 147 typedef GrGLSLFragmentProcessor INHERITED; |
| 141 }; | 148 }; |
| 142 | 149 |
| 143 private: | 150 private: |
| 144 YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture
, | 151 YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture
, |
| 145 const SkMatrix yuvMatrix[3], GrTextureParams::FilterMode uvFi
lterMode, | 152 const SkMatrix yuvMatrix[3], GrTextureParams::FilterMode uvFi
lterMode, |
| 146 SkYUVColorSpace colorSpace) | 153 SkYUVColorSpace colorSpace, bool nv12) |
| 147 : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kN
one_FilterMode) | 154 : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams
::kNone_FilterMode) |
| 148 , fYAccess(yTexture) | 155 , fYAccess(yTexture) |
| 149 , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode) | 156 , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode) |
| 150 , fUAccess(uTexture, uvFilterMode) | 157 , fUAccess(uTexture, uvFilterMode) |
| 151 , fVTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, uvFilterMode) | 158 , fVAccess(vTexture, uvFilterMode) |
| 152 , fVAccess(vTexture, uvFilterMode) | 159 , fColorSpace(colorSpace) |
| 153 , fColorSpace(colorSpace) { | 160 , fNV12(nv12) { |
| 154 this->initClassID<YUVtoRGBEffect>(); | 161 this->initClassID<YUVtoRGBEffect>(); |
| 155 this->addCoordTransform(&fYTransform); | 162 this->addCoordTransform(&fYTransform); |
| 156 this->addTextureAccess(&fYAccess); | 163 this->addTextureAccess(&fYAccess); |
| 157 this->addCoordTransform(&fUTransform); | 164 this->addCoordTransform(&fUTransform); |
| 158 this->addTextureAccess(&fUAccess); | 165 this->addTextureAccess(&fUAccess); |
| 159 this->addCoordTransform(&fVTransform); | 166 if (!fNV12) { |
| 160 this->addTextureAccess(&fVAccess); | 167 fVTransform = GrCoordTransform(kLocal_GrCoordSet, yuvMatrix[2], vTex
ture, uvFilterMode); |
| 168 this->addCoordTransform(&fVTransform); |
| 169 this->addTextureAccess(&fVAccess); |
| 170 } |
| 161 } | 171 } |
| 162 | 172 |
| 163 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { | 173 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
| 164 return new GLSLProcessor; | 174 return new GLSLProcessor; |
| 165 } | 175 } |
| 166 | 176 |
| 167 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { | 177 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { |
| 168 GLSLProcessor::GenKey(*this, caps, b); | 178 b->add32(fNV12); |
| 169 } | 179 } |
| 170 | 180 |
| 171 bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 181 bool onIsEqual(const GrFragmentProcessor& sBase) const override { |
| 172 const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>(); | 182 const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>(); |
| 173 return fColorSpace == s.getColorSpace(); | 183 return (fColorSpace == s.getColorSpace()) && (fNV12 == s.isNV12()); |
| 174 } | 184 } |
| 175 | 185 |
| 176 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | 186 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 177 // YUV is opaque | 187 // YUV is opaque |
| 178 inout->setToOther(kA_GrColorComponentFlag, 0xFF << GrColor_SHIFT_A, | 188 inout->setToOther(kA_GrColorComponentFlag, 0xFF << GrColor_SHIFT_A, |
| 179 GrInvariantOutput::kWillNot_ReadInput); | 189 GrInvariantOutput::kWillNot_ReadInput); |
| 180 } | 190 } |
| 181 | 191 |
| 182 GrCoordTransform fYTransform; | 192 GrCoordTransform fYTransform; |
| 183 GrTextureAccess fYAccess; | 193 GrTextureAccess fYAccess; |
| 184 GrCoordTransform fUTransform; | 194 GrCoordTransform fUTransform; |
| 185 GrTextureAccess fUAccess; | 195 GrTextureAccess fUAccess; |
| 186 GrCoordTransform fVTransform; | 196 GrCoordTransform fVTransform; |
| 187 GrTextureAccess fVAccess; | 197 GrTextureAccess fVAccess; |
| 188 SkYUVColorSpace fColorSpace; | 198 SkYUVColorSpace fColorSpace; |
| 199 bool fNV12; |
| 189 | 200 |
| 190 typedef GrFragmentProcessor INHERITED; | 201 typedef GrFragmentProcessor INHERITED; |
| 191 }; | 202 }; |
| 192 | 203 |
| 193 | 204 |
| 194 class RGBToYUVEffect : public GrFragmentProcessor { | 205 class RGBToYUVEffect : public GrFragmentProcessor { |
| 195 public: | 206 public: |
| 196 enum OutputChannels { | 207 enum OutputChannels { |
| 197 // output color r = y, g = u, b = v, a = a | 208 // output color r = y, g = u, b = v, a = a |
| 198 kYUV_OutputChannels, | 209 kYUV_OutputChannels, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 SkYUVColorSpace fColorSpace; | 354 SkYUVColorSpace fColorSpace; |
| 344 OutputChannels fOutputChannels; | 355 OutputChannels fOutputChannels; |
| 345 | 356 |
| 346 typedef GrFragmentProcessor INHERITED; | 357 typedef GrFragmentProcessor INHERITED; |
| 347 }; | 358 }; |
| 348 | 359 |
| 349 } | 360 } |
| 350 | 361 |
| 351 ////////////////////////////////////////////////////////////////////////////// | 362 ////////////////////////////////////////////////////////////////////////////// |
| 352 | 363 |
| 353 sk_sp<GrFragmentProcessor> | 364 sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrText
ure* uTexture, |
| 354 GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture, GrTexture* v
Texture, | 365 GrTexture* vTexture, const
SkISize sizes[3], |
| 355 const SkISize sizes[3], SkYUVColorSpace colorSpace)
{ | 366 SkYUVColorSpace colorSpace,
bool nv12) { |
| 356 SkASSERT(yTexture && uTexture && vTexture && sizes); | 367 SkASSERT(yTexture && uTexture && vTexture && sizes); |
| 357 return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace)
; | 368 return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace,
nv12); |
| 358 } | 369 } |
| 359 | 370 |
| 360 sk_sp<GrFragmentProcessor> | 371 sk_sp<GrFragmentProcessor> |
| 361 GrYUVEffect::MakeRGBToYUV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colo
rSpace) { | 372 GrYUVEffect::MakeRGBToYUV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colo
rSpace) { |
| 362 SkASSERT(rgbFP); | 373 SkASSERT(rgbFP); |
| 363 return sk_sp<GrFragmentProcessor>( | 374 return sk_sp<GrFragmentProcessor>( |
| 364 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kYUV_Ou
tputChannels)); | 375 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kYUV_Ou
tputChannels)); |
| 365 } | 376 } |
| 366 | 377 |
| 367 sk_sp<GrFragmentProcessor> | 378 sk_sp<GrFragmentProcessor> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 384 return sk_sp<GrFragmentProcessor>( | 395 return sk_sp<GrFragmentProcessor>( |
| 385 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kU_Outp
utChannels)); | 396 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kU_Outp
utChannels)); |
| 386 } | 397 } |
| 387 | 398 |
| 388 sk_sp<GrFragmentProcessor> | 399 sk_sp<GrFragmentProcessor> |
| 389 GrYUVEffect::MakeRGBToV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorS
pace) { | 400 GrYUVEffect::MakeRGBToV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorS
pace) { |
| 390 SkASSERT(rgbFP); | 401 SkASSERT(rgbFP); |
| 391 return sk_sp<GrFragmentProcessor>( | 402 return sk_sp<GrFragmentProcessor>( |
| 392 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kV_Outp
utChannels)); | 403 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kV_Outp
utChannels)); |
| 393 } | 404 } |
| OLD | NEW |