diff options
-rw-r--r-- | include/gpu/GrTypes.h | 4 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrBackendTextureImageGenerator.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrResourceProvider.cpp | 61 | ||||
-rw-r--r-- | src/gpu/GrResourceProvider.h | 9 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrTexture.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrTexturePriv.h | 2 | ||||
-rw-r--r-- | src/gpu/GrTextureProxy.cpp | 7 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 3 | ||||
-rw-r--r-- | tests/GrSurfaceTest.cpp | 127 | ||||
-rw-r--r-- | tests/ResourceCacheTest.cpp | 1 |
12 files changed, 111 insertions, 113 deletions
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 606fc00cb3..6ba9ffe429 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -594,7 +594,8 @@ struct GrSurfaceDesc { , fWidth(0) , fHeight(0) , fConfig(kUnknown_GrPixelConfig) - , fSampleCnt(0) { + , fSampleCnt(0) + , fIsMipMapped(false) { } GrSurfaceFlags fFlags; //!< bitfield of TextureFlags @@ -616,6 +617,7 @@ struct GrSurfaceDesc { * max supported count. */ int fSampleCnt; + bool fIsMipMapped; //!< Indicates if the texture has mipmaps }; /** diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index bf18771bb7..2fc10ede40 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -963,6 +963,7 @@ sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture( texDesc.fWidth = profileSize; texDesc.fHeight = 1; texDesc.fConfig = kAlpha_8_GrPixelConfig; + texDesc.fIsMipMapped = false; std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma)); diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp index 78e514a8a4..712ebb8bb1 100644 --- a/src/gpu/GrBackendTextureImageGenerator.cpp +++ b/src/gpu/GrBackendTextureImageGenerator.cpp @@ -182,6 +182,7 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture( desc.fWidth = info.width(); desc.fHeight = info.height(); desc.fConfig = proxy->config(); + desc.fIsMipMapped = proxy->isMipMapped(); sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeDeferredSurfaceContext( desc, SkBackingFit::kExact, SkBudgeted::kYes)); diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index cd337b27c2..8dce5497d8 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -87,12 +87,7 @@ sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, Sk return nullptr; } - - // TODO: Try finding an exact scratch texture and use that instead of always creating a new - // texture. We need to update GrSurfaceContext writePixels to take an array of texels to be able - // to do this. sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount)); - if (tex) { tex->texturePriv().setMipColorMode(mipColorMode); } @@ -101,11 +96,8 @@ sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, Sk } sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc, - SkBudgeted budgeted, uint32_t flags, - bool isMipMapped) { - if (isMipMapped) { - flags |= kMipMapped_Flag; - } + SkBudgeted budgeted, uint32_t flags) { + flags |= kExact_Flag | kNoCreate_Flag; sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags)); if (tex && SkBudgeted::kNo == budgeted) { tex->resourcePriv().makeUnbudgeted(); @@ -146,7 +138,7 @@ sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc SkImageInfo srcInfo; if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) { - sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0, false); + sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0); sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin); if (proxy) { sk_sp<GrSurfaceContext> sContext = @@ -175,7 +167,7 @@ sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, Sk return nullptr; } - sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags, false); + sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags); if (tex) { return tex; } @@ -196,52 +188,51 @@ sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& de return nullptr; } - if (auto tex = this->refScratchTexture(desc, flags)) { - return tex; - } - - GrSurfaceDesc copyDesc = desc; - // bin by pow2 with a reasonable min - copyDesc.fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth)); - copyDesc.fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight)); - - if (auto tex = this->refScratchTexture(copyDesc, flags)) { - return tex; - } - - return fGpu->createTexture(copyDesc, SkBudgeted::kYes); + return this->refScratchTexture(desc, flags); } -sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc, uint32_t flags) { +sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& inDesc, + uint32_t flags) { ASSERT_SINGLE_OWNER SkASSERT(!this->isAbandoned()); - SkASSERT(validate_desc(desc, *fCaps)); + SkASSERT(validate_desc(inDesc, *fCaps)); + + SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc); // We could make initial clears work with scratch textures but it is a rare case so we just opt // to fall back to making a new texture. - if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) && - (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) { + if (!SkToBool(inDesc.fFlags & kPerformInitialClear_GrSurfaceFlag) && + (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag))) { + if (!(kExact_Flag & flags)) { + // bin by pow2 with a reasonable min + GrSurfaceDesc* wdesc = desc.writable(); + wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fWidth)); + wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fHeight)); + } GrScratchKey key; - bool isMipMapped = SkToBool(kMipMapped_Flag & flags); - GrTexturePriv::ComputeScratchKey(desc, isMipMapped, &key); + GrTexturePriv::ComputeScratchKey(*desc, &key); uint32_t scratchFlags = 0; if (kNoPendingIO_Flag & flags) { scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag; - } else if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) { + } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) { // If it is not a render target then it will most likely be populated by // writePixels() which will trigger a flush if the texture has pending IO. scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag; } GrGpuResource* resource = fCache->findAndRefScratchResource(key, - GrSurface::WorstCaseSize(desc), - scratchFlags); + GrSurface::WorstCaseSize(*desc), + scratchFlags); if (resource) { GrSurface* surface = static_cast<GrSurface*>(resource); return sk_sp<GrTexture>(surface->asTexture()); } } + if (!(kNoCreate_Flag & flags)) { + return fGpu->createTexture(*desc, SkBudgeted::kYes); + } + return nullptr; } diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h index 7b794ad236..1ab1ec42fc 100644 --- a/src/gpu/GrResourceProvider.h +++ b/src/gpu/GrResourceProvider.h @@ -163,7 +163,7 @@ public: /** These flags govern which scratch resources we are allowed to return */ enum Flags { - kMipMapped_Flag = 0x1, + kExact_Flag = 0x1, /** If the caller intends to do direct reads/writes to/from the CPU then this flag must be * set when accessing resources during a GrOpList flush. This includes the execution of @@ -173,10 +173,12 @@ public: */ kNoPendingIO_Flag = 0x2, + kNoCreate_Flag = 0x4, + /** Normally the caps may indicate a preference for client-side buffers. Set this flag when * creating a buffer to guarantee it resides in GPU memory. */ - kRequireGpuMemory_Flag = 0x4, + kRequireGpuMemory_Flag = 0x8, }; /** @@ -260,8 +262,7 @@ private: * Try to find an existing scratch texture that exactly matches 'desc'. If successful * update the budgeting accordingly. */ - sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc&, SkBudgeted, uint32_t flags, - bool isMipMapped); + sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc&, SkBudgeted, uint32_t flags); GrResourceCache* cache() { return fCache; } const GrResourceCache* cache() const { return fCache; } diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 55447f72a6..5918830bf8 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -63,7 +63,7 @@ sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl( int sampleCnt, bool needsStencil, GrSurfaceFlags flags, bool isMipMapped, SkDestinationSurfaceColorMode mipColorMode) const { - SkASSERT(!isMipMapped); + GrSurfaceDesc desc; desc.fFlags = flags; if (fNeedsClear) { @@ -74,6 +74,7 @@ sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl( desc.fHeight = fHeight; desc.fConfig = fConfig; desc.fSampleCnt = sampleCnt; + desc.fIsMipMapped = isMipMapped; sk_sp<GrSurface> surface; if (SkBackingFit::kApprox == fFit) { diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index c94c7e0803..c749fb731b 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -87,10 +87,9 @@ void GrTexturePriv::ComputeScratchKey(GrPixelConfig config, int width, int heigh builder[2] = config | (isMipMapped << 5) | (sampleCnt << 6) | (flags << 14); } -void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, bool isMipMapped, - GrScratchKey* key) { +void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) { // Note: the fOrigin field is not used in the scratch key return ComputeScratchKey(desc.fConfig, desc.fWidth, desc.fHeight, SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag), desc.fSampleCnt, - isMipMapped, key); + desc.fIsMipMapped, key); } diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h index e3af9e3302..a470b3bee6 100644 --- a/src/gpu/GrTexturePriv.h +++ b/src/gpu/GrTexturePriv.h @@ -55,7 +55,7 @@ public: } SkDestinationSurfaceColorMode mipColorMode() const { return fTexture->fMipColorMode; } - static void ComputeScratchKey(const GrSurfaceDesc&, bool isMipMapped, GrScratchKey*); + static void ComputeScratchKey(const GrSurfaceDesc&, GrScratchKey*); static void ComputeScratchKey(GrPixelConfig config, int width, int height, bool isRenderTarget, int sampleCnt, bool isMipMapped, GrScratchKey* key); diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 245562899e..3cb87b3faf 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -7,18 +7,14 @@ #include "GrTextureProxy.h" -#include "GrResourceProvider.h" #include "GrTexturePriv.h" GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, SkBudgeted budgeted, const void* srcData, size_t /*rowBytes*/, uint32_t flags) : INHERITED(srcDesc, fit, budgeted, flags) - , fIsMipMapped(SkToBool(GrResourceProvider::kMipMapped_Flag & flags)) + , fIsMipMapped(srcDesc.fIsMipMapped) , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy) { SkASSERT(!srcData); // currently handled in Make() - // Currently we do not support creating GrTextureProxys that are not wrapped that are mip - // mapped. This will be changed once we update our mip mapping support. - SkASSERT(!fIsMipMapped); } GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin) @@ -84,4 +80,3 @@ size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const { return GrSurface::ComputeSize(fConfig, fWidth, fHeight, 1, kHasMipMaps, SkBackingFit::kApprox == fFit); } - diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 579784b6ba..4943804553 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -197,6 +197,9 @@ sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx, return nullptr; } + const bool isMipMapped = mipLevelCount > 1; + desc.fIsMipMapped = isMipMapped; + std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); texels[0].fPixels = pmap->addr(); diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp index 8f5aa55685..54b87bf10d 100644 --- a/tests/GrSurfaceTest.cpp +++ b/tests/GrSurfaceTest.cpp @@ -166,75 +166,78 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info) continue; } desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; - for (GrSurfaceOrigin origin : - {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) { - desc.fOrigin = origin; - for (bool approx : {false, true}) { - auto resourceProvider = context->resourceProvider(); - // Try directly creating the texture. - // Do this twice in an attempt to hit the cache on the second time through. - for (int i = 0; i < 2; ++i) { - sk_sp<GrTexture> tex; - if (approx) { - tex = sk_sp<GrTexture>( - resourceProvider->createApproxTexture(desc, 0)); - } else { - tex = resourceProvider->createTexture(desc, SkBudgeted::kYes); - } - if (!tex) { - continue; - } - auto proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin); - auto texCtx = context->contextPriv().makeWrappedSurfaceContext( - std::move(proxy), nullptr); - SkImageInfo info = SkImageInfo::Make( - kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType); - memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t)); - if (texCtx->readPixels(info, data.get(), 0, 0, 0)) { - uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0; - for (int i = 0; i < kSize * kSize; ++i) { - if (cmp != data.get()[i]) { - ERRORF(reporter, "Failed on config %d", desc.fConfig); - break; + for (bool mipped : {false, true}) { + desc.fIsMipMapped = mipped; + for (GrSurfaceOrigin origin : + {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) { + desc.fOrigin = origin; + for (bool approx : {false, true}) { + auto resourceProvider = context->resourceProvider(); + // Try directly creating the texture. + // Do this twice in an attempt to hit the cache on the second time through. + for (int i = 0; i < 2; ++i) { + sk_sp<GrTexture> tex; + if (approx) { + tex = sk_sp<GrTexture>( + resourceProvider->createApproxTexture(desc, 0)); + } else { + tex = resourceProvider->createTexture(desc, SkBudgeted::kYes); + } + if (!tex) { + continue; + } + auto proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin); + auto texCtx = context->contextPriv().makeWrappedSurfaceContext( + std::move(proxy), nullptr); + SkImageInfo info = SkImageInfo::Make( + kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t)); + if (texCtx->readPixels(info, data.get(), 0, 0, 0)) { + uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0; + for (int i = 0; i < kSize * kSize; ++i) { + if (cmp != data.get()[i]) { + ERRORF(reporter, "Failed on config %d", desc.fConfig); + break; + } } } + memset(data.get(), 0xBC, kSize * kSize * sizeof(uint32_t)); + // Here we overwrite the texture so that the second time through we + // test against recycling without reclearing. + if (0 == i) { + texCtx->writePixels(info, data.get(), 0, 0, 0); + } } - memset(data.get(), 0xBC, kSize * kSize * sizeof(uint32_t)); - // Here we overwrite the texture so that the second time through we - // test against recycling without reclearing. - if (0 == i) { - texCtx->writePixels(info, data.get(), 0, 0, 0); - } - } - context->purgeAllUnlockedResources(); - - // Try creating the texture as a deferred proxy. - for (int i = 0; i < 2; ++i) { - auto surfCtx = context->contextPriv().makeDeferredSurfaceContext( - desc, approx ? SkBackingFit::kApprox : SkBackingFit::kExact, - SkBudgeted::kYes); - if (!surfCtx) { - continue; - } - SkImageInfo info = SkImageInfo::Make( - kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType); - memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t)); - if (surfCtx->readPixels(info, data.get(), 0, 0, 0)) { - uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0; - for (int i = 0; i < kSize * kSize; ++i) { - if (cmp != data.get()[i]) { - ERRORF(reporter, "Failed on config %d", desc.fConfig); - break; + context->purgeAllUnlockedResources(); + + // Try creating the texture as a deferred proxy. + for (int i = 0; i < 2; ++i) { + auto surfCtx = context->contextPriv().makeDeferredSurfaceContext( + desc, approx ? SkBackingFit::kApprox : SkBackingFit::kExact, + SkBudgeted::kYes); + if (!surfCtx) { + continue; + } + SkImageInfo info = SkImageInfo::Make( + kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t)); + if (surfCtx->readPixels(info, data.get(), 0, 0, 0)) { + uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0; + for (int i = 0; i < kSize * kSize; ++i) { + if (cmp != data.get()[i]) { + ERRORF(reporter, "Failed on config %d", desc.fConfig); + break; + } } } + // Here we overwrite the texture so that the second time through we + // test against recycling without reclearing. + if (0 == i) { + surfCtx->writePixels(info, data.get(), 0, 0, 0); + } } - // Here we overwrite the texture so that the second time through we - // test against recycling without reclearing. - if (0 == i) { - surfCtx->writePixels(info, data.get(), 0, 0, 0); - } + context->purgeAllUnlockedResources(); } - context->purgeAllUnlockedResources(); } } } diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index 056f6dd95e..c10d581288 100644 --- a/tests/ResourceCacheTest.cpp +++ b/tests/ResourceCacheTest.cpp @@ -1682,6 +1682,7 @@ static sk_sp<GrTextureProxy> make_mipmap_proxy(GrResourceProvider* provider, desc.fHeight = height; desc.fConfig = kRGBA_8888_GrPixelConfig; desc.fSampleCnt = sampleCnt; + desc.fIsMipMapped = true; return GrSurfaceProxy::MakeDeferredMipMap(provider, desc, SkBudgeted::kYes, texels.get(), mipLevelCount); |