Index: src/gpu/SkGr.cpp |
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
index 70c81f930a8e54b0482aece09b6bcc44b2a2ea6e..a87caf7a708ccbb1fdef30ad76fb72978a47fb1b 100644 |
--- a/src/gpu/SkGr.cpp |
+++ b/src/gpu/SkGr.cpp |
@@ -88,34 +88,59 @@ static void build_index8_data(void* buffer, const SkBitmap& bitmap) { |
//////////////////////////////////////////////////////////////////////////////// |
-enum Stretch { |
- kNo_Stretch, |
- kBilerp_Stretch, |
- kNearest_Stretch |
+struct Stretch { |
+ enum Type { |
+ kNone_Type, |
+ kBilerp_Type, |
+ kNearest_Type |
+ } fType; |
+ int fWidth; |
+ int fHeight; |
}; |
-static Stretch get_stretch_type(const GrContext* ctx, int width, int height, |
- const GrTextureParams* params) { |
- if (params && params->isTiled()) { |
- if (!ctx->caps()->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(height))) { |
- switch(params->filterMode()) { |
- case GrTextureParams::kNone_FilterMode: |
- return kNearest_Stretch; |
- case GrTextureParams::kBilerp_FilterMode: |
- case GrTextureParams::kMipMap_FilterMode: |
- return kBilerp_Stretch; |
- } |
+static void get_stretch(const GrContext* ctx, int width, int height, |
+ const GrTextureParams* params, Stretch* stretch) { |
+ stretch->fType = Stretch::kNone_Type; |
+ bool doStretch = false; |
+ if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && |
+ (!SkIsPow2(width) || !SkIsPow2(height))) { |
+ doStretch = true; |
+ stretch->fWidth = GrNextPow2(width); |
+ stretch->fHeight = GrNextPow2(height); |
+ } else if (width < ctx->caps()->minTextureSize() || |
+ height < ctx->caps()->minTextureSize()) { |
+ // The small texture issues appear to be with tiling. Hence it seems ok to scale them |
+ // up using the GPU. If issues persist we may need to CPU-stretch. |
+ doStretch = true; |
+ stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); |
+ stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); |
+ } |
+ if (doStretch) { |
+ switch(params->filterMode()) { |
+ case GrTextureParams::kNone_FilterMode: |
+ stretch->fType = Stretch::kNearest_Type; |
+ break; |
+ case GrTextureParams::kBilerp_FilterMode: |
+ case GrTextureParams::kMipMap_FilterMode: |
+ stretch->fType = Stretch::kBilerp_Type; |
+ break; |
} |
+ } else { |
+ stretch->fWidth = -1; |
+ stretch->fHeight = -1; |
+ stretch->fType = Stretch::kNone_Type; |
} |
- return kNo_Stretch; |
} |
-static bool make_stretched_key(const GrUniqueKey& origKey, Stretch stretch, |
+static bool make_stretched_key(const GrUniqueKey& origKey, const Stretch& stretch, |
GrUniqueKey* stretchedKey) { |
- if (origKey.isValid() && kNo_Stretch != stretch) { |
+ if (origKey.isValid() && Stretch::kNone_Type != stretch.fType) { |
+ uint32_t width = SkToU16(stretch.fWidth); |
+ uint32_t height = SkToU16(stretch.fHeight); |
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
- GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 1); |
- builder[0] = stretch; |
+ GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 3); |
+ builder[0] = stretch.fType; |
+ builder[1] = width | (height << 16); |
builder.finish(); |
return true; |
} |
@@ -140,11 +165,11 @@ static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) { |
} |
static void make_bitmap_keys(const SkBitmap& bitmap, |
- Stretch stretch, |
+ const Stretch& stretch, |
GrUniqueKey* key, |
GrUniqueKey* stretchedKey) { |
make_unstretched_key(bitmap, key); |
- if (kNo_Stretch != stretch) { |
+ if (Stretch::kNone_Type != stretch.fType) { |
make_stretched_key(*key, stretch, stretchedKey); |
} |
} |
@@ -189,13 +214,13 @@ static GrTexture* create_texture_for_bmp(GrContext* ctx, |
return result; |
} |
-// creates a new texture that is the input texture scaled up to the next power of two in |
-// width or height. If optionalKey is valid it will be set on the new texture. stretch |
-// controls whether the scaling is done using nearest or bilerp filtering. |
-GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, |
- SkPixelRef* pixelRef, |
- const GrUniqueKey& optionalKey) { |
- SkASSERT(kNo_Stretch != stretch); |
+// creates a new texture that is the input texture scaled up. If optionalKey is valid it will be |
+// set on the new texture. stretch controls whether the scaling is done using nearest or bilerp |
+// filtering and the size to stretch the texture to. |
+GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch, |
+ SkPixelRef* pixelRef, |
+ const GrUniqueKey& optionalKey) { |
+ SkASSERT(Stretch::kNone_Type != stretch.fType); |
GrContext* context = inputTexture->getContext(); |
SkASSERT(context); |
@@ -204,8 +229,8 @@ GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, |
// Either it's a cache miss or the original wasn't cached to begin with. |
GrSurfaceDesc rtDesc = inputTexture->desc(); |
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; |
- rtDesc.fWidth = GrNextPow2(rtDesc.fWidth); |
- rtDesc.fHeight = GrNextPow2(rtDesc.fHeight); |
+ rtDesc.fWidth = stretch.fWidth; |
+ rtDesc.fHeight = stretch.fHeight; |
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); |
// If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise, |
@@ -241,8 +266,9 @@ GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, |
// If filtering is not desired then we want to ensure all texels in the resampled image are |
// copies of texels from the original. |
GrTextureParams params(SkShader::kClamp_TileMode, |
- kBilerp_Stretch == stretch ? GrTextureParams::kBilerp_FilterMode : |
- GrTextureParams::kNone_FilterMode); |
+ Stretch::kBilerp_Type == stretch.fType ? |
+ GrTextureParams::kBilerp_FilterMode : |
+ GrTextureParams::kNone_FilterMode); |
paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); |
SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight)); |
@@ -479,10 +505,10 @@ static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
static GrTexture* create_bitmap_texture(GrContext* ctx, |
const SkBitmap& bmp, |
- Stretch stretch, |
+ const Stretch& stretch, |
const GrUniqueKey& unstretchedKey, |
const GrUniqueKey& stretchedKey) { |
- if (kNo_Stretch != stretch) { |
+ if (Stretch::kNone_Type != stretch.fType) { |
SkAutoTUnref<GrTexture> unstretched; |
// Check if we have the unstretched version in the cache, if not create it. |
if (unstretchedKey.isValid()) { |
@@ -494,8 +520,7 @@ static GrTexture* create_bitmap_texture(GrContext* ctx, |
return NULL; |
} |
} |
- GrTexture* stretched = stretch_texture_to_next_pot(unstretched, stretch, bmp.pixelRef(), |
- stretchedKey); |
+ GrTexture* stretched = stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKey); |
return stretched; |
} |
@@ -506,12 +531,13 @@ static GrTexture* create_bitmap_texture(GrContext* ctx, |
bool GrIsBitmapInCache(const GrContext* ctx, |
const SkBitmap& bitmap, |
const GrTextureParams* params) { |
- Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params); |
+ Stretch stretch; |
+ get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
// Handle the case where the bitmap is explicitly texture backed. |
GrTexture* texture = bitmap.getTexture(); |
if (texture) { |
- if (kNo_Stretch == stretch) { |
+ if (Stretch::kNone_Type == stretch.fType) { |
return true; |
} |
// No keys for volatile bitmaps. |
@@ -535,18 +561,19 @@ bool GrIsBitmapInCache(const GrContext* ctx, |
GrUniqueKey key, stretchedKey; |
make_bitmap_keys(bitmap, stretch, &key, &stretchedKey); |
return ctx->textureProvider()->existsTextureWithUniqueKey( |
- (kNo_Stretch == stretch) ? key : stretchedKey); |
+ (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey); |
} |
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
const SkBitmap& bitmap, |
const GrTextureParams* params) { |
- Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params); |
+ Stretch stretch; |
+ get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
GrTexture* result = bitmap.getTexture(); |
if (result) { |
- if (kNo_Stretch == stretch) { |
+ if (Stretch::kNone_Type == stretch.fType) { |
return SkRef(result); |
} |
GrUniqueKey stretchedKey; |
@@ -562,7 +589,7 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
} |
} |
} |
- return stretch_texture_to_next_pot(result, stretch, bitmap.pixelRef(), stretchedKey); |
+ return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey); |
} |
GrUniqueKey key, resizedKey; |