diff options
author | Romain Guy <romainguy@google.com> | 2013-03-28 18:50:53 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-03-28 18:50:53 +0000 |
commit | 58f7689ac634afa616d2b754b68d65f9a2e83814 (patch) | |
tree | 0436306c1a30bbcf7a318ca1f3da75902bde0c01 /libs | |
parent | ce449d9ee521052bb6c24885a3599a19841eae5d (diff) | |
parent | ce4a7dfc516ee61301e9af91fad17ca1320efaab (diff) | |
download | frameworks_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.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 6 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 25 |
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; } } |