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 |