diff options
author | Greg Daniel <egdaniel@google.com> | 2018-02-15 13:06:26 -0500 |
---|---|---|
committer | Greg Daniel <egdaniel@google.com> | 2018-02-15 20:13:32 +0000 |
commit | f6f7b67ac230b14a725fbdabe951c70ea5b4428f (patch) | |
tree | a75cefe0e22e69aeaa9a862714818d4684afddc3 | |
parent | 602836138e02935885c77f9dd93dcb51a3ec9a64 (diff) |
When creating emptyp MipMap proxies, don't instantiate them immediately. Attempt 3
original: https://skia-review.googlesource.com/106966
Bug: skia:
Change-Id: I779985cef2d3c4f36a0129d8ecedd12e510bec7e
Reviewed-on: https://skia-review.googlesource.com/107781
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | include/private/GrTextureProxy.h | 2 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.cpp | 40 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.h | 9 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 31 | ||||
-rw-r--r-- | src/gpu/GrTextureProxy.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.h | 2 | ||||
-rw-r--r-- | src/image/SkImage_Lazy.cpp | 9 | ||||
-rw-r--r-- | tests/GrMipMappedTest.cpp | 2 |
9 files changed, 65 insertions, 42 deletions
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h index 826efed9b3..508b512ee3 100644 --- a/include/private/GrTextureProxy.h +++ b/include/private/GrTextureProxy.h @@ -72,7 +72,7 @@ protected: friend class GrTextureProxyPriv; // Deferred version - GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit, SkBudgeted, + GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped, SkBackingFit, SkBudgeted, const void* srcData, size_t srcRowBytes, uint32_t flags); // Lazy-callback version diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp index d051bfdc13..e520046e7c 100644 --- a/src/gpu/GrProxyProvider.cpp +++ b/src/gpu/GrProxyProvider.cpp @@ -252,28 +252,7 @@ sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& de return nullptr; } - // SkMipMap doesn't include the base level in the level count so we have to add 1 - int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1; - if (1 == mipCount) { - return this->createProxy(desc, SkBackingFit::kExact, budgeted); - } - - std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]); - - // We don't want to upload any texel data - for (int i = 0; i < mipCount; i++) { - texels[i].fPixels = nullptr; - texels[i].fRowBytes = 0; - } - - sk_sp<GrTexture> tex(fResourceProvider->createTexture(desc, budgeted, - texels.get(), mipCount, - SkDestinationSurfaceColorMode::kLegacy)); - if (!tex) { - return nullptr; - } - - return this->createWrapped(std::move(tex), desc.fOrigin); + return this->createProxy(desc, GrMipMapped::kYes, SkBackingFit::kExact, budgeted, 0); } sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap, @@ -361,12 +340,21 @@ sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitma } sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc, + GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) { SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags); - if (!this->caps()->validateSurfaceDesc(desc, GrMipMapped::kNo)) { + if (GrMipMapped::kYes == mipMapped) { + // SkMipMap doesn't include the base level in the level count so we have to add 1 + int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1; + if (1 == mipCount) { + mipMapped = GrMipMapped::kNo; + } + } + + if (!this->caps()->validateSurfaceDesc(desc, mipMapped)) { return nullptr; } GrSurfaceDesc copyDesc = desc; @@ -379,10 +367,12 @@ sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc, // We know anything we instantiate later from this deferred path will be // both texturable and renderable return sk_sp<GrTextureProxy>( - new GrTextureRenderTargetProxy(*this->caps(), copyDesc, fit, budgeted, flags)); + new GrTextureRenderTargetProxy(*this->caps(), copyDesc, mipMapped, fit, budgeted, + flags)); } - return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0, flags)); + return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, mipMapped, fit, budgeted, nullptr, 0, + flags)); } sk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy( diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h index 7e7f852d91..01b3b1f305 100644 --- a/src/gpu/GrProxyProvider.h +++ b/src/gpu/GrProxyProvider.h @@ -106,8 +106,13 @@ public: /* * Create a GrSurfaceProxy without any data. */ - sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted, - uint32_t flags = 0); + sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, GrMipMapped, SkBackingFit, SkBudgeted, + uint32_t flags); + + sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc& desc, SkBackingFit fit, + SkBudgeted budgeted, uint32_t flags = 0) { + return this->createProxy(desc, GrMipMapped::kNo, fit, budgeted, flags); + } // These match the definitions in SkImage & GrTexture.h, for whence they came typedef void* ReleaseContext; diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 48d4be1c8a..800b44723c 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -117,7 +117,6 @@ sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl( GrSurfaceFlags flags, GrMipMapped mipMapped) const { SkASSERT(GrSurfaceProxy::LazyState::kNot == this->lazyInstantiationState()); SkASSERT(!fTarget); - SkASSERT(GrMipMapped::kNo == mipMapped); GrSurfaceDesc desc; desc.fFlags = flags; if (fNeedsClear) { @@ -130,10 +129,34 @@ sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl( desc.fSampleCnt = sampleCnt; sk_sp<GrSurface> surface; - if (SkBackingFit::kApprox == fFit) { - surface.reset(resourceProvider->createApproxTexture(desc, fFlags).release()); + if (GrMipMapped::kYes == mipMapped) { + SkASSERT(SkBackingFit::kExact == fFit); + + // SkMipMap doesn't include the base level in the level count so we have to add 1 + int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1; + // We should have caught the case where mipCount == 1 when making the proxy and instead + // created a non-mipmapped proxy. + SkASSERT(mipCount > 1); + std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]); + + // We don't want to upload any texel data + for (int i = 0; i < mipCount; i++) { + texels[i].fPixels = nullptr; + texels[i].fRowBytes = 0; + } + + surface = resourceProvider->createTexture(desc, fBudgeted, texels.get(), mipCount, + SkDestinationSurfaceColorMode::kLegacy); + if (surface) { + SkASSERT(surface->asTexture()); + SkASSERT(GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped()); + } } else { - surface.reset(resourceProvider->createTexture(desc, fBudgeted, fFlags).release()); + if (SkBackingFit::kApprox == fFit) { + surface = resourceProvider->createApproxTexture(desc, fFlags); + } else { + surface = resourceProvider->createTexture(desc, fBudgeted, fFlags); + } } if (!surface) { return nullptr; diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 9245221ef3..d6ce9feda4 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -15,10 +15,11 @@ #include "GrTexturePriv.h" // Deferred version -GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, SkBudgeted budgeted, - const void* srcData, size_t /*rowBytes*/, uint32_t flags) +GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped mipMapped, + SkBackingFit fit, SkBudgeted budgeted, const void* srcData, + size_t /*rowBytes*/, uint32_t flags) : INHERITED(srcDesc, fit, budgeted, flags) - , fMipMapped(GrMipMapped::kNo) + , fMipMapped(mipMapped) , fProxyProvider(nullptr) , fDeferredUploader(nullptr) { SkASSERT(!srcData); // currently handled in Make() diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp index 2d5dbeee9f..50077c4c0f 100644 --- a/src/gpu/GrTextureRenderTargetProxy.cpp +++ b/src/gpu/GrTextureRenderTargetProxy.cpp @@ -19,12 +19,13 @@ // GrRenderTargetProxy) so its constructor must be explicitly called. GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc, + GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) : GrSurfaceProxy(desc, fit, budgeted, flags) // for now textures w/ data are always wrapped - , GrTextureProxy(desc, fit, budgeted, nullptr, 0, flags) + , GrTextureProxy(desc, mipMapped, fit, budgeted, nullptr, 0, flags) , GrRenderTargetProxy(caps, desc, fit, budgeted, flags) { } @@ -59,7 +60,7 @@ size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize() const { int colorSamplesPerPixel = this->numColorSamples(); if (colorSamplesPerPixel > 1) { // Add one to account for the resolve buffer. - ++colorSamplesPerPixel += 1; + ++colorSamplesPerPixel; } // TODO: do we have enough information to improve this worst case estimate? diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h index 178185d77b..06a84c206d 100644 --- a/src/gpu/GrTextureRenderTargetProxy.h +++ b/src/gpu/GrTextureRenderTargetProxy.h @@ -28,7 +28,7 @@ private: friend class GrProxyProvider; // for ctors // Deferred version - GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, + GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrMipMapped, SkBackingFit, SkBudgeted, uint32_t flags); // Lazy-callback version diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp index 1fc6d95094..4adf4e8368 100644 --- a/src/image/SkImage_Lazy.cpp +++ b/src/image/SkImage_Lazy.cpp @@ -701,12 +701,13 @@ static void set_key_on_proxy(GrProxyProvider* proxyProvider, const GrUniqueKey& key) { if (key.isValid()) { SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin); - if (originalProxy) { + if (originalProxy && originalProxy->getUniqueKey().isValid()) { + SkASSERT(originalProxy->getUniqueKey() == key); SkASSERT(GrMipMapped::kYes == proxy->mipMapped() && GrMipMapped::kNo == originalProxy->mipMapped()); - // If we had an originalProxy, that means there already is a proxy in the cache which - // matches the key, but it does not have mip levels and we require them. Thus we must - // remove the unique key from that proxy. + // If we had an originalProxy with a valid key, that means there already is a proxy in + // the cache which matches the key, but it does not have mip levels and we require them. + // Thus we must remove the unique key from that proxy. proxyProvider->removeUniqueKeyFromProxy(key, originalProxy); } proxyProvider->assignUniqueKeyToProxy(key, proxy); diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp index 0436bd4213..1462648a78 100644 --- a/tests/GrMipMappedTest.cpp +++ b/tests/GrMipMappedTest.cpp @@ -161,6 +161,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, if (GrSurfaceProxy::LazyState::kNot != genProxy->lazyInstantiationState()) { genProxy->priv().doLazyInstantiation(context->contextPriv().resourceProvider()); + } else if (!genProxy->priv().isInstantiated()) { + genProxy->instantiate(context->contextPriv().resourceProvider()); } REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated()); |