aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar rileya <rileya@chromium.org>2014-09-12 17:45:58 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-12 17:45:58 -0700
commitabaef86f2b37d8a939506a2076da07f6db456951 (patch)
treee206bd6ee9f049c43c0ba9033c8417bb5008258c /src
parent94c415170b6f62fa80b598fe30bf2f99f0aecf6a (diff)
Add support for the Rec601 YUV color space to GrYUVtoRGBEffect.
R=bsalomon@google.com, senorblanco@chromium.org, sugoi@chromium.org, reed@google.com Author: rileya@chromium.org Review URL: https://codereview.chromium.org/516463005
Diffstat (limited to 'src')
-rw-r--r--src/core/SkImageGenerator.cpp17
-rw-r--r--src/core/SkPixelRef.cpp3
-rw-r--r--src/gpu/SkGr.cpp9
-rw-r--r--src/gpu/effects/GrYUVtoRGBEffect.cpp70
-rw-r--r--src/gpu/effects/GrYUVtoRGBEffect.h5
-rw-r--r--src/lazy/SkDiscardablePixelRef.h5
6 files changed, 84 insertions, 25 deletions
diff --git a/src/core/SkImageGenerator.cpp b/src/core/SkImageGenerator.cpp
index 7008e7b42f..c062978f0f 100644
--- a/src/core/SkImageGenerator.cpp
+++ b/src/core/SkImageGenerator.cpp
@@ -57,7 +57,8 @@ bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t r
}
#endif
-bool SkImageGenerator::getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) {
+bool SkImageGenerator::getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace) {
#ifdef SK_DEBUG
// In all cases, we need the sizes array
SkASSERT(sizes);
@@ -89,13 +90,25 @@ bool SkImageGenerator::getYUV8Planes(SkISize sizes[3], void* planes[3], size_t r
(rowBytes[2] >= (size_t)sizes[2].fWidth)));
#endif
- return this->onGetYUV8Planes(sizes, planes, rowBytes);
+ return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace);
}
bool SkImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) {
return false;
}
+bool SkImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace) {
+ // In order to maintain compatibility with clients that implemented the original
+ // onGetYUV8Planes interface, we assume that the color space is JPEG.
+ // TODO(rileya): remove this and the old onGetYUV8Planes once clients switch over to
+ // the new interface.
+ if (colorSpace) {
+ *colorSpace = kJPEG_SkYUVColorSpace;
+ }
+ return this->onGetYUV8Planes(sizes, planes, rowBytes);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////////
SkData* SkImageGenerator::onRefEncodedData() {
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index 1e6db7ec5a..0aa00e0bf5 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -253,7 +253,8 @@ SkData* SkPixelRef::onRefEncodedData() {
return NULL;
}
-bool SkPixelRef::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) {
+bool SkPixelRef::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace) {
return false;
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 73773b00d1..56f3a16b6d 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -222,7 +222,7 @@ static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa
const SkBitmap& bm, const GrTextureDesc& desc) {
SkPixelRef* pixelRef = bm.pixelRef();
SkISize yuvSizes[3];
- if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL)) {
+ if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL, NULL)) {
return NULL;
}
@@ -239,8 +239,10 @@ static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa
planes[1] = (uint8_t*)planes[0] + sizes[0];
planes[2] = (uint8_t*)planes[1] + sizes[1];
+ SkYUVColorSpace colorSpace;
+
// Get the YUV planes
- if (!pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes)) {
+ if (!pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes, &colorSpace)) {
return NULL;
}
@@ -269,7 +271,8 @@ static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa
GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL;
if (renderTarget) {
SkAutoTUnref<GrEffect> yuvToRgbEffect(GrYUVtoRGBEffect::Create(
- yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].texture()));
+ yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].texture(),
+ colorSpace));
GrPaint paint;
paint.addColorEffect(yuvToRgbEffect);
SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth),
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 1a46c969ef..0023b1b300 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -17,8 +17,9 @@ namespace {
class YUVtoRGBEffect : public GrEffect {
public:
- static GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) {
- return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture));
+ static GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+ SkYUVColorSpace colorSpace) {
+ return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace));
}
static const char* Name() { return "YUV to RGB"; }
@@ -34,8 +35,15 @@ public:
*validFlags = kA_GrColorComponentFlag;
}
+ SkYUVColorSpace getColorSpace() const {
+ return fColorSpace;
+ }
+
class GLEffect : public GrGLEffect {
public:
+ static const GrGLfloat kJPEGConversionMatrix[16];
+ static const GrGLfloat kRec601ConversionMatrix[16];
+
// this class always generates the same code.
static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
@@ -45,19 +53,18 @@ public:
}
virtual void emitCode(GrGLProgramBuilder* builder,
- const GrDrawEffect&,
+ const GrDrawEffect& drawEffect,
const GrEffectKey&,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
- const char* yuvMatrix = "yuvMatrix";
- fsBuilder->codeAppendf("\tconst mat4 %s = mat4(1.0, 0.0, 1.402, -0.701,\n\t\t\t"
- "1.0, -0.344, -0.714, 0.529,\n\t\t\t"
- "1.0, 1.772, 0.0, -0.886,\n\t\t\t"
- "0.0, 0.0, 0.0, 1.0);\n",
- yuvMatrix);
+
+ const char* yuvMatrix = NULL;
+ fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kMat44f_GrSLType, "YUVMatrix",
+ &yuvMatrix);
fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
fsBuilder->codeAppend(".r,\n\t\t");
@@ -67,16 +74,34 @@ public:
fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
}
+ virtual void setData(const GrGLProgramDataManager& pdman,
+ const GrDrawEffect& drawEffect) SK_OVERRIDE {
+ const YUVtoRGBEffect& yuvEffect = drawEffect.castEffect<YUVtoRGBEffect>();
+ switch (yuvEffect.getColorSpace()) {
+ case kJPEG_SkYUVColorSpace:
+ pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix);
+ break;
+ case kRec601_SkYUVColorSpace:
+ pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
+ break;
+ }
+ }
+
+ private:
+ GrGLProgramDataManager::UniformHandle fMatrixUni;
+
typedef GrGLEffect INHERITED;
};
private:
- YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture)
- : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
- yTexture)
+ YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+ SkYUVColorSpace colorSpace)
+ : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
+ yTexture)
, fYAccess(yTexture)
, fUAccess(uTexture)
- , fVAccess(vTexture) {
+ , fVAccess(vTexture)
+ , fColorSpace(colorSpace) {
this->addCoordTransform(&fCoordTransform);
this->addTextureAccess(&fYAccess);
this->addTextureAccess(&fUAccess);
@@ -88,21 +113,34 @@ private:
const YUVtoRGBEffect& s = CastEffect<YUVtoRGBEffect>(sBase);
return fYAccess.getTexture() == s.fYAccess.getTexture() &&
fUAccess.getTexture() == s.fUAccess.getTexture() &&
- fVAccess.getTexture() == s.fVAccess.getTexture();
+ fVAccess.getTexture() == s.fVAccess.getTexture() &&
+ fColorSpace == s.getColorSpace();
}
GrCoordTransform fCoordTransform;
GrTextureAccess fYAccess;
GrTextureAccess fUAccess;
GrTextureAccess fVAccess;
+ SkYUVColorSpace fColorSpace;
typedef GrEffect INHERITED;
};
+const GrGLfloat YUVtoRGBEffect::GLEffect::kJPEGConversionMatrix[16] = {
+ 1.0f, 0.0f, 1.402f, -0.701f,
+ 1.0f, -0.34414f, -0.71414f, 0.529f,
+ 1.0f, 1.772f, 0.0f, -0.886f,
+ 0.0f, 0.0f, 0.0f, 1.0};
+const GrGLfloat YUVtoRGBEffect::GLEffect::kRec601ConversionMatrix[16] = {
+ 1.164f, 0.0f, 1.596f, -1.08175f,
+ 1.164f, -0.391f, -0.813f, 0.529f,
+ 1.164f, 2.018f, 0.0f, -1.08175f,
+ 0.0f, 0.0f, 0.0f, 1.0};
}
//////////////////////////////////////////////////////////////////////////////
-GrEffect* GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) {
- return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture);
+GrEffect* GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+ SkYUVColorSpace colorSpace) {
+ return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);
}
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.h b/src/gpu/effects/GrYUVtoRGBEffect.h
index 150acd5a90..52ccd23bbb 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.h
+++ b/src/gpu/effects/GrYUVtoRGBEffect.h
@@ -8,6 +8,8 @@
#ifndef GrYUVtoRGBEffect_DEFINED
#define GrYUVtoRGBEffect_DEFINED
+#include "SkImageInfo.h"
+
class GrEffect;
class GrTexture;
@@ -15,7 +17,8 @@ namespace GrYUVtoRGBEffect {
/**
* Creates an effect that performs color conversion from YUV to RGB
*/
- GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture);
+ GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+ SkYUVColorSpace colorSpace);
};
#endif
diff --git a/src/lazy/SkDiscardablePixelRef.h b/src/lazy/SkDiscardablePixelRef.h
index d31a040164..142c8a4539 100644
--- a/src/lazy/SkDiscardablePixelRef.h
+++ b/src/lazy/SkDiscardablePixelRef.h
@@ -50,8 +50,9 @@ private:
virtual bool onGetYUV8Planes(SkISize sizes[3],
void* planes[3],
- size_t rowBytes[3]) SK_OVERRIDE {
- return fGenerator->getYUV8Planes(sizes, planes, rowBytes);
+ size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace) SK_OVERRIDE {
+ return fGenerator->getYUV8Planes(sizes, planes, rowBytes, colorSpace);
}
friend bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap*,