Index: src/gpu/effects/GrYUVEffect.cpp |
diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp |
index 94dca84df663d28f36e07adfe18aa3ae513c2fa3..7f959306f4a836ffa3ccdf59b0f896cdb638f54d 100644 |
--- a/src/gpu/effects/GrYUVEffect.cpp |
+++ b/src/gpu/effects/GrYUVEffect.cpp |
@@ -64,7 +64,7 @@ class YUVtoRGBEffect : public GrFragmentProcessor { |
public: |
static sk_sp<GrFragmentProcessor> Make(GrTexture* yTexture, GrTexture* uTexture, |
GrTexture* vTexture, const SkISize sizes[3], |
- SkYUVColorSpace colorSpace) { |
+ SkYUVColorSpace colorSpace, bool nv12) { |
SkScalar w[3], h[3]; |
w[0] = SkIntToScalar(sizes[0].fWidth) / SkIntToScalar(yTexture->width()); |
h[0] = SkIntToScalar(sizes[0].fHeight) / SkIntToScalar(yTexture->height()); |
@@ -85,21 +85,23 @@ public: |
(sizes[2].fHeight != sizes[0].fHeight)) ? |
GrTextureParams::kBilerp_FilterMode : |
GrTextureParams::kNone_FilterMode; |
- return sk_sp<GrFragmentProcessor>( |
- new YUVtoRGBEffect(yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace)); |
+ return sk_sp<GrFragmentProcessor>(new YUVtoRGBEffect( |
+ yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace, nv12)); |
} |
const char* name() const override { return "YUV to RGB"; } |
SkYUVColorSpace getColorSpace() const { return fColorSpace; } |
+ bool isNV12() const { |
+ return fNV12; |
+ } |
+ |
class GLSLProcessor : public GrGLSLFragmentProcessor { |
public: |
- // this class always generates the same code. |
- static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {} |
- |
void emitCode(EmitArgs& args) override { |
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; |
+ const YUVtoRGBEffect& effect = args.fFp.cast<YUVtoRGBEffect>(); |
const char* colorSpaceMatrix = nullptr; |
fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, |
@@ -111,10 +113,15 @@ public: |
fragBuilder->codeAppend(".r,"); |
fragBuilder->appendTextureLookup(args.fTexSamplers[1], args.fCoords[1].c_str(), |
args.fCoords[1].getType()); |
- fragBuilder->codeAppend(".r,"); |
- fragBuilder->appendTextureLookup(args.fTexSamplers[2], args.fCoords[2].c_str(), |
- args.fCoords[2].getType()); |
- fragBuilder->codeAppendf(".r, 1.0) * %s;", colorSpaceMatrix); |
+ if (effect.fNV12) { |
+ fragBuilder->codeAppendf(".rg,"); |
+ } else { |
+ fragBuilder->codeAppend(".r,"); |
+ fragBuilder->appendTextureLookup(args.fTexSamplers[2], args.fCoords[2].c_str(), |
+ args.fCoords[2].getType()); |
+ fragBuilder->codeAppendf(".g,"); |
+ } |
+ fragBuilder->codeAppendf("1.0) * %s;", colorSpaceMatrix); |
} |
protected: |
@@ -143,21 +150,24 @@ public: |
private: |
YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, |
const SkMatrix yuvMatrix[3], GrTextureParams::FilterMode uvFilterMode, |
- SkYUVColorSpace colorSpace) |
- : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode) |
- , fYAccess(yTexture) |
- , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode) |
- , fUAccess(uTexture, uvFilterMode) |
- , fVTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, uvFilterMode) |
- , fVAccess(vTexture, uvFilterMode) |
- , fColorSpace(colorSpace) { |
+ SkYUVColorSpace colorSpace, bool nv12) |
+ : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode) |
+ , fYAccess(yTexture) |
+ , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode) |
+ , fUAccess(uTexture, uvFilterMode) |
+ , fVAccess(vTexture, uvFilterMode) |
+ , fColorSpace(colorSpace) |
+ , fNV12(nv12) { |
this->initClassID<YUVtoRGBEffect>(); |
this->addCoordTransform(&fYTransform); |
this->addTextureAccess(&fYAccess); |
this->addCoordTransform(&fUTransform); |
this->addTextureAccess(&fUAccess); |
- this->addCoordTransform(&fVTransform); |
- this->addTextureAccess(&fVAccess); |
+ if (!fNV12) { |
+ fVTransform = GrCoordTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, uvFilterMode); |
+ this->addCoordTransform(&fVTransform); |
+ this->addTextureAccess(&fVAccess); |
+ } |
} |
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
@@ -165,12 +175,12 @@ private: |
} |
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { |
- GLSLProcessor::GenKey(*this, caps, b); |
+ b->add32(fNV12); |
} |
bool onIsEqual(const GrFragmentProcessor& sBase) const override { |
const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>(); |
- return fColorSpace == s.getColorSpace(); |
+ return (fColorSpace == s.getColorSpace()) && (fNV12 == s.isNV12()); |
} |
void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
@@ -186,6 +196,7 @@ private: |
GrCoordTransform fVTransform; |
GrTextureAccess fVAccess; |
SkYUVColorSpace fColorSpace; |
+ bool fNV12; |
typedef GrFragmentProcessor INHERITED; |
}; |
@@ -350,11 +361,11 @@ private: |
////////////////////////////////////////////////////////////////////////////// |
-sk_sp<GrFragmentProcessor> |
-GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, |
- const SkISize sizes[3], SkYUVColorSpace colorSpace) { |
+sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture, |
+ GrTexture* vTexture, const SkISize sizes[3], |
+ SkYUVColorSpace colorSpace, bool nv12) { |
SkASSERT(yTexture && uTexture && vTexture && sizes); |
- return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace); |
+ return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace, nv12); |
} |
sk_sp<GrFragmentProcessor> |