aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/yuvtorgbeffect.cpp18
-rw-r--r--gn/gpu.gni4
-rw-r--r--gn/sksl.gni1
-rw-r--r--src/gpu/GrProcessor.h2
-rw-r--r--src/gpu/GrYUVProvider.cpp10
-rw-r--r--src/gpu/effects/GrYUVEffect.cpp215
-rw-r--r--src/gpu/effects/GrYUVEffect.h29
-rw-r--r--src/gpu/effects/GrYUVtoRGBEffect.cpp173
-rw-r--r--src/gpu/effects/GrYUVtoRGBEffect.fp116
-rw-r--r--src/gpu/effects/GrYUVtoRGBEffect.h84
-rw-r--r--src/image/SkImage_Gpu.cpp6
11 files changed, 394 insertions, 264 deletions
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index f957566d9f..f5a905c03f 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -17,7 +17,7 @@
#include "SkBitmap.h"
#include "SkGr.h"
#include "SkGradientShader.h"
-#include "effects/GrYUVEffect.h"
+#include "effects/GrYUVtoRGBEffect.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
@@ -119,12 +119,12 @@ protected:
for (int i = 0; i < 6; ++i) {
std::unique_ptr<GrFragmentProcessor> fp(
- GrYUVEffect::MakeYUVToRGB(proxy[indices[i][0]],
- proxy[indices[i][1]],
- proxy[indices[i][2]],
- sizes,
- static_cast<SkYUVColorSpace>(space),
- false));
+ GrYUVtoRGBEffect::Make(proxy[indices[i][0]],
+ proxy[indices[i][1]],
+ proxy[indices[i][2]],
+ sizes,
+ static_cast<SkYUVColorSpace>(space),
+ false));
if (fp) {
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
@@ -247,8 +247,8 @@ protected:
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
- auto fp = GrYUVEffect::MakeYUVToRGB(proxy[0], proxy[1], proxy[2], sizes,
- static_cast<SkYUVColorSpace>(space), true);
+ auto fp = GrYUVtoRGBEffect::Make(proxy[0], proxy[1], proxy[2], sizes,
+ static_cast<SkYUVColorSpace>(space), true);
if (fp) {
SkMatrix viewMatrix;
viewMatrix.setTranslate(x, y);
diff --git a/gn/gpu.gni b/gn/gpu.gni
index fb512bf10b..fee613c951 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -384,8 +384,8 @@ skia_gpu_sources = [
"$_src/gpu/effects/GrUnpremulInputFragmentProcessor.h",
"$_src/gpu/effects/GrXfermodeFragmentProcessor.cpp",
"$_src/gpu/effects/GrXfermodeFragmentProcessor.h",
- "$_src/gpu/effects/GrYUVEffect.cpp",
- "$_src/gpu/effects/GrYUVEffect.h",
+ "$_src/gpu/effects/GrYUVtoRGBEffect.cpp",
+ "$_src/gpu/effects/GrYUVtoRGBEffect.h",
# text
"$_src/gpu/text/GrAtlasGlyphCache.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 1bb57718c0..6248e695e3 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -44,4 +44,5 @@ skia_gpu_processor_sources = [
"$_src/gpu/effects/GrOverdrawFragmentProcessor.fp",
"$_src/gpu/effects/GrSimpleTextureEffect.fp",
"$_src/gpu/effects/GrUnpremulInputFragmentProcessor.fp",
+ "$_src/gpu/effects/GrYUVtoRGBEffect.fp",
]
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 0736d036cd..aac22f32b7 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -135,6 +135,7 @@ public:
kGrSweepGradient_ClassID,
kGrTextureDomainEffect_ClassID,
kGrUnpremulInputFragmentProcessor_ClassID,
+ kGrYUVtoRGBEffect_ClassID,
kHighContrastFilterEffect_ClassID,
kInstanceProcessor_ClassID,
kLumaColorFilterEffect_ClassID,
@@ -150,7 +151,6 @@ public:
kSwizzleFragmentProcessor_ClassID,
kTestFP_ClassID,
kTextureGeometryProcessor_ClassID,
- kYUVtoRGBEffect_ClassID
};
virtual ~GrProcessor() = default;
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 930a33e961..42319d2c06 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -18,7 +18,7 @@
#include "SkYUVPlanesCache.h"
#include "effects/GrNonlinearColorSpaceXformEffect.h"
#include "effects/GrSRGBEffect.h"
-#include "effects/GrYUVEffect.h"
+#include "effects/GrYUVtoRGBEffect.h"
namespace {
/**
@@ -139,10 +139,10 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS
GrPaint paint;
auto yuvToRgbProcessor =
- GrYUVEffect::MakeYUVToRGB(yuvTextureContexts[0]->asTextureProxyRef(),
- yuvTextureContexts[1]->asTextureProxyRef(),
- yuvTextureContexts[2]->asTextureProxyRef(),
- yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false);
+ GrYUVtoRGBEffect::Make(yuvTextureContexts[0]->asTextureProxyRef(),
+ yuvTextureContexts[1]->asTextureProxyRef(),
+ yuvTextureContexts[2]->asTextureProxyRef(),
+ yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false);
paint.addColorFragmentProcessor(std::move(yuvToRgbProcessor));
// If we're decoding an sRGB image, the result of our linear math on the YUV planes is already
diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp
deleted file mode 100644
index 6e0f766071..0000000000
--- a/src/gpu/effects/GrYUVEffect.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrYUVEffect.h"
-
-#include "GrCoordTransform.h"
-#include "GrFragmentProcessor.h"
-#include "GrProcessor.h"
-#include "GrTextureProxy.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
-#include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
-
-namespace {
-
-static const float kJPEGConversionMatrix[16] = {
- 1.0f, 0.0f, 1.402f, -0.703749f,
- 1.0f, -0.344136f, -0.714136f, 0.531211f,
- 1.0f, 1.772f, 0.0f, -0.889475f,
- 0.0f, 0.0f, 0.0f, 1.0
-};
-
-static const float kRec601ConversionMatrix[16] = {
- 1.164f, 0.0f, 1.596f, -0.87075f,
- 1.164f, -0.391f, -0.813f, 0.52925f,
- 1.164f, 2.018f, 0.0f, -1.08175f,
- 0.0f, 0.0f, 0.0f, 1.0}
-;
-
-static const float kRec709ConversionMatrix[16] = {
- 1.164f, 0.0f, 1.793f, -0.96925f,
- 1.164f, -0.213f, -0.533f, 0.30025f,
- 1.164f, 2.112f, 0.0f, -1.12875f,
- 0.0f, 0.0f, 0.0f, 1.0f}
-;
-
-class YUVtoRGBEffect : public GrFragmentProcessor {
-public:
- static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy,
- sk_sp<GrTextureProxy> uProxy,
- sk_sp<GrTextureProxy> vProxy,
- const SkISize sizes[3],
- SkYUVColorSpace colorSpace, bool nv12) {
- SkScalar w[3], h[3];
- w[0] = SkIntToScalar(sizes[0].fWidth);
- h[0] = SkIntToScalar(sizes[0].fHeight);
- w[1] = SkIntToScalar(sizes[1].fWidth);
- h[1] = SkIntToScalar(sizes[1].fHeight);
- w[2] = SkIntToScalar(sizes[2].fWidth);
- h[2] = SkIntToScalar(sizes[2].fHeight);
- const SkMatrix yuvMatrix[3] = {
- SkMatrix::I(),
- SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]),
- SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0])
- };
- GrSamplerState::Filter uvFilterMode =
- ((sizes[1].fWidth != sizes[0].fWidth) ||
- (sizes[1].fHeight != sizes[0].fHeight) ||
- (sizes[2].fWidth != sizes[0].fWidth) ||
- (sizes[2].fHeight != sizes[0].fHeight)) ?
- GrSamplerState::Filter::kBilerp :
- GrSamplerState::Filter::kNearest;
- return std::unique_ptr<GrFragmentProcessor>(
- new YUVtoRGBEffect(std::move(yProxy), std::move(uProxy), std::move(vProxy),
- yuvMatrix, uvFilterMode, colorSpace, nv12));
- }
-
- const char* name() const override { return "YUV to RGB"; }
-
- std::unique_ptr<GrFragmentProcessor> clone() const override {
- return std::unique_ptr<GrFragmentProcessor>(new YUVtoRGBEffect(*this));
- }
-
- SkYUVColorSpace getColorSpace() const { return fColorSpace; }
-
- bool isNV12() const {
- return fNV12;
- }
-
- class GLSLProcessor : public GrGLSLFragmentProcessor {
- public:
- 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, kHalf4x4_GrSLType,
- "ColorSpaceMatrix", &colorSpaceMatrix);
- fragBuilder->codeAppendf("%s = half4(", args.fOutputColor);
- fragBuilder->appendTextureLookup(args.fTexSamplers[0],
- args.fTransformedCoords[0].c_str(),
- args.fTransformedCoords[0].getType());
- fragBuilder->codeAppend(".r,");
- fragBuilder->appendTextureLookup(args.fTexSamplers[1],
- args.fTransformedCoords[1].c_str(),
- args.fTransformedCoords[1].getType());
- if (effect.fNV12) {
- fragBuilder->codeAppendf(".rg,");
- } else {
- fragBuilder->codeAppend(".r,");
- fragBuilder->appendTextureLookup(args.fTexSamplers[2],
- args.fTransformedCoords[2].c_str(),
- args.fTransformedCoords[2].getType());
- fragBuilder->codeAppendf(".r,");
- }
- fragBuilder->codeAppendf("1.0) * %s;", colorSpaceMatrix);
- }
-
- protected:
- void onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& processor) override {
- const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>();
- switch (yuvEffect.getColorSpace()) {
- case kJPEG_SkYUVColorSpace:
- pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix);
- break;
- case kRec601_SkYUVColorSpace:
- pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
- break;
- case kRec709_SkYUVColorSpace:
- pdman.setMatrix4f(fMatrixUni, kRec709ConversionMatrix);
- break;
- }
- }
-
- private:
- GrGLSLProgramDataManager::UniformHandle fMatrixUni;
-
- typedef GrGLSLFragmentProcessor INHERITED;
- };
-
-private:
- YUVtoRGBEffect(sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy,
- sk_sp<GrTextureProxy> vProxy, const SkMatrix yuvMatrix[3],
- GrSamplerState::Filter uvFilterMode, SkYUVColorSpace colorSpace, bool nv12)
- : INHERITED(kYUVtoRGBEffect_ClassID, kPreservesOpaqueInput_OptimizationFlag)
- , fYTransform(yuvMatrix[0], yProxy.get())
- , fYSampler(std::move(yProxy))
- , fUTransform(yuvMatrix[1], uProxy.get())
- , fUSampler(std::move(uProxy), uvFilterMode)
- , fVSampler(vProxy, uvFilterMode)
- , fColorSpace(colorSpace)
- , fNV12(nv12) {
- this->addCoordTransform(&fYTransform);
- this->addTextureSampler(&fYSampler);
- this->addCoordTransform(&fUTransform);
- this->addTextureSampler(&fUSampler);
- if (!fNV12) {
- fVTransform = GrCoordTransform(yuvMatrix[2], vProxy.get());
- this->addCoordTransform(&fVTransform);
- this->addTextureSampler(&fVSampler);
- }
- }
-
- YUVtoRGBEffect(const YUVtoRGBEffect& that)
- : INHERITED(kYUVtoRGBEffect_ClassID, kPreservesOpaqueInput_OptimizationFlag)
- , fYTransform(that.fYTransform)
- , fYSampler(that.fYSampler)
- , fUTransform(that.fUTransform)
- , fUSampler(that.fUSampler)
- , fVTransform(that.fVTransform)
- , fVSampler(that.fVSampler)
- , fColorSpace(that.fColorSpace)
- , fNV12(that.fNV12) {
- this->addCoordTransform(&fYTransform);
- this->addTextureSampler(&fYSampler);
- this->addCoordTransform(&fUTransform);
- this->addTextureSampler(&fUSampler);
- if (!fNV12) {
- this->addCoordTransform(&fVTransform);
- this->addTextureSampler(&fVSampler);
- }
- }
-
- GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
- return new GLSLProcessor;
- }
-
- void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
- b->add32(fNV12);
- }
-
- bool onIsEqual(const GrFragmentProcessor& sBase) const override {
- const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
- return (fColorSpace == s.getColorSpace()) && (fNV12 == s.isNV12());
- }
-
- GrCoordTransform fYTransform;
- TextureSampler fYSampler;
- GrCoordTransform fUTransform;
- TextureSampler fUSampler;
- GrCoordTransform fVTransform;
- TextureSampler fVSampler;
- SkYUVColorSpace fColorSpace;
- bool fNV12;
-
- typedef GrFragmentProcessor INHERITED;
-};
-
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-std::unique_ptr<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(
- sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy, sk_sp<GrTextureProxy> vProxy,
- const SkISize sizes[3], SkYUVColorSpace colorSpace, bool nv12) {
- SkASSERT(yProxy && uProxy && vProxy && sizes);
- return YUVtoRGBEffect::Make(std::move(yProxy), std::move(uProxy), std::move(vProxy),
- sizes, colorSpace, nv12);
-}
diff --git a/src/gpu/effects/GrYUVEffect.h b/src/gpu/effects/GrYUVEffect.h
deleted file mode 100644
index e111d4e153..0000000000
--- a/src/gpu/effects/GrYUVEffect.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrYUVEffect_DEFINED
-#define GrYUVEffect_DEFINED
-
-#include "SkImageInfo.h"
-
-class GrFragmentProcessor;
-class GrTextureProxy;
-
-namespace GrYUVEffect {
-
-/**
- * Creates an effect that performs color conversion from YUV to RGB. The input textures are
- * assumed to be kA8_GrPixelConfig.
- */
-std::unique_ptr<GrFragmentProcessor> MakeYUVToRGB(sk_sp<GrTextureProxy> yProxy,
- sk_sp<GrTextureProxy> uProxy,
- sk_sp<GrTextureProxy> vProxy,
- const SkISize sizes[3],
- SkYUVColorSpace colorSpace, bool nv12);
-};
-
-#endif
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
new file mode 100644
index 0000000000..b1cd36f72b
--- /dev/null
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * This file was autogenerated from GrYUVtoRGBEffect.fp; do not modify.
+ */
+#include "GrYUVtoRGBEffect.h"
+#if SK_SUPPORT_GPU
+
+static const float kJPEGConversionMatrix[16] = {
+ 1.0f, 0.0f, 1.402f, -0.703749f, 1.0f, -0.344136f, -0.714136f, 0.531211f,
+ 1.0f, 1.772f, 0.0f, -0.889475f, 0.0f, 0.0f, 0.0f, 1.0};
+
+static const float kRec601ConversionMatrix[16] = {
+ 1.164f, 0.0f, 1.596f, -0.87075f, 1.164f, -0.391f, -0.813f, 0.52925f,
+ 1.164f, 2.018f, 0.0f, -1.08175f, 0.0f, 0.0f, 0.0f, 1.0};
+
+static const float kRec709ConversionMatrix[16] = {
+ 1.164f, 0.0f, 1.793f, -0.96925f, 1.164f, -0.213f, -0.533f, 0.30025f,
+ 1.164f, 2.112f, 0.0f, -1.12875f, 0.0f, 0.0f, 0.0f, 1.0f};
+
+std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy>
+ uProxy,
+ sk_sp<GrTextureProxy>
+ vProxy,
+ const SkISize sizes[3],
+ SkYUVColorSpace colorSpace,
+ bool nv12) {
+ SkScalar w[3], h[3];
+ w[0] = SkIntToScalar(sizes[0].fWidth);
+ h[0] = SkIntToScalar(sizes[0].fHeight);
+ w[1] = SkIntToScalar(sizes[1].fWidth);
+ h[1] = SkIntToScalar(sizes[1].fHeight);
+ w[2] = SkIntToScalar(sizes[2].fWidth);
+ h[2] = SkIntToScalar(sizes[2].fHeight);
+ SkMatrix yTransform = SkMatrix::I();
+ SkMatrix uTransform = SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]);
+ SkMatrix vTransform = SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]);
+ GrSamplerState::Filter uvFilterMode =
+ ((sizes[1].fWidth != sizes[0].fWidth) || (sizes[1].fHeight != sizes[0].fHeight) ||
+ (sizes[2].fWidth != sizes[0].fWidth) || (sizes[2].fHeight != sizes[0].fHeight))
+ ? GrSamplerState::Filter::kBilerp
+ : GrSamplerState::Filter::kNearest;
+ SkMatrix44 mat;
+ switch (colorSpace) {
+ case kJPEG_SkYUVColorSpace:
+ mat.setColMajorf(kJPEGConversionMatrix);
+ break;
+ case kRec601_SkYUVColorSpace:
+ mat.setColMajorf(kRec601ConversionMatrix);
+ break;
+ case kRec709_SkYUVColorSpace:
+ mat.setColMajorf(kRec709ConversionMatrix);
+ break;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(
+ std::move(yProxy), yTransform, std::move(uProxy), uTransform, std::move(vProxy),
+ vTransform, mat, nv12, GrSamplerState(GrSamplerState::WrapMode::kClamp, uvFilterMode)));
+}
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLYUVtoRGBEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLYUVtoRGBEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrYUVtoRGBEffect& _outer = args.fFp.cast<GrYUVtoRGBEffect>();
+ (void)_outer;
+ auto ySamplerTransform = _outer.ySamplerTransform();
+ (void)ySamplerTransform;
+ auto uSamplerTransform = _outer.uSamplerTransform();
+ (void)uSamplerTransform;
+ auto vSamplerTransform = _outer.vSamplerTransform();
+ (void)vSamplerTransform;
+ auto colorSpaceMatrix = _outer.colorSpaceMatrix();
+ (void)colorSpaceMatrix;
+ auto nv12 = _outer.nv12();
+ (void)nv12;
+ fColorSpaceMatrixVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4x4_GrSLType,
+ kDefault_GrSLPrecision, "colorSpaceMatrix");
+ SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_1 = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]);
+ SkString sk_TransformedCoords2D_2 = fragBuilder->ensureCoords2D(args.fTransformedCoords[2]);
+ fragBuilder->codeAppendf(
+ "@if (%s) {\n %s = half4(texture(%s, %s).%s.x, texture(%s, %s).%s.xy, 1.0) * "
+ "%s;\n} else {\n %s = half4(texture(%s, %s).%s.x, texture(%s, %s).%s.x, "
+ "texture(%s, %s).%s.x, 1.0) * %s;\n}\n",
+ (_outer.nv12() ? "true" : "false"), args.fOutputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ sk_TransformedCoords2D_0.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(),
+ sk_TransformedCoords2D_1.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(),
+ args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar), args.fOutputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ sk_TransformedCoords2D_0.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(),
+ sk_TransformedCoords2D_1.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[2]).c_str(),
+ sk_TransformedCoords2D_2.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[2]).c_str(),
+ args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar));
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrYUVtoRGBEffect& _outer = _proc.cast<GrYUVtoRGBEffect>();
+ {
+ float colorSpaceMatrixValue[16];
+ _outer.colorSpaceMatrix().asColMajorf(colorSpaceMatrixValue);
+ pdman.setMatrix4f(fColorSpaceMatrixVar, colorSpaceMatrixValue);
+ }
+ }
+ UniformHandle fColorSpaceMatrixVar;
+};
+GrGLSLFragmentProcessor* GrYUVtoRGBEffect::onCreateGLSLInstance() const {
+ return new GrGLSLYUVtoRGBEffect();
+}
+void GrYUVtoRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)fNv12);
+}
+bool GrYUVtoRGBEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrYUVtoRGBEffect& that = other.cast<GrYUVtoRGBEffect>();
+ (void)that;
+ if (fYSampler != that.fYSampler) return false;
+ if (fYSamplerTransform != that.fYSamplerTransform) return false;
+ if (fUSampler != that.fUSampler) return false;
+ if (fUSamplerTransform != that.fUSamplerTransform) return false;
+ if (fVSampler != that.fVSampler) return false;
+ if (fVSamplerTransform != that.fVSamplerTransform) return false;
+ if (fColorSpaceMatrix != that.fColorSpaceMatrix) return false;
+ if (fNv12 != that.fNv12) return false;
+ return true;
+}
+GrYUVtoRGBEffect::GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src)
+ : INHERITED(kGrYUVtoRGBEffect_ClassID, src.optimizationFlags())
+ , fYSampler(src.fYSampler)
+ , fYSamplerTransform(src.fYSamplerTransform)
+ , fUSampler(src.fUSampler)
+ , fUSamplerTransform(src.fUSamplerTransform)
+ , fVSampler(src.fVSampler)
+ , fVSamplerTransform(src.fVSamplerTransform)
+ , fColorSpaceMatrix(src.fColorSpaceMatrix)
+ , fNv12(src.fNv12)
+ , fYSamplerCoordTransform(src.fYSamplerCoordTransform)
+ , fUSamplerCoordTransform(src.fUSamplerCoordTransform)
+ , fVSamplerCoordTransform(src.fVSamplerCoordTransform) {
+ this->addTextureSampler(&fYSampler);
+ this->addTextureSampler(&fUSampler);
+ this->addTextureSampler(&fVSampler);
+ this->addCoordTransform(&fYSamplerCoordTransform);
+ this->addCoordTransform(&fUSamplerCoordTransform);
+ this->addCoordTransform(&fVSamplerCoordTransform);
+}
+std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(*this));
+}
+#endif
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.fp b/src/gpu/effects/GrYUVtoRGBEffect.fp
new file mode 100644
index 0000000000..999d95502d
--- /dev/null
+++ b/src/gpu/effects/GrYUVtoRGBEffect.fp
@@ -0,0 +1,116 @@
+in uniform sampler2D ySampler;
+in half4x4 ySamplerTransform;
+@coordTransform(ySampler) {
+ ySamplerTransform
+}
+
+in uniform sampler2D uSampler;
+in half4x4 uSamplerTransform;
+@coordTransform(uSampler) {
+ uSamplerTransform
+}
+@samplerParams(uSampler) {
+ uvSamplerParams
+}
+
+in uniform sampler2D vSampler;
+in half4x4 vSamplerTransform;
+@coordTransform(vSampler) {
+ vSamplerTransform
+}
+@samplerParams(vSampler) {
+ uvSamplerParams
+}
+
+in uniform half4x4 colorSpaceMatrix;
+layout(key) in bool nv12;
+
+@constructorParams {
+ GrSamplerState uvSamplerParams
+}
+
+@class {
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
+ const SkISize sizes[3],
+ SkYUVColorSpace colorSpace, bool nv12);
+}
+
+@cpp {
+ static const float kJPEGConversionMatrix[16] = {
+ 1.0f, 0.0f, 1.402f, -0.703749f,
+ 1.0f, -0.344136f, -0.714136f, 0.531211f,
+ 1.0f, 1.772f, 0.0f, -0.889475f,
+ 0.0f, 0.0f, 0.0f, 1.0
+ };
+
+ static const float kRec601ConversionMatrix[16] = {
+ 1.164f, 0.0f, 1.596f, -0.87075f,
+ 1.164f, -0.391f, -0.813f, 0.52925f,
+ 1.164f, 2.018f, 0.0f, -1.08175f,
+ 0.0f, 0.0f, 0.0f, 1.0}
+ ;
+
+ static const float kRec709ConversionMatrix[16] = {
+ 1.164f, 0.0f, 1.793f, -0.96925f,
+ 1.164f, -0.213f, -0.533f, 0.30025f,
+ 1.164f, 2.112f, 0.0f, -1.12875f,
+ 0.0f, 0.0f, 0.0f, 1.0f}
+ ;
+
+ std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
+ const SkISize sizes[3],
+ SkYUVColorSpace colorSpace,
+ bool nv12) {
+ SkScalar w[3], h[3];
+ w[0] = SkIntToScalar(sizes[0].fWidth);
+ h[0] = SkIntToScalar(sizes[0].fHeight);
+ w[1] = SkIntToScalar(sizes[1].fWidth);
+ h[1] = SkIntToScalar(sizes[1].fHeight);
+ w[2] = SkIntToScalar(sizes[2].fWidth);
+ h[2] = SkIntToScalar(sizes[2].fHeight);
+ SkMatrix yTransform = SkMatrix::I();
+ SkMatrix uTransform = SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]);
+ SkMatrix vTransform = SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]);
+ GrSamplerState::Filter uvFilterMode =
+ ((sizes[1].fWidth != sizes[0].fWidth) ||
+ (sizes[1].fHeight != sizes[0].fHeight) ||
+ (sizes[2].fWidth != sizes[0].fWidth) ||
+ (sizes[2].fHeight != sizes[0].fHeight)) ?
+ GrSamplerState::Filter::kBilerp :
+ GrSamplerState::Filter::kNearest;
+ SkMatrix44 mat;
+ switch (colorSpace) {
+ case kJPEG_SkYUVColorSpace:
+ mat.setColMajorf(kJPEGConversionMatrix);
+ break;
+ case kRec601_SkYUVColorSpace:
+ mat.setColMajorf(kRec601ConversionMatrix);
+ break;
+ case kRec709_SkYUVColorSpace:
+ mat.setColMajorf(kRec709ConversionMatrix);
+ break;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrYUVtoRGBEffect(std::move(yProxy), yTransform, std::move(uProxy), uTransform,
+ std::move(vProxy), vTransform, mat, nv12,
+ GrSamplerState(GrSamplerState::WrapMode::kClamp,
+ uvFilterMode)));
+ }
+}
+
+void main() {
+ @if (nv12) {
+ sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r,
+ texture(uSampler, sk_TransformedCoords2D[1]).rg,
+ 1.0) * colorSpaceMatrix;
+ } else {
+ sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r,
+ texture(uSampler, sk_TransformedCoords2D[1]).r,
+ texture(vSampler, sk_TransformedCoords2D[2]).r,
+ 1.0) * colorSpaceMatrix;
+ }
+}
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.h b/src/gpu/effects/GrYUVtoRGBEffect.h
new file mode 100644
index 0000000000..68223efa1e
--- /dev/null
+++ b/src/gpu/effects/GrYUVtoRGBEffect.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * This file was autogenerated from GrYUVtoRGBEffect.fp; do not modify.
+ */
+#ifndef GrYUVtoRGBEffect_DEFINED
+#define GrYUVtoRGBEffect_DEFINED
+#include "SkTypes.h"
+#if SK_SUPPORT_GPU
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrYUVtoRGBEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
+ const SkISize sizes[3],
+ SkYUVColorSpace colorSpace, bool nv12);
+ SkMatrix44 ySamplerTransform() const { return fYSamplerTransform; }
+ SkMatrix44 uSamplerTransform() const { return fUSamplerTransform; }
+ SkMatrix44 vSamplerTransform() const { return fVSamplerTransform; }
+ SkMatrix44 colorSpaceMatrix() const { return fColorSpaceMatrix; }
+ bool nv12() const { return fNv12; }
+ static std::unique_ptr<GrFragmentProcessor> Make(
+ sk_sp<GrTextureProxy> ySampler, SkMatrix44 ySamplerTransform,
+ sk_sp<GrTextureProxy> uSampler, SkMatrix44 uSamplerTransform,
+ sk_sp<GrTextureProxy> vSampler, SkMatrix44 vSamplerTransform,
+ SkMatrix44 colorSpaceMatrix, bool nv12, GrSamplerState uvSamplerParams) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(
+ ySampler, ySamplerTransform, uSampler, uSamplerTransform, vSampler,
+ vSamplerTransform, colorSpaceMatrix, nv12, uvSamplerParams));
+ }
+ GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "YUVtoRGBEffect"; }
+
+private:
+ GrYUVtoRGBEffect(sk_sp<GrTextureProxy> ySampler, SkMatrix44 ySamplerTransform,
+ sk_sp<GrTextureProxy> uSampler, SkMatrix44 uSamplerTransform,
+ sk_sp<GrTextureProxy> vSampler, SkMatrix44 vSamplerTransform,
+ SkMatrix44 colorSpaceMatrix, bool nv12, GrSamplerState uvSamplerParams)
+ : INHERITED(kGrYUVtoRGBEffect_ClassID, kNone_OptimizationFlags)
+ , fYSampler(std::move(ySampler))
+ , fYSamplerTransform(ySamplerTransform)
+ , fUSampler(std::move(uSampler), uvSamplerParams)
+ , fUSamplerTransform(uSamplerTransform)
+ , fVSampler(std::move(vSampler), uvSamplerParams)
+ , fVSamplerTransform(vSamplerTransform)
+ , fColorSpaceMatrix(colorSpaceMatrix)
+ , fNv12(nv12)
+ , fYSamplerCoordTransform(ySamplerTransform, fYSampler.proxy())
+ , fUSamplerCoordTransform(uSamplerTransform, fUSampler.proxy())
+ , fVSamplerCoordTransform(vSamplerTransform, fVSampler.proxy()) {
+ this->addTextureSampler(&fYSampler);
+ this->addTextureSampler(&fUSampler);
+ this->addTextureSampler(&fVSampler);
+ this->addCoordTransform(&fYSamplerCoordTransform);
+ this->addCoordTransform(&fUSamplerCoordTransform);
+ this->addCoordTransform(&fVSamplerCoordTransform);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ TextureSampler fYSampler;
+ SkMatrix44 fYSamplerTransform;
+ TextureSampler fUSampler;
+ SkMatrix44 fUSamplerTransform;
+ TextureSampler fVSampler;
+ SkMatrix44 fVSamplerTransform;
+ SkMatrix44 fColorSpaceMatrix;
+ bool fNv12;
+ GrCoordTransform fYSamplerCoordTransform;
+ GrCoordTransform fUSamplerCoordTransform;
+ GrCoordTransform fVSamplerCoordTransform;
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
+#endif
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 9d2b9490de..54a7e98236 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -28,7 +28,7 @@
#include "GrTexturePriv.h"
#include "GrTextureProxy.h"
#include "effects/GrNonlinearColorSpaceXformEffect.h"
-#include "effects/GrYUVEffect.h"
+#include "effects/GrYUVtoRGBEffect.h"
#include "SkCanvas.h"
#include "SkBitmapCache.h"
#include "SkGr.h"
@@ -427,8 +427,8 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.addColorFragmentProcessor(GrYUVEffect::MakeYUVToRGB(yProxy, uProxy, vProxy,
- yuvSizes, colorSpace, nv12));
+ paint.addColorFragmentProcessor(GrYUVtoRGBEffect::Make(yProxy, uProxy, vProxy,
+ yuvSizes, colorSpace, nv12));
const SkRect rect = SkRect::MakeIWH(width, height);