summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-03-28 18:50:53 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-03-28 18:50:53 +0000
commit58f7689ac634afa616d2b754b68d65f9a2e83814 (patch)
tree0436306c1a30bbcf7a318ca1f3da75902bde0c01 /libs
parentce449d9ee521052bb6c24885a3599a19841eae5d (diff)
parentce4a7dfc516ee61301e9af91fad17ca1320efaab (diff)
downloadframeworks_base-58f7689ac634afa616d2b754b68d65f9a2e83814.zip
frameworks_base-58f7689ac634afa616d2b754b68d65f9a2e83814.tar.gz
frameworks_base-58f7689ac634afa616d2b754b68d65f9a2e83814.tar.bz2
Merge "Don't crash when making a layer larger than supported dimensions Bug #8437401" into jb-mr2-dev
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/DisplayListRenderer.cpp4
-rw-r--r--libs/hwui/DisplayListRenderer.h6
-rw-r--r--libs/hwui/Layer.cpp7
-rw-r--r--libs/hwui/LayerRenderer.cpp25
4 files changed, 32 insertions, 10 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 07daa3b..0b8f7e6 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -248,9 +248,7 @@ status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
}
status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) {
- mLayers.add(layer);
- mCaches.resourceCache.incrementRefcount(layer);
-
+ layer = refLayer(layer);
addDrawOp(new (alloc()) DrawLayerOp(layer, x, y));
return DrawGlInfo::kStatusDone;
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 50e552f..19f7eb6 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -271,6 +271,12 @@ private:
return copy;
}
+ inline Layer* refLayer(Layer* layer) {
+ mLayers.add(layer);
+ mCaches.resourceCache.incrementRefcount(layer);
+ return layer;
+ }
+
inline SkBitmap* refBitmap(SkBitmap* bitmap) {
// Note that this assumes the bitmap is immutable. There are cases this won't handle
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 2998535..7f4977a 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -75,6 +75,13 @@ bool Layer::resize(const uint32_t width, const uint32_t height) {
return true;
}
+ const uint32_t maxTextureSize = Caches::getInstance().maxTextureSize;
+ if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) {
+ ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
+ desiredWidth, desiredHeight, maxTextureSize, maxTextureSize);
+ return false;
+ }
+
uint32_t oldWidth = getWidth();
uint32_t oldHeight = getHeight();
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index bb02286..8451048 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -222,6 +222,21 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
return NULL;
}
+ // We first obtain a layer before comparing against the max texture size
+ // because layers are not allocated at the exact desired size. They are
+ // always created slighly larger to improve recycling
+ const uint32_t maxTextureSize = caches.maxTextureSize;
+ if (layer->getWidth() > maxTextureSize || layer->getHeight() > maxTextureSize) {
+ ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
+ width, height, maxTextureSize, maxTextureSize);
+
+ // Creating a new layer always increment its refcount by 1, this allows
+ // us to destroy the layer object if one was created for us
+ Caches::getInstance().resourceCache.decrementRefcount(layer);
+
+ return NULL;
+ }
+
layer->setFbo(fbo);
layer->layer.set(0.0f, 0.0f, width, height);
layer->texCoords.set(0.0f, height / float(layer->getHeight()),
@@ -243,14 +258,11 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
layer->setEmpty(false);
layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
+ // This should only happen if we run out of memory
if (glGetError() != GL_NO_ERROR) {
- ALOGD("Could not allocate texture for layer (fbo=%d %dx%d)",
- fbo, width, height);
-
+ ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-
- Caches::getInstance().resourceCache.decrementRefcount(layer);
-
+ caches.resourceCache.decrementRefcount(layer);
return NULL;
}
}
@@ -272,7 +284,6 @@ bool LayerRenderer::resizeLayer(Layer* layer, uint32_t width, uint32_t height) {
layer->texCoords.set(0.0f, height / float(layer->getHeight()),
width / float(layer->getWidth()), 0.0f);
} else {
- Caches::getInstance().resourceCache.decrementRefcount(layer);
return false;
}
}