Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: src/gpu/effects/GrYUVEffect.cpp

Issue 2016593002: Add NV12 texture conversion support. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrYUVEffect.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrYUVEffect.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698