summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathias Agopian <mathias@google.com> 2010-04-14 16:43:44 -0700
committer Mathias Agopian <mathias@google.com> 2010-04-14 16:43:44 -0700
commitca99fb8f65f3ea249c56fb6dccefffb54e87696e (patch)
tree6071c87bf800c60d8c2f8dbd85a2f0c2b6e669f7
parentdaeec8c5b335ba84aa932a80e6319be5d71f1956 (diff)
fix [2594950] Flash: Zooming in on some content crashes the Nexus One and causes it to reboot (runtime restart)
We now limit the size of the surface to the maximum size supported by the GPU. On Nexus One this will 2048 -- it could be different on other devices. Surface creation fails if the limit is exceeded. Change-Id: I9ecfc2e9c58c9e283782b61ebfc6b590f71df785
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp8
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.h4
-rw-r--r--libs/surfaceflinger/Layer.cpp17
3 files changed, 27 insertions, 2 deletions
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 59696172fe..ea68352828 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -90,6 +90,8 @@ float DisplayHardware::getRefreshRate() const { return mRefreshRate; }
int DisplayHardware::getWidth() const { return mWidth; }
int DisplayHardware::getHeight() const { return mHeight; }
PixelFormat DisplayHardware::getFormat() const { return mFormat; }
+uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
+uint32_t DisplayHardware::getMaxViewportDims() const { return mMaxViewportDims; }
void DisplayHardware::init(uint32_t dpy)
{
@@ -246,6 +248,11 @@ void DisplayHardware::init(uint32_t dpy)
LOGI("version : %s", glGetString(GL_VERSION));
LOGI("extensions: %s", gl_extensions);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+ glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims);
+ LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
+ LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims);
+
#if 0
// for drivers that don't have proper support for flushing cached buffers
// on gralloc unlock, uncomment this block and test for the specific
@@ -273,6 +280,7 @@ void DisplayHardware::init(uint32_t dpy)
#warning "EGL_ANDROID_image_native_buffer not supported"
#endif
+
// Unbind the context from this thread
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index 6914d0cdec..df046af95a 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -76,6 +76,8 @@ public:
PixelFormat getFormat() const;
uint32_t getFlags() const;
void makeCurrent() const;
+ uint32_t getMaxTextureSize() const;
+ uint32_t getMaxViewportDims() const;
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
@@ -104,6 +106,8 @@ private:
PixelFormat mFormat;
uint32_t mFlags;
mutable uint32_t mPageFlipCount;
+ GLint mMaxViewportDims;
+ GLint mMaxTextureSize;
sp<FramebufferNativeWindow> mNativeWindow;
overlay_control_device_t* mOverlayEngine;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 4dc4a153e0..0a3254dec5 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -41,6 +41,10 @@
namespace android {
+template <typename T> inline T min(T a, T b) {
+ return a<b ? a : b;
+}
+
// ---------------------------------------------------------------------------
const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
@@ -109,17 +113,26 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
// the display's pixel format
const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ uint32_t const maxSurfaceDims = min(
+ hw.getMaxTextureSize(), hw.getMaxViewportDims());
+
+ // never allow a surface larger than what our underlying GL implementation
+ // can handle.
+ if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
+ return BAD_VALUE;
+ }
+
PixelFormatInfo displayInfo;
getPixelFormatInfo(hw.getFormat(), &displayInfo);
const uint32_t hwFlags = hw.getFlags();
mFormat = format;
- mWidth = w;
+ mWidth = w;
mHeight = h;
mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
-
+
// we use the red index
int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);