Tag HardwareRenderers with a name to help debugging

The name of the renderer is the same as the window it belongs to.

Change-Id: Ie9adc0a1978afa026923ea41f5540eda6ba65a92
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index e0cf3b2..8051923 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -144,6 +144,14 @@
         }
     }
 
+    @Override
+    public void setName(String name) {
+        super.setName(name);
+        nSetName(mRenderer, name);
+    }
+
+    private static native void nSetName(int renderer, String name);
+
     ///////////////////////////////////////////////////////////////////////////
     // Hardware layers
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index 168ae81..7da2451 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -43,7 +43,7 @@
     private GLES20DisplayList mDisplayList;
 
     private GLES20RecordingCanvas() {
-        super(true /*record*/, true /*translucent*/);
+        super(true, true);
     }
 
     static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index eeae3ed..3d19260 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -27,6 +27,8 @@
  * @hide 
  */
 public abstract class HardwareCanvas extends Canvas {
+    private String mName;
+
     @Override
     public boolean isHardwareAccelerated() {
         return true;
@@ -36,7 +38,30 @@
     public void setBitmap(Bitmap bitmap) {
         throw new UnsupportedOperationException();
     }
-    
+
+    /**
+     * Specifies the name of this canvas. Naming the canvas is entirely
+     * optional but can be useful for debugging purposes.
+     *
+     * @param name The name of the canvas, can be null
+     *
+     * @see #getName()
+     */
+    public void setName(String name) {
+        mName = name;
+    }
+
+    /**
+     * Returns the name of this canvas.
+     *
+     * @return The name of the canvas or null
+     *
+     * @see #setName(String)
+     */
+    public String getName() {
+        return mName;
+    }
+
     /**
      * Invoked before any drawing operation is performed in this canvas.
      * 
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 5e6125f..e0d48a4 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -543,6 +543,13 @@
     }
 
     /**
+     * Optional, sets the name of the renderer. Useful for debugging purposes.
+     *
+     * @param name The name of this renderer, can be null
+     */
+    abstract void setName(String name);
+
+    /**
      * Creates a hardware renderer using OpenGL.
      * 
      * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.)
@@ -756,6 +763,8 @@
         GL mGl;
         HardwareCanvas mCanvas;
 
+        String mName;
+
         long mFrameCount;
         Paint mDebugPaint;
 
@@ -963,6 +972,7 @@
                     } else {
                         if (mCanvas == null) {
                             mCanvas = createCanvas();
+                            mCanvas.setName(mName);
                         }
                         if (mCanvas != null) {
                             setEnabled(true);
@@ -1277,6 +1287,11 @@
             return mCanvas;
         }
 
+        @Override
+        void setName(String name) {
+            mName = name;
+        }
+
         boolean canDraw() {
             return mGl != null && mCanvas != null;
         }        
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ba9eb89..c3321ea 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -739,6 +739,7 @@
 
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE;
                 mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
+                mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
                 mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
                         = mAttachInfo.mHardwareRenderer != null;
 
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index f4fcc81..33ed0b9 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -156,6 +156,17 @@
     return Stencil::getStencilSize();
 }
 
+static void android_view_GLES20Canvas_setName(JNIEnv* env,
+        jobject clazz, OpenGLRenderer* renderer, jstring name) {
+    if (name != NULL) {
+        const char* textArray = env->GetStringUTFChars(name, NULL);
+        renderer->setName(textArray);
+        env->ReleaseStringUTFChars(name, textArray);
+    } else {
+        renderer->setName(NULL);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // Functor
 // ----------------------------------------------------------------------------
@@ -949,6 +960,8 @@
     { "nPrepare",           "(IZ)I",           (void*) android_view_GLES20Canvas_prepare },
     { "nPrepareDirty",      "(IIIIIZ)I",       (void*) android_view_GLES20Canvas_prepareDirty },
     { "nFinish",            "(I)V",            (void*) android_view_GLES20Canvas_finish },
+    { "nSetName",           "(ILjava/lang/String;)V",
+            (void*) android_view_GLES20Canvas_setName },
 
     { "nGetStencilSize",    "()I",             (void*) android_view_GLES20Canvas_getStencilSize },
 
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 69c81c8..1c4d05f 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -215,7 +215,7 @@
     bool disableScissor();
     void setScissorEnabled(bool enabled);
 
-    void startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool preserve);
+    void startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard);
     void endTiling();
 
     /**
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 9f0a38b..6a05789 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -142,6 +142,18 @@
 // Setup
 ///////////////////////////////////////////////////////////////////////////////
 
+void OpenGLRenderer::setName(const char* name) {
+    if (name) {
+        mName.setTo(name);
+    } else {
+        mName.clear();
+    }
+}
+
+const char* OpenGLRenderer::getName() const {
+    return mName.string();
+}
+
 bool OpenGLRenderer::isDeferred() {
     return false;
 }
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 594580e..750b3d2 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -64,6 +64,19 @@
     virtual ~OpenGLRenderer();
 
     /**
+     * Sets the name of this renderer. The name is optional and
+     * empty by default. If the pointer is null the name is set
+     * to the empty string.
+     */
+    ANDROID_API void setName(const char* name);
+
+    /**
+     * Returns the name of this renderer as UTF8 string.
+     * The returned pointer is never null.
+     */
+    ANDROID_API const char* getName() const;
+
+    /**
      * Read externally defined properties to control the behavior
      * of the renderer.
      */
@@ -904,6 +917,9 @@
     // No-ops start/endTiling when set
     bool mSuppressTiling;
 
+    // Optional name of the renderer
+    String8 mName;
+
     friend class DisplayListRenderer;
 
 }; // class OpenGLRenderer