When creating emptyp MipMap proxies, don't instantiate them immediately.

This chnages makes it match how we handle non mipped proxies where we
don't actually instantiate them until we need to.

Bug: skia:
Change-Id: Id0c50eefce43ef1458a3ff0bb1881a817b045279
Reviewed-on: https://skia-review.googlesource.com/106966
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Greg Daniel 2018-02-13 15:34:14 -05:00 committed by Skia Commit-Bot
parent b8ea6fb507
commit 8242c5c199
8 changed files with 56 additions and 38 deletions

View File

@ -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

View File

@ -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(

View File

@ -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;

View File

@ -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,30 @@ 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);
} 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;

View File

@ -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()

View File

@ -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?

View File

@ -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

View File

@ -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());