OSDN Git Service

Make sure we have a current EGL context when invoking EGL
authorRomain Guy <romainguy@google.com>
Wed, 27 Jul 2011 01:57:28 +0000 (18:57 -0700)
committerRomain Guy <romainguy@google.com>
Wed, 27 Jul 2011 01:57:28 +0000 (18:57 -0700)
Bug #5081795

Change-Id: Iee3382d362a71c1e6c5c498b319bf7f7bcf5a2f0

core/java/android/view/HardwareRenderer.java
core/java/android/view/ViewRootImpl.java
libs/hwui/Layer.h
libs/hwui/LayerCache.cpp
libs/hwui/TextureCache.cpp

index 14a77b4..d2476af 100644 (file)
@@ -283,7 +283,7 @@ public abstract class HardwareRenderer {
      *              see {@link android.content.ComponentCallbacks}
      */
     static void trimMemory(int level) {
-        Gl20Renderer.flushCaches(level);
+        Gl20Renderer.trimMemory(level);
     }
 
     /**
@@ -677,22 +677,13 @@ public abstract class HardwareRenderer {
         }
 
         EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
-            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };
+            int[] attribs = { EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };
 
             return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
-                    mGlVersion != 0 ? attrib_list : null);            
+                    mGlVersion != 0 ? attribs : null);            
         }
 
         @Override
-        void initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
-                SurfaceHolder holder) throws Surface.OutOfResourcesException {
-            if (isRequested()) {
-                checkEglErrors();
-                super.initializeIfNeeded(width, height, attachInfo, holder);
-            }
-        }
-        
-        @Override
         void destroy(boolean full) {
             if (full && mCanvas != null) {
                 mCanvas = null;
@@ -726,6 +717,7 @@ public abstract class HardwareRenderer {
 
         @Override
         void setup(int width, int height) {
+            checkCurrent();
             mCanvas.setViewport(width, height);
         }
 
@@ -819,7 +811,7 @@ public abstract class HardwareRenderer {
          *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
          *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
          */
-        private int checkCurrent() {
+        int checkCurrent() {
             if (mEglThread != Thread.currentThread()) {
                 throw new IllegalStateException("Hardware acceleration can only be used with a " +
                         "single UI thread.\nOriginal thread: " + mEglThread + "\n" +
@@ -847,6 +839,9 @@ public abstract class HardwareRenderer {
     static class Gl20Renderer extends GlRenderer {
         private GLES20Canvas mGlCanvas;
 
+        private static EGLSurface sPbuffer;
+        private static final Object[] sPbufferLock = new Object[0];
+
         Gl20Renderer(boolean translucent) {
             super(2, translucent);
         }
@@ -926,14 +921,26 @@ public abstract class HardwareRenderer {
             return ((GLES20TextureLayer) layer).getSurfaceTexture();
         }
 
-        static HardwareRenderer create(boolean translucent) {
-            if (GLES20Canvas.isAvailable()) {
-                return new Gl20Renderer(translucent);
+        static void trimMemory(int level) {
+            if (sEgl == null || sEglConfig == null) return;
+
+            EGLContext eglContext = sEglContextStorage.get();
+            // We do not have OpenGL objects
+            if (eglContext == null) {
+                return;
+            } else {
+                synchronized (sPbufferLock) {
+                    // Create a temporary 1x1 pbuffer so we have a context
+                    // to clear our OpenGL objects
+                    if (sPbuffer == null) {
+                        sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
+                                EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
+                        });
+                    }
+                }
+                sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
             }
-            return null;
-        }
-        
-        static void flushCaches(int level) {
+
             switch (level) {
                 case ComponentCallbacks.TRIM_MEMORY_MODERATE:
                     GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
@@ -943,5 +950,12 @@ public abstract class HardwareRenderer {
                     break;
             }
         }
+
+        static HardwareRenderer create(boolean translucent) {
+            if (GLES20Canvas.isAvailable()) {
+                return new Gl20Renderer(translucent);
+            }
+            return null;
+        }
     }
 }
index 470493d..35a40fc 100644 (file)
@@ -235,6 +235,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
     final Configuration mLastConfiguration = new Configuration();
     final Configuration mPendingConfiguration = new Configuration();
 
+    
     class ResizedInfo {
         Rect coveredInsets;
         Rect visibleInsets;
index 0c536b0..dd75497 100644 (file)
@@ -191,6 +191,10 @@ struct Layer {
         if (texture.id) glDeleteTextures(1, &texture.id);
     }
 
+    inline void deleteFbo() {
+        if (fbo) glDeleteFramebuffers(1, &fbo);
+    }
+
     inline void allocateTexture(GLenum format, GLenum storage) {
         glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL);
     }
index 36083af..58c0fac 100644 (file)
@@ -69,6 +69,7 @@ void LayerCache::setMaxSize(uint32_t maxSize) {
 void LayerCache::deleteLayer(Layer* layer) {
     if (layer) {
         mSize -= layer->getWidth() * layer->getHeight() * 4;
+        layer->deleteFbo();
         layer->deleteTexture();
         delete layer;
     }
index f926fdd..fbdbf92 100644 (file)
@@ -165,7 +165,7 @@ void TextureCache::clearGarbage() {
 
 void TextureCache::clear() {
     mCache.clear();
-    TEXTURE_LOGD("TextureCache:clear(), miSize = %d", mSize);
+    TEXTURE_LOGD("TextureCache:clear(), mSize = %d", mSize);
 }
 
 void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {