aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrTypes.h4
-rw-r--r--src/effects/SkBlurMaskFilter.cpp1
-rw-r--r--src/gpu/GrBackendTextureImageGenerator.cpp1
-rw-r--r--src/gpu/GrResourceProvider.cpp61
-rw-r--r--src/gpu/GrResourceProvider.h9
-rw-r--r--src/gpu/GrSurfaceProxy.cpp3
-rw-r--r--src/gpu/GrTexture.cpp5
-rw-r--r--src/gpu/GrTexturePriv.h2
-rw-r--r--src/gpu/GrTextureProxy.cpp7
-rw-r--r--src/gpu/SkGr.cpp3
-rw-r--r--tests/GrSurfaceTest.cpp127
-rw-r--r--tests/ResourceCacheTest.cpp1
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);