aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-06-01 07:13:42 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-06-01 07:13:42 -0700
commitc59a1df65516eb60f9d41823d52e7ebffa900e9a (patch)
treeb1d71d42f6d8a1e0c44423f76607018aac7215d3 /src/gpu
parentc58e5326bbb296ddf598f7d3cdb652baad7bcb6b (diff)
Stretch small textures up to 16 pixels on PowerVR 54x
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrCaps.cpp3
-rw-r--r--src/gpu/SkGr.cpp113
-rw-r--r--src/gpu/gl/GrGLCaps.cpp5
3 files changed, 78 insertions, 43 deletions
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 1f277b7f7e..aaa585e3bb 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -98,6 +98,7 @@ GrCaps::GrCaps(const GrContextOptions& options) {
fMaxRenderTargetSize = 0;
fMaxTextureSize = 0;
+ fMinTextureSize = 0;
fMaxSampleCount = 0;
memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
@@ -110,6 +111,7 @@ GrCaps::GrCaps(const GrContextOptions& options) {
void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride);
+ fMinTextureSize = SkTMax(fMinTextureSize, options.fMinTextureSizeOverride);
}
static SkString map_flags_to_string(uint32_t flags) {
@@ -148,6 +150,7 @@ SkString GrCaps::dump() const {
r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
+ r.appendf("Min Texture Size : %d\n", fMinTextureSize);
r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
r.appendf("Max Sample Count : %d\n", fMaxSampleCount);
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 70c81f930a..a87caf7a70 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;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 13ce5070a6..99bc6da1fa 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -294,6 +294,11 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
// attachment, hence this min:
fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
+ // This GPU seems to have problems when tiling small textures
+ if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
+ fMinTextureSize = 16;
+ }
+
fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
// Disable scratch texture reuse on Mali and Adreno devices