Index: src/gpu/SkGr.cpp |
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
index 09c83b929a8c575b1a2b9e15116c76abc4968c5c..a4464e55a9d3752f48e12ab8961f57b5dfd9d47f 100644 |
--- a/src/gpu/SkGr.cpp |
+++ b/src/gpu/SkGr.cpp |
@@ -19,6 +19,8 @@ |
#include "SkErrorInternals.h" |
#include "SkGrPixelRef.h" |
#include "SkMessageBus.h" |
+#include "SkMipMap.h" |
+#include "SkMipMapLevel.h" |
#include "SkPixelRef.h" |
#include "SkResourceCache.h" |
#include "SkTextureCompressor.h" |
@@ -421,7 +423,7 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe |
pixelRef->addGenIDChangeListener(listener); |
ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture); |
} |
- return texture; |
+ return texture; |
} |
static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
@@ -560,6 +562,68 @@ bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, |
params); |
} |
+static GrTexture* create_mipmapped_texture(GrContext* ctx, |
bsalomon
2015/09/30 18:01:29
You should coordinate with reed@ about landing thi
cblume
2015/10/08 09:27:57
I rebased ontop of those changes. There was a conf
|
+ const SkBitmap& bitmap, |
+ const GrUniqueKey& optionalKey, |
+ SkDiscardableFactoryProc fact) { |
+ GrTexture* texture = bitmap.getTexture(); |
+ // If the SkBitmap is already backed by a texture, we do not want to read the contents back |
+ // to the cpu and generate the mipmap only to send it back to the GPU. |
+ SkASSERT(!texture); |
+ |
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info()); |
+ |
+ SkMipMap* mipmap = SkMipMap::Build(bitmap, fact); |
+ if (mipmap == nullptr) { |
+ // could not create the mipmap |
+ return nullptr; |
+ } else { |
+ int mipLevelCount = mipmap->getLevelsCount() + 1; |
+ desc.fIsMipMapped = mipLevelCount > 1; |
+ SkTArray<SkMipMapLevel> texels(mipLevelCount); |
+ |
+ SkAutoPixmapUnlock srcUnlocker; |
+ if (!bitmap.requestLock(&srcUnlocker)) { |
+ return nullptr; |
+ } |
+ const SkPixmap& srcPixmap = srcUnlocker.pixmap(); |
+ if (nullptr == srcPixmap.addr()) { |
+ return nullptr; |
+ } |
+ |
+ int width = bitmap.width(); |
+ int height = bitmap.height(); |
+ if (width < 0 || height < 0) { |
+ return nullptr; |
+ } |
+ uint32_t baseLevelWidth = width; |
+ uint32_t baseLevelHeight = height; |
+ SkMipMapLevel baseLevel(srcPixmap.addr(), bitmap.rowBytes(), baseLevelWidth, |
+ baseLevelHeight); |
+ texels.push_back(baseLevel); |
+ |
+ for (int i = 1; i < mipLevelCount; i++) { |
+ SkMipMap::Level level; |
+ if (!mipmap->getLevel(i, &level)) { |
+ return nullptr; |
+ } |
+ |
+ SkMipMapLevel currentMipLevel(level.fPixels, level.fRowBytes, level.fWidth, |
+ level.fHeight); |
+ texels.push_back(currentMipLevel); |
+ } |
+ |
+ SkPixelRef* pixelRef = bitmap.pixelRef(); |
+ if (optionalKey.isValid()) { |
+ BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); |
+ pixelRef->addGenIDChangeListener(listener); |
+ ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture); |
+ } |
+ |
+ return ctx->textureProvider()->createTexture(desc, true, texels); |
+ } |
+} |
+ |
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
const SkBitmap& bitmap, |
const GrTextureParams* params) { |
@@ -601,7 +665,13 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
} |
} |
- result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); |
+ if (params && params->filterMode() == GrTextureParams::kMipMap_FilterMode) { |
+ const SkDiscardableFactoryProc fact = nullptr; |
+ result = create_mipmapped_texture(ctx, bitmap, key, fact); |
+ } else { |
+ result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); |
+ } |
+ |
if (result) { |
return result; |
} |