aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-02-07 10:21:48 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-07 15:46:02 +0000
commita4ead65e2c80b6e649f31e28e8fa116aca83fad4 (patch)
treee707b3a79ab62bf9920daf47ff2bf8fabc07d086
parent2a223358ed19f3dd25f9b127aa21f1dd138cb9f0 (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>
-rw-r--r--gm/gamut.cpp1
-rw-r--r--src/gpu/GrBitmapTextureMaker.cpp2
-rw-r--r--src/gpu/GrProxyProvider.cpp88
-rw-r--r--src/gpu/GrProxyProvider.h7
-rw-r--r--src/gpu/SkGr.cpp44
-rw-r--r--src/gpu/SkGr.h3
-rw-r--r--src/image/SkImage_Gpu.cpp2
-rw-r--r--src/image/SkImage_Lazy.cpp2
8 files changed, 99 insertions, 50 deletions
diff --git a/gm/gamut.cpp b/gm/gamut.cpp
index c2303af594..55f1b28acf 100644
--- a/gm/gamut.cpp
+++ b/gm/gamut.cpp
@@ -43,6 +43,7 @@ struct BitmapCellRenderer : public CellRenderer {
int scaledSize = sk_float_round2int(scale * gRectSize);
fBitmap.allocPixels(SkImageInfo::MakeS32(scaledSize, scaledSize, kPremul_SkAlphaType));
fBitmap.eraseColor(color);
+ fBitmap.setImmutable();
const char* qualityNames[] = { "None", "Low", "Medium", "High" };
fLabel = SkStringPrintf("Bitmap (%s)", qualityNames[quality]);
}
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 7531bf6680..2fd8016818 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -49,7 +49,7 @@ sk_sp<GrTextureProxy> GrBitmapTextureMaker::refOriginalTextureProxy(bool willBeM
if (!proxy) {
if (willBeMipped) {
- proxy = GrGenerateMipMapsAndUploadToTextureProxy(proxyProvider, fBitmap, dstColorSpace);
+ proxy = proxyProvider->createMipMapProxyFromBitmap(fBitmap, dstColorSpace);
}
if (!proxy) {
proxy = GrUploadBitmapToTextureProxy(proxyProvider, fBitmap, dstColorSpace);
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,
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index c5191a681c..aa1d991fae 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -18,6 +18,7 @@ class GrCaps;
class GrResourceProvider;
class GrSingleOwner;
class GrBackendRenderTarget;
+class SkBitmap;
class SkImage;
/*
@@ -110,6 +111,12 @@ public:
sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, SkBudgeted);
/*
+ * Creates a new mipmapped texture proxy for the bitmap with mip levels generated by the cpu.
+ */
+ sk_sp<GrTextureProxy> createMipMapProxyFromBitmap(const SkBitmap& bitmap,
+ SkColorSpace* dstColorSpace);
+
+ /*
* Create a GrSurfaceProxy without any data.
*/
sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 09ad206b50..1d210c4008 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -112,50 +112,6 @@ void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pix
pixelRef->addGenIDChangeListener(new Invalidator(key));
}
-sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrProxyProvider* proxyProvider,
- const SkBitmap& bitmap,
- SkColorSpace* dstColorSpace) {
- SkDestinationSurfaceColorMode colorMode = dstColorSpace
- ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
- : SkDestinationSurfaceColorMode::kLegacy;
-
- if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
- return nullptr;
- }
-
- SkPixmap pixmap;
- if (!bitmap.peekPixels(&pixmap)) {
- return nullptr;
- }
-
- ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height());
- GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
- std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(pixmap, colorMode, nullptr));
- if (!mipmaps) {
- return nullptr;
- }
-
- const int mipLevelCount = mipmaps->countLevels() + 1;
- if (mipLevelCount < 1) {
- return nullptr;
- }
-
- std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
-
- 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();
- }
-
- return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes, texels.get(), mipLevelCount,
- colorMode);
-}
-
sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx, GrTextureProxy* baseProxy) {
SkASSERT(baseProxy);
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index c131ef8f22..86f584cf58 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -208,9 +208,6 @@ sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext*,
sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrProxyProvider*, const SkBitmap&,
SkColorSpace* dstColorSpace);
-sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrProxyProvider*, const SkBitmap&,
- SkColorSpace* dstColorSpace);
-
/**
* Creates a new texture for the pixmap.
*/
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index df342ceee3..042670b6c4 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -628,7 +628,7 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrContext* context, const SkP
if (buildMips) {
SkBitmap bmp;
bmp.installPixels(pixmap);
- proxy = GrGenerateMipMapsAndUploadToTextureProxy(proxyProvider, bmp, dstColorSpace);
+ proxy = proxyProvider->createMipMapProxyFromBitmap(bmp, dstColorSpace);
} else {
proxy = GrUploadPixmapToTextureProxy(proxyProvider, pixmap, SkBudgeted::kYes,
dstColorSpace);
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index 92d3a2fed9..1fc6d95094 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -830,7 +830,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
SkBitmap bitmap;
if (!proxy && this->lockAsBitmap(&bitmap, chint, format, genPixelsInfo, behavior)) {
if (willBeMipped) {
- proxy = GrGenerateMipMapsAndUploadToTextureProxy(proxyProvider, bitmap, dstColorSpace);
+ proxy = proxyProvider->createMipMapProxyFromBitmap(bitmap, dstColorSpace);
}
if (!proxy) {
proxy = GrUploadBitmapToTextureProxy(proxyProvider, bitmap, dstColorSpace);