aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image/SkImage_Lazy.cpp
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-10-02 10:59:28 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-02 16:25:34 +0000
commit97abf014b40cc17c4100768299ef8cccd335aff7 (patch)
tree7e67b1325ddbc5c8e50a66cc2f9435d621b69fe8 /src/image/SkImage_Lazy.cpp
parentc405b9d5e369c43d12b637518504dc51878d1c78 (diff)
Update lockTextureProxy to return mipped proxys if mipping is requested.
We will either create a new mipped surface from scratch, or just create the base layer and copy that into the mipped surface. We then defer the creation of the rest of the mips to the GPU. Bug: skia: Change-Id: Ida3000ad5e666153c61b05e714f033138593b09b Reviewed-on: https://skia-review.googlesource.com/52743 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/image/SkImage_Lazy.cpp')
-rw-r--r--src/image/SkImage_Lazy.cpp73
1 files changed, 55 insertions, 18 deletions
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index 003b28ba98..c67d4df356 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -696,9 +696,17 @@ public:
};
static void set_key_on_proxy(GrResourceProvider* resourceProvider,
- GrTextureProxy* proxy, const GrUniqueKey& key) {
+ GrTextureProxy* proxy, GrTextureProxy* originalProxy,
+ const GrUniqueKey& key) {
if (key.isValid()) {
SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
+ if (originalProxy) {
+ SkASSERT(proxy->isMipMapped() && !originalProxy->isMipMapped());
+ // 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.
+ resourceProvider->removeUniqueKeyFromProxy(key, originalProxy);
+ }
resourceProvider->assignUniqueKeyToProxy(key, proxy);
}
}
@@ -751,13 +759,18 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
GrUniqueKey key;
this->makeCacheKeyFromOrigKey(origKey, format, &key);
+ sk_sp<GrTextureProxy> proxy;
+
// 1. Check the cache for a pre-existing one
if (key.isValid()) {
- if (sk_sp<GrTextureProxy> proxy = ctx->resourceProvider()->findOrCreateProxyByUniqueKey(
- key, kTopLeft_GrSurfaceOrigin)) {
+ proxy = ctx->resourceProvider()->findOrCreateProxyByUniqueKey(key,
+ kTopLeft_GrSurfaceOrigin);
+ if (proxy) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kPreExisting_LockTexturePath,
kLockTexturePathCount);
- return proxy;
+ if (!willBeMipped || proxy->isMipMapped()) {
+ return proxy;
+ }
}
}
@@ -769,23 +782,27 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
SkTransferFunctionBehavior behavior = getGeneratorBehaviorAndInfo(&genPixelsInfo);
// 2. Ask the generator to natively create one
- {
+ if (!proxy) {
ScopedGenerator generator(fSharedGenerator);
if (GrTextureMaker::AllowedTexGenType::kCheap == genType &&
SkImageGenerator::TexGenType::kCheap != generator->onCanGenerateTexture()) {
return nullptr;
}
- if (sk_sp<GrTextureProxy> proxy =
- generator->generateTexture(ctx, genPixelsInfo, fOrigin, behavior)) {
+ // TODO: Pass a flag into generateTexture which says we want to be mipped. If the generator
+ // can handle creating a mipped surface, then it can either generate the base layer or all
+ // the layers directly. Otherwise it just returns a non mipped surface as it currently does.
+ if ((proxy = generator->generateTexture(ctx, genPixelsInfo, fOrigin, behavior))) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kNative_LockTexturePath,
kLockTexturePathCount);
- set_key_on_proxy(ctx->resourceProvider(), proxy.get(), key);
- return proxy;
+ set_key_on_proxy(ctx->resourceProvider(), proxy.get(), nullptr, key);
+ if (!willBeMipped || proxy->isMipMapped()) {
+ return proxy;
+ }
}
}
// 3. Ask the generator to return YUV planes, which the GPU can convert
- if (!ctx->contextPriv().disableGpuYUVConversion()) {
+ if (!proxy && !ctx->contextPriv().disableGpuYUVConversion()) {
const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(cacheInfo, *ctx->caps());
ScopedGenerator generator(fSharedGenerator);
Generator_GrYUVProvider provider(generator);
@@ -797,33 +814,53 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
fSharedGenerator->fGenerator->getInfo().colorSpace();
const SkColorSpace* thisColorSpace = fInfo.colorSpace();
- sk_sp<GrTextureProxy> proxy =
- provider.refAsTextureProxy(ctx, desc, true, generatorColorSpace, thisColorSpace);
+ // TODO: Update to create the mipped surface in the YUV generator and draw the base layer
+ // directly into the mipped surface.
+ proxy = provider.refAsTextureProxy(ctx, desc, true, generatorColorSpace, thisColorSpace);
if (proxy) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kYUV_LockTexturePath,
kLockTexturePathCount);
- set_key_on_proxy(ctx->resourceProvider(), proxy.get(), key);
- return proxy;
+ set_key_on_proxy(ctx->resourceProvider(), proxy.get(), nullptr, key);
+ if (!willBeMipped || proxy->isMipMapped()) {
+ return proxy;
+ }
}
}
// 4. Ask the generator to return RGB(A) data, which the GPU can convert
SkBitmap bitmap;
- if (this->lockAsBitmap(&bitmap, chint, format, genPixelsInfo, behavior)) {
- sk_sp<GrTextureProxy> proxy;
+ if (!proxy && this->lockAsBitmap(&bitmap, chint, format, genPixelsInfo, behavior)) {
if (willBeMipped) {
proxy = GrGenerateMipMapsAndUploadToTextureProxy(ctx, bitmap, dstColorSpace);
}
if (!proxy) {
proxy = GrUploadBitmapToTextureProxy(ctx->resourceProvider(), bitmap, dstColorSpace);
}
- if (proxy) {
+ if (proxy && (!willBeMipped || proxy->isMipMapped())) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kRGBA_LockTexturePath,
kLockTexturePathCount);
- set_key_on_proxy(ctx->resourceProvider(), proxy.get(), key);
+ set_key_on_proxy(ctx->resourceProvider(), proxy.get(), nullptr, key);
return proxy;
}
}
+
+ if (proxy) {
+ // We need a mipped proxy, but we either found a proxy earlier that wasn't mipped, generated
+ // a native non mipped proxy, or generated a non-mipped yuv proxy. Thus we generate a new
+ // mipped surface and copy the original proxy into the base layer. We will then let the gpu
+ // generate the rest of the mips.
+ SkASSERT(willBeMipped);
+ SkASSERT(!proxy->isMipMapped());
+ if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(ctx, proxy.get(), dstColorSpace)) {
+ set_key_on_proxy(ctx->resourceProvider(), mippedProxy.get(), proxy.get(), key);
+ return mippedProxy;
+ }
+ // We failed to make a mipped proxy with the base copied into it. This could have
+ // been from failure to make the proxy or failure to do the copy. Thus we will fall
+ // back to just using the non mipped proxy; See skbug.com/7094.
+ return proxy;
+ }
+
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kFailure_LockTexturePath,
kLockTexturePathCount);
return nullptr;