Take into accout the GrBackendFormat when deciding if we can chain textures together.
Bug: skia:
Change-Id: I8c26bed1bb18318f96d248c227e3b33b190d2a05
Reviewed-on: https://skia-review.googlesource.com/c/173320
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index e50f222..c72283e 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -66,6 +66,9 @@
return GrBackendFormat(config);
}
+ bool operator==(const GrBackendFormat& that) const;
+ bool operator!=(const GrBackendFormat& that) const { return !(*this == that); }
+
GrBackendApi backend() const { return fBackend; }
GrTextureType textureType() const { return fTextureType; }
diff --git a/include/gpu/vk/GrVkTypes.h b/include/gpu/vk/GrVkTypes.h
index c76c878..ec88a5f 100644
--- a/include/gpu/vk/GrVkTypes.h
+++ b/include/gpu/vk/GrVkTypes.h
@@ -93,9 +93,15 @@
, fChromaFilter(chromaFilter)
, fForceExplicitReconstruction(forceExplicitReconstruction)
, fExternalFormat(externalFormat)
- , fExternalFormatFeatures(externalFormatFeatures) {}
+ , fExternalFormatFeatures(externalFormatFeatures) {
+ SkASSERT(fExternalFormat);
+ }
bool operator==(const GrVkYcbcrConversionInfo& that) const {
+ // Invalid objects are not required to have all other fields intialized or matching.
+ if (!this->isValid() && !that.isValid()) {
+ return true;
+ }
return this->fYcbcrModel == that.fYcbcrModel &&
this->fYcbcrRange == that.fYcbcrRange &&
this->fXChromaOffset == that.fXChromaOffset &&
@@ -106,6 +112,7 @@
// We don't check fExternalFormatFeatures here since all matching external formats must have
// the same format features at least in terms of how they effect ycbcr sampler conversion.
}
+ bool operator!=(const GrVkYcbcrConversionInfo& that) const { return !(*this == that); }
bool isValid() const { return fExternalFormat != 0; }
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
index cdfd07a..0926f16 100644
--- a/include/private/GrTextureProxy.h
+++ b/include/private/GrTextureProxy.h
@@ -44,6 +44,12 @@
bool hasRestrictedSampling() const {
return GrTextureTypeHasRestrictedSampling(this->textureType());
}
+
+ // Returns true if the passed in proxies can be used as dynamic state together when flushing
+ // draws to the gpu.
+ static bool ProxiesAreCompatibleAsDynamicState(const GrTextureProxy* first,
+ const GrTextureProxy* second);
+
/**
* Return the texture proxy's unique key. It will be invalid if the proxy doesn't have one.
*/
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index 72f4fb4..c512c0a 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -135,6 +135,38 @@
return copy;
}
+bool GrBackendFormat::operator==(const GrBackendFormat& that) const {
+ // Invalid GrBackendFormats are never equal to anything.
+ if (!fValid || !that.fValid) {
+ return false;
+ }
+
+ if (fBackend != that.fBackend) {
+ return false;
+ }
+
+ switch (fBackend) {
+ case GrBackendApi::kOpenGL:
+ return fGLFormat == that.fGLFormat;
+ case GrBackendApi::kVulkan:
+#ifdef SK_VULKAN
+ return fVk.fFormat == that.fVk.fFormat &&
+ fVk.fYcbcrConversionInfo == that.fVk.fYcbcrConversionInfo;
+#endif
+ break;
+#ifdef SK_METAL
+ case GrBackendApi::kMetal:
+ return fMtlFormat == that.fMtlFormat;
+#endif
+ break;
+ case GrBackendApi::kMock:
+ return fMockFormat == that.fMockFormat;
+ default:
+ SK_ABORT("Unknown GrBackend");
+ }
+ return false;
+}
+
GrBackendTexture::GrBackendTexture(int width,
int height,
const GrVkImageInfo& vkInfo)
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 517b832..854ed17 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -138,6 +138,13 @@
this->proxyMipMapped(), !this->priv().isExact());
}
+bool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrTextureProxy* first,
+ const GrTextureProxy* second) {
+ return first->config() == second->config() &&
+ first->textureType() == second->textureType() &&
+ first->backendFormat() == second->backendFormat();
+}
+
void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
SkASSERT(key.isValid());
SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 088d693..1ca23df 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1509,8 +1509,8 @@
textures[i].fAlpha = set[i].fAlpha;
textures[i].fAAFlags = SkToGrQuadAAFlags(set[i].fAAFlags);
if (n > 0 &&
- (textures[i].fProxy->textureType() != textures[base].fProxy->textureType() ||
- textures[i].fProxy->config() != textures[base].fProxy->config() ||
+ (!GrTextureProxy::ProxiesAreCompatibleAsDynamicState(textures[i].fProxy.get(),
+ textures[base].fProxy.get()) ||
set[i].fImage->alphaType() != set[base].fImage->alphaType() ||
!SkColorSpace::Equals(set[i].fImage->colorSpace(), set[base].fImage->colorSpace()))) {
draw();
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 987d65a..11f996b 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -556,8 +556,7 @@
if (fProxyCnt > 1 || that->fProxyCnt > 1 ||
thisProxy->uniqueID() != thatProxy->uniqueID()) {
// We can't merge across different proxies. Check if 'this' can be chained with 'that'.
- if (thisProxy->config() == thatProxy->config() &&
- thisProxy->textureType() == thatProxy->textureType() &&
+ if (GrTextureProxy::ProxiesAreCompatibleAsDynamicState(thisProxy, thatProxy) &&
caps.dynamicStateArrayGeometryProcessorTextureSupport()) {
return CombineResult::kMayChain;
}