aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-07-15 10:12:16 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-07-15 10:12:16 -0700
commitb4d40ef72432429d22c6be2e228b7f73e5c3a91d (patch)
tree8fe83ee1670474755bf80887f439cac0bad4bf39 /src
parent3aaa0db1c4a3177cfe498012b2905dc3dfa92a6f (diff)
Don't upload texture smaller than the min texture size when stretching a bmp up to a POT
Diffstat (limited to 'src')
-rw-r--r--src/gpu/SkGr.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 5608030776..bb04131245 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -12,6 +12,7 @@
#include "GrXferProcessor.h"
#include "SkColorFilter.h"
#include "SkConfig8888.h"
+#include "SkCanvas.h"
#include "SkData.h"
#include "SkErrorInternals.h"
#include "SkGrPixelRef.h"
@@ -105,10 +106,9 @@ static void get_stretch(const GrContext* ctx, int width, int height,
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()) {
+ stretch->fWidth = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize()));
+ stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize()));
+ } 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;
@@ -450,6 +450,10 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe
static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx,
const SkBitmap& origBitmap,
const GrUniqueKey& optionalKey) {
+ if (origBitmap.width() < ctx->caps()->minTextureSize() ||
+ origBitmap.height() < ctx->caps()->minTextureSize()) {
+ return NULL;
+ }
SkBitmap tmpBitmap;
const SkBitmap* bitmap = &origBitmap;
@@ -508,6 +512,27 @@ static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx,
bitmap->getPixels(), bitmap->rowBytes());
}
+static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) {
+ SkBitmap stretched;
+ stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight);
+ SkCanvas canvas(stretched);
+ SkPaint paint;
+ switch (stretch.fType) {
+ case Stretch::kNearest_Type:
+ paint.setFilterQuality(kNone_SkFilterQuality);
+ break;
+ case Stretch::kBilerp_Type:
+ paint.setFilterQuality(kLow_SkFilterQuality);
+ break;
+ case Stretch::kNone_Type:
+ SkDEBUGFAIL("Shouldn't get here.");
+ break;
+ }
+ SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar(stretch.fHeight));
+ canvas.drawBitmapRectToRect(bmp, NULL, dstRect, &paint);
+ return stretched;
+}
+
static GrTexture* create_bitmap_texture(GrContext* ctx,
const SkBitmap& bmp,
const Stretch& stretch,
@@ -522,15 +547,15 @@ static GrTexture* create_bitmap_texture(GrContext* ctx,
if (!unstretched) {
unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey));
if (!unstretched) {
- return NULL;
+ // We might not have been able to create a unstrecthed texture because it is smaller
+ // than the min texture size. In that case do cpu stretching.
+ SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch);
+ return create_unstretched_bitmap_texture(ctx, stretchedBmp, stretchedKey);
}
}
- GrTexture* stretched = stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKey);
- return stretched;
+ return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKey);
}
-
return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
-
}
bool GrIsBitmapInCache(const GrContext* ctx,