Add GrMipMapsStatus to GrTextureProxy
Bug: skia:
Change-Id: I5adf10f730b04c2b3b62c3b12aa5899da4db3431
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/229922
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index aedff7f..19f157b 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -153,6 +153,7 @@
if (usesGLFBO0) {
surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
}
+ // FIXME: Why do we use GrMipMapped::kNo instead of SkSurfaceCharacterization::fIsMipMapped?
static constexpr GrProxyProvider::TextureInfo kTextureInfo{GrMipMapped::kNo,
GrTextureType::k2D};
const GrProxyProvider::TextureInfo* optionalTextureInfo = nullptr;
@@ -174,6 +175,7 @@
fCharacterization.origin(),
surfaceFlags,
optionalTextureInfo,
+ GrMipMapsStatus::kNotAllocated,
SkBackingFit::kExact,
SkBudgeted::kYes,
fCharacterization.isProtected(),
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 14e8478..72c4979 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -187,8 +187,8 @@
return std::move(tex);
},
backendFormat, desc, GrRenderable::kNo, 1, fSurfaceOrigin, GrMipMapped::kNo,
- GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
- GrProtected::kNo);
+ GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact,
+ SkBudgeted::kNo, GrProtected::kNo);
return texProxy;
}
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index f1d6c6e..0f0ec38 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -152,6 +152,11 @@
desc.fConfig = config;
GrMipMapped mipMapped = fBackendTexture.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo;
+ // Ganesh assumes that, when wrapping a mipmapped backend texture from a client, that its
+ // mipmaps are fully fleshed out.
+ GrMipMapsStatus mipMapsStatus = fBackendTexture.hasMipMaps()
+ ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
+
// Must make copies of member variables to capture in the lambda since this image generator may
// be deleted before we actually execute the lambda.
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
@@ -194,7 +199,7 @@
// unrelated to the whatever SkImage key may be assigned to the proxy.
return {std::move(tex), GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
},
- backendFormat, desc, GrRenderable::kNo, 1, fSurfaceOrigin, mipMapped,
+ backendFormat, desc, GrRenderable::kNo, 1, fSurfaceOrigin, mipMapped, mipMapsStatus,
GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
GrProtected::kNo);
if (!proxy) {
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index e70917c..3d0bace 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -263,7 +263,7 @@
GrResourceProvider::Flags::kNoPendingIO));
},
format, desc, renderable, sampleCnt, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
- surfaceFlags, fit, budgeted, GrProtected::kNo);
+ GrMipMapsStatus::kNotAllocated, surfaceFlags, fit, budgeted, GrProtected::kNo);
if (!proxy) {
return nullptr;
@@ -390,7 +390,7 @@
texels.get(), mipLevelCount));
},
format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes,
- SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
+ GrMipMapsStatus::kValid, SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
if (!proxy) {
return nullptr;
@@ -461,6 +461,9 @@
return nullptr;
}
GrSurfaceDesc copyDesc = desc;
+ GrMipMapsStatus mipMapsStatus = (GrMipMapped::kYes == mipMapped)
+ ? GrMipMapsStatus::kDirty
+ : GrMipMapsStatus::kNotAllocated;
GrSwizzle texSwizzle = caps->getTextureSwizzle(format, colorType);
if (renderable == GrRenderable::kYes) {
renderTargetSampleCnt =
@@ -469,12 +472,13 @@
// both texturable and renderable
GrSwizzle outSwizzle = caps->getOutputSwizzle(format, colorType);
return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(
- *caps, format, copyDesc, renderTargetSampleCnt, origin, mipMapped, texSwizzle,
- outSwizzle, fit, budgeted, isProtected, surfaceFlags));
+ *caps, format, copyDesc, renderTargetSampleCnt, origin, mipMapped, mipMapsStatus,
+ texSwizzle, outSwizzle, fit, budgeted, isProtected, surfaceFlags));
}
- return sk_sp<GrTextureProxy>(new GrTextureProxy(format, copyDesc, origin, mipMapped, texSwizzle,
- fit, budgeted, isProtected, surfaceFlags));
+ return sk_sp<GrTextureProxy>(new GrTextureProxy(
+ format, copyDesc, origin, mipMapped, mipMapsStatus, texSwizzle, fit, budgeted,
+ isProtected, surfaceFlags));
}
sk_sp<GrTextureProxy> GrProxyProvider::createCompressedTextureProxy(
@@ -499,7 +503,8 @@
width, height, compressionType, budgeted, data.get()));
},
format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
- SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
+ GrMipMapsStatus::kNotAllocated, SkBackingFit::kExact, SkBudgeted::kYes,
+ GrProtected::kNo);
if (!proxy) {
return nullptr;
@@ -729,11 +734,12 @@
int renderTargetSampleCnt,
GrSurfaceOrigin origin,
GrMipMapped mipMapped,
+ GrMipMapsStatus mipMapsStatus,
SkBackingFit fit,
SkBudgeted budgeted,
GrProtected isProtected) {
return this->createLazyProxy(std::move(callback), format, desc, renderable,
- renderTargetSampleCnt, origin, mipMapped,
+ renderTargetSampleCnt, origin, mipMapped, mipMapsStatus,
GrInternalSurfaceFlags::kNone, fit, budgeted, isProtected);
}
@@ -744,6 +750,7 @@
int renderTargetSampleCnt,
GrSurfaceOrigin origin,
GrMipMapped mipMapped,
+ GrMipMapsStatus mipMapsStatus,
GrInternalSurfaceFlags surfaceFlags,
SkBackingFit fit,
SkBudgeted budgeted,
@@ -752,8 +759,8 @@
LazyInstantiationType lazyType = this->renderingDirectly() ? LazyInstantiationType::kSingleUse
: LazyInstantiationType::kMultipleUse;
return this->createLazyProxy(std::move(callback), format, desc, renderable,
- renderTargetSampleCnt, origin, mipMapped, surfaceFlags, fit,
- budgeted, isProtected, lazyType);
+ renderTargetSampleCnt, origin, mipMapped, mipMapsStatus,
+ surfaceFlags, fit, budgeted, isProtected, lazyType);
}
sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
@@ -763,6 +770,7 @@
int renderTargetSampleCnt,
GrSurfaceOrigin origin,
GrMipMapped mipMapped,
+ GrMipMapsStatus mipMapsStatus,
GrInternalSurfaceFlags surfaceFlags,
SkBackingFit fit,
SkBudgeted budgeted,
@@ -786,22 +794,22 @@
GrSwizzle texSwizzle = this->caps()->getTextureSwizzle(format, colorType);
GrSwizzle outSwizzle = this->caps()->getOutputSwizzle(format, colorType);
- return sk_sp<GrTextureProxy>(
- renderable == GrRenderable::kYes
- ? new GrTextureRenderTargetProxy(std::move(callback), lazyType, format, desc,
- renderTargetSampleCnt, origin, mipMapped,
- texSwizzle, outSwizzle, fit, budgeted,
- isProtected, surfaceFlags)
- : new GrTextureProxy(std::move(callback), lazyType, format, desc, origin,
- mipMapped, texSwizzle, fit, budgeted, isProtected,
- surfaceFlags));
+ return sk_sp<GrTextureProxy>((renderable == GrRenderable::kYes)
+ ? new GrTextureRenderTargetProxy(
+ std::move(callback), lazyType, format, desc, renderTargetSampleCnt, origin,
+ mipMapped, mipMapsStatus, texSwizzle, outSwizzle, fit, budgeted, isProtected,
+ surfaceFlags)
+ : new GrTextureProxy(
+ std::move(callback), lazyType, format, desc, origin, mipMapped, mipMapsStatus,
+ texSwizzle, fit, budgeted, isProtected, surfaceFlags));
}
sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy(
LazyInstantiateCallback&& callback, const GrBackendFormat& format,
const GrSurfaceDesc& desc, int sampleCnt, GrSurfaceOrigin origin,
- GrInternalSurfaceFlags surfaceFlags, const TextureInfo* textureInfo, SkBackingFit fit,
- SkBudgeted budgeted, GrProtected isProtected, bool wrapsVkSecondaryCB) {
+ GrInternalSurfaceFlags surfaceFlags, const TextureInfo* textureInfo,
+ GrMipMapsStatus mipMapsStatus, SkBackingFit fit, SkBudgeted budgeted,
+ GrProtected isProtected, bool wrapsVkSecondaryCB) {
SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
(desc.fWidth > 0 && desc.fHeight > 0));
@@ -827,8 +835,8 @@
SkASSERT(!wrapsVkSecondaryCB);
return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(
std::move(callback), lazyType, format, desc, sampleCnt, origin,
- textureInfo->fMipMapped, texSwizzle, outSwizzle, fit, budgeted, isProtected,
- surfaceFlags));
+ textureInfo->fMipMapped, mipMapsStatus, texSwizzle, outSwizzle, fit, budgeted,
+ isProtected, surfaceFlags));
}
GrRenderTargetProxy::WrapsVkSecondaryCB vkSCB =
@@ -860,17 +868,16 @@
GrSwizzle texSwizzle = caps.getTextureSwizzle(format, colorType);
GrSwizzle outSwizzle = caps.getOutputSwizzle(format, colorType);
- return sk_sp<GrTextureProxy>(
- (GrRenderable::kYes == renderable)
- ? new GrTextureRenderTargetProxy(
- std::move(callback), LazyInstantiationType::kSingleUse, format, desc,
- renderTargetSampleCnt, origin, GrMipMapped::kNo, texSwizzle,
- outSwizzle, SkBackingFit::kApprox, SkBudgeted::kYes, isProtected,
- surfaceFlags)
- : new GrTextureProxy(std::move(callback), LazyInstantiationType::kSingleUse,
- format, desc, origin, GrMipMapped::kNo, texSwizzle,
- SkBackingFit::kApprox, SkBudgeted::kYes, isProtected,
- surfaceFlags));
+ return sk_sp<GrTextureProxy>((GrRenderable::kYes == renderable)
+ ? new GrTextureRenderTargetProxy(
+ std::move(callback), LazyInstantiationType::kSingleUse, format, desc,
+ renderTargetSampleCnt, origin, GrMipMapped::kNo, GrMipMapsStatus::kNotAllocated,
+ texSwizzle, outSwizzle, SkBackingFit::kApprox, SkBudgeted::kYes, isProtected,
+ surfaceFlags)
+ : new GrTextureProxy(
+ std::move(callback), LazyInstantiationType::kSingleUse, format, desc, origin,
+ GrMipMapped::kNo, GrMipMapsStatus::kNotAllocated, texSwizzle,
+ SkBackingFit::kApprox, SkBudgeted::kYes, isProtected, surfaceFlags));
}
bool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index bfaca5d..6a971a6 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -166,20 +166,21 @@
*/
sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
const GrSurfaceDesc&, GrRenderable,
- int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
- GrInternalSurfaceFlags, SkBackingFit, SkBudgeted,
- GrProtected, LazyInstantiationType);
+ int renderTargetSampleCnt, GrSurfaceOrigin,
+ GrMipMapped, GrMipMapsStatus, GrInternalSurfaceFlags,
+ SkBackingFit, SkBudgeted, GrProtected,
+ LazyInstantiationType);
sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
const GrSurfaceDesc&, GrRenderable,
int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
- GrInternalSurfaceFlags, SkBackingFit, SkBudgeted,
- GrProtected);
+ GrMipMapsStatus, GrInternalSurfaceFlags, SkBackingFit,
+ SkBudgeted, GrProtected);
sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
const GrSurfaceDesc&, GrRenderable,
int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
- SkBackingFit, SkBudgeted, GrProtected);
+ GrMipMapsStatus, SkBackingFit, SkBudgeted, GrProtected);
/** A null TextureInfo indicates a non-textureable render target. */
sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
@@ -188,10 +189,8 @@
int renderTargetSampleCnt,
GrSurfaceOrigin origin,
GrInternalSurfaceFlags,
- const TextureInfo*,
- SkBackingFit,
- SkBudgeted,
- GrProtected,
+ const TextureInfo*, GrMipMapsStatus,
+ SkBackingFit, SkBudgeted, GrProtected,
bool wrapsVkSecondaryCB);
/**
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 381539c..97f4478 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -19,6 +19,7 @@
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrResourceAllocator.h"
+#include "src/gpu/GrTexturePriv.h"
#include "src/gpu/geometry/GrRect.h"
#include "src/gpu/ops/GrClearOp.h"
#include "src/gpu/ops/GrCopySurfaceOp.h"
@@ -468,6 +469,15 @@
// no ops just to do a discard.
if (fOpChains.empty() && GrLoadOp::kClear != fColorLoadOp &&
GrLoadOp::kDiscard != fColorLoadOp) {
+ // TEMPORARY: We are in the process of moving GrMipMapsStatus from the texture to the proxy.
+ // During this time we want to assert that the proxy resolves mipmaps at the exact same
+ // times the old code would have. A null opList is very exceptional, and the proxy will have
+ // assumed mipmaps are dirty in this scenario. We mark them dirty here on the texture as
+ // well, in order to keep the assert passing.
+ GrTexture* tex = fTarget->peekTexture();
+ if (tex && GrMipMapped::kYes == tex->texturePriv().mipMapped()) {
+ tex->texturePriv().markMipMapsDirty();
+ }
return false;
}
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 078541b..c45d6be 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -160,13 +160,20 @@
texels[i].fPixels = nullptr;
texels[i].fRowBytes = 0;
}
-
surface = resourceProvider->createTexture(desc, renderable, sampleCnt, fBudgeted,
fIsProtected, texels.get(), mipCount);
+#ifdef SK_DEBUG
if (surface) {
- SkASSERT(surface->asTexture());
- SkASSERT(GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
+ const GrTextureProxy* thisTexProxy = this->asTextureProxy();
+ SkASSERT(thisTexProxy);
+
+ GrTexture* texture = surface->asTexture();
+ SkASSERT(texture);
+
+ SkASSERT(GrMipMapped::kYes == texture->texturePriv().mipMapped());
+ SkASSERT(thisTexProxy->fInitialMipMapsStatus == texture->texturePriv().mipMapsStatus());
}
+#endif
} else {
if (SkBackingFit::kApprox == fFit) {
surface = resourceProvider->createApproxTexture(desc, renderable, sampleCnt,
diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp
index 0613c5f..b58f735 100644
--- a/src/gpu/GrTextureOpList.cpp
+++ b/src/gpu/GrTextureOpList.cpp
@@ -16,6 +16,7 @@
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrResourceAllocator.h"
+#include "src/gpu/GrTexturePriv.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/ops/GrCopySurfaceOp.h"
#include "src/gpu/ops/GrTransferFromOp.h"
@@ -98,6 +99,15 @@
bool GrTextureOpList::onExecute(GrOpFlushState* flushState) {
if (0 == fRecordedOps.count()) {
+ // TEMPORARY: We are in the process of moving GrMipMapsStatus from the texture to the proxy.
+ // During this time we want to assert that the proxy resolves mipmaps at the exact same
+ // times the old code would have. A null opList is very exceptional, and the proxy will have
+ // assumed mipmaps are dirty in this scenario. We mark them dirty here on the texture as
+ // well, in order to keep the assert passing.
+ GrTexture* tex = fTarget->peekTexture();
+ if (tex && GrMipMapped::kYes == tex->texturePriv().mipMapped()) {
+ tex->texturePriv().markMipMapsDirty();
+ }
return false;
}
diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h
index 69404b0..8603ad5 100644
--- a/src/gpu/GrTexturePriv.h
+++ b/src/gpu/GrTexturePriv.h
@@ -25,12 +25,14 @@
fTexture->markMipMapsClean();
}
+ GrMipMapsStatus mipMapsStatus() const { return fTexture->fMipMapsStatus; }
+
bool mipMapsAreDirty() const {
- return GrMipMapsStatus::kValid != fTexture->fMipMapsStatus;
+ return GrMipMapsStatus::kValid != this->mipMapsStatus();
}
GrMipMapped mipMapped() const {
- if (GrMipMapsStatus::kNotAllocated != fTexture->fMipMapsStatus) {
+ if (GrMipMapsStatus::kNotAllocated != this->mipMapsStatus()) {
return GrMipMapped::kYes;
}
return GrMipMapped::kNo;
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index a71b9f3..5c7d304 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -18,12 +18,14 @@
// Deferred version - no data
GrTextureProxy::GrTextureProxy(const GrBackendFormat& format, const GrSurfaceDesc& srcDesc,
GrSurfaceOrigin origin, GrMipMapped mipMapped,
- const GrSwizzle& textureSwizzle, SkBackingFit fit,
- SkBudgeted budgeted, GrProtected isProtected,
+ GrMipMapsStatus mipMapsStatus, const GrSwizzle& textureSwizzle,
+ SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected,
GrInternalSurfaceFlags surfaceFlags)
: INHERITED(format, srcDesc, GrRenderable::kNo, origin, textureSwizzle, fit, budgeted,
isProtected, surfaceFlags)
, fMipMapped(mipMapped)
+ , fMipMapsStatus(mipMapsStatus)
+ SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
, fProxyProvider(nullptr)
, fDeferredUploader(nullptr) {}
@@ -31,11 +33,14 @@
GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
const GrBackendFormat& format, const GrSurfaceDesc& desc,
GrSurfaceOrigin origin, GrMipMapped mipMapped,
- const GrSwizzle& texSwizzle, SkBackingFit fit, SkBudgeted budgeted,
- GrProtected isProtected, GrInternalSurfaceFlags surfaceFlags)
+ GrMipMapsStatus mipMapsStatus, const GrSwizzle& texSwizzle,
+ SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected,
+ GrInternalSurfaceFlags surfaceFlags)
: INHERITED(std::move(callback), lazyType, format, desc, GrRenderable::kNo, origin,
texSwizzle, fit, budgeted, isProtected, surfaceFlags)
, fMipMapped(mipMapped)
+ , fMipMapsStatus(mipMapsStatus)
+ SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
, fProxyProvider(nullptr)
, fDeferredUploader(nullptr) {}
@@ -44,6 +49,8 @@
const GrSwizzle& textureSwizzle)
: INHERITED(std::move(surf), origin, textureSwizzle, SkBackingFit::kExact)
, fMipMapped(fTarget->asTexture()->texturePriv().mipMapped())
+ , fMipMapsStatus(fTarget->asTexture()->texturePriv().mipMapsStatus())
+ SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
, fProxyProvider(nullptr)
, fDeferredUploader(nullptr) {
if (fTarget->getUniqueKey().isValid()) {
@@ -162,6 +169,7 @@
// Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
SkASSERT(surface->asTexture());
+ // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture.
SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
diff --git a/src/gpu/GrTextureProxy.h b/src/gpu/GrTextureProxy.h
index c0f24dc..091d0ca 100644
--- a/src/gpu/GrTextureProxy.h
+++ b/src/gpu/GrTextureProxy.h
@@ -36,6 +36,12 @@
// generation later.
GrMipMapped mipMapped() const;
+ bool mipMapsAreDirty() const {
+ SkASSERT((GrMipMapped::kNo == fMipMapped) ==
+ (GrMipMapsStatus::kNotAllocated == fMipMapsStatus));
+ return GrMipMapped::kYes == fMipMapped && GrMipMapsStatus::kValid != fMipMapsStatus;
+ }
+
// Returns the GrMipMapped value of the proxy from creation time regardless of whether it has
// been instantiated or not.
GrMipMapped proxyMipMapped() const { return fMipMapped; }
@@ -93,8 +99,8 @@
// Deferred version - no data.
GrTextureProxy(const GrBackendFormat&, const GrSurfaceDesc& srcDesc, GrSurfaceOrigin,
- GrMipMapped, const GrSwizzle& textureSwizzle, SkBackingFit, SkBudgeted,
- GrProtected, GrInternalSurfaceFlags);
+ GrMipMapped, GrMipMapsStatus, const GrSwizzle& textureSwizzle, SkBackingFit,
+ SkBudgeted, GrProtected, GrInternalSurfaceFlags);
// Lazy-callback version
// There are two main use cases for lazily-instantiated proxies:
@@ -107,8 +113,8 @@
// The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
// know the final size until flush time.
GrTextureProxy(LazyInstantiateCallback&&, LazyInstantiationType, const GrBackendFormat&,
- const GrSurfaceDesc& desc, GrSurfaceOrigin, GrMipMapped, const GrSwizzle&,
- SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags);
+ const GrSurfaceDesc& desc, GrSurfaceOrigin, GrMipMapped, GrMipMapsStatus,
+ const GrSwizzle&, SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags);
// Wrapped version
GrTextureProxy(sk_sp<GrSurface>, GrSurfaceOrigin, const GrSwizzle&);
@@ -129,6 +135,19 @@
// address of other types, leading to this problem.
GrMipMapped fMipMapped;
+
+ // This tracks the mipmap status at the proxy level and is thus somewhat distinct from the
+ // backing GrTexture's mipmap status. In particular, this status is used to determine when
+ // mipmap levels need to be explicitly regenerated during the execution of a DAG of opLists.
+ GrMipMapsStatus fMipMapsStatus;
+ // TEMPORARY: We are in the process of moving GrMipMapsStatus from the texture to the proxy.
+ // We track the fInitialMipMapsStatus here so we can assert that the proxy did indeed expect
+ // the correct mipmap status immediately after instantiation.
+ //
+ // NOTE: fMipMapsStatus may no longer be equal to fInitialMipMapsStatus by the time the texture
+ // is instantiated, since it tracks mipmaps in the time frame in which the DAG is being built.
+ SkDEBUGCODE(const GrMipMapsStatus fInitialMipMapsStatus);
+
bool fSyncTargetKey = true; // Should target's unique key be sync'ed with ours.
GrUniqueKey fUniqueKey;
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index 63716b5..3d17a67 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -24,6 +24,7 @@
int sampleCnt,
GrSurfaceOrigin origin,
GrMipMapped mipMapped,
+ GrMipMapsStatus mipMapsStatus,
const GrSwizzle& texSwizzle,
const GrSwizzle& outSwizzle,
SkBackingFit fit,
@@ -35,8 +36,8 @@
// for now textures w/ data are always wrapped
, GrRenderTargetProxy(caps, format, desc, sampleCnt, origin, texSwizzle, outSwizzle, fit,
budgeted, isProtected, surfaceFlags)
- , GrTextureProxy(format, desc, origin, mipMapped, texSwizzle, fit, budgeted, isProtected,
- surfaceFlags) {}
+ , GrTextureProxy(format, desc, origin, mipMapped, mipMapsStatus, texSwizzle, fit, budgeted,
+ isProtected, surfaceFlags) {}
// Lazy-callback version
GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(LazyInstantiateCallback&& callback,
@@ -46,6 +47,7 @@
int sampleCnt,
GrSurfaceOrigin origin,
GrMipMapped mipMapped,
+ GrMipMapsStatus mipMapsStatus,
const GrSwizzle& texSwizzle,
const GrSwizzle& outSwizzle,
SkBackingFit fit,
@@ -60,7 +62,7 @@
texSwizzle, outSwizzle, fit, budgeted, isProtected, surfaceFlags,
WrapsVkSecondaryCB::kNo)
, GrTextureProxy(LazyInstantiateCallback(), lazyType, format, desc, origin, mipMapped,
- texSwizzle, fit, budgeted, isProtected, surfaceFlags) {}
+ mipMapsStatus, texSwizzle, fit, budgeted, isProtected, surfaceFlags) {}
// Wrapped version
// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index 3270d05..a736793 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -29,16 +29,16 @@
// Deferred version
GrTextureRenderTargetProxy(const GrCaps&, const GrBackendFormat&, const GrSurfaceDesc&,
- int sampleCnt, GrSurfaceOrigin, GrMipMapped,
+ int sampleCnt, GrSurfaceOrigin, GrMipMapped, GrMipMapsStatus,
const GrSwizzle& textureSwizzle, const GrSwizzle& outputSwizzle,
SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags);
// Lazy-callback version
GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType,
const GrBackendFormat&, const GrSurfaceDesc& desc, int sampleCnt,
- GrSurfaceOrigin, GrMipMapped, const GrSwizzle& textureSwizzle,
- const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted,
- GrProtected, GrInternalSurfaceFlags);
+ GrSurfaceOrigin, GrMipMapped, GrMipMapsStatus,
+ const GrSwizzle& textureSwizzle, const GrSwizzle& outputSwizzle,
+ SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags);
// Wrapped version
GrTextureRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 8ede79b..ea1b29c 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -990,7 +990,8 @@
int mipLevelCount,
int baseWidth,
int baseHeight,
- bool* changedUnpackRowLength) {
+ bool* changedUnpackRowLength,
+ GrMipMapsStatus* mipMapsStatus) {
CLEAR_ERROR_BEFORE_ALLOC(&interface);
if (caps.configSupportsTexStorage(config)) {
@@ -1006,6 +1007,9 @@
for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
const void* currentMipData = texels[currentMipLevel].fPixels;
if (currentMipData == nullptr) {
+ if (mipMapsStatus) {
+ *mipMapsStatus = GrMipMapsStatus::kDirty;
+ }
continue;
}
int twoToTheMipLevel = 1 << currentMipLevel;
@@ -1061,7 +1065,8 @@
const int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
const int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
- if (texels[currentMipLevel].fPixels) {
+ const void* currentMipData = texels[currentMipLevel].fPixels;
+ if (currentMipData) {
const size_t trimRowBytes = currentWidth * bpp;
const size_t rowBytes = texels[currentMipLevel].fRowBytes;
if (rowBytes != trimRowBytes) {
@@ -1074,9 +1079,10 @@
GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
*changedUnpackRowLength = false;
}
+ } else if (mipMapsStatus) {
+ *mipMapsStatus = GrMipMapsStatus::kDirty;
}
- const void* currentMipData = texels[currentMipLevel].fPixels;
// Even if curremtMipData is nullptr, continue to call TexImage2D.
// This will allocate texture memory which we can later populate.
GL_ALLOC_CALL(&interface,
@@ -1180,11 +1186,8 @@
SkAutoSMalloc<128 * 128> tempStorage;
if (mipMapsStatus) {
- *mipMapsStatus = GrMipMapsStatus::kValid;
- }
-
- if (mipMapsStatus && mipLevelCount <= 1) {
- *mipMapsStatus = GrMipMapsStatus::kNotAllocated;
+ *mipMapsStatus = (mipLevelCount > 1) ?
+ GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
}
if (mipLevelCount) {
@@ -1197,13 +1200,16 @@
succeeded = allocate_and_populate_texture(
texConfig, *interface, caps, target, internalFormat,
internalFormatForTexStorage, externalFormat, externalType, texels,
- mipLevelCount, width, height, &restoreGLRowLength);
+ mipLevelCount, width, height, &restoreGLRowLength, mipMapsStatus);
} else {
succeeded = false;
}
} else {
for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
if (!texels[currentMipLevel].fPixels) {
+ if (mipMapsStatus) {
+ *mipMapsStatus = GrMipMapsStatus::kDirty;
+ }
continue;
}
int twoToTheMipLevel = 1 << currentMipLevel;
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 60fc1c4..f319f9f 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -491,10 +491,15 @@
desc.fHeight = height;
desc.fConfig = config;
+ // Ganesh assumes that, when wrapping a mipmapped backend texture from a client, that its
+ // mipmaps are fully fleshed out.
+ GrMipMapsStatus mipMapsStatus = (GrMipMapped::kYes == mipMapped)
+ ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
+
// We pass kReadOnly here since we should treat content of the client's texture as immutable.
// The promise API provides no way for the client to indicated that the texture is protected.
return proxyProvider->createLazyProxy(
std::move(callback), backendFormat, desc, GrRenderable::kNo, 1, origin, mipMapped,
- GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
+ mipMapsStatus, GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
GrProtected::kNo, GrSurfaceProxy::LazyInstantiationType::kDeinstantiate);
}
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index c3d1685..72aa374 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -562,8 +562,9 @@
auto proxy = context->priv().proxyProvider()->createLazyProxy(
singleUseLazyCB, backendFormat, desc, renderable, 1,
GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
- GrInternalSurfaceFlags ::kNone, SkBackingFit::kExact, budgeted,
- GrProtected::kNo, GrSurfaceProxy::LazyInstantiationType::kSingleUse);
+ GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags ::kNone,
+ SkBackingFit::kExact, budgeted, GrProtected::kNo,
+ GrSurfaceProxy::LazyInstantiationType::kSingleUse);
rtc->drawTexture(GrNoClip(), proxy, GrSamplerState::Filter::kNearest,
SkBlendMode::kSrcOver, SkPMColor4f(), SkRect::MakeWH(w, h),
SkRect::MakeWH(w, h), GrAA::kNo, GrQuadAAFlags::kNone,
@@ -599,8 +600,9 @@
proxy = context->priv().proxyProvider()->createLazyProxy(
deinstantiateLazyCB, backendFormat, desc, renderable, 1,
GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
- GrInternalSurfaceFlags ::kNone, SkBackingFit::kExact, budgeted,
- GrProtected::kNo, GrSurfaceProxy::LazyInstantiationType::kDeinstantiate);
+ GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags ::kNone,
+ SkBackingFit::kExact, budgeted, GrProtected::kNo,
+ GrSurfaceProxy::LazyInstantiationType::kDeinstantiate);
rtc->drawTexture(GrNoClip(), std::move(proxy), GrSamplerState::Filter::kNearest,
SkBlendMode::kSrcOver, SkPMColor4f(), SkRect::MakeWH(w, h),
SkRect::MakeWH(w, h), GrAA::kNo, GrQuadAAFlags::kNone,
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index a94b880..1307f0c 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -269,8 +269,9 @@
};
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
TestCallback(&testCount), format, desc, GrRenderable::kNo, 1,
- kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
- SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, lazyType);
+ kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrMipMapsStatus::kNotAllocated,
+ GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo,
+ GrProtected::kNo, lazyType);
REPORTER_ASSERT(reporter, proxy.get());
REPORTER_ASSERT(reporter, 0 == testCount);
@@ -341,7 +342,8 @@
GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
},
format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
- SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo);
+ GrMipMapsStatus::kNotAllocated, SkBackingFit::kExact, SkBudgeted::kNo,
+ GrProtected::kNo);
SkASSERT(fLazyProxy.get());
@@ -479,8 +481,8 @@
return std::move(texture);
},
format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
- GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
- GrProtected::kNo, lazyType);
+ GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kReadOnly,
+ SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, lazyType);
REPORTER_ASSERT(reporter, lazyProxy.get());
diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp
index ce257b5..2b81256 100644
--- a/tests/ResourceAllocatorTest.cpp
+++ b/tests/ResourceAllocatorTest.cpp
@@ -296,9 +296,9 @@
auto lazyType = deinstantiate ? GrSurfaceProxy::LazyInstantiationType ::kDeinstantiate
: GrSurfaceProxy::LazyInstantiationType ::kSingleUse;
GrInternalSurfaceFlags flags = GrInternalSurfaceFlags::kNone;
- return proxyProvider->createLazyProxy(callback, format, desc, p.fRenderable, p.fSampleCnt,
- p.fOrigin, GrMipMapped::kNo, flags, p.fFit, p.fBudgeted,
- GrProtected::kNo, lazyType);
+ return proxyProvider->createLazyProxy(
+ callback, format, desc, p.fRenderable, p.fSampleCnt, p.fOrigin, GrMipMapped::kNo,
+ GrMipMapsStatus::kNotAllocated, flags, p.fFit, p.fBudgeted, GrProtected::kNo, lazyType);
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(LazyDeinstantiation, reporter, ctxInfo) {