aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/GrBitmapTextureMaker.cpp83
-rw-r--r--src/image/SkImage_Lazy.cpp73
2 files changed, 106 insertions, 50 deletions
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index ab8ee249a9..efb9e20291 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -37,51 +37,70 @@ sk_sp<GrTextureProxy> GrBitmapTextureMaker::refOriginalTextureProxy(bool willBeM
return nullptr;
}
- sk_sp<GrTextureProxy> originalProxy;
+ sk_sp<GrTextureProxy> proxy;
if (fOriginalKey.isValid()) {
- originalProxy = this->context()->resourceProvider()->findOrCreateProxyByUniqueKey(
+ proxy = this->context()->resourceProvider()->findOrCreateProxyByUniqueKey(
fOriginalKey, kTopLeft_GrSurfaceOrigin);
- if (originalProxy && (!willBeMipped || originalProxy->isMipMapped())) {
- return originalProxy;
+ if (proxy && (!willBeMipped || proxy->isMipMapped())) {
+ return proxy;
}
}
- sk_sp<GrTextureProxy> proxy;
- if (willBeMipped) {
- if (!originalProxy) {
+ if (!proxy) {
+ if (willBeMipped) {
proxy = GrGenerateMipMapsAndUploadToTextureProxy(this->context(), fBitmap,
dstColorSpace);
- } else {
- proxy = GrCopyBaseMipMapToTextureProxy(this->context(), originalProxy.get(),
- dstColorSpace);
- if (!proxy) {
- // 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 originalProxy;
+ }
+ if (!proxy) {
+ proxy = GrUploadBitmapToTextureProxy(this->context()->resourceProvider(), fBitmap,
+ dstColorSpace);
+ }
+ if (proxy) {
+ if (fOriginalKey.isValid()) {
+ this->context()->resourceProvider()->assignUniqueKeyToProxy(fOriginalKey,
+ proxy.get());
+ }
+ if (!willBeMipped || proxy->isMipMapped()) {
+ SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
+ if (fOriginalKey.isValid()) {
+ GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, fBitmap.pixelRef());
+ }
+ return proxy;
}
}
}
- if (!proxy) {
- proxy = GrUploadBitmapToTextureProxy(this->context()->resourceProvider(), fBitmap,
- dstColorSpace);
- }
- if (proxy && fOriginalKey.isValid()) {
- SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
- if (originalProxy) {
- // In this case we are stealing the key from the original proxy which should only happen
- // when we have just generated mipmaps for an originally unmipped proxy/texture. This
- // means that all future uses of the key will access the mipmapped version. The texture
- // backing the unmipped version will remain in the resource cache until the last texture
- // proxy referencing it is deleted at which time it too will be deleted or recycled.
- this->context()->resourceProvider()->removeUniqueKeyFromProxy(fOriginalKey,
- originalProxy.get());
+
+ if (proxy) {
+ SkASSERT(willBeMipped);
+ SkASSERT(!proxy->isMipMapped());
+ // We need a mipped proxy, but we either found a proxy earlier that wasn't mipped or
+ // generated a non mipped 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.
+ if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get(),
+ dstColorSpace)) {
+ SkASSERT(mippedProxy->origin() == kTopLeft_GrSurfaceOrigin);
+ if (fOriginalKey.isValid()) {
+ // In this case we are stealing the key from the original proxy which should only
+ // happen when we have just generated mipmaps for an originally unmipped
+ // proxy/texture. This means that all future uses of the key will access the
+ // mipmapped version. The texture backing the unmipped version will remain in the
+ // resource cache until the last texture proxy referencing it is deleted at which
+ // time it too will be deleted or recycled.
+ this->context()->resourceProvider()->removeUniqueKeyFromProxy(fOriginalKey,
+ proxy.get());
+ this->context()->resourceProvider()->assignUniqueKeyToProxy(fOriginalKey,
+ mippedProxy.get());
+ GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, fBitmap.pixelRef());
+ }
+ return mippedProxy;
}
- this->context()->resourceProvider()->assignUniqueKeyToProxy(fOriginalKey, proxy.get());
- GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, fBitmap.pixelRef());
+ // 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;
}
- return proxy;
+ return nullptr;
}
void GrBitmapTextureMaker::makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey,
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;