aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-01-23 15:30:35 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-24 12:23:28 +0000
commitbc7a4fb06780f9829b4b21470fe6f0503d2297cd (patch)
treed8a2460df05c73909530a3316cdc8b6192d5c55e
parentad24145e41b473012a900818933291541e80815c (diff)
Make GrYUVEffect take GrTextureProxies
This opens the door for swapping all the effects over to taking GrTextureProxies. Change-Id: I3b03ba93a68f9945c9a8fee008fd170ed57616eb Reviewed-on: https://skia-review.googlesource.com/7344 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r--gm/yuvtorgbeffect.cpp77
-rw-r--r--include/gpu/GrCoordTransform.h26
-rw-r--r--include/gpu/GrProcessor.h8
-rw-r--r--src/gpu/GrCoordTransform.cpp69
-rw-r--r--src/gpu/GrProcessor.cpp11
-rw-r--r--src/gpu/GrSurfaceProxy.cpp4
-rw-r--r--src/gpu/GrYUVProvider.cpp35
-rw-r--r--src/gpu/effects/GrYUVEffect.cpp41
-rw-r--r--src/gpu/effects/GrYUVEffect.h22
-rw-r--r--src/image/SkImage_Gpu.cpp20
10 files changed, 226 insertions, 87 deletions
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index 324446392d..fa82f9090b 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -13,6 +13,7 @@
#include "GrContext.h"
#include "GrRenderTargetContextPriv.h"
+#include "GrTextureProxy.h"
#include "SkBitmap.h"
#include "SkGr.h"
#include "SkGradientShader.h"
@@ -72,7 +73,7 @@ protected:
canvas->internal_private_accessTopLayerRenderTargetContext();
if (!renderTargetContext) {
skiagm::GM::DrawGpuOnlyMessage(canvas);
- return;
+ return;
}
GrContext* context = canvas->getGrContext();
@@ -80,16 +81,25 @@ protected:
return;
}
- sk_sp<GrTexture> texture[3];
- texture[0].reset(
- GrRefCachedBitmapTexture(context, fBmp[0], GrSamplerParams::ClampBilerp(), nullptr));
- texture[1].reset(
- GrRefCachedBitmapTexture(context, fBmp[1], GrSamplerParams::ClampBilerp(), nullptr));
- texture[2].reset(
- GrRefCachedBitmapTexture(context, fBmp[2], GrSamplerParams::ClampBilerp(), nullptr));
+ sk_sp<GrSurfaceProxy> proxy[3];
- if (!texture[0] || !texture[1] || !texture[2]) {
- return;
+ {
+ GrSurfaceDesc desc;
+ desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+ desc.fConfig = kAlpha_8_GrPixelConfig;
+
+ for (int i = 0; i < 3; ++i) {
+ desc.fWidth = fBmp[i].width();
+ desc.fHeight = fBmp[i].height();
+
+ proxy[i] = GrSurfaceProxy::MakeDeferred(*context->caps(),
+ context->textureProvider(),
+ desc, SkBudgeted::kYes,
+ fBmp[i].getPixels(), fBmp[i].rowBytes());
+ if (!proxy[i]) {
+ return;
+ }
+ }
}
constexpr SkScalar kDrawPad = 10.f;
@@ -97,8 +107,7 @@ protected:
constexpr SkScalar kColorSpaceOffset = 36.f;
SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
- for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace;
- ++space) {
+ for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
SkIntToScalar(fBmp[0].height()));
renderRect.outset(kDrawPad, kDrawPad);
@@ -111,9 +120,10 @@ protected:
for (int i = 0; i < 6; ++i) {
sk_sp<GrFragmentProcessor> fp(
- GrYUVEffect::MakeYUVToRGB(texture[indices[i][0]].get(),
- texture[indices[i][1]].get(),
- texture[indices[i][2]].get(),
+ GrYUVEffect::MakeYUVToRGB(context,
+ sk_ref_sp(proxy[indices[i][0]]->asTextureProxy()),
+ sk_ref_sp(proxy[indices[i][1]]->asTextureProxy()),
+ sk_ref_sp(proxy[indices[i][2]]->asTextureProxy()),
sizes,
static_cast<SkYUVColorSpace>(space),
false));
@@ -202,16 +212,30 @@ protected:
return;
}
- sk_sp<GrTexture> texture[3];
- texture[0].reset(
- GrRefCachedBitmapTexture(context, fBmp[0], GrSamplerParams::ClampBilerp(), nullptr));
- texture[1].reset(
- GrRefCachedBitmapTexture(context, fBmp[1], GrSamplerParams::ClampBilerp(), nullptr));
- texture[2].reset(
- GrRefCachedBitmapTexture(context, fBmp[1], GrSamplerParams::ClampBilerp(), nullptr));
+ sk_sp<GrSurfaceProxy> proxy[3];
- if (!texture[0] || !texture[1] || !texture[2]) {
- return;
+ {
+ GrSurfaceDesc desc;
+ desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+
+ for (int i = 0; i < 3; ++i) {
+ int index = (0 == i) ? 0 : 1;
+
+ desc.fConfig = kAlpha_8_SkColorType == fBmp[index].colorType()
+ ? kAlpha_8_GrPixelConfig
+ : kBGRA_8888_GrPixelConfig;
+ desc.fWidth = fBmp[index].width();
+ desc.fHeight = fBmp[index].height();
+
+ proxy[i] = GrSurfaceProxy::MakeDeferred(*context->caps(),
+ context->textureProvider(),
+ desc, SkBudgeted::kYes,
+ fBmp[index].getPixels(),
+ fBmp[index].rowBytes());
+ if (!proxy[i]) {
+ return;
+ }
+ }
}
constexpr SkScalar kDrawPad = 10.f;
@@ -230,7 +254,10 @@ protected:
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
sk_sp<GrFragmentProcessor> fp(
- GrYUVEffect::MakeYUVToRGB(texture[0].get(), texture[1].get(), texture[2].get(),
+ GrYUVEffect::MakeYUVToRGB(context,
+ sk_ref_sp(proxy[0]->asTextureProxy()),
+ sk_ref_sp(proxy[1]->asTextureProxy()),
+ sk_ref_sp(proxy[2]->asTextureProxy()),
sizes, static_cast<SkYUVColorSpace>(space), true));
if (fp) {
SkMatrix viewMatrix;
diff --git a/include/gpu/GrCoordTransform.h b/include/gpu/GrCoordTransform.h
index 5c16c89679..a4d7d3565d 100644
--- a/include/gpu/GrCoordTransform.h
+++ b/include/gpu/GrCoordTransform.h
@@ -14,6 +14,8 @@
#include "GrTypes.h"
#include "GrShaderVar.h"
+class GrTextureProxy;
+
/**
* A class representing a linear transformation of local coordinates. GrFragnentProcessors
* these transformations, and the GrGeometryProcessor implements the transformation.
@@ -22,7 +24,9 @@ class GrCoordTransform : SkNoncopyable {
public:
GrCoordTransform()
: fTexture(nullptr)
- , fNormalize(false) {
+ , fNormalize(false)
+ , fReverseY(false)
+ , fPrecision(kDefault_GrSLPrecision) {
SkDEBUGCODE(fInProcessor = false);
}
@@ -37,17 +41,31 @@ public:
this->reset(SkMatrix::I(), texture, filter);
}
+ GrCoordTransform(GrContext* context, GrTextureProxy* proxy,
+ GrSamplerParams::FilterMode filter) {
+ SkASSERT(proxy);
+ SkDEBUGCODE(fInProcessor = false);
+ this->reset(context, SkMatrix::I(), proxy, filter);
+ }
+
/**
* Create a transformation from a matrix. The precision is inferred from the texture size and
* filter. The texture origin also implies whether a y-reversal should be performed.
*/
GrCoordTransform(const SkMatrix& m, const GrTexture* texture,
GrSamplerParams::FilterMode filter) {
- SkDEBUGCODE(fInProcessor = false);
SkASSERT(texture);
+ SkDEBUGCODE(fInProcessor = false);
this->reset(m, texture, filter);
}
+ GrCoordTransform(GrContext* context, const SkMatrix& m, GrTextureProxy* proxy,
+ GrSamplerParams::FilterMode filter) {
+ SkASSERT(proxy);
+ SkDEBUGCODE(fInProcessor = false);
+ this->reset(context, m, proxy, filter);
+ }
+
/**
* Create a transformation that applies the matrix to a coord set.
*/
@@ -56,9 +74,13 @@ public:
this->reset(m, precision);
}
+ // MDB TODO: rm the GrTexture* flavor of reset
void reset(const SkMatrix&, const GrTexture*, GrSamplerParams::FilterMode filter,
bool normalize = true);
+ void reset(GrContext* context, const SkMatrix&, GrTextureProxy*,
+ GrSamplerParams::FilterMode filter, bool normalize = true);
+
void reset(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
SkASSERT(!fInProcessor);
fMatrix = m;
diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h
index f933c9a9f7..a8e31f2c86 100644
--- a/include/gpu/GrProcessor.h
+++ b/include/gpu/GrProcessor.h
@@ -22,6 +22,8 @@
class GrContext;
class GrCoordTransform;
class GrInvariantOutput;
+class GrTextureProvider;
+class GrTextureProxy;
/**
* Used by processors to build their keys. It incorporates each per-processor key into a larger
@@ -209,6 +211,12 @@ public:
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
GrShaderFlags visibility = kFragment_GrShaderFlag);
+ // MDB TODO: ultimately we shouldn't need the texProvider parameter
+ explicit TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>,
+ GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
+ SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
+ GrShaderFlags visibility = kFragment_GrShaderFlag);
+
void reset(GrTexture*, const GrSamplerParams&,
GrShaderFlags visibility = kFragment_GrShaderFlag);
void reset(GrTexture*,
diff --git a/src/gpu/GrCoordTransform.cpp b/src/gpu/GrCoordTransform.cpp
index 4afd0efbce..99b3a09fc9 100644
--- a/src/gpu/GrCoordTransform.cpp
+++ b/src/gpu/GrCoordTransform.cpp
@@ -9,30 +9,23 @@
#include "GrCaps.h"
#include "GrContext.h"
#include "GrGpu.h"
+#include "GrTextureProxy.h"
-void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
- GrSamplerParams::FilterMode filter, bool normalize) {
- SkASSERT(texture);
- SkASSERT(!fInProcessor);
-
- fMatrix = m;
- fTexture = texture;
- fNormalize = normalize;
- fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
-
+static GrSLPrecision compute_precision(const GrShaderCaps* caps,
+ int width, int height,
+ GrSamplerParams::FilterMode filter) {
// Always start at kDefault. Then if precisions differ we see if the precision needs to be
// increased. Our rule is that we want at least 4 subpixel values in the representation for
// coords between 0 to 1 when bi- or tri-lerping and 1 value when nearest filtering. Note that
// this still might not be enough when drawing with repeat or mirror-repeat modes but that case
// can be arbitrarily bad.
int subPixelThresh = filter > GrSamplerParams::kNone_FilterMode ? 4 : 1;
- fPrecision = kDefault_GrSLPrecision;
- if (texture->getContext()) {
- const GrShaderCaps* caps = texture->getContext()->caps()->shaderCaps();
+ GrSLPrecision precision = kDefault_GrSLPrecision;
+ if (caps) {
if (caps->floatPrecisionVaries()) {
- int maxD = SkTMax(texture->width(), texture->height());
+ int maxD = SkTMax(width, height);
const GrShaderCaps::PrecisionInfo* info;
- info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, fPrecision);
+ info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, precision);
do {
SkASSERT(info->supported());
// Make sure there is at least 2 bits of subpixel precision in the range of
@@ -40,17 +33,57 @@ void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
if ((2 << info->fBits) / maxD > subPixelThresh) {
break;
}
- if (kHigh_GrSLPrecision == fPrecision) {
+ if (kHigh_GrSLPrecision == precision) {
break;
}
- GrSLPrecision nextP = static_cast<GrSLPrecision>(fPrecision + 1);
+ GrSLPrecision nextP = static_cast<GrSLPrecision>(precision + 1);
info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, nextP);
if (!info->supported()) {
break;
}
- fPrecision = nextP;
+ precision = nextP;
} while (true);
}
}
+
+ return precision;
+}
+
+void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
+ GrSamplerParams::FilterMode filter, bool normalize) {
+ SkASSERT(texture);
+ SkASSERT(!fInProcessor);
+
+ fMatrix = m;
+ fTexture = texture;
+ fNormalize = normalize;
+ fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
+
+ if (texture->getContext()) {
+ fPrecision = compute_precision(texture->getContext()->caps()->shaderCaps(),
+ texture->width(), texture->height(), filter);
+ } else {
+ fPrecision = kDefault_GrSLPrecision;
+ }
+}
+
+void GrCoordTransform::reset(GrContext* context, const SkMatrix& m,
+ GrTextureProxy* proxy,
+ GrSamplerParams::FilterMode filter, bool normalize) {
+ SkASSERT(proxy);
+ SkASSERT(!fInProcessor);
+
+ fMatrix = m;
+ // MDB TODO: just GrCaps is needed for this method
+ // MDB TODO: once all the coord transforms take a proxy just store it here and
+ // instantiate later
+ fTexture = proxy->instantiate(context->textureProvider());
+ fNormalize = normalize;
+ fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin();
+
+ const GrCaps* caps = context->caps();
+ fPrecision = compute_precision(caps->shaderCaps(),
+ proxy->worstCaseWidth(*caps),
+ proxy->worstCaseHeight(*caps), filter);
}
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index f4bead2d08..3e1346482f 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -12,6 +12,7 @@
#include "GrMemoryPool.h"
#include "GrSamplerParams.h"
#include "GrTexturePriv.h"
+#include "GrTextureProxy.h"
#include "GrXferProcessor.h"
#include "SkSpinlock.h"
@@ -207,6 +208,16 @@ GrProcessor::TextureSampler::TextureSampler(GrTexture* texture,
this->reset(texture, filterMode, tileXAndY, visibility);
}
+GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
+ sk_sp<GrTextureProxy> proxy,
+ GrSamplerParams::FilterMode filterMode,
+ SkShader::TileMode tileXAndY,
+ GrShaderFlags visibility) {
+ // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
+ // to taking a GrSurfaceProxy just use the IORefs on the proxy
+ this->reset( proxy->instantiate(texProvider), filterMode, tileXAndY, visibility);
+}
+
void GrProcessor::TextureSampler::reset(GrTexture* texture,
const GrSamplerParams& params,
GrShaderFlags visibility) {
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 780ff8aa44..48fc401b4e 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -113,6 +113,10 @@ GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
}
sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) {
+ if (!surf) {
+ return nullptr;
+ }
+
if (surf->asTexture()) {
if (surf->asRenderTarget()) {
return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(std::move(surf)));
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 2f75d92b46..f3231a49da 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -6,7 +6,9 @@
*/
#include "GrContext.h"
+#include "GrContextPriv.h"
#include "GrRenderTargetContext.h"
+#include "GrTextureProxy.h"
#include "GrYUVProvider.h"
#include "effects/GrGammaEffect.h"
#include "effects/GrYUVEffect.h"
@@ -93,25 +95,29 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
}
GrSurfaceDesc yuvDesc;
+ yuvDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
- sk_sp<GrTexture> yuvTextures[3];
+ sk_sp<GrSurfaceContext> yuvTextureContexts[3];
for (int i = 0; i < 3; i++) {
yuvDesc.fWidth = yuvInfo.fSizeInfo.fSizes[i].fWidth;
yuvDesc.fHeight = yuvInfo.fSizeInfo.fSizes[i].fHeight;
// TODO: why do we need this check?
- bool needsExactTexture =
+ SkBackingFit fit =
(yuvDesc.fWidth != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth) ||
- (yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
- if (needsExactTexture) {
- yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc, SkBudgeted::kYes));
- } else {
- yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuvDesc));
+ (yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight)
+ ? SkBackingFit::kExact : SkBackingFit::kApprox;
+
+ yuvTextureContexts[i] = ctx->contextPriv().makeDeferredSurfaceContext(yuvDesc, fit,
+ SkBudgeted::kYes);
+ if (!yuvTextureContexts[i]) {
+ return nullptr;
+ }
+
+ const SkImageInfo ii = SkImageInfo::MakeA8(yuvDesc.fWidth, yuvDesc.fHeight);
+ if (!yuvTextureContexts[i]->writePixels(ii, planes[i],
+ yuvInfo.fSizeInfo.fWidthBytes[i], 0, 0)) {
+ return nullptr;
}
- if (!yuvTextures[i] ||
- !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, yuvDesc.fConfig,
- planes[i], yuvInfo.fSizeInfo.fWidthBytes[i])) {
- return nullptr;
- }
}
// We never want to perform color-space conversion during the decode
@@ -126,7 +132,10 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
GrPaint paint;
sk_sp<GrFragmentProcessor> yuvToRgbProcessor(
- GrYUVEffect::MakeYUVToRGB(yuvTextures[0].get(), yuvTextures[1].get(), yuvTextures[2].get(),
+ GrYUVEffect::MakeYUVToRGB(ctx,
+ sk_ref_sp(yuvTextureContexts[0]->asDeferredTexture()),
+ sk_ref_sp(yuvTextureContexts[1]->asDeferredTexture()),
+ sk_ref_sp(yuvTextureContexts[2]->asDeferredTexture()),
yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false));
paint.addColorFragmentProcessor(std::move(yuvToRgbProcessor));
diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp
index 6b15c0dc72..254cdffd2b 100644
--- a/src/gpu/effects/GrYUVEffect.cpp
+++ b/src/gpu/effects/GrYUVEffect.cpp
@@ -7,10 +7,12 @@
#include "GrYUVEffect.h"
+#include "GrContext.h"
#include "GrCoordTransform.h"
#include "GrFragmentProcessor.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
+#include "GrTextureProxy.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
@@ -62,8 +64,10 @@ static const float kRec709InverseConversionMatrix[16] = {
class YUVtoRGBEffect : public GrFragmentProcessor {
public:
- static sk_sp<GrFragmentProcessor> Make(GrTexture* yTexture, GrTexture* uTexture,
- GrTexture* vTexture, const SkISize sizes[3],
+ static sk_sp<GrFragmentProcessor> Make(GrContext* context,
+ 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);
@@ -85,7 +89,8 @@ public:
GrSamplerParams::kBilerp_FilterMode :
GrSamplerParams::kNone_FilterMode;
return sk_sp<GrFragmentProcessor>(new YUVtoRGBEffect(
- yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace, nv12));
+ context, std::move(yProxy), std::move(uProxy), std::move(vProxy),
+ yuvMatrix, uvFilterMode, colorSpace, nv12));
}
const char* name() const override { return "YUV to RGB"; }
@@ -150,14 +155,17 @@ public:
};
private:
- YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+ YUVtoRGBEffect(GrContext* ctx,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
const SkMatrix yuvMatrix[3], GrSamplerParams::FilterMode uvFilterMode,
SkYUVColorSpace colorSpace, bool nv12)
- : fYTransform(yuvMatrix[0], yTexture, GrSamplerParams::kNone_FilterMode)
- , fYSampler(yTexture)
- , fUTransform(yuvMatrix[1], uTexture, uvFilterMode)
- , fUSampler(uTexture, uvFilterMode)
- , fVSampler(vTexture, uvFilterMode)
+ : fYTransform(ctx, yuvMatrix[0], yProxy.get(), GrSamplerParams::kNone_FilterMode)
+ , fYSampler(ctx->textureProvider(), std::move(yProxy))
+ , fUTransform(ctx, yuvMatrix[1], uProxy.get(), uvFilterMode)
+ , fUSampler(ctx->textureProvider(), std::move(uProxy), uvFilterMode)
+ , fVSampler(ctx->textureProvider(), vProxy, uvFilterMode)
, fColorSpace(colorSpace)
, fNV12(nv12) {
this->initClassID<YUVtoRGBEffect>();
@@ -166,7 +174,7 @@ private:
this->addCoordTransform(&fUTransform);
this->addTextureSampler(&fUSampler);
if (!fNV12) {
- fVTransform = GrCoordTransform(yuvMatrix[2], vTexture, uvFilterMode);
+ fVTransform = GrCoordTransform(ctx, yuvMatrix[2], vProxy.get(), uvFilterMode);
this->addCoordTransform(&fVTransform);
this->addTextureSampler(&fVSampler);
}
@@ -362,11 +370,16 @@ private:
//////////////////////////////////////////////////////////////////////////////
-sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture,
- GrTexture* vTexture, const SkISize sizes[3],
+sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrContext* context,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
+ const SkISize sizes[3],
SkYUVColorSpace colorSpace, bool nv12) {
- SkASSERT(yTexture && uTexture && vTexture && sizes);
- return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace, nv12);
+ SkASSERT(yProxy && uProxy && vProxy && sizes);
+ return YUVtoRGBEffect::Make(context,
+ std::move(yProxy), std::move(uProxy), std::move(vProxy),
+ sizes, colorSpace, nv12);
}
sk_sp<GrFragmentProcessor>
diff --git a/src/gpu/effects/GrYUVEffect.h b/src/gpu/effects/GrYUVEffect.h
index 902a181fd4..6af442ea9a 100644
--- a/src/gpu/effects/GrYUVEffect.h
+++ b/src/gpu/effects/GrYUVEffect.h
@@ -10,16 +10,20 @@
#include "SkImageInfo.h"
+class GrContext;
class GrFragmentProcessor;
-class GrTexture;
+class GrTextureProvider;
+class GrTextureProxy;
namespace GrYUVEffect {
/**
* Creates an effect that performs color conversion from YUV to RGB. The input textures are
* assumed to be kA8_GrPixelConfig.
*/
- sk_sp<GrFragmentProcessor> MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture,
- GrTexture* vTexture, const SkISize sizes[3],
+ sk_sp<GrFragmentProcessor> MakeYUVToRGB(GrContext* context,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy, const SkISize sizes[3],
SkYUVColorSpace colorSpace, bool nv12);
/**
@@ -27,24 +31,22 @@ namespace GrYUVEffect {
* channels to Y, U ,and V channels. The output color is (y, u, v, a) where a is the passed in
* processor's alpha output.
*/
- sk_sp<GrFragmentProcessor> MakeRGBToYUV(sk_sp<GrFragmentProcessor>,
- SkYUVColorSpace colorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToYUV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
/**
* Creates a processor that performs color conversion from the passed in processor's RGB
* channels to U and V channels. The output color is (u, v, 0, a) where a is the passed in
* processor's alpha output.
*/
- sk_sp<GrFragmentProcessor> MakeRGBToUV(sk_sp<GrFragmentProcessor>,
- SkYUVColorSpace colorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToUV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
/**
* Creates a processor that performs color conversion from the passed in fragment processors's
* RGB channels to Y, U, or V (replicated across all four output color channels). The alpha
* output of the passed in fragment processor is ignored.
*/
- sk_sp<GrFragmentProcessor> MakeRGBToY(sk_sp<GrFragmentProcessor>, SkYUVColorSpace colorSpace);
- sk_sp<GrFragmentProcessor> MakeRGBToU(sk_sp<GrFragmentProcessor>, SkYUVColorSpace colorSpace);
- sk_sp<GrFragmentProcessor> MakeRGBToV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace colorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToY(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToU(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
};
#endif
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index fb93350039..a1ecf5bdad 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -18,6 +18,7 @@
#include "GrRenderTargetContext.h"
#include "GrTextureAdjuster.h"
#include "GrTexturePriv.h"
+#include "GrTextureProxy.h"
#include "effects/GrYUVEffect.h"
#include "SkCanvas.h"
#include "SkBitmapCache.h"
@@ -272,11 +273,16 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
sk_sp<GrTexture> yTex(
ctx->textureProvider()->wrapBackendTexture(yDesc, kBorrow_GrWrapOwnership));
+ sk_sp<GrSurfaceProxy> yProxy = GrSurfaceProxy::MakeWrapped(std::move(yTex));
+
sk_sp<GrTexture> uTex(
ctx->textureProvider()->wrapBackendTexture(uDesc, kBorrow_GrWrapOwnership));
- sk_sp<GrTexture> vTex;
+ sk_sp<GrSurfaceProxy> uProxy = GrSurfaceProxy::MakeWrapped(std::move(uTex));
+
+ sk_sp<GrSurfaceProxy> vProxy;
+
if (nv12) {
- vTex = uTex;
+ vProxy = uProxy;
} else {
GrBackendTextureDesc vDesc;
vDesc.fConfig = kConfig;
@@ -286,10 +292,11 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
vDesc.fWidth = yuvSizes[2].fWidth;
vDesc.fHeight = yuvSizes[2].fHeight;
- vTex = sk_sp<GrTexture>(
+ sk_sp<GrTexture> vTex = sk_sp<GrTexture>(
ctx->textureProvider()->wrapBackendTexture(vDesc, kBorrow_GrWrapOwnership));
+ vProxy = GrSurfaceProxy::MakeWrapped(std::move(vTex));
}
- if (!yTex || !uTex || !vTex) {
+ if (!yProxy || !uProxy || !vProxy) {
return nullptr;
}
@@ -311,7 +318,10 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
paint.addColorFragmentProcessor(
- GrYUVEffect::MakeYUVToRGB(yTex.get(), uTex.get(), vTex.get(), yuvSizes, colorSpace, nv12));
+ GrYUVEffect::MakeYUVToRGB(ctx,
+ sk_ref_sp(yProxy->asTextureProxy()),
+ sk_ref_sp(uProxy->asTextureProxy()),
+ sk_ref_sp(vProxy->asTextureProxy()), yuvSizes, colorSpace, nv12));
const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));