diff options
author | Greg Daniel <egdaniel@google.com> | 2018-02-07 10:21:48 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-07 15:46:02 +0000 |
commit | a4ead65e2c80b6e649f31e28e8fa116aca83fad4 (patch) | |
tree | e707b3a79ab62bf9920daf47ff2bf8fabc07d086 /src/gpu/GrProxyProvider.cpp | |
parent | 2a223358ed19f3dd25f9b127aa21f1dd138cb9f0 (diff) |
Add function to GrProxyProvider to lazily upload mip map data
Bug: skia:
Change-Id: I906207727242bed8a109bf3ca10b5a6e8e4b952e
Reviewed-on: https://skia-review.googlesource.com/104581
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/gpu/GrProxyProvider.cpp')
-rw-r--r-- | src/gpu/GrProxyProvider.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp index 4e37ac88e9..b73d92446d 100644 --- a/src/gpu/GrProxyProvider.cpp +++ b/src/gpu/GrProxyProvider.cpp @@ -17,10 +17,14 @@ #include "GrTextureProxyCacheAccess.h" #include "GrTextureRenderTargetProxy.h" #include "../private/GrSingleOwner.h" +#include "SkBitmap.h" #include "SkGr.h" #include "SkImage.h" #include "SkImage_Base.h" +#include "SkImageInfoPriv.h" +#include "SkImagePriv.h" #include "SkMipMap.h" +#include "SkTraceEvent.h" #define ASSERT_SINGLE_OWNER \ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);) @@ -309,6 +313,90 @@ sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& de SkDestinationSurfaceColorMode::kLegacy); } +sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap, + SkColorSpace* dstColorSpace) { + SkDestinationSurfaceColorMode mipColorMode = dstColorSpace + ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware + : SkDestinationSurfaceColorMode::kLegacy; + + if (!SkImageInfoIsValid(bitmap.info(), mipColorMode)) { + return nullptr; + } + + SkPixmap pixmap; + if (!bitmap.peekPixels(&pixmap)) { + return nullptr; + } + + ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height()); + sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, mipColorMode, nullptr)); + if (!mipmaps) { + return nullptr; + } + + if (mipmaps->countLevels() < 0) { + return nullptr; + } + + // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap + // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the + // upload of the data to the gpu can happen at anytime and the bitmap may change by then. + SkCopyPixelsMode copyMode = fResourceProvider ? kNever_SkCopyPixelsMode + : kIfMutable_SkCopyPixelsMode; + sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode); + + if (!baseLevel) { + return nullptr; + } + + GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *this->caps()); + + if (0 == mipmaps->countLevels()) { + return this->createTextureProxy(baseLevel, kNone_GrSurfaceFlags, kTopLeft_GrSurfaceOrigin, + 1, SkBudgeted::kYes, SkBackingFit::kExact); + + } + + sk_sp<GrTextureProxy> proxy = this->createLazyProxy( + [desc, baseLevel, mipmaps, mipColorMode] + (GrResourceProvider* resourceProvider, GrSurfaceOrigin* /*outOrigin*/) { + if (!resourceProvider) { + return sk_sp<GrTexture>(); + } + + const int mipLevelCount = mipmaps->countLevels() + 1; + std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); + + SkPixmap pixmap; + SkAssertResult(baseLevel->peekPixels(&pixmap)); + + // DDL TODO: Instead of copying all this info into GrMipLevels we should just plumb + // the use of SkMipMap down through Ganesh. + texels[0].fPixels = pixmap.addr(); + texels[0].fRowBytes = pixmap.rowBytes(); + + for (int i = 1; i < mipLevelCount; ++i) { + SkMipMap::Level generatedMipLevel; + mipmaps->getLevel(i - 1, &generatedMipLevel); + texels[i].fPixels = generatedMipLevel.fPixmap.addr(); + texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes(); + SkASSERT(texels[i].fPixels); + } + + return resourceProvider->createTexture(desc, SkBudgeted::kYes, texels.get(), + mipLevelCount, mipColorMode); + }, desc, GrMipMapped::kYes, SkBackingFit::kExact, SkBudgeted::kYes); + + if (fResourceProvider) { + // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however + // we're better off instantiating the proxy immediately here. + if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { + return nullptr; + } + } + return proxy; +} + sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, |