diff options
Diffstat (limited to 'src/gpu')
-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 |
6 files changed, 127 insertions, 55 deletions
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 |