aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-06-08 17:22:23 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-08 23:07:25 +0000
commit8f5bbda0071e5663f454804e370e66f86b87078b (patch)
tree7214467a0ba834ae948b8f108c0ccc5b7cb2dde5
parent09c9400695c87be11f0ef5268e0f6efce0e62831 (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>
-rw-r--r--src/gpu/GrBitmapTextureMaker.cpp4
-rw-r--r--src/gpu/GrGpu.cpp36
-rw-r--r--src/gpu/GrGpu.h17
-rw-r--r--src/gpu/GrTextureAdjuster.cpp24
-rw-r--r--src/gpu/GrTextureMaker.cpp41
-rw-r--r--src/gpu/gl/GrGLGpu.cpp6
-rw-r--r--src/image/SkImage_Lazy.cpp4
7 files changed, 97 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, &copyParams,
- scaleAdjust)) {
- return proxy;
+ bool needsCopyForMipsOnly = false;
+ if (!params.isRepeated() ||
+ !GrGpu::IsACopyNeededForRepeatWrapMode(fContext->contextPriv().caps(), proxy.get(),
+ proxy->width(), proxy->height(), params.filter(),
+ &copyParams, scaleAdjust)) {
+ needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(fContext->contextPriv().caps(),
+ proxy.get(), params.filter(),
+ &copyParams);
+ 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,
- &copyParams, scaleAdjust)) {
- return original;
+ if (!params.isRepeated() ||
+ !GrGpu::IsACopyNeededForRepeatWrapMode(fContext->contextPriv().caps(), original.get(),
+ original->width(), original->height(),
+ params.filter(), &copyParams, scaleAdjust)) {
+ needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(fContext->contextPriv().caps(),
+ original.get(), params.filter(),
+ &copyParams);
+ if (!needsCopyForMipsOnly) {
+ return original;
+ }
}
} else {
- if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), nullptr,
- this->width(), this->height(), params,
- &copyParams, scaleAdjust)) {
+ if (!params.isRepeated() ||
+ !GrGpu::IsACopyNeededForRepeatWrapMode(fContext->contextPriv().caps(), nullptr,
+ this->width(), this->height(),
+ params.filter(), &copyParams, 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;
}
}
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index 33e430726e..19b324beaa 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -866,6 +866,10 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
set_key_on_proxy(proxyProvider, mippedProxy.get(), proxy.get(), key);
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;
}
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kFailure_LockTexturePath,