diff options
author | Greg Daniel <egdaniel@google.com> | 2018-06-08 17:22:23 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-08 23:07:25 +0000 |
commit | 8f5bbda0071e5663f454804e370e66f86b87078b (patch) | |
tree | 7214467a0ba834ae948b8f108c0ccc5b7cb2dde5 /src/gpu | |
parent | 09c9400695c87be11f0ef5268e0f6efce0e62831 (diff) |
Fall back to bilerp if we are undable to do a copy for mips.
Bug: skia:
Change-Id: I52b86d83aaec1fa245be2ee17bbd56defcb5881f
Reviewed-on: https://skia-review.googlesource.com/133587
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrBitmapTextureMaker.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 36 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 17 | ||||
-rw-r--r-- | src/gpu/GrTextureAdjuster.cpp | 24 | ||||
-rw-r--r-- | src/gpu/GrTextureMaker.cpp | 41 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 6 |
6 files changed, 93 insertions, 35 deletions
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp index 4ecd761e37..d2a1fbe3e9 100644 --- a/src/gpu/GrBitmapTextureMaker.cpp +++ b/src/gpu/GrBitmapTextureMaker.cpp @@ -89,6 +89,10 @@ sk_sp<GrTextureProxy> GrBitmapTextureMaker::refOriginalTextureProxy(bool willBeM } return mippedProxy; } + // We failed to make a mipped proxy with the base copied into it. This could have + // been from failure to make the proxy or failure to do the copy. Thus we will fall + // back to just using the non mipped proxy; See skbug.com/7094. + return proxy; } return nullptr; } diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 8781cbfe6d..3ebfa364d4 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -45,12 +45,12 @@ void GrGpu::disconnect(DisconnectType) {} //////////////////////////////////////////////////////////////////////////////// -bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps, GrTextureProxy* texProxy, - int width, int height, - const GrSamplerState& textureParams, - GrTextureProducer::CopyParams* copyParams, - SkScalar scaleAdjust[2]) { - if (textureParams.isRepeated() && !caps->npotTextureTileSupport() && +bool GrGpu::IsACopyNeededForRepeatWrapMode(const GrCaps* caps, GrTextureProxy* texProxy, + int width, int height, + GrSamplerState::Filter filter, + GrTextureProducer::CopyParams* copyParams, + SkScalar scaleAdjust[2]) { + if (!caps->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(height))) { SkASSERT(scaleAdjust); copyParams->fWidth = GrNextPow2(width); @@ -58,7 +58,7 @@ bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps, GrTextureProxy* te SkASSERT(scaleAdjust); scaleAdjust[0] = ((SkScalar)copyParams->fWidth) / width; scaleAdjust[1] = ((SkScalar)copyParams->fHeight) / height; - switch (textureParams.filter()) { + switch (filter) { case GrSamplerState::Filter::kNearest: copyParams->fFilter = GrSamplerState::Filter::kNearest; break; @@ -72,12 +72,9 @@ bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps, GrTextureProxy* te } if (texProxy) { - bool willNeedMips = GrSamplerState::Filter::kMipMap == textureParams.filter() && - caps->mipMapSupport(); // If the texture format itself doesn't support repeat wrap mode or mipmapping (and // those capabilities are required) force a copy. - if ((textureParams.isRepeated() && texProxy->texPriv().isClampOnly()) || - (willNeedMips && texProxy->mipMapped() == GrMipMapped::kNo)) { + if (texProxy->texPriv().isClampOnly()) { copyParams->fFilter = GrSamplerState::Filter::kNearest; copyParams->fWidth = texProxy->width(); copyParams->fHeight = texProxy->height(); @@ -88,6 +85,23 @@ bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps, GrTextureProxy* te return false; } +bool GrGpu::IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy, + GrSamplerState::Filter filter, + GrTextureProducer::CopyParams* copyParams) { + SkASSERT(texProxy); + bool willNeedMips = GrSamplerState::Filter::kMipMap == filter && caps->mipMapSupport(); + // If the texture format itself doesn't support mipmapping (and those capabilities are required) + // force a copy. + if (willNeedMips && texProxy->mipMapped() == GrMipMapped::kNo) { + copyParams->fFilter = GrSamplerState::Filter::kNearest; + copyParams->fWidth = texProxy->width(); + copyParams->fHeight = texProxy->height(); + return true; + } + + return false; +} + sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budgeted, const GrMipLevel texels[], int mipLevelCount) { GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "createTexture", fContext); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index ad20d52366..d97a22edd0 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -379,10 +379,19 @@ public: // Determines whether a texture will need to be rescaled in order to be used with the // GrSamplerState. - static bool IsACopyNeededForTextureParams(const GrCaps*, GrTextureProxy* texProxy, - int width, int height, - const GrSamplerState&, GrTextureProducer::CopyParams*, - SkScalar scaleAdjust[2]); + static bool IsACopyNeededForRepeatWrapMode(const GrCaps*, GrTextureProxy* texProxy, + int width, int height, + GrSamplerState::Filter, + GrTextureProducer::CopyParams*, + SkScalar scaleAdjust[2]); + + // Determines whether a texture will need to be copied because the draw requires mips but the + // texutre doesn't have any. This call should be only checked if IsACopyNeededForTextureParams + // fails. If the previous call succeeds, then a copy should be done using those params and the + // mip mapping requirements will be handled there. + static bool IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy, + GrSamplerState::Filter filter, + GrTextureProducer::CopyParams* copyParams); void handleDirtyContext() { if (fResetBits) { diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp index cb296f9ce9..05b1cf4241 100644 --- a/src/gpu/GrTextureAdjuster.cpp +++ b/src/gpu/GrTextureAdjuster.cpp @@ -92,15 +92,29 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::onRefTextureProxyForParams( SkASSERT(this->width() <= fContext->contextPriv().caps()->maxTextureSize() && this->height() <= fContext->contextPriv().caps()->maxTextureSize()); - if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), proxy.get(), - proxy->width(), proxy->height(), params, ©Params, - scaleAdjust)) { - return proxy; + bool needsCopyForMipsOnly = false; + if (!params.isRepeated() || + !GrGpu::IsACopyNeededForRepeatWrapMode(fContext->contextPriv().caps(), proxy.get(), + proxy->width(), proxy->height(), params.filter(), + ©Params, scaleAdjust)) { + needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(fContext->contextPriv().caps(), + proxy.get(), params.filter(), + ©Params); + if (!needsCopyForMipsOnly) { + return proxy; + } } bool willBeMipped = GrSamplerState::Filter::kMipMap == params.filter() && fContext->contextPriv().caps()->mipMapSupport(); - return this->refTextureProxyCopy(copyParams, willBeMipped); + sk_sp<GrTextureProxy> result = this->refTextureProxyCopy(copyParams, willBeMipped); + if (!result && needsCopyForMipsOnly) { + // If we were unable to make a copy and we only needed a copy for mips, then we will return + // the source texture here and require that the GPU backend is able to fall back to using + // bilerp if mips are required. + return this->originalProxyRef(); + } + return result; } std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor( diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp index 58ab38de97..a8295129ef 100644 --- a/src/gpu/GrTextureMaker.cpp +++ b/src/gpu/GrTextureMaker.cpp @@ -35,16 +35,24 @@ sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSampler sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace, AllowedTexGenType::kCheap)); + bool needsCopyForMipsOnly = false; if (original) { - if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), original.get(), - original->width(), original->height(), params, - ©Params, scaleAdjust)) { - return original; + if (!params.isRepeated() || + !GrGpu::IsACopyNeededForRepeatWrapMode(fContext->contextPriv().caps(), original.get(), + original->width(), original->height(), + params.filter(), ©Params, scaleAdjust)) { + needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(fContext->contextPriv().caps(), + original.get(), params.filter(), + ©Params); + if (!needsCopyForMipsOnly) { + return original; + } } } else { - if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), nullptr, - this->width(), this->height(), params, - ©Params, scaleAdjust)) { + if (!params.isRepeated() || + !GrGpu::IsACopyNeededForRepeatWrapMode(fContext->contextPriv().caps(), nullptr, + this->width(), this->height(), + params.filter(), ©Params, scaleAdjust)) { return this->refOriginalTextureProxy(willBeMipped, dstColorSpace, AllowedTexGenType::kAny); } @@ -63,23 +71,30 @@ sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSampler } } - sk_sp<GrTextureProxy> result; + sk_sp<GrTextureProxy> source; if (original) { - result = std::move(original); + source = std::move(original); } else if (cachedProxy) { - result = cachedProxy; + source = cachedProxy; } else { // Since we will be copying this texture there is no reason to make it mipped - result = this->refOriginalTextureProxy(false, dstColorSpace, + source = this->refOriginalTextureProxy(false, dstColorSpace, AllowedTexGenType::kAny); } - if (!result) { + + if (!source) { return nullptr; } - result = CopyOnGpu(fContext, std::move(result), copyParams, willBeMipped); + sk_sp<GrTextureProxy> result = CopyOnGpu(fContext, source, copyParams, willBeMipped); if (!result) { + // If we were unable to make a copy and we only needed a copy for mips, then we will return + // the source texture here and require that the GPU backend is able to fall back to using + // bilerp if mips are required. + if (needsCopyForMipsOnly) { + return source; + } return nullptr; } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index f37356454a..42291ed571 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2738,7 +2738,8 @@ void GrGLGpu::bindTexture(int unitIdx, const GrSamplerState& samplerState, GrGLT GrSamplerState::Filter filterMode = samplerState.filter(); if (GrSamplerState::Filter::kMipMap == filterMode) { - if (!this->caps()->mipMapSupport()) { + if (!this->caps()->mipMapSupport() || + texture->texturePriv().mipMapped() == GrMipMapped::kNo) { filterMode = GrSamplerState::Filter::kBilerp; } } @@ -2849,7 +2850,8 @@ void GrGLGpu::generateMipmaps(const GrSamplerState& params, GrGLTexture* texture GrSamplerState::Filter filterMode = params.filter(); if (GrSamplerState::Filter::kMipMap == filterMode) { - if (!this->caps()->mipMapSupport()) { + if (!this->caps()->mipMapSupport() || + texture->texturePriv().mipMapped() == GrMipMapped::kNo) { filterMode = GrSamplerState::Filter::kBilerp; } } |