Chromium Code Reviews| 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; |
| } |