diff options
author | Greg Daniel <egdaniel@google.com> | 2017-10-02 10:59:28 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-02 16:25:34 +0000 |
commit | 97abf014b40cc17c4100768299ef8cccd335aff7 (patch) | |
tree | 7e67b1325ddbc5c8e50a66cc2f9435d621b69fe8 /src/image/SkImage_Lazy.cpp | |
parent | c405b9d5e369c43d12b637518504dc51878d1c78 (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.cpp | 73 |
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; |