diff options
author | Robert Phillips <robertphillips@google.com> | 2017-01-23 15:30:35 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-24 12:23:28 +0000 |
commit | bc7a4fb06780f9829b4b21470fe6f0503d2297cd (patch) | |
tree | d8a2460df05c73909530a3316cdc8b6192d5c55e | |
parent | ad24145e41b473012a900818933291541e80815c (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.cpp | 77 | ||||
-rw-r--r-- | include/gpu/GrCoordTransform.h | 26 | ||||
-rw-r--r-- | include/gpu/GrProcessor.h | 8 | ||||
-rw-r--r-- | src/gpu/GrCoordTransform.cpp | 69 | ||||
-rw-r--r-- | src/gpu/GrProcessor.cpp | 11 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrYUVProvider.cpp | 35 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVEffect.cpp | 41 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVEffect.h | 22 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 20 |
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)); |