Merge "MediaRecorder: add getSurface() api and SURFACE video source"
diff --git a/api/current.txt b/api/current.txt
index 951e5a8..1495277 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11062,7 +11062,6 @@
     method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
-    method public abstract void waitUntilIdle() throws android.hardware.camera2.CameraAccessException;
     field public static final int TEMPLATE_PREVIEW = 1; // 0x1
     field public static final int TEMPLATE_RECORD = 3; // 0x3
     field public static final int TEMPLATE_STILL_CAPTURE = 2; // 0x2
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index ddefc70..22322e3 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -412,27 +412,28 @@
      *             if an i/o error occurs.
      */
     /*package*/ void flush() throws IOException {
+        if (mSocketOS == null) throw new IOException("flush is called on null OutputStream");
         if (VDBG) Log.d(TAG, "flush: " + mSocketOS);
         mSocketOS.flush();
     }
 
     /*package*/ int read(byte[] b, int offset, int length) throws IOException {
-
-            if (VDBG) Log.d(TAG, "read in:  " + mSocketIS + " len: " + length);
-            int ret = mSocketIS.read(b, offset, length);
-            if(ret < 0)
-                throw new IOException("bt socket closed, read return: " + ret);
-            if (VDBG) Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret);
-            return ret;
+        if (mSocketIS == null) throw new IOException("read is called on null InputStream");
+        if (VDBG) Log.d(TAG, "read in:  " + mSocketIS + " len: " + length);
+        int ret = mSocketIS.read(b, offset, length);
+        if(ret < 0)
+            throw new IOException("bt socket closed, read return: " + ret);
+        if (VDBG) Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret);
+        return ret;
     }
 
     /*package*/ int write(byte[] b, int offset, int length) throws IOException {
-
-            if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
-            mSocketOS.write(b, offset, length);
-            // There is no good way to confirm since the entire process is asynchronous anyway
-            if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
-            return length;
+        if (mSocketOS == null) throw new IOException("write is called on null OutputStream");
+        if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
+        mSocketOS.write(b, offset, length);
+        // There is no good way to confirm since the entire process is asynchronous anyway
+        if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
+        return length;
     }
 
     @Override
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 9e8d7d1..42880af 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -501,31 +501,6 @@
     public void stopRepeating() throws CameraAccessException;
 
     /**
-     * <p>Wait until all the submitted requests have finished processing</p>
-     *
-     * <p>This method blocks until all the requests that have been submitted to
-     * the camera device, either through {@link #capture capture},
-     * {@link #captureBurst captureBurst},
-     * {@link #setRepeatingRequest setRepeatingRequest}, or
-     * {@link #setRepeatingBurst setRepeatingBurst}, have completed their
-     * processing.</p>
-     *
-     * <p>Once this call returns successfully, the device is in an idle state,
-     * and can be reconfigured with {@link #configureOutputs configureOutputs}.</p>
-     *
-     * <p>This method cannot be used if there is an active repeating request or
-     * burst, set with {@link #setRepeatingRequest setRepeatingRequest} or
-     * {@link #setRepeatingBurst setRepeatingBurst}. Call
-     * {@link #stopRepeating stopRepeating} before calling this method.</p>
-     *
-     * @throws CameraAccessException if the camera device is no longer connected
-     * @throws IllegalStateException if the camera device has been closed, the
-     * device has encountered a fatal error, or if there is an active repeating
-     * request or burst.
-     */
-    public void waitUntilIdle() throws CameraAccessException;
-
-    /**
      * Flush all captures currently pending and in-progress as fast as
      * possible.
      *
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 40586f0..2c8a5c2 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -106,9 +106,7 @@
 
     private final Runnable mCallOnClosed = new Runnable() {
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onClosed(CameraDevice.this);
-            }
+            mDeviceListener.onClosed(CameraDevice.this);
         }
     };
 
@@ -351,8 +349,7 @@
         }
     }
 
-    @Override
-    public void waitUntilIdle() throws CameraAccessException {
+    private void waitUntilIdle() throws CameraAccessException {
 
         synchronized (mLock) {
             checkIfCameraClosed();
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index aa43bad..32c9885 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -91,6 +91,8 @@
     private static final String TAG_1995 = "blink";
     private static final String TAG_REQUEST_FOCUS = "requestFocus";
 
+    private static final String ATTR_THEME = "theme";
+
     /**
      * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed
      * to be inflated.
@@ -677,23 +679,44 @@
             name = attrs.getAttributeValue(null, "class");
         }
 
+        // Apply a theme override, if necessary.
+        final Context viewContext;
+        final int themeResId = attrs.getAttributeResourceValue(null, ATTR_THEME, 0);
+        if (themeResId != 0) {
+            viewContext = new ContextThemeWrapper(mContext, themeResId);
+        } else if (parent != null) {
+            viewContext = parent.getContext();
+        } else {
+            viewContext = mContext;
+        }
+
         if (DEBUG) System.out.println("******** Creating view: " + name);
 
         try {
             View view;
-            if (mFactory2 != null) view = mFactory2.onCreateView(parent, name, mContext, attrs);
-            else if (mFactory != null) view = mFactory.onCreateView(name, mContext, attrs);
-            else view = null;
+            if (mFactory2 != null) {
+                view = mFactory2.onCreateView(parent, name, viewContext, attrs);
+            } else if (mFactory != null) {
+                view = mFactory.onCreateView(name, viewContext, attrs);
+            } else {
+                view = null;
+            }
 
             if (view == null && mPrivateFactory != null) {
-                view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);
+                view = mPrivateFactory.onCreateView(parent, name, viewContext, attrs);
             }
-            
+
             if (view == null) {
-                if (-1 == name.indexOf('.')) {
-                    view = onCreateView(parent, name, attrs);
-                } else {
-                    view = createView(name, null, attrs);
+                final Object lastContext = mConstructorArgs[0];
+                mConstructorArgs[0] = viewContext;
+                try {
+                    if (-1 == name.indexOf('.')) {
+                        view = onCreateView(parent, name, attrs);
+                    } else {
+                        view = createView(name, null, attrs);
+                    }
+                } finally {
+                    mConstructorArgs[0] = lastContext;
                 }
             }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 8ea35ff..11dbce8 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -315,7 +315,7 @@
 
                 mErrorPopup = null;
             }
-
+            mShowErrorAfterAttach = false;
         } else {
             setErrorIcon(icon);
             if (mTextView.isFocused()) {
diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd
index 3f02907..d2e65d4 100644
--- a/docs/html/google/gcm/gs.jd
+++ b/docs/html/google/gcm/gs.jd
@@ -36,7 +36,7 @@
 <h2 id="create-proj">Creating a Google API project</h2>
 <p>To create a Google API project:</p>
 <ol>
-  <li>Open the <a href="https://cloud.google.com/console">Google Cloud Console</a>.
+  <li>Open the <a href="https://cloud.google.com/console">Google Developers Console</a>.
   </li>
   <li>If you haven't created an API project yet, click <strong>Create Project</strong>.</li>
 
@@ -60,25 +60,27 @@
 <h2 id="access-key">Obtaining an API Key</h2>
 <p>To obtain an API  key:</p>
 <ol>
- <li>In the sidebar on the left, select <strong>APIs &amp; auth > Registered apps</strong>.</li>
-<li>Click <strong>Register app</strong>. </li>
+ <li>In the sidebar on the left, select <strong>APIs &amp; auth > Credentials</strong>.</li>
 
-<li>In the <strong>Name</strong> field, type your app's name.</li>
-<li>Click <strong>Android > Accessing APIs directly from Android</strong>.</li>
-<li>Under <strong>Android identification</strong>, type the package name for your app.</li>
-<li>Enter an SHA1 fingerprint. To get this value, follow the instructions in the
+ <li>Under <strong>Public API access</strong>, click <strong>Create new key</strong>.</li>
+
+<li>In the <strong>Create a new key</strong> dialog, click <strong>Android key</strong>.</li>
+
+<li>In the resulting configuration dialog, supply one SHA1 fingerprint and
+the package name for your app, separated by a semicolon. For example,
+{@code 45:B5:E4:6F:36:AD:0A:98:94:B4:02:66:2B:12:17:F2:56:26:A0:E0;com.myexample}.
+<p>To get the value for the SHA1 fingerprint, follow the instructions in the
 <a href="http://developers.google.com/console/help/new/#installedapplications">console
-help</a>.</li>
-<li>Click <strong>Register</strong>.</li>
+help</a>.</p></li>
+<li>Click <strong>Create</strong>.</li>
 
-<li>In the new page, open the <strong>Android Key</strong> section and copy the
+<li>In the refreshed page, copy the
 <a href="{@docRoot}google/gcm/gcm.html#apikey">API key</a>.
 You will need the API key later on to perform authentication in your application server.</li>
 
 <p class="note"><strong>Note:</strong> If you need to rotate the key, click
-the "recycle key" icon. A new key  will be created. If you think the key has been compromised
-and you want to delete it immediately, you can accomplish this by deleting the app from
-the console. Then create a new entry for the app with the same SHA1 and package name.</p>
+<strong>Regenerate key</strong>. A new key  will be created. If you think the key has been
+compromised and you want to delete it immediately, click <strong>Delete</strong>.</p>
 </ol>
 
 <h2 id="next">Next Steps</h2>
diff --git a/docs/html/google/play/billing/gp-purchase-status-api.jd b/docs/html/google/play/billing/gp-purchase-status-api.jd
index 8db7133..d272301 100644
--- a/docs/html/google/play/billing/gp-purchase-status-api.jd
+++ b/docs/html/google/play/billing/gp-purchase-status-api.jd
@@ -58,7 +58,7 @@
 
 <p>The Purchase Status API is part of the <a
 href="https://developers.google.com/android-publisher/v1_1/">Google Play Android
-Developer API v1.1</a>, available through the Google Cloud Console. The new version
+Developer API v1.1</a>, available through the Google Developers Console. The new version
 of the API supersedes the v1 API, which is deprecated. If you are using the v1
 API, please migrate your operations to the v1.1 API as soon as possible.</p>
 
@@ -66,7 +66,7 @@
 <h2 id="using">Using the API</h2>
 
 <p>To use the API, you must first register a project at the <a
-href="https://cloud.google.com/console">Google Cloud Console</a> and receive
+href="https://cloud.google.com/console">Google Developers Console</a> and receive
 a Client ID and shared secret that  your app will present when calling the
 API. All calls are authenticated with OAuth 2.0.</p>
 
@@ -95,7 +95,8 @@
 
 <p>If you need to request a higher limit for your application, see the
 instructions in the <a
-href="https://developers.google.com/console/help/new/#trafficcontrols">Google Cloud Console Help</a>.
+href="https://developers.google.com/console/help/new/#trafficcontrols">Google Developers
+Console Help</a>.
 Also, please read the section below on design best practices for minimizing your
 use of the API.</p>
 
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 923571e..1f5d26c 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -18,6 +18,7 @@
 
 #include <math.h>
 #include <utils/Log.h>
+#include <utils/Vector.h>
 
 #include "AmbientShadow.h"
 #include "Vertex.h"
@@ -60,10 +61,11 @@
     Vector2 centroid;
     calculatePolygonCentroid(vertices, vertexCount, centroid);
 
-    Vector2 dir[rays];
+    Vector<Vector2> dir; // TODO: use C++11 unique_ptr
+    dir.setCapacity(rays);
     float rayDist[rays];
     float rayHeight[rays];
-    calculateRayDirections(rays, dir);
+    calculateRayDirections(rays, dir.editArray());
 
     // Calculate the length and height of the points along the edge.
     //
@@ -105,7 +107,7 @@
         for (int i = 0; i < rays; i++) {
 
             Vector2 normal(1.0f, 0.0f);
-            calculateNormal(rays, i, dir, rayDist, normal);
+            calculateNormal(rays, i, dir.array(), rayDist, normal);
 
             float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor);
 
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 9d31232..4f0d15a 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -4,7 +4,7 @@
 # Only build libhwui when USE_OPENGL_RENDERER is
 # defined in the current device/board configuration
 ifeq ($(USE_OPENGL_RENDERER),true)
-	LOCAL_SRC_FILES:= \
+	LOCAL_SRC_FILES := \
 		utils/Blur.cpp \
 		utils/SortedListImpl.cpp \
 		thread/TaskManager.cpp \
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index eb8bb9f..fddfe90 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -74,12 +74,12 @@
 // Entries
 ///////////////////////////////////////////////////////////////////////////////
 
-AssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const {
+AssetAtlas::Entry* AssetAtlas::getEntry(const SkBitmap* bitmap) const {
     ssize_t index = mEntries.indexOfKey(bitmap);
     return index >= 0 ? mEntries.valueAt(index) : NULL;
 }
 
-Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const {
+Texture* AssetAtlas::getEntryTexture(const SkBitmap* bitmap) const {
     ssize_t index = mEntries.indexOfKey(bitmap);
     return index >= 0 ? mEntries.valueAt(index)->texture : NULL;
 }
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index a28efc6..57c8a60 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -160,13 +160,13 @@
      * Returns the entry in the atlas associated with the specified
      * bitmap. If the bitmap is not in the atlas, return NULL.
      */
-    Entry* getEntry(SkBitmap* const bitmap) const;
+    Entry* getEntry(const SkBitmap* bitmap) const;
 
     /**
      * Returns the texture for the atlas entry associated with the
      * specified bitmap. If the bitmap is not in the atlas, return NULL.
      */
-    Texture* getEntryTexture(SkBitmap* const bitmap) const;
+    Texture* getEntryTexture(const SkBitmap* bitmap) const;
 
     /**
      * Returns the current generation id of the atlas.
@@ -186,7 +186,7 @@
     const bool mBlendKey;
     const bool mOpaqueKey;
 
-    KeyedVector<SkBitmap*, Entry*> mEntries;
+    KeyedVector<const SkBitmap*, Entry*> mEntries;
 }; // class AssetAtlas
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index caed2b1..8da425d 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -90,7 +90,7 @@
     }
 
     for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
-        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
+        const SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
         caches.resourceCache.decrementRefcountLocked(bitmap);
         caches.resourceCache.destructorLocked(bitmap);
     }
@@ -173,16 +173,16 @@
     caches.registerFunctors(mFunctorCount);
     caches.resourceCache.lock();
 
-    const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
+    const Vector<const SkBitmap*>& bitmapResources = recorder.getBitmapResources();
     for (size_t i = 0; i < bitmapResources.size(); i++) {
-        SkBitmap* resource = bitmapResources.itemAt(i);
+        const SkBitmap* resource = bitmapResources.itemAt(i);
         mBitmapResources.add(resource);
         caches.resourceCache.incrementRefcountLocked(resource);
     }
 
-    const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
+    const Vector<const SkBitmap*>& ownedBitmapResources = recorder.getOwnedBitmapResources();
     for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
-        SkBitmap* resource = ownedBitmapResources.itemAt(i);
+        const SkBitmap* resource = ownedBitmapResources.itemAt(i);
         mOwnedBitmapResources.add(resource);
         caches.resourceCache.incrementRefcountLocked(resource);
     }
@@ -194,9 +194,9 @@
         caches.resourceCache.incrementRefcountLocked(resource);
     }
 
-    const Vector<Res_png_9patch*>& patchResources = recorder.getPatchResources();
+    const Vector<const Res_png_9patch*>& patchResources = recorder.getPatchResources();
     for (size_t i = 0; i < patchResources.size(); i++) {
-        Res_png_9patch* resource = patchResources.itemAt(i);
+        const Res_png_9patch* resource = patchResources.itemAt(i);
         mPatchResources.add(resource);
         caches.resourceCache.incrementRefcountLocked(resource);
     }
@@ -208,7 +208,7 @@
         caches.resourceCache.incrementRefcountLocked(resource);
     }
 
-    const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
+    const SortedVector<const SkPath*>& sourcePaths = recorder.getSourcePaths();
     for (size_t i = 0; i < sourcePaths.size(); i++) {
         mSourcePaths.add(sourcePaths.itemAt(i));
         caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
@@ -610,14 +610,14 @@
     handler(op, PROPERTY_SAVECOUNT, mClipToBounds);
     int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
 
-    for (int i = 0; i < m3dNodes.size(); i++) {
+    for (size_t i = 0; i < m3dNodes.size(); i++) {
         const float zValue = m3dNodes.keyAt(i);
 
         if (mode == kPositiveZChildren && zValue < 0.0f) continue;
         if (mode == kNegativeZChildren && zValue > 0.0f) break;
 
         const Vector<DrawDisplayListOp*>& nodesAtZ = m3dNodes[i];
-        for (int j = 0; j < nodesAtZ.size(); j++) {
+        for (size_t j = 0; j < nodesAtZ.size(); j++) {
             DrawDisplayListOp* op = nodesAtZ[j];
             if (mode == kPositiveZChildren) {
                 /* draw shadow on renderer with parent matrix applied, passing in the child's total matrix
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 9933d9d..3f9ad9b 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -549,16 +549,16 @@
         const char* mText;
     };
 
-    Vector<SkBitmap*> mBitmapResources;
-    Vector<SkBitmap*> mOwnedBitmapResources;
+    Vector<const SkBitmap*> mBitmapResources;
+    Vector<const SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
-    Vector<Res_png_9patch*> mPatchResources;
+    Vector<const Res_png_9patch*> mPatchResources;
 
-    Vector<SkPaint*> mPaints;
-    Vector<SkPath*> mPaths;
-    SortedVector<SkPath*> mSourcePaths;
-    Vector<SkRegion*> mRegions;
-    Vector<SkMatrix*> mMatrices;
+    Vector<const SkPaint*> mPaints;
+    Vector<const SkPath*> mPaths;
+    SortedVector<const SkPath*> mSourcePaths;
+    Vector<const SkRegion*> mRegions;
+    Vector<const SkMatrix*> mMatrices;
     Vector<SkiaShader*> mShaders;
     Vector<Layer*> mLayers;
 
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 1980b03..c375bfa 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -111,7 +111,7 @@
 class DrawOp : public DisplayListOp {
 friend class MergingDrawBatch;
 public:
-    DrawOp(SkPaint* paint)
+    DrawOp(const SkPaint* paint)
             : mPaint(paint), mQuickRejected(false) {}
 
     virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
@@ -191,7 +191,7 @@
     }
 
 protected:
-    SkPaint* getPaint(OpenGLRenderer& renderer) {
+    const SkPaint* getPaint(OpenGLRenderer& renderer) {
         return renderer.filterPaint(mPaint);
     }
 
@@ -212,22 +212,22 @@
 
     }
 
-    SkPaint* mPaint; // should be accessed via getPaint() when applying
+    const SkPaint* mPaint; // should be accessed via getPaint() when applying
     bool mQuickRejected;
 };
 
 class DrawBoundedOp : public DrawOp {
 public:
-    DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawBoundedOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
 
-    DrawBoundedOp(const Rect& localBounds, SkPaint* paint)
+    DrawBoundedOp(const Rect& localBounds, const SkPaint* paint)
             : DrawOp(paint), mLocalBounds(localBounds) {}
 
     // Calculates bounds as smallest rect encompassing all points
     // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in
     // subclass' constructor)
-    DrawBoundedOp(const float* points, int count, SkPaint* paint)
+    DrawBoundedOp(const float* points, int count, const SkPaint* paint)
             : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) {
         for (int i = 2; i < count; i += 2) {
             mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
@@ -238,7 +238,7 @@
     }
 
     // default empty constructor for bounds, to be overridden in child constructor body
-    DrawBoundedOp(SkPaint* paint): DrawOp(paint) { }
+    DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { }
 
     bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
         localBounds.set(mLocalBounds);
@@ -456,7 +456,7 @@
 
 class SetMatrixOp : public StateOp {
 public:
-    SetMatrixOp(SkMatrix* matrix)
+    SetMatrixOp(const SkMatrix* matrix)
             : mMatrix(matrix) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -474,12 +474,12 @@
     virtual const char* name() { return "SetMatrix"; }
 
 private:
-    SkMatrix* mMatrix;
+    const SkMatrix* mMatrix;
 };
 
 class ConcatMatrixOp : public StateOp {
 public:
-    ConcatMatrixOp(SkMatrix* matrix)
+    ConcatMatrixOp(const SkMatrix* matrix)
             : mMatrix(matrix) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -493,7 +493,7 @@
     virtual const char* name() { return "ConcatMatrix"; }
 
 private:
-    SkMatrix* mMatrix;
+    const SkMatrix* mMatrix;
 };
 
 class ClipOp : public StateOp {
@@ -551,7 +551,7 @@
 
 class ClipPathOp : public ClipOp {
 public:
-    ClipPathOp(SkPath* path, SkRegion::Op op)
+    ClipPathOp(const SkPath* path, SkRegion::Op op)
             : ClipOp(op), mPath(path) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -567,12 +567,12 @@
     virtual const char* name() { return "ClipPath"; }
 
 private:
-    SkPath* mPath;
+    const SkPath* mPath;
 };
 
 class ClipRegionOp : public ClipOp {
 public:
-    ClipRegionOp(SkRegion* region, SkRegion::Op op)
+    ClipRegionOp(const SkRegion* region, SkRegion::Op op)
             : ClipOp(op), mRegion(region) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -588,7 +588,7 @@
     virtual const char* name() { return "ClipRegion"; }
 
 private:
-    SkRegion* mRegion;
+    const SkRegion* mRegion;
 };
 
 class ResetShaderOp : public StateOp {
@@ -728,7 +728,7 @@
 
 class DrawBitmapOp : public DrawBoundedOp {
 public:
-    DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+    DrawBitmapOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
             : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
             mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) {
         mEntry = mAtlas.getEntry(bitmap);
@@ -827,7 +827,7 @@
 
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
-    SkBitmap* mBitmap;
+    const SkBitmap* mBitmap;
     const AssetAtlas& mAtlas;
     uint32_t mEntryGenerationId;
     AssetAtlas::Entry* mEntry;
@@ -836,7 +836,7 @@
 
 class DrawBitmapMatrixOp : public DrawBoundedOp {
 public:
-    DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint)
+    DrawBitmapMatrixOp(const SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint)
             : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
         mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
         const mat4 transform(*matrix);
@@ -859,14 +859,15 @@
     }
 
 private:
-    SkBitmap* mBitmap;
-    SkMatrix* mMatrix;
+    const SkBitmap* mBitmap;
+    const SkMatrix* mMatrix;
 };
 
 class DrawBitmapRectOp : public DrawBoundedOp {
 public:
-    DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
-            float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint)
+    DrawBitmapRectOp(const SkBitmap* bitmap,
+            float srcLeft, float srcTop, float srcRight, float srcBottom,
+            float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint)
             : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
             mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
 
@@ -889,13 +890,13 @@
     }
 
 private:
-    SkBitmap* mBitmap;
+    const SkBitmap* mBitmap;
     Rect mSrc;
 };
 
 class DrawBitmapDataOp : public DrawBitmapOp {
 public:
-    DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+    DrawBitmapDataOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
             : DrawBitmapOp(bitmap, left, top, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -917,8 +918,8 @@
 
 class DrawBitmapMeshOp : public DrawBoundedOp {
 public:
-    DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
-            float* vertices, int* colors, SkPaint* paint)
+    DrawBitmapMeshOp(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint)
             : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint),
             mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
             mVertices(vertices), mColors(colors) {}
@@ -940,17 +941,17 @@
     }
 
 private:
-    SkBitmap* mBitmap;
+    const SkBitmap* mBitmap;
     int mMeshWidth;
     int mMeshHeight;
-    float* mVertices;
-    int* mColors;
+    const float* mVertices;
+    const int* mColors;
 };
 
 class DrawPatchOp : public DrawBoundedOp {
 public:
-    DrawPatchOp(SkBitmap* bitmap, Res_png_9patch* patch,
-            float left, float top, float right, float bottom, SkPaint* paint)
+    DrawPatchOp(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint),
             mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
             mAtlas(Caches::getInstance().assetAtlas) {
@@ -1082,8 +1083,8 @@
     }
 
 private:
-    SkBitmap* mBitmap;
-    Res_png_9patch* mPatch;
+    const SkBitmap* mBitmap;
+    const Res_png_9patch* mPatch;
 
     uint32_t mGenerationId;
     const Patch* mMesh;
@@ -1115,7 +1116,7 @@
 
 class DrawStrokableOp : public DrawBoundedOp {
 public:
-    DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint) {};
 
     bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
@@ -1140,7 +1141,7 @@
 
 class DrawRectOp : public DrawStrokableOp {
 public:
-    DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1164,7 +1165,7 @@
 
 class DrawRectsOp : public DrawBoundedOp {
 public:
-    DrawRectsOp(const float* rects, int count, SkPaint* paint)
+    DrawRectsOp(const float* rects, int count, const SkPaint* paint)
             : DrawBoundedOp(rects, count, paint),
             mRects(rects), mCount(count) {}
 
@@ -1191,7 +1192,7 @@
 class DrawRoundRectOp : public DrawStrokableOp {
 public:
     DrawRoundRectOp(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint)
+            float rx, float ry, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1212,7 +1213,7 @@
 
 class DrawCircleOp : public DrawStrokableOp {
 public:
-    DrawCircleOp(float x, float y, float radius, SkPaint* paint)
+    DrawCircleOp(float x, float y, float radius, const SkPaint* paint)
             : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
             mX(x), mY(y), mRadius(radius) {}
 
@@ -1234,7 +1235,7 @@
 
 class DrawOvalOp : public DrawStrokableOp {
 public:
-    DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1252,7 +1253,7 @@
 class DrawArcOp : public DrawStrokableOp {
 public:
     DrawArcOp(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint)
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint),
             mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
 
@@ -1277,7 +1278,7 @@
 
 class DrawPathOp : public DrawBoundedOp {
 public:
-    DrawPathOp(SkPath* path, SkPaint* paint)
+    DrawPathOp(const SkPath* path, const SkPaint* paint)
             : DrawBoundedOp(paint), mPath(path) {
         float left, top, offset;
         uint32_t width, height;
@@ -1293,7 +1294,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
-        SkPaint* paint = getPaint(renderer);
+        const SkPaint* paint = getPaint(renderer);
         renderer.getCaches().pathCache.precache(mPath, paint);
 
         deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
@@ -1306,12 +1307,12 @@
     virtual const char* name() { return "DrawPath"; }
 
 private:
-    SkPath* mPath;
+    const SkPath* mPath;
 };
 
 class DrawLinesOp : public DrawBoundedOp {
 public:
-    DrawLinesOp(float* points, int count, SkPaint* paint)
+    DrawLinesOp(const float* points, int count, const SkPaint* paint)
             : DrawBoundedOp(points, count, paint),
             mPoints(points), mCount(count) {
         mLocalBounds.outset(strokeWidthOutset());
@@ -1335,13 +1336,13 @@
     }
 
 protected:
-    float* mPoints;
+    const float* mPoints;
     int mCount;
 };
 
 class DrawPointsOp : public DrawLinesOp {
 public:
-    DrawPointsOp(float* points, int count, SkPaint* paint)
+    DrawPointsOp(const float* points, int count, const SkPaint* paint)
             : DrawLinesOp(points, count, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1357,7 +1358,7 @@
 
 class DrawSomeTextOp : public DrawOp {
 public:
-    DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
+    DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint)
             : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
 
     virtual void output(int level, uint32_t logFlags) const {
@@ -1366,7 +1367,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
-        SkPaint* paint = getPaint(renderer);
+        const SkPaint* paint = getPaint(renderer);
         FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
         fontRenderer.precache(paint, mText, mCount, mat4::identity());
 
@@ -1384,7 +1385,7 @@
 class DrawTextOnPathOp : public DrawSomeTextOp {
 public:
     DrawTextOnPathOp(const char* text, int bytesCount, int count,
-            SkPath* path, float hOffset, float vOffset, SkPaint* paint)
+            const SkPath* path, float hOffset, float vOffset, const SkPaint* paint)
             : DrawSomeTextOp(text, bytesCount, count, paint),
             mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
         /* TODO: inherit from DrawBounded and init mLocalBounds */
@@ -1398,7 +1399,7 @@
     virtual const char* name() { return "DrawTextOnPath"; }
 
 private:
-    SkPath* mPath;
+    const SkPath* mPath;
     float mHOffset;
     float mVOffset;
 };
@@ -1406,7 +1407,7 @@
 class DrawPosTextOp : public DrawSomeTextOp {
 public:
     DrawPosTextOp(const char* text, int bytesCount, int count,
-            const float* positions, SkPaint* paint)
+            const float* positions, const SkPaint* paint)
             : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) {
         /* TODO: inherit from DrawBounded and init mLocalBounds */
     }
@@ -1424,7 +1425,7 @@
 class DrawTextOp : public DrawBoundedOp {
 public:
     DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds)
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds)
             : DrawBoundedOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
             mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) {
         memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float));
@@ -1432,7 +1433,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
-        SkPaint* paint = getPaint(renderer);
+        const SkPaint* paint = getPaint(renderer);
         FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
         const mat4& transform = renderer.findBestFontTransform(state.mMatrix);
         if (mPrecacheTransform != transform) {
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 9c5db6e..051ccfe 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -203,13 +203,13 @@
     StatefulBaseRenderer::skew(sx, sy);
 }
 
-void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
+void DisplayListRenderer::setMatrix(const SkMatrix* matrix) {
     matrix = refMatrix(matrix);
     addStateOp(new (alloc()) SetMatrixOp(matrix));
     StatefulBaseRenderer::setMatrix(matrix);
 }
 
-void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
+void DisplayListRenderer::concatMatrix(const SkMatrix* matrix) {
     matrix = refMatrix(matrix);
     addStateOp(new (alloc()) ConcatMatrixOp(matrix));
     StatefulBaseRenderer::concatMatrix(matrix);
@@ -218,19 +218,19 @@
 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
         SkRegion::Op op) {
     addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
-    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
+    return StatefulBaseRenderer::clipRect(left, top, right, bottom, op);
 }
 
-bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
+bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
     path = refPath(path);
     addStateOp(new (alloc()) ClipPathOp(path, op));
-    return OpenGLRenderer::clipPath(path, op);
+    return StatefulBaseRenderer::clipPath(path, op);
 }
 
-bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
+bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
     region = refRegion(region);
     addStateOp(new (alloc()) ClipRegionOp(region, op));
-    return OpenGLRenderer::clipRegion(region, op);
+    return StatefulBaseRenderer::clipRegion(region, op);
 }
 
 status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
@@ -242,7 +242,8 @@
     //       resources cache, but we rely on the caller (UI toolkit) to
     //       do the right thing for now
 
-    DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList, flags, currentTransform());
+    DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList,
+            flags, *currentTransform());
     addDrawOp(op);
     mDisplayListData->children.push(op);
 
@@ -255,7 +256,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
@@ -263,7 +265,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+        const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     matrix = refMatrix(matrix);
     paint = refPaint(paint);
@@ -272,9 +275,9 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
-        float dstRight, float dstBottom, SkPaint* paint) {
+        float dstRight, float dstBottom, const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
@@ -293,8 +296,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
-        SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     bitmap = refBitmapData(bitmap);
     paint = refPaint(paint);
 
@@ -302,8 +305,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-        float* vertices, int* colors, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+        const float* vertices, const int* colors, const SkPaint* paint) {
     int count = (meshWidth + 1) * (meshHeight + 1) * 2;
     bitmap = refBitmap(bitmap);
     vertices = refBuffer<float>(vertices, count);
@@ -315,8 +318,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-        float left, float top, float right, float bottom, SkPaint* paint) {
+status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+        float left, float top, float right, float bottom, const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     patch = refPatch(patch);
     paint = refPaint(paint);
@@ -331,41 +334,41 @@
 }
 
 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
-        float rx, float ry, SkPaint* paint) {
+        float rx, float ry, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
                     startAngle, sweepAngle, useCenter, paint));
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
+status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
     path = refPath(path);
     paint = refPaint(paint);
 
@@ -373,7 +376,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
     points = refBuffer<float>(points, count);
     paint = refPaint(paint);
 
@@ -381,7 +384,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
     points = refBuffer<float>(points, count);
     paint = refPaint(paint);
 
@@ -390,7 +393,7 @@
 }
 
 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
-        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
+        const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
 
     text = refText(text, bytesCount);
@@ -404,7 +407,7 @@
 }
 
 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
-        const float* positions, SkPaint* paint) {
+        const float* positions, const SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
 
     text = refText(text, bytesCount);
@@ -417,7 +420,7 @@
 }
 
 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
-        float x, float y, const float* positions, SkPaint* paint,
+        float x, float y, const float* positions, const SkPaint* paint,
         float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
 
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
@@ -432,7 +435,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
     if (count <= 0) return DrawGlInfo::kStatusDone;
 
     rects = refBuffer<float>(rects, count);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index b5d9924..f129c10 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -54,7 +54,7 @@
 class StateOp;
 
 /**
- * Records drawing commands in a display list for latter playback.
+ * Records drawing commands in a display list for later playback into an OpenGLRenderer.
  */
 class DisplayListRenderer: public OpenGLRenderer {
 public:
@@ -63,7 +63,7 @@
 
     ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
 
-    virtual bool isRecording() { return true; }
+    virtual bool isRecording() const { return true; }
 
 // ----------------------------------------------------------------------------
 // Frame state operations
@@ -90,13 +90,13 @@
     virtual void scale(float sx, float sy);
     virtual void skew(float sx, float sy);
 
-    virtual void setMatrix(SkMatrix* matrix);
-    virtual void concatMatrix(SkMatrix* matrix);
+    virtual void setMatrix(const SkMatrix* matrix);
+    virtual void concatMatrix(const SkMatrix* matrix);
 
     // Clip
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
-    virtual bool clipPath(SkPath* path, SkRegion::Op op);
-    virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
+    virtual bool clipPath(const SkPath* path, SkRegion::Op op);
+    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
 
     // Misc - should be implemented with SkPaint inspection
     virtual void resetShader();
@@ -117,38 +117,43 @@
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
 
     // Bitmap-based
-    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
-    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
-            float dstRight, float dstBottom, SkPaint* paint);
-    virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-            float* vertices, int* colors, SkPaint* paint);
-    virtual status_t drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-            float left, float top, float right, float bottom, SkPaint* paint);
+            float dstRight, float dstBottom, const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint);
+    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint);
 
     // Shapes
-    virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
-    virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
+    virtual status_t drawRect(float left, float top, float right, float bottom,
+            const SkPaint* paint);
+    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint);
-    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
-    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+            float rx, float ry, const SkPaint* paint);
+    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
+    virtual status_t drawOval(float left, float top, float right, float bottom,
+            const SkPaint* paint);
     virtual status_t drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
-    virtual status_t drawPath(SkPath* path, SkPaint* paint);
-    virtual status_t drawLines(float* points, int count, SkPaint* paint);
-    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
+    virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
+    virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
+    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
 
     // Text
     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
             DrawOpMode drawOpMode = kDrawOpMode_Immediate);
-    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-            float hOffset, float vOffset, SkPaint* paint);
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+            float hOffset, float vOffset, const SkPaint* paint);
     virtual status_t drawPosText(const char* text, int bytesCount, int count,
-            const float* positions, SkPaint* paint);
+            const float* positions, const SkPaint* paint);
 
 // ----------------------------------------------------------------------------
 // Canvas draw operations - special
@@ -169,11 +174,11 @@
         return mDisplayListData;
     }
 
-    const Vector<SkBitmap*>& getBitmapResources() const {
+    const Vector<const SkBitmap*>& getBitmapResources() const {
         return mBitmapResources;
     }
 
-    const Vector<SkBitmap*>& getOwnedBitmapResources() const {
+    const Vector<const SkBitmap*>& getOwnedBitmapResources() const {
         return mOwnedBitmapResources;
     }
 
@@ -181,7 +186,7 @@
         return mFilterResources;
     }
 
-    const Vector<Res_png_9patch*>& getPatchResources() const {
+    const Vector<const Res_png_9patch*>& getPatchResources() const {
         return mPatchResources;
     }
 
@@ -189,19 +194,19 @@
         return mShaders;
     }
 
-    const Vector<SkPaint*>& getPaints() const {
+    const Vector<const SkPaint*>& getPaints() const {
         return mPaints;
     }
 
-    const Vector<SkPath*>& getPaths() const {
+    const Vector<const SkPath*>& getPaths() const {
         return mPaths;
     }
 
-    const SortedVector<SkPath*>& getSourcePaths() const {
+    const SortedVector<const SkPath*>& getSourcePaths() const {
         return mSourcePaths;
     }
 
-    const Vector<SkRegion*>& getRegions() const {
+    const Vector<const SkRegion*>& getRegions() const {
         return mRegions;
     }
 
@@ -209,7 +214,7 @@
         return mLayers;
     }
 
-    const Vector<SkMatrix*>& getMatrices() const {
+    const Vector<const SkMatrix*>& getMatrices() const {
         return mMatrices;
     }
 
@@ -231,8 +236,9 @@
     }
 
     template<class T>
-    inline T* refBuffer(const T* srcBuffer, int32_t count) {
-        if (srcBuffer == NULL) return NULL;
+    inline const T* refBuffer(const T* srcBuffer, int32_t count) {
+        if (!srcBuffer) return NULL;
+
         T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
         memcpy(dstBuffer, srcBuffer, count * sizeof(T));
         return dstBuffer;
@@ -242,13 +248,15 @@
         return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
     }
 
-    inline SkPath* refPath(SkPath* path) {
+    inline const SkPath* refPath(const SkPath* path) {
         if (!path) return NULL;
 
-        SkPath* pathCopy = mPathMap.valueFor(path);
+        const SkPath* pathCopy = mPathMap.valueFor(path);
         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
-            pathCopy = new SkPath(*path);
-            pathCopy->setSourcePath(path);
+            SkPath* newPathCopy = new SkPath(*path);
+            newPathCopy->setSourcePath(path);
+
+            pathCopy = newPathCopy;
             // replaceValueFor() performs an add if the entry doesn't exist
             mPathMap.replaceValueFor(path, pathCopy);
             mPaths.add(pathCopy);
@@ -260,12 +268,12 @@
         return pathCopy;
     }
 
-    inline SkPaint* refPaint(SkPaint* paint) {
+    inline const SkPaint* refPaint(const SkPaint* paint) {
         if (!paint) {
             return paint;
         }
 
-        SkPaint* paintCopy = mPaintMap.valueFor(paint);
+        const SkPaint* paintCopy = mPaintMap.valueFor(paint);
         if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
             paintCopy = new SkPaint(*paint);
             // replaceValueFor() performs an add if the entry doesn't exist
@@ -276,12 +284,12 @@
         return paintCopy;
     }
 
-    inline SkRegion* refRegion(SkRegion* region) {
+    inline const SkRegion* refRegion(const SkRegion* region) {
         if (!region) {
             return region;
         }
 
-        SkRegion* regionCopy = mRegionMap.valueFor(region);
+        const SkRegion* regionCopy = mRegionMap.valueFor(region);
         // TODO: Add generation ID to SkRegion
         if (regionCopy == NULL) {
             regionCopy = new SkRegion(*region);
@@ -293,11 +301,11 @@
         return regionCopy;
     }
 
-    inline SkMatrix* refMatrix(SkMatrix* matrix) {
+    inline const SkMatrix* refMatrix(const SkMatrix* matrix) {
         if (matrix) {
             // Copying the matrix is cheap and prevents against the user changing
             // the original matrix before the operation that uses it
-            SkMatrix* copy = new SkMatrix(*matrix);
+            const SkMatrix* copy = new SkMatrix(*matrix);
             mMatrices.add(copy);
             return copy;
         }
@@ -310,7 +318,7 @@
         return layer;
     }
 
-    inline SkBitmap* refBitmap(SkBitmap* bitmap) {
+    inline const SkBitmap* refBitmap(const 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
         // contents, and drawing again. The only fix would be to always copy it the first time,
@@ -320,7 +328,7 @@
         return bitmap;
     }
 
-    inline SkBitmap* refBitmapData(SkBitmap* bitmap) {
+    inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
         mOwnedBitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
         return bitmap;
@@ -347,33 +355,33 @@
         return colorFilter;
     }
 
-    inline Res_png_9patch* refPatch(Res_png_9patch* patch) {
+    inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
         mPatchResources.add(patch);
         mCaches.resourceCache.incrementRefcount(patch);
         return patch;
     }
 
     // TODO: move these to DisplayListData
-    Vector<SkBitmap*> mBitmapResources;
-    Vector<SkBitmap*> mOwnedBitmapResources;
+    Vector<const SkBitmap*> mBitmapResources;
+    Vector<const SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
-    Vector<Res_png_9patch*> mPatchResources;
+    Vector<const Res_png_9patch*> mPatchResources;
 
-    Vector<SkPaint*> mPaints;
-    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
+    Vector<const SkPaint*> mPaints;
+    DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap;
 
-    Vector<SkPath*> mPaths;
-    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
+    Vector<const SkPath*> mPaths;
+    DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
 
-    SortedVector<SkPath*> mSourcePaths;
+    SortedVector<const SkPath*> mSourcePaths;
 
-    Vector<SkRegion*> mRegions;
-    DefaultKeyedVector<SkRegion*, SkRegion*> mRegionMap;
+    Vector<const SkRegion*> mRegions;
+    DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
 
     Vector<SkiaShader*> mShaders;
     DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
 
-    Vector<SkMatrix*> mMatrices;
+    Vector<const SkMatrix*> mMatrices;
 
     Vector<Layer*> mLayers;
 
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index f7493a3..f907d64 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -587,11 +587,11 @@
     }
 }
 
-void FontRenderer::setFont(SkPaint* paint, const mat4& matrix) {
+void FontRenderer::setFont(const SkPaint* paint, const mat4& matrix) {
     mCurrentFont = Font::create(this, paint, matrix);
 }
 
-FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
+FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text,
         uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions) {
     checkInit();
 
@@ -676,7 +676,8 @@
     issueDrawCommand();
 }
 
-void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix) {
+void FontRenderer::precache(const SkPaint* paint, const char* text, int numGlyphs,
+        const mat4& matrix) {
     Font* font = Font::create(this, paint, matrix);
     font->precache(paint, text, numGlyphs);
 }
@@ -685,7 +686,7 @@
     checkTextureUpdate();
 }
 
-bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
+bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
         uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
         const float* positions, Rect* bounds, Functor* functor, bool forceFinish) {
     if (!mCurrentFont) {
@@ -703,8 +704,8 @@
     return mDrawn;
 }
 
-bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text,
-        uint32_t startIndex, uint32_t len, int numGlyphs, SkPath* path,
+bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
+        uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path,
         float hOffset, float vOffset, Rect* bounds, Functor* functor) {
     if (!mCurrentFont) {
         ALOGE("No font set");
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index db4e020..9259028 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -62,7 +62,7 @@
     };
 
     TextSetupFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate,
-            int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
+            int alpha, SkXfermode::Mode mode, const SkPaint* paint): Functor(),
             renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
             alpha(alpha), mode(mode), paint(paint) {
     }
@@ -76,7 +76,7 @@
     bool pureTranslate;
     int alpha;
     SkXfermode::Mode mode;
-    SkPaint* paint;
+    const SkPaint* paint;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -95,20 +95,20 @@
         mGammaTable = gammaTable;
     }
 
-    void setFont(SkPaint* paint, const mat4& matrix);
+    void setFont(const SkPaint* paint, const mat4& matrix);
 
-    void precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
+    void precache(const SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
     void endPrecaching();
 
     // bounds is an out parameter
-    bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
-            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds,
-            Functor* functor, bool forceFinish = true);
+    bool renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
+            uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, const float* positions,
+            Rect* bounds, Functor* functor, bool forceFinish = true);
 
     // bounds is an out parameter
-    bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
-            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds,
-            Functor* functor);
+    bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
+            uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path,
+            float hOffset, float vOffset, Rect* bounds, Functor* functor);
 
     struct DropShadow {
         DropShadow() { };
@@ -128,7 +128,7 @@
 
     // After renderDropShadow returns, the called owns the memory in DropShadow.image
     // and is responsible for releasing it when it's done with it
-    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
+    DropShadow renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex,
             uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
 
     void setTextureFiltering(bool linearFiltering) {
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index b70042f..471a4a6 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -49,7 +49,8 @@
 /**
  * A layer has dimensions and is backed by an OpenGL texture or FBO.
  */
-struct Layer {
+class Layer {
+public:
     Layer(const uint32_t layerWidth, const uint32_t layerHeight);
     ~Layer();
 
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 35fd46e..0b38c4d 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -117,7 +117,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Region* LayerRenderer::getRegion() const {
-    if (getSnapshot()->flags & Snapshot::kFlagFboTarget) {
+    if (currentSnapshot()->flags & Snapshot::kFlagFboTarget) {
         return OpenGLRenderer::getRegion();
     }
     return &mLayer->region;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index a3a4432..22cd2d4 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -208,7 +208,7 @@
     // invoked during the frame
     mSuppressTiling = mCaches.hasRegisteredFunctors();
 
-    startTiling(*mSnapshot, true);
+    startTilingCurrentClip(true);
 
     debugOverdraw(true, true);
 
@@ -225,7 +225,7 @@
     // The framebuffer renderer will first defer the display list
     // for each layer and wait until the first drawing command
     // to start the frame
-    if (currentSnapshot().fbo == 0) {
+    if (currentSnapshot()->fbo == 0) {
         syncState();
         updateLayers();
     } else {
@@ -252,7 +252,7 @@
 status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
     if (!opaque || mCountOverdraw) {
         mCaches.enableScissor();
-        mCaches.setScissor(left, currentSnapshot().height - bottom, right - left, bottom - top);
+        mCaches.setScissor(left, currentSnapshot()->height - bottom, right - left, bottom - top);
         glClear(GL_COLOR_BUFFER_BIT);
         return DrawGlInfo::kStatusDrew;
     }
@@ -269,14 +269,16 @@
     }
 }
 
-void OpenGLRenderer::startTiling(const Snapshot& s, bool opaque) {
+void OpenGLRenderer::startTilingCurrentClip(bool opaque) {
     if (!mSuppressTiling) {
+        const Snapshot* snapshot = currentSnapshot();
+
         const Rect* clip = &mTilingClip;
-        if (s.flags & Snapshot::kFlagFboTarget) {
-            clip = &(s.layer->clipRect);
+        if (snapshot->flags & Snapshot::kFlagFboTarget) {
+            clip = &(snapshot->layer->clipRect);
         }
 
-        startTiling(*clip, s.height, opaque);
+        startTiling(*clip, snapshot->height, opaque);
     }
 }
 
@@ -355,9 +357,9 @@
 }
 
 void OpenGLRenderer::resume() {
-    const Snapshot& snapshot = currentSnapshot();
-    glViewport(0, 0, snapshot.viewport.getWidth(), snapshot.viewport.getHeight());
-    glBindFramebuffer(GL_FRAMEBUFFER, snapshot.fbo);
+    const Snapshot* snapshot = currentSnapshot();
+    glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
+    glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
     debugOverdraw(true, false);
 
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -377,9 +379,9 @@
 }
 
 void OpenGLRenderer::resumeAfterLayer() {
-    const Snapshot& snapshot = currentSnapshot();
-    glViewport(0, 0, snapshot.viewport.getWidth(), snapshot.viewport.getHeight());
-    glBindFramebuffer(GL_FRAMEBUFFER, snapshot.fbo);
+    const Snapshot* snapshot = currentSnapshot();
+    glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
+    glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
     debugOverdraw(true, false);
 
     mCaches.resetScissor();
@@ -433,16 +435,16 @@
 }
 
 status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
-    if (currentSnapshot().isIgnored()) return DrawGlInfo::kStatusDone;
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
     detachFunctor(functor);
 
 
-    Rect clip(currentClipRect());
+    Rect clip(*currentClipRect());
     clip.snapToPixelBoundaries();
 
     // Since we don't know what the functor will draw, let's dirty
-    // tne entire clip region
+    // the entire clip region
     if (hasLayer()) {
         dirtyLayerUnchecked(clip, getRegion());
     }
@@ -453,9 +455,9 @@
     info.clipRight = clip.right;
     info.clipBottom = clip.bottom;
     info.isLayer = hasLayer();
-    info.width = getSnapshot()->viewport.getWidth();
-    info.height = getSnapshot()->height;
-    getSnapshot()->transform->copyTo(&info.transform[0]);
+    info.width = currentSnapshot()->viewport.getWidth();
+    info.height = currentSnapshot()->height;
+    currentTransform()->copyTo(&info.transform[0]);
 
     bool dirtyClip = mDirtyClip;
     // setup GL state for functor
@@ -518,7 +520,7 @@
         const Rect* clip = &mTilingClip;
 
         mCaches.enableScissor();
-        mCaches.setScissor(clip->left, mFirstSnapshot->height - clip->bottom,
+        mCaches.setScissor(clip->left, firstSnapshot()->height - clip->bottom,
                 clip->right - clip->left, clip->bottom - clip->top);
 
         // 1x overdraw
@@ -580,7 +582,7 @@
 
         if (inFrame) {
             resumeAfterLayer();
-            startTiling(*mSnapshot);
+            startTilingCurrentClip();
         }
 
         layer->debugDrawUpdate = mCaches.debugLayersUpdates;
@@ -709,7 +711,7 @@
     if (restoreOrtho) {
         const Rect& r = restored.viewport;
         glViewport(r.left, r.top, r.right, r.bottom);
-        mViewProjMatrix.load(removed.orthoMatrix); // todo: should ortho be stored in 'restored'?
+        mViewProjMatrix.load(removed.orthoMatrix); // TODO: should ortho be stored in 'restored'?
     }
 
     if (restoreClip) {
@@ -732,7 +734,7 @@
         int alpha, SkXfermode::Mode mode, int flags) {
     const int count = saveSnapshot(flags);
 
-    if (!currentSnapshot().isIgnored()) {
+    if (!currentSnapshot()->isIgnored()) {
         createLayer(left, top, right, bottom, alpha, mode, flags);
     }
 
@@ -742,22 +744,22 @@
 void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer) {
     const Rect untransformedBounds(bounds);
 
-    currentTransform().mapRect(bounds);
+    currentTransform()->mapRect(bounds);
 
     // Layers only make sense if they are in the framebuffer's bounds
-    if (bounds.intersect(currentClipRect())) {
+    if (bounds.intersect(*currentClipRect())) {
         // We cannot work with sub-pixels in this case
         bounds.snapToPixelBoundaries();
 
         // When the layer is not an FBO, we may use glCopyTexImage so we
         // need to make sure the layer does not extend outside the bounds
         // of the framebuffer
-        if (!bounds.intersect(currentSnapshot().previous->viewport)) {
+        if (!bounds.intersect(currentSnapshot()->previous->viewport)) {
             bounds.setEmpty();
         } else if (fboLayer) {
             clip.set(bounds);
             mat4 inverse;
-            inverse.loadInverse(currentTransform());
+            inverse.loadInverse(*currentTransform());
             inverse.mapRect(clip);
             clip.snapToPixelBoundaries();
             if (clip.intersect(untransformedBounds)) {
@@ -787,7 +789,7 @@
         int alpha, SkXfermode::Mode mode, int flags) {
     const int count = saveSnapshot(flags);
 
-    if (!currentSnapshot().isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
+    if (!currentSnapshot()->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
         // initialize the snapshot as though it almost represents an FBO layer so deferred draw
         // operations will be able to store and restore the current clip and transform info, and
         // quick rejection will be correct (for display lists)
@@ -797,7 +799,7 @@
         calculateLayerBoundsAndClip(bounds, clip, true);
         updateSnapshotIgnoreForLayer(bounds, clip, true, alpha);
 
-        if (!currentSnapshot().isIgnored()) {
+        if (!currentSnapshot()->isIgnored()) {
             mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
             mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
             mSnapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
@@ -873,7 +875,7 @@
     updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, alpha);
 
     // Bail out if we won't draw in this snapshot
-    if (currentSnapshot().isIgnored()) {
+    if (currentSnapshot()->isIgnored()) {
         return false;
     }
 
@@ -952,7 +954,7 @@
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
             layer->getTexture(), 0);
 
-    startTiling(*mSnapshot, true);
+    startTilingCurrentClip(true);
 
     // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
     mCaches.enableScissor();
@@ -1001,7 +1003,7 @@
         glBindFramebuffer(GL_FRAMEBUFFER, restored.fbo);
         debugOverdraw(true, false);
 
-        startTiling(restored);
+        startTilingCurrentClip();
     }
 
     if (!fboLayer && layer->getAlpha() < 255) {
@@ -1067,11 +1069,11 @@
     } else {
         setupDrawExternalTexture(layer->getTexture());
     }
-    if (currentTransform().isPureTranslate() &&
+    if (currentTransform()->isPureTranslate() &&
             layer->getWidth() == (uint32_t) rect.getWidth() &&
             layer->getHeight() == (uint32_t) rect.getHeight()) {
-        const float x = (int) floorf(rect.left + currentTransform().getTranslateX() + 0.5f);
-        const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
+        const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+        const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
 
         layer->setFilter(GL_NEAREST);
         setupDrawModelView(kModelViewMode_TranslateAndScale, false,
@@ -1095,15 +1097,15 @@
 
         float x = rect.left;
         float y = rect.top;
-        bool simpleTransform = currentTransform().isPureTranslate() &&
+        bool simpleTransform = currentTransform()->isPureTranslate() &&
                 layer->getWidth() == (uint32_t) rect.getWidth() &&
                 layer->getHeight() == (uint32_t) rect.getHeight();
 
         if (simpleTransform) {
             // When we're swapping, the layer is already in screen coordinates
             if (!swap) {
-                x = (int) floorf(rect.left + currentTransform().getTranslateX() + 0.5f);
-                y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
+                x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+                y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
             }
 
             layer->setFilter(GL_NEAREST, true);
@@ -1186,9 +1188,9 @@
         setupDrawPureColorUniforms();
         setupDrawColorFilterUniforms();
         setupDrawTexture(layer->getTexture());
-        if (currentTransform().isPureTranslate()) {
-            const float x = (int) floorf(rect.left + currentTransform().getTranslateX() + 0.5f);
-            const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
+        if (currentTransform()->isPureTranslate()) {
+            const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+            const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
 
             layer->setFilter(GL_NEAREST);
             setupDrawModelView(kModelViewMode_Translate, false,
@@ -1298,7 +1300,7 @@
 }
 
 void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
-    if (bounds.intersect(currentClipRect())) {
+    if (bounds.intersect(*currentClipRect())) {
         bounds.snapToPixelBoundaries();
         android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
         if (!dirty.isEmpty()) {
@@ -1326,7 +1328,7 @@
     const size_t count = mLayers.size();
     if (count == 0) return;
 
-    if (!currentSnapshot().isIgnored()) {
+    if (!currentSnapshot()->isIgnored()) {
         // Doing several glScissor/glClear here can negatively impact
         // GPUs with a tiler architecture, instead we draw quads with
         // the Clear blending mode
@@ -1378,51 +1380,51 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) {
-    const Rect& currentClip = currentClipRect();
-    const mat4& currentMatrix = currentTransform();
+    const Rect* currentClip = currentClipRect();
+    const mat4* currentMatrix = currentTransform();
 
     if (stateDeferFlags & kStateDeferFlag_Draw) {
         // state has bounds initialized in local coordinates
         if (!state.mBounds.isEmpty()) {
-            currentMatrix.mapRect(state.mBounds);
+            currentMatrix->mapRect(state.mBounds);
             Rect clippedBounds(state.mBounds);
             // NOTE: if we ever want to use this clipping info to drive whether the scissor
             // is used, it should more closely duplicate the quickReject logic (in how it uses
             // snapToPixelBoundaries)
 
-            if(!clippedBounds.intersect(currentClip)) {
+            if(!clippedBounds.intersect(*currentClip)) {
                 // quick rejected
                 return true;
             }
 
             state.mClipSideFlags = kClipSide_None;
-            if (!currentClip.contains(state.mBounds)) {
+            if (!currentClip->contains(state.mBounds)) {
                 int& flags = state.mClipSideFlags;
                 // op partially clipped, so record which sides are clipped for clip-aware merging
-                if (currentClip.left > state.mBounds.left) flags |= kClipSide_Left;
-                if (currentClip.top > state.mBounds.top) flags |= kClipSide_Top;
-                if (currentClip.right < state.mBounds.right) flags |= kClipSide_Right;
-                if (currentClip.bottom < state.mBounds.bottom) flags |= kClipSide_Bottom;
+                if (currentClip->left > state.mBounds.left) flags |= kClipSide_Left;
+                if (currentClip->top > state.mBounds.top) flags |= kClipSide_Top;
+                if (currentClip->right < state.mBounds.right) flags |= kClipSide_Right;
+                if (currentClip->bottom < state.mBounds.bottom) flags |= kClipSide_Bottom;
             }
             state.mBounds.set(clippedBounds);
         } else {
             // Empty bounds implies size unknown. Label op as conservatively clipped to disable
             // overdraw avoidance (since we don't know what it overlaps)
             state.mClipSideFlags = kClipSide_ConservativeFull;
-            state.mBounds.set(currentClip);
+            state.mBounds.set(*currentClip);
         }
     }
 
     state.mClipValid = (stateDeferFlags & kStateDeferFlag_Clip);
     if (state.mClipValid) {
-        state.mClip.set(currentClip);
+        state.mClip.set(*currentClip);
     }
 
     // Transform, drawModifiers, and alpha always deferred, since they are used by state operations
     // (Note: saveLayer/restore use colorFilter and alpha, so we just save restore everything)
-    state.mMatrix.load(currentMatrix);
+    state.mMatrix.load(*currentMatrix);
     state.mDrawModifiers = mDrawModifiers;
-    state.mAlpha = currentSnapshot().alpha;
+    state.mAlpha = currentSnapshot()->alpha;
     return false;
 }
 
@@ -1460,10 +1462,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setScissorFromClip() {
-    Rect clip(currentClipRect());
+    Rect clip(*currentClipRect());
     clip.snapToPixelBoundaries();
 
-    if (mCaches.setScissor(clip.left, currentSnapshot().height - clip.bottom,
+    if (mCaches.setScissor(clip.left, currentSnapshot()->height - clip.bottom,
             clip.getWidth(), clip.getHeight())) {
         mDirtyClip = false;
     }
@@ -1474,7 +1476,7 @@
     // cannot attach a stencil buffer to fbo0 dynamically. Let's
     // just hope we have one when hasLayer() returns false.
     if (hasLayer()) {
-        attachStencilBufferToLayer(currentSnapshot().layer);
+        attachStencilBufferToLayer(currentSnapshot()->layer);
     }
 }
 
@@ -1496,7 +1498,7 @@
 
 void OpenGLRenderer::setStencilFromClip() {
     if (!mCaches.debugOverdraw) {
-        if (!currentSnapshot().clipRegion->isEmpty()) {
+        if (!currentSnapshot()->clipRegion->isEmpty()) {
             // NOTE: The order here is important, we must set dirtyClip to false
             //       before any draw call to avoid calling back into this method
             mDirtyClip = false;
@@ -1521,7 +1523,7 @@
 
             // The last parameter is important: we are not drawing in the color buffer
             // so we don't want to dirty the current layer, if any
-            drawRegionRects(*(currentSnapshot().clipRegion),
+            drawRegionRects(*(currentSnapshot()->clipRegion),
                     0xff000000, SkXfermode::kSrc_Mode, false);
 
             mCaches.stencil.enableTest();
@@ -1529,7 +1531,7 @@
             // Draw the region used to generate the stencil if the appropriate debug
             // mode is enabled
             if (mCaches.debugStencilClip == Caches::kStencilShowRegion) {
-                drawRegionRects(*(currentSnapshot().clipRegion),
+                drawRegionRects(*(currentSnapshot()->clipRegion),
                         0x7f0000ff, SkXfermode::kSrcOver_Mode);
             }
         } else {
@@ -1545,7 +1547,7 @@
  *         style, and tessellated AA ramp
  */
 bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, float bottom,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     bool clipRequired = false;
     bool snapOut = paint && paint->isAntiAlias();
 
@@ -1570,64 +1572,12 @@
 
 void OpenGLRenderer::debugClip() {
 #if DEBUG_CLIP_REGIONS
-    if (!isRecording() && !currentSnapshot().clipRegion->isEmpty()) {
-        drawRegionRects(*(currentSnapshot().clipRegion), 0x7f00ff00, SkXfermode::kSrcOver_Mode);
+    if (!isRecording() && !currentSnapshot()->clipRegion->isEmpty()) {
+        drawRegionRects(*(currentSnapshot()->clipRegion), 0x7f00ff00, SkXfermode::kSrcOver_Mode);
     }
 #endif
 }
 
-bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
-    if (CC_LIKELY(currentTransform().rectToRect())) {
-        bool clipped = mSnapshot->clip(left, top, right, bottom, op);
-        if (clipped) {
-            dirtyClip();
-        }
-        return !mSnapshot->clipRect->isEmpty();
-    }
-
-    SkPath path;
-    path.addRect(left, top, right, bottom);
-
-    return OpenGLRenderer::clipPath(&path, op);
-}
-
-bool OpenGLRenderer::clipPath(SkPath* path, SkRegion::Op op) {
-    SkMatrix transform;
-    currentTransform().copyTo(transform);
-
-    SkPath transformed;
-    path->transform(transform, &transformed);
-
-    SkRegion clip;
-    if (!mSnapshot->previous->clipRegion->isEmpty()) {
-        clip.setRegion(*mSnapshot->previous->clipRegion);
-    } else {
-        if (mSnapshot->previous == mFirstSnapshot) {
-            clip.setRect(0, 0, getWidth(), getHeight());
-        } else {
-            Rect* bounds = mSnapshot->previous->clipRect;
-            clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom);
-        }
-    }
-
-    SkRegion region;
-    region.setPath(transformed, clip);
-
-    bool clipped = mSnapshot->clipRegionTransformed(region, op);
-    if (clipped) {
-        dirtyClip();
-    }
-    return !mSnapshot->clipRect->isEmpty();
-}
-
-bool OpenGLRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
-    bool clipped = mSnapshot->clipRegionTransformed(*region, op);
-    if (clipped) {
-        dirtyClip();
-    }
-    return !mSnapshot->clipRect->isEmpty();
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Drawing commands
 ///////////////////////////////////////////////////////////////////////////////
@@ -1772,8 +1722,8 @@
 
     bool dirty = right - left > 0.0f && bottom - top > 0.0f;
     if (!ignoreTransform) {
-        mCaches.currentProgram->set(mViewProjMatrix, mModelView, currentTransform(), offset);
-        if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform());
+        mCaches.currentProgram->set(mViewProjMatrix, mModelView, *currentTransform(), offset);
+        if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *currentTransform());
     } else {
         mCaches.currentProgram->set(mViewProjMatrix, mModelView, mat4::identity(), offset);
         if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
@@ -1799,7 +1749,7 @@
             // because it was built into modelView / the geometry, and the SkiaShader needs to
             // compensate.
             mat4 modelViewWithoutTransform;
-            modelViewWithoutTransform.loadInverse(currentTransform());
+            modelViewWithoutTransform.loadInverse(*currentTransform());
             modelViewWithoutTransform.multiply(mModelView);
             mModelView.load(modelViewWithoutTransform);
         }
@@ -1845,7 +1795,8 @@
             GL_FALSE, &transform.data[0]);
 }
 
-void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
+void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices,
+        const GLvoid* texCoords, GLuint vbo) {
     bool force = false;
     if (!vertices || vbo) {
         force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
@@ -1861,7 +1812,8 @@
     mCaches.unbindIndicesBuffer();
 }
 
-void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors) {
+void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices,
+        const GLvoid* texCoords, const GLvoid* colors) {
     bool force = mCaches.unbindMeshBuffer();
     GLsizei stride = sizeof(ColorTextureVertex);
 
@@ -1878,7 +1830,8 @@
     mCaches.unbindIndicesBuffer();
 }
 
-void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
+void OpenGLRenderer::setupDrawMeshIndices(const GLvoid* vertices,
+        const GLvoid* texCoords, GLuint vbo) {
     bool force = false;
     // If vbo is != 0 we want to treat the vertices parameter as an offset inside
     // a VBO. However, if vertices is set to NULL and vbo == 0 then we want to
@@ -1929,7 +1882,7 @@
         }
 
         bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs!
-        DeferredDisplayList deferredList(*(mSnapshot->clipRect), avoidOverdraw);
+        DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw);
         DeferStateStruct deferStruct(deferredList, *this, replayFlags);
         displayList->defer(deferStruct, 0);
 
@@ -1942,7 +1895,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint) {
+void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) {
     int alpha;
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
@@ -1955,9 +1908,9 @@
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
     bool ignoreTransform = false;
-    if (currentTransform().isPureTranslate()) {
-        x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
-        y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
+    if (currentTransform()->isPureTranslate()) {
+        x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
+        y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
         ignoreTransform = true;
 
         texture->setFilter(GL_NEAREST, true);
@@ -1977,8 +1930,9 @@
  * will not set the scissor enable or dirty the current layer, if any.
  * The caller is responsible for properly dirtying the current layer.
  */
-status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
-        TextureVertex* vertices, bool pureTranslate, const Rect& bounds, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+        int bitmapCount, TextureVertex* vertices, bool pureTranslate,
+        const Rect& bounds, const SkPaint* paint) {
     mCaches.activeTexture(0);
     Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
@@ -2012,7 +1966,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
@@ -2034,7 +1989,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+        const SkPaint* paint) {
     Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
     const mat4 transform(*matrix);
     transform.mapRect(r);
@@ -2062,7 +2018,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
@@ -2083,9 +2040,9 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-        float* vertices, int* colors, SkPaint* paint) {
-    if (!vertices || mSnapshot->isIgnored()) {
+status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+        const float* vertices, const int* colors, const SkPaint* paint) {
+    if (!vertices || currentSnapshot()->isIgnored()) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2099,14 +2056,16 @@
 
     const uint32_t count = meshWidth * meshHeight * 6;
 
-    ColorTextureVertex mesh[count];
-    ColorTextureVertex* vertex = mesh;
+    Vector<ColorTextureVertex> mesh; // TODO: use C++11 unique_ptr
+    mesh.setCapacity(count);
+    ColorTextureVertex* vertex = mesh.editArray();
 
     bool cleanupColors = false;
     if (!colors) {
         uint32_t colorsCount = (meshWidth + 1) * (meshHeight + 1);
-        colors = new int[colorsCount];
-        memset(colors, 0xff, colorsCount * sizeof(int));
+        int* newColors = new int[colorsCount];
+        memset(newColors, 0xff, colorsCount * sizeof(int));
+        colors = newColors;
         cleanupColors = true;
     }
 
@@ -2173,7 +2132,7 @@
     float a = alpha / 255.0f;
 
     if (hasLayer()) {
-        dirtyLayer(left, top, right, bottom, currentTransform());
+        dirtyLayer(left, top, right, bottom, *currentTransform());
     }
 
     setupDraw();
@@ -2201,10 +2160,10 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
          float srcLeft, float srcTop, float srcRight, float srcBottom,
          float dstLeft, float dstTop, float dstRight, float dstBottom,
-         SkPaint* paint) {
+         const SkPaint* paint) {
     if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2243,9 +2202,9 @@
     bool useScaleTransform = mDrawModifiers.mShader && scaled;
     bool ignoreTransform = false;
 
-    if (CC_LIKELY(currentTransform().isPureTranslate() && !useScaleTransform)) {
-        float x = (int) floorf(dstLeft + currentTransform().getTranslateX() + 0.5f);
-        float y = (int) floorf(dstTop + currentTransform().getTranslateY() + 0.5f);
+    if (CC_LIKELY(currentTransform()->isPureTranslate() && !useScaleTransform)) {
+        float x = (int) floorf(dstLeft + currentTransform()->getTranslateX() + 0.5f);
+        float y = (int) floorf(dstTop + currentTransform()->getTranslateY() + 0.5f);
 
         dstRight = x + (dstRight - dstLeft);
         dstBottom = y + (dstBottom - dstTop);
@@ -2293,8 +2252,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-        float left, float top, float right, float bottom, SkPaint* paint) {
+status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+        float left, float top, float right, float bottom, const SkPaint* paint) {
     if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2306,8 +2265,9 @@
     return drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint);
 }
 
-status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
-        float left, float top, float right, float bottom, SkPaint* paint) {
+status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
+        AssetAtlas::Entry* entry, float left, float top, float right, float bottom,
+        const SkPaint* paint) {
     if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2325,11 +2285,11 @@
         SkXfermode::Mode mode;
         getAlphaAndMode(paint, &alpha, &mode);
 
-        const bool pureTranslate = currentTransform().isPureTranslate();
+        const bool pureTranslate = currentTransform()->isPureTranslate();
         // Mark the current layer dirty where we are going to draw the patch
         if (hasLayer() && mesh->hasEmptyQuads) {
-            const float offsetX = left + currentTransform().getTranslateX();
-            const float offsetY = top + currentTransform().getTranslateY();
+            const float offsetX = left + currentTransform()->getTranslateX();
+            const float offsetY = top + currentTransform()->getTranslateY();
             const size_t count = mesh->quads.size();
             for (size_t i = 0; i < count; i++) {
                 const Rect& bounds = mesh->quads.itemAt(i);
@@ -2339,15 +2299,15 @@
                     dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight());
                 } else {
                     dirtyLayer(left + bounds.left, top + bounds.top,
-                            left + bounds.right, top + bounds.bottom, currentTransform());
+                            left + bounds.right, top + bounds.bottom, *currentTransform());
                 }
             }
         }
 
         bool ignoreTransform = false;
         if (CC_LIKELY(pureTranslate)) {
-            const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
-            const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
+            const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
+            const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
 
             right = x + right - left;
             bottom = y + bottom - top;
@@ -2369,8 +2329,8 @@
  * will not set the scissor enable or dirty the current layer, if any.
  * The caller is responsible for properly dirtying the current layer.
  */
-status_t OpenGLRenderer::drawPatches(SkBitmap* bitmap, AssetAtlas::Entry* entry,
-        TextureVertex* vertices, uint32_t indexCount, SkPaint* paint) {
+status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+        TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) {
     mCaches.activeTexture(0);
     Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
@@ -2390,7 +2350,7 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
+status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint,
         bool useOffset) {
     // not missing call to quickReject/dirtyLayer, always done at a higher level
 
@@ -2450,15 +2410,15 @@
  *
  * Doesn't yet support joins, caps, or path effects.
  */
-status_t OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
+status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) {
     VertexBuffer vertexBuffer;
     // TODO: try clipping large paths to viewport
-    PathTessellator::tessellatePath(path, paint, mSnapshot->transform, vertexBuffer);
+    PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer);
 
     if (hasLayer()) {
         SkRect bounds = path.getBounds();
         PathTessellator::expandBoundsForStroke(bounds, paint);
-        dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
+        dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
     }
 
     return drawVertexBuffer(vertexBuffer, paint);
@@ -2475,41 +2435,41 @@
  * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce
  * memory transfer by removing need for degenerate vertices.
  */
-status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored() || count < 4) return DrawGlInfo::kStatusDone;
+status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored() || count < 4) return DrawGlInfo::kStatusDone;
 
     count &= ~0x3; // round down to nearest four
 
     VertexBuffer buffer;
     SkRect bounds;
-    PathTessellator::tessellateLines(points, count, paint, mSnapshot->transform, bounds, buffer);
+    PathTessellator::tessellateLines(points, count, paint, *currentTransform(), bounds, buffer);
 
     // can't pass paint, since style would be checked for outset. outset done by tessellation.
     if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
-    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
     return drawVertexBuffer(buffer, paint, useOffset);
 }
 
-status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
+status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
 
     count &= ~0x1; // round down to nearest two
 
     VertexBuffer buffer;
     SkRect bounds;
-    PathTessellator::tessellatePoints(points, count, paint, mSnapshot->transform, bounds, buffer);
+    PathTessellator::tessellatePoints(points, count, paint, *currentTransform(), bounds, buffer);
 
     // can't pass paint, since style would be checked for outset. outset done by tessellation.
     if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
-    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
     return drawVertexBuffer(buffer, paint, useOffset);
@@ -2517,9 +2477,9 @@
 
 status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
     // No need to check against the clip, we fill the clip region
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
-    Rect& clip(*mSnapshot->clipRect);
+    Rect clip(*currentClipRect());
     clip.snapToPixelBoundaries();
 
     drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
@@ -2528,7 +2488,7 @@
 }
 
 status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
@@ -2541,8 +2501,8 @@
 }
 
 status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
-        float rx, float ry, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
+        float rx, float ry, const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2566,8 +2526,8 @@
     return drawConvexPath(path, p);
 }
 
-status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectSetupScissor(x - radius, y - radius,
+status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(x - radius, y - radius,
             x + radius, y + radius, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
@@ -2588,8 +2548,8 @@
 }
 
 status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
-        SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
+        const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2610,8 +2570,8 @@
 }
 
 status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2647,8 +2607,9 @@
 // See SkPaintDefaults.h
 #define SkPaintDefaults_MiterLimit SkIntToScalar(4)
 
-status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
+status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
+        const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2672,7 +2633,7 @@
         return drawConvexPath(path, p);
     }
 
-    if (p->isAntiAlias() && !currentTransform().isSimple()) {
+    if (p->isAntiAlias() && !currentTransform()->isSimple()) {
         SkPath path;
         path.addRect(left, top, right, bottom);
         return drawConvexPath(path, p);
@@ -2682,9 +2643,9 @@
     }
 }
 
-void OpenGLRenderer::drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
-        const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
-        float x, float y) {
+void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text,
+        int bytesCount, int count, const float* positions,
+        FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode, float x, float y) {
     mCaches.activeTexture(0);
 
     // NOTE: The drop shadow will not perform gamma correction
@@ -2730,13 +2691,13 @@
 }
 
 status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
-        const float* positions, SkPaint* paint) {
-    if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
+        const float* positions, const SkPaint* paint) {
+    if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) {
         return DrawGlInfo::kStatusDone;
     }
 
     // NOTE: Skia does not support perspective transform on drawPosText yet
-    if (!currentTransform().isSimple()) {
+    if (!currentTransform()->isSimple()) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2744,10 +2705,10 @@
 
     float x = 0.0f;
     float y = 0.0f;
-    const bool pureTranslate = currentTransform().isPureTranslate();
+    const bool pureTranslate = currentTransform()->isPureTranslate();
     if (pureTranslate) {
-        x = (int) floorf(x + currentTransform().getTranslateX() + 0.5f);
-        y = (int) floorf(y + currentTransform().getTranslateY() + 0.5f);
+        x = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f);
+        y = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f);
     }
 
     FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
@@ -2763,7 +2724,7 @@
     }
 
     // Pick the appropriate texture filtering
-    bool linearFilter = currentTransform().changesBounds();
+    bool linearFilter = currentTransform()->changesBounds();
     if (pureTranslate && !linearFilter) {
         linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
     }
@@ -2779,7 +2740,7 @@
             positions, hasActiveLayer ? &bounds : NULL, &functor)) {
         if (hasActiveLayer) {
             if (!pureTranslate) {
-                currentTransform().mapRect(bounds);
+                currentTransform()->mapRect(bounds);
             }
             dirtyLayerUnchecked(bounds, getRegion());
         }
@@ -2797,7 +2758,7 @@
             fontTransform = mat4::identity();
         } else {
             float sx, sy;
-            currentTransform().decomposeScale(sx, sy);
+            currentTransform()->decomposeScale(sx, sy);
             fontTransform.loadScale(sx, sy, 1.0f);
         }
     }
@@ -2805,13 +2766,13 @@
 }
 
 status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
-        const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+        const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
         DrawOpMode drawOpMode) {
 
     if (drawOpMode == kDrawOpMode_Immediate) {
         // The checks for corner-case ignorable text and quick rejection is only done for immediate
         // drawing as ops from DeferredDisplayList are already filtered for these
-        if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint) ||
+        if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint) ||
                 quickRejectSetupScissor(bounds)) {
             return DrawGlInfo::kStatusDone;
         }
@@ -2820,7 +2781,7 @@
     const float oldX = x;
     const float oldY = y;
 
-    const mat4& transform = currentTransform();
+    const mat4& transform = *currentTransform();
     const bool pureTranslate = transform.isPureTranslate();
 
     if (CC_LIKELY(pureTranslate)) {
@@ -2861,7 +2822,7 @@
     fontRenderer.setTextureFiltering(linearFilter);
 
     // TODO: Implement better clipping for scaled/rotated text
-    const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
+    const Rect* clip = !pureTranslate ? NULL : currentClipRect();
     Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
 
     bool status;
@@ -2891,9 +2852,9 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-        float hOffset, float vOffset, SkPaint* paint) {
-    if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
+status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+        const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
+    if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2917,7 +2878,7 @@
     if (fontRenderer.renderTextOnPath(paint, clip, text, 0, bytesCount, count, path,
             hOffset, vOffset, hasActiveLayer ? &bounds : NULL, &functor)) {
         if (hasActiveLayer) {
-            currentTransform().mapRect(bounds);
+            currentTransform()->mapRect(bounds);
             dirtyLayerUnchecked(bounds, getRegion());
         }
     }
@@ -2925,8 +2886,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+status_t OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
 
@@ -2990,9 +2951,9 @@
             setupDrawPureColorUniforms();
             setupDrawColorFilterUniforms();
             setupDrawTexture(layer->getTexture());
-            if (CC_LIKELY(currentTransform().isPureTranslate())) {
-                int tx = (int) floorf(x + currentTransform().getTranslateX() + 0.5f);
-                int ty = (int) floorf(y + currentTransform().getTranslateY() + 0.5f);
+            if (CC_LIKELY(currentTransform()->isPureTranslate())) {
+                int tx = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f);
+                int ty = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f);
 
                 layer->setFilter(GL_NEAREST);
                 setupDrawModelView(kModelViewMode_Translate, false, tx, ty,
@@ -3102,7 +3063,7 @@
     mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags;
 }
 
-SkPaint* OpenGLRenderer::filterPaint(SkPaint* paint) {
+const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
     if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) {
         return paint;
     }
@@ -3120,7 +3081,7 @@
 // Drawing implementation
 ///////////////////////////////////////////////////////////////////////////////
 
-Texture* OpenGLRenderer::getTexture(SkBitmap* bitmap) {
+Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
     Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
@@ -3129,7 +3090,7 @@
 }
 
 void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
-        float x, float y, SkPaint* paint) {
+        float x, float y, const SkPaint* paint) {
     if (quickRejectSetupScissor(x, y, x + texture->width, y + texture->height)) {
         return;
     }
@@ -3161,7 +3122,8 @@
 #define kStdUnderline_Offset    (1.0f / 9.0f)
 #define kStdUnderline_Thickness (1.0f / 18.0f)
 
-void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y, SkPaint* paint) {
+void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y,
+        const SkPaint* paint) {
     // Handle underline and strike-through
     uint32_t flags = paint->getFlags();
     if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
@@ -3205,8 +3167,8 @@
     }
 }
 
-status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) {
+status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored()) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -3222,7 +3184,7 @@
 
 status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlpha,
         float width, float height) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
     // For now, always and scissor
     // TODO: use quickReject
@@ -3275,7 +3237,7 @@
 
     setupDraw();
     setupDrawNoTexture();
-    setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
+    setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
     setupDrawShader();
     setupDrawColorFilter();
     setupDrawBlending(mode);
@@ -3288,7 +3250,7 @@
     setupDrawColorFilterUniforms();
 
     if (dirty && hasLayer()) {
-        dirtyLayer(left, top, right, bottom, currentTransform());
+        dirtyLayer(left, top, right, bottom, *currentTransform());
     }
 
     issueIndexedQuadDraw(&mesh[0], count / 4);
@@ -3305,7 +3267,7 @@
 
     setupDraw();
     setupDrawNoTexture();
-    setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
+    setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
     setupDrawShader();
     setupDrawColorFilter();
     setupDrawBlending(mode);
@@ -3321,7 +3283,7 @@
 }
 
 void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
-        Texture* texture, SkPaint* paint) {
+        Texture* texture, const SkPaint* paint) {
     int alpha;
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
@@ -3341,9 +3303,9 @@
         resetDrawTextureTexCoords(uvs.left, uvs.top, uvs.right, uvs.bottom);
     }
 
-    if (CC_LIKELY(currentTransform().isPureTranslate())) {
-        const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
-        const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
+    if (CC_LIKELY(currentTransform()->isPureTranslate())) {
+        const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
+        const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
 
         texture->setFilter(GL_NEAREST, true);
         drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
@@ -3510,13 +3472,13 @@
     TextureVertex::setUV(v++, u2, v2);
 }
 
-void OpenGLRenderer::getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const {
+void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const {
     getAlphaAndModeDirect(paint, alpha,  mode);
     if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) {
         // if drawing a layer, ignore the paint's alpha
         *alpha = mDrawModifiers.mOverrideLayerAlpha * 255;
     }
-    *alpha *= mSnapshot->alpha;
+    *alpha *= currentSnapshot()->alpha;
 }
 
 float OpenGLRenderer::getLayerAlpha(Layer* layer) const {
@@ -3526,7 +3488,7 @@
     } else {
         alpha = layer->getAlpha() / 255.0f;
     }
-    return alpha * mSnapshot->alpha;
+    return alpha * currentSnapshot()->alpha;
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 1325bf7..fb780ce 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -170,47 +170,48 @@
     int saveLayerDeferred(float left, float top, float right, float bottom,
             int alpha, SkXfermode::Mode mode, int flags);
 
-    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
-    virtual bool clipPath(SkPath* path, SkRegion::Op op);
-    virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
-
     virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t replayFlags);
     virtual status_t drawLayer(Layer* layer, float x, float y);
-    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    status_t drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
-            TextureVertex* vertices, bool pureTranslate, const Rect& bounds, SkPaint* paint);
-    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
-    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+            TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
-            float dstRight, float dstBottom, SkPaint* paint);
-    virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-            float* vertices, int* colors, SkPaint* paint);
-    status_t drawPatches(SkBitmap* bitmap, AssetAtlas::Entry* entry,
-            TextureVertex* vertices, uint32_t indexCount, SkPaint* paint);
-    virtual status_t drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-            float left, float top, float right, float bottom, SkPaint* paint);
-    status_t drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
-            float left, float top, float right, float bottom, SkPaint* paint);
+            float dstRight, float dstBottom, const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint);
+    status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+            TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
+    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint);
+    status_t drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
+            float left, float top, float right, float bottom, const SkPaint* paint);
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
-    virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+    virtual status_t drawRect(float left, float top, float right, float bottom,
+            const SkPaint* paint);
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint);
-    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
-    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+            float rx, float ry, const SkPaint* paint);
+    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
+    virtual status_t drawOval(float left, float top, float right, float bottom,
+            const SkPaint* paint);
     virtual status_t drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
-    virtual status_t drawPath(SkPath* path, SkPaint* paint);
-    virtual status_t drawLines(float* points, int count, SkPaint* paint);
-    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
-    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-            float hOffset, float vOffset, SkPaint* paint);
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
+    virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
+    virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
+    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+            float hOffset, float vOffset, const SkPaint* paint);
     virtual status_t drawPosText(const char* text, int bytesCount, int count,
-            const float* positions, SkPaint* paint);
+            const float* positions, const SkPaint* paint);
     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
             DrawOpMode drawOpMode = kDrawOpMode_Immediate);
-    virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
+    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
 
     status_t drawShadow(const mat4& casterTransform, float casterAlpha,
             float width, float height);
@@ -230,7 +231,7 @@
     // If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer)
     void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; }
 
-    SkPaint* filterPaint(SkPaint* paint);
+    const SkPaint* filterPaint(const SkPaint* paint);
 
     /**
      * Store the current display state (most importantly, the current clip and transform), and
@@ -246,7 +247,7 @@
     void setDrawModifiers(const DrawModifiers& drawModifiers) { mDrawModifiers = drawModifiers; }
 
     ANDROID_API bool isCurrentTransformSimple() {
-        return currentTransform().isSimple();
+        return currentTransform()->isSimple();
     }
 
     Caches& getCaches() {
@@ -258,8 +259,8 @@
         return mSnapshot->clipRegion->isEmpty();
     }
 
-    int getViewportWidth() { return getSnapshot()->viewport.getWidth(); }
-    int getViewportHeight() { return getSnapshot()->viewport.getHeight(); }
+    int getViewportWidth() { return currentSnapshot()->viewport.getWidth(); }
+    int getViewportHeight() { return currentSnapshot()->viewport.getHeight(); }
 
     /**
      * Scales the alpha on the current snapshot. This alpha value will be modulated
@@ -296,12 +297,12 @@
      * @param alpha Where to store the resulting alpha
      * @param mode Where to store the resulting xfermode
      */
-    static inline void getAlphaAndModeDirect(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
+    static inline void getAlphaAndModeDirect(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
         *mode = getXfermodeDirect(paint);
         *alpha = getAlphaDirect(paint);
     }
 
-    static inline SkXfermode::Mode getXfermodeDirect(SkPaint* paint) {
+    static inline SkXfermode::Mode getXfermodeDirect(const SkPaint* paint) {
         if (!paint) return SkXfermode::kSrcOver_Mode;
         return getXfermode(paint->getXfermode());
     }
@@ -374,8 +375,8 @@
     void attachStencilBufferToLayer(Layer* layer);
 
     bool quickRejectSetupScissor(float left, float top, float right, float bottom,
-            SkPaint* paint = NULL);
-    bool quickRejectSetupScissor(const Rect& bounds, SkPaint* paint = NULL) {
+            const SkPaint* paint = NULL);
+    bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = NULL) {
         return quickRejectSetupScissor(bounds.left, bounds.top,
                 bounds.right, bounds.bottom, paint);
     }
@@ -396,10 +397,6 @@
      */
     void dirtyLayerUnchecked(Rect& bounds, Region* region);
 
-    sp<Snapshot> getSnapshot() const {
-        return mSnapshot;
-    }
-
     /**
      * Returns the region of the current layer.
      */
@@ -438,7 +435,7 @@
      * @param alpha Where to store the resulting alpha
      * @param mode Where to store the resulting xfermode
      */
-    inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const;
+    inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const;
 
     /**
      * Gets the alpha from a layer, accounting for snapshot alpha and overrideLayerAlpha
@@ -482,12 +479,11 @@
 
     /**
      * Tells the GPU what part of the screen is about to be redrawn.
-     * This method will use the clip rect that we started drawing the
-     * frame with.
+     * This method will use the current layer space clip rect.
      * This method needs to be invoked every time getTargetFbo() is
      * bound again.
      */
-    void startTiling(const Snapshot& snapshot, bool opaque = false);
+    void startTilingCurrentClip(bool opaque = false);
 
     /**
      * Tells the GPU what part of the screen is about to be redrawn.
@@ -633,7 +629,7 @@
      * @param texture The texture reprsenting the shape
      * @param paint The paint to draw the shape with
      */
-    status_t drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
+    status_t drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint);
 
     /**
      * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
@@ -644,7 +640,7 @@
      * @param top The y coordinate of the bitmap
      * @param paint The paint to render with
      */
-    void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);
+    void drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint);
 
     /**
      * Renders a strip of polygons with the specified paint, used for tessellated geometry.
@@ -653,7 +649,7 @@
      * @param paint The paint to render with
      * @param useOffset Offset the vertexBuffer (used in drawing non-AA lines)
      */
-    status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
+    status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint,
             bool useOffset = false);
 
     /**
@@ -662,7 +658,7 @@
      * @param path The hull of the path to draw
      * @param paint The paint to render with
      */
-    status_t drawConvexPath(const SkPath& path, SkPaint* paint);
+    status_t drawConvexPath(const SkPath& path, const SkPaint* paint);
 
     /**
      * Draws a textured rectangle with the specified texture. The specified coordinates
@@ -692,7 +688,7 @@
      * @param paint The paint containing the alpha, blending mode, etc.
      */
     void drawTextureRect(float left, float top, float right, float bottom,
-            Texture* texture, SkPaint* paint);
+            Texture* texture, const SkPaint* paint);
 
     /**
      * Draws a textured mesh with the specified texture. If the indices are omitted,
@@ -751,7 +747,7 @@
      * @param y The y coordinate where the text will be drawn
      * @param paint The paint to draw the text with
      */
-    void drawTextDecorations(float totalAdvance, float x, float y, SkPaint* paint);
+    void drawTextDecorations(float totalAdvance, float x, float y, const SkPaint* paint);
 
    /**
      * Draws shadow layer on text (with optional positions).
@@ -767,7 +763,7 @@
      * @param x The x coordinate where the shadow will be drawn
      * @param y The y coordinate where the shadow will be drawn
      */
-    void drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
+    void drawTextShadow(const SkPaint* paint, const char* text, int bytesCount, int count,
             const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
             float x, float y);
 
@@ -780,7 +776,7 @@
      * @param y The y coordinate where the texture will be drawn
      * @param paint The paint to draw the texture with
      */
-     void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
+     void drawPathTexture(const PathTexture* texture, float x, float y, const SkPaint* paint);
 
     /**
      * Resets the texture coordinates stored in mMeshVertices. Setting the values
@@ -870,7 +866,7 @@
      * transformations are stored in the modelView matrix and uploaded to the shader.
      *
      * @param offset Set to true if the the matrix should be fudged (translated) slightly to disambiguate
-     * geometry pixel positioning. See Vertex::gGeometryFudgeFactor.
+     * geometry pixel positioning. See Vertex::GeometryFudgeFactor().
      *
      * @param ignoreTransform Set to true if l,t,r,b coordinates already in layer space,
      * currentTransform() will be ignored. (e.g. when drawing clip in layer coordinates to stencil,
@@ -888,9 +884,9 @@
     void setupDrawTextureTransform();
     void setupDrawTextureTransformUniforms(mat4& transform);
     void setupDrawTextGammaUniforms();
-    void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
-    void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors);
-    void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0);
+    void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords = NULL, GLuint vbo = 0);
+    void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords, const GLvoid* colors);
+    void setupDrawMeshIndices(const GLvoid* vertices, const GLvoid* texCoords, GLuint vbo = 0);
     void setupDrawIndexedVertices(GLvoid* vertices);
     void accountForClear(SkXfermode::Mode mode);
 
@@ -939,7 +935,7 @@
      * come from the texture cache or an atlas. If this method returns
      * NULL, the texture could not be found and/or allocated.
      */
-    Texture* getTexture(SkBitmap* bitmap);
+    Texture* getTexture(const SkBitmap* bitmap);
 
     // Matrix used for view/projection in shaders
     mat4 mViewProjMatrix;
@@ -988,9 +984,6 @@
     // List of layers to update at the beginning of a frame
     Vector<Layer*> mLayerUpdates;
 
-    // Indicates whether the clip must be restored
-    bool mDirtyClip;
-
     // The following fields are used to setup drawing
     // Used to describe the shaders to generate
     ProgramDescription mDescription;
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 763a785..489064b 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -36,7 +36,8 @@
 // 9-patch structures
 ///////////////////////////////////////////////////////////////////////////////
 
-struct Patch {
+class Patch {
+public:
     Patch();
     ~Patch();
 
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 5df6408..9459885 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -51,7 +51,7 @@
     memset(&shape, 0, sizeof(Shape));
 }
 
-PathDescription::PathDescription(ShapeType type, SkPaint* paint):
+PathDescription::PathDescription(ShapeType type, const SkPaint* paint):
         type(type),
         join(paint->getStrokeJoin()),
         cap(paint->getStrokeCap()),
@@ -82,7 +82,7 @@
 // Utilities
 ///////////////////////////////////////////////////////////////////////////////
 
-bool PathCache::canDrawAsConvexPath(SkPath* path, SkPaint* paint) {
+bool PathCache::canDrawAsConvexPath(SkPath* path, const SkPaint* paint) {
     // NOTE: This should only be used after PathTessellator handles joins properly
     return paint->getPathEffect() == NULL && path->getConvexity() == SkPath::kConvex_Convexity;
 }
@@ -413,7 +413,7 @@
  * in the cache. The source path is also used to reclaim garbage when a
  * Dalvik Path object is collected.
  */
-static SkPath* getSourcePath(SkPath* path) {
+static const SkPath* getSourcePath(const SkPath* path) {
     const SkPath* sourcePath = path->getSourcePath();
     if (sourcePath && sourcePath->getGenerationID() == path->getGenerationID()) {
         return const_cast<SkPath*>(sourcePath);
@@ -421,7 +421,7 @@
     return path;
 }
 
-PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
+PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
     path = getSourcePath(path);
 
     PathDescription entry(kShapePath, paint);
@@ -459,7 +459,7 @@
     return texture;
 }
 
-void PathCache::precache(SkPath* path, SkPaint* paint) {
+void PathCache::precache(const SkPath* path, const SkPaint* paint) {
     if (!Caches::getInstance().tasks.canRunTasks()) {
         return;
     }
@@ -507,7 +507,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PathTexture* PathCache::getRoundRect(float width, float height,
-        float rx, float ry, SkPaint* paint) {
+        float rx, float ry, const SkPaint* paint) {
     PathDescription entry(kShapeRoundRect, paint);
     entry.shape.roundRect.mWidth = width;
     entry.shape.roundRect.mHeight = height;
@@ -532,7 +532,7 @@
 // Circles
 ///////////////////////////////////////////////////////////////////////////////
 
-PathTexture* PathCache::getCircle(float radius, SkPaint* paint) {
+PathTexture* PathCache::getCircle(float radius, const SkPaint* paint) {
     PathDescription entry(kShapeCircle, paint);
     entry.shape.circle.mRadius = radius;
 
@@ -552,7 +552,7 @@
 // Ovals
 ///////////////////////////////////////////////////////////////////////////////
 
-PathTexture* PathCache::getOval(float width, float height, SkPaint* paint) {
+PathTexture* PathCache::getOval(float width, float height, const SkPaint* paint) {
     PathDescription entry(kShapeOval, paint);
     entry.shape.oval.mWidth = width;
     entry.shape.oval.mHeight = height;
@@ -575,7 +575,7 @@
 // Rects
 ///////////////////////////////////////////////////////////////////////////////
 
-PathTexture* PathCache::getRect(float width, float height, SkPaint* paint) {
+PathTexture* PathCache::getRect(float width, float height, const SkPaint* paint) {
     PathDescription entry(kShapeRect, paint);
     entry.shape.rect.mWidth = width;
     entry.shape.rect.mHeight = height;
@@ -599,7 +599,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PathTexture* PathCache::getArc(float width, float height,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
     PathDescription entry(kShapeArc, paint);
     entry.shape.arc.mWidth = width;
     entry.shape.arc.mHeight = height;
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 16d20a8..847853a 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -32,7 +32,7 @@
 class SkCanvas;
 class SkPaint;
 class SkPath;
-class SkRect;
+struct SkRect;
 
 namespace android {
 namespace uirenderer {
@@ -116,7 +116,7 @@
     SkPathEffect* pathEffect;
     union Shape {
         struct Path {
-            SkPath* mPath;
+            const SkPath* mPath;
         } path;
         struct RoundRect {
             float mWidth;
@@ -145,7 +145,7 @@
     } shape;
 
     PathDescription();
-    PathDescription(ShapeType shapeType, SkPaint* paint);
+    PathDescription(ShapeType shapeType, const SkPaint* paint);
 
     hash_t hash() const;
 
@@ -207,13 +207,13 @@
      */
     uint32_t getSize();
 
-    PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
-    PathTexture* getCircle(float radius, SkPaint* paint);
-    PathTexture* getOval(float width, float height, SkPaint* paint);
-    PathTexture* getRect(float width, float height, SkPaint* paint);
+    PathTexture* getRoundRect(float width, float height, float rx, float ry, const SkPaint* paint);
+    PathTexture* getCircle(float radius, const SkPaint* paint);
+    PathTexture* getOval(float width, float height, const SkPaint* paint);
+    PathTexture* getRect(float width, float height, const SkPaint* paint);
     PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
-            bool useCenter, SkPaint* paint);
-    PathTexture* get(SkPath* path, SkPaint* paint);
+            bool useCenter, const SkPaint* paint);
+    PathTexture* get(const SkPath* path, const SkPaint* paint);
 
     /**
      * Removes the specified path. This is meant to be called from threads
@@ -239,9 +239,9 @@
     /**
      * Precaches the specified path using background threads.
      */
-    void precache(SkPath* path, SkPaint* paint);
+    void precache(const SkPath* path, const SkPaint* paint);
 
-    static bool canDrawAsConvexPath(SkPath* path, SkPaint* paint);
+    static bool canDrawAsConvexPath(SkPath* path, const SkPaint* paint);
     static void computePathBounds(const SkPath* path, const SkPaint* paint,
             float& left, float& top, float& offset, uint32_t& width, uint32_t& height);
     static void computeBounds(const SkRect& bounds, const SkPaint* paint,
@@ -292,7 +292,7 @@
 
     class PathTask: public Task<SkBitmap*> {
     public:
-        PathTask(SkPath* path, SkPaint* paint, PathTexture* texture):
+        PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
             path(path), paint(paint), texture(texture) {
         }
 
@@ -300,8 +300,8 @@
             delete future()->get();
         }
 
-        SkPath* path;
-        SkPaint* paint;
+        const SkPath* path;
+        const SkPaint* paint;
         PathTexture* texture;
     };
 
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 7a86dfc..c6ce67c 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -88,16 +88,16 @@
  */
 struct PaintInfo {
 public:
-    PaintInfo(const SkPaint* paint, const mat4 *transform) :
+    PaintInfo(const SkPaint* paint, const mat4& transform) :
             style(paint->getStyle()), cap(paint->getStrokeCap()), isAA(paint->isAntiAlias()),
             inverseScaleX(1.0f), inverseScaleY(1.0f),
             halfStrokeWidth(paint->getStrokeWidth() * 0.5f), maxAlpha(1.0f) {
         // compute inverse scales
-        if (CC_UNLIKELY(!transform->isPureTranslate())) {
-            float m00 = transform->data[Matrix4::kScaleX];
-            float m01 = transform->data[Matrix4::kSkewY];
-            float m10 = transform->data[Matrix4::kSkewX];
-            float m11 = transform->data[Matrix4::kScaleY];
+        if (CC_UNLIKELY(!transform.isPureTranslate())) {
+            float m00 = transform.data[Matrix4::kScaleX];
+            float m01 = transform.data[Matrix4::kSkewY];
+            float m10 = transform.data[Matrix4::kSkewX];
+            float m11 = transform.data[Matrix4::kScaleY];
             float scaleX = sqrt(m00 * m00 + m01 * m01);
             float scaleY = sqrt(m10 * m10 + m11 * m11);
             inverseScaleX = (scaleX != 0) ? (1.0f / scaleX) : 1.0f;
@@ -162,8 +162,8 @@
     void expandBoundsForStrokeAA(SkRect& bounds) const {
         float outset = halfStrokeWidth;
         if (outset == 0) outset = 0.5f;
-        bounds.outset(outset * inverseScaleX + Vertex::gGeometryFudgeFactor,
-                outset * inverseScaleY + Vertex::gGeometryFudgeFactor);
+        bounds.outset(outset * inverseScaleX + Vertex::GeometryFudgeFactor(),
+                outset * inverseScaleY + Vertex::GeometryFudgeFactor());
     }
 };
 
@@ -718,7 +718,7 @@
 }
 
 void PathTessellator::tessellatePath(const SkPath &path, const SkPaint* paint,
-        const mat4 *transform, VertexBuffer& vertexBuffer) {
+        const mat4& transform, VertexBuffer& vertexBuffer) {
     ATRACE_CALL();
 
     const PaintInfo paintInfo(paint, transform);
@@ -805,8 +805,8 @@
     dstBuffer.createDegenerateSeparators<TYPE>(verticesPerPoint);
 }
 
-void PathTessellator::tessellatePoints(const float* points, int count, SkPaint* paint,
-        const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+void PathTessellator::tessellatePoints(const float* points, int count, const SkPaint* paint,
+        const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
     const PaintInfo paintInfo(paint, transform);
 
     // determine point shape
@@ -845,8 +845,8 @@
 
 }
 
-void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
-        const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+void PathTessellator::tessellateLines(const float* points, int count, const SkPaint* paint,
+        const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
     ATRACE_CALL();
     const PaintInfo paintInfo(paint, transform);
 
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index 236658d..e43b101 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -32,13 +32,13 @@
     static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint);
 
     static void tessellatePath(const SkPath& path, const SkPaint* paint,
-            const mat4 *transform, VertexBuffer& vertexBuffer);
+            const mat4& transform, VertexBuffer& vertexBuffer);
 
-    static void tessellatePoints(const float* points, int count, SkPaint* paint,
-            const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+    static void tessellatePoints(const float* points, int count, const SkPaint* paint,
+            const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer);
 
-    static void tessellateLines(const float* points, int count, SkPaint* paint,
-            const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+    static void tessellateLines(const float* points, int count, const SkPaint* paint,
+            const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer);
 
 private:
     static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 7814a01..a679552 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -173,7 +173,7 @@
             // up and to the left.
             // This offset value is based on an assumption that some hardware may use as
             // little as 12.4 precision, so we offset by slightly more than 1/16.
-            p.translate(Vertex::gGeometryFudgeFactor, Vertex::gGeometryFudgeFactor);
+            p.translate(Vertex::GeometryFudgeFactor(), Vertex::GeometryFudgeFactor());
             glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
         }
         mProjection = projectionMatrix;
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 83b3436..c230149 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -190,19 +190,19 @@
              * from this inset will only incur similarly small errors in output, due to transparency
              * in extreme outside of the geometry.
              */
-            left = floorf(left + Vertex::gGeometryFudgeFactor);
-            top = floorf(top + Vertex::gGeometryFudgeFactor);
-            right = ceilf(right - Vertex::gGeometryFudgeFactor);
-            bottom = ceilf(bottom - Vertex::gGeometryFudgeFactor);
+            left = floorf(left + Vertex::GeometryFudgeFactor());
+            top = floorf(top + Vertex::GeometryFudgeFactor());
+            right = ceilf(right - Vertex::GeometryFudgeFactor());
+            bottom = ceilf(bottom - Vertex::GeometryFudgeFactor());
         } else {
             /* For other geometry, we do the regular rounding in order to snap, but also outset the
              * bounds by a fudge factor. This ensures that ambiguous geometry (e.g. a non-AA Rect
              * with top left at (0.5, 0.5)) will err on the side of a larger damage rect.
              */
-            left = floorf(left + 0.5f - Vertex::gGeometryFudgeFactor);
-            top = floorf(top + 0.5f - Vertex::gGeometryFudgeFactor);
-            right = floorf(right + 0.5f + Vertex::gGeometryFudgeFactor);
-            bottom = floorf(bottom + 0.5f + Vertex::gGeometryFudgeFactor);
+            left = floorf(left + 0.5f - Vertex::GeometryFudgeFactor());
+            top = floorf(top + 0.5f - Vertex::GeometryFudgeFactor());
+            right = floorf(right + 0.5f + Vertex::GeometryFudgeFactor());
+            bottom = floorf(bottom + 0.5f + Vertex::GeometryFudgeFactor());
         }
     }
 
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index faf663a..38e1c91 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -27,7 +27,7 @@
 namespace android {
 
 class Functor;
-class Res_png_9patch;
+struct Res_png_9patch;
 
 namespace uirenderer {
 
@@ -190,16 +190,16 @@
     virtual void scale(float sx, float sy) = 0;
     virtual void skew(float sx, float sy) = 0;
 
-    virtual void setMatrix(SkMatrix* matrix) = 0;
-    virtual void concatMatrix(SkMatrix* matrix) = 0;
+    virtual void setMatrix(const SkMatrix* matrix) = 0;
+    virtual void concatMatrix(const SkMatrix* matrix) = 0;
 
     // clip
     virtual const Rect& getClipBounds() const = 0;
     virtual bool quickRejectConservative(float left, float top,
             float right, float bottom) const = 0;
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) = 0;
-    virtual bool clipPath(SkPath* path, SkRegion::Op op) = 0;
-    virtual bool clipRegion(SkRegion* region, SkRegion::Op op) = 0;
+    virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
+    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
 
     // Misc - should be implemented with SkPaint inspection
     virtual void resetShader() = 0;
@@ -220,38 +220,43 @@
     virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0;
 
     // Bitmap-based
-    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) = 0;
-    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) = 0;
-    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint) = 0;
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+            const SkPaint* paint) = 0;
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
-            float dstRight, float dstBottom, SkPaint* paint) = 0;
-    virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) = 0;
-    virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-            float* vertices, int* colors, SkPaint* paint) = 0;
-    virtual status_t drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-            float left, float top, float right, float bottom, SkPaint* paint) = 0;
+            float dstRight, float dstBottom, const SkPaint* paint) = 0;
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint) = 0;
+    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint) = 0;
+    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint) = 0;
 
     // Shapes
-    virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint) = 0;
-    virtual status_t drawRects(const float* rects, int count, SkPaint* paint) = 0;
+    virtual status_t drawRect(float left, float top, float right, float bottom,
+            const SkPaint* paint) = 0;
+    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint) = 0;
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint) = 0;
-    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint) = 0;
-    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint) = 0;
+            float rx, float ry, const SkPaint* paint) = 0;
+    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint) = 0;
+    virtual status_t drawOval(float left, float top, float right, float bottom,
+            const SkPaint* paint) = 0;
     virtual status_t drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) = 0;
-    virtual status_t drawPath(SkPath* path, SkPaint* paint) = 0;
-    virtual status_t drawLines(float* points, int count, SkPaint* paint) = 0;
-    virtual status_t drawPoints(float* points, int count, SkPaint* paint) = 0;
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) = 0;
+    virtual status_t drawPath(const SkPath* path, const SkPaint* paint) = 0;
+    virtual status_t drawLines(const float* points, int count, const SkPaint* paint) = 0;
+    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint) = 0;
 
     // Text
     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
             DrawOpMode drawOpMode = kDrawOpMode_Immediate) = 0;
-    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-            float hOffset, float vOffset, SkPaint* paint) = 0;
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+            float hOffset, float vOffset, const SkPaint* paint) = 0;
     virtual status_t drawPosText(const char* text, int bytesCount, int count,
-            const float* positions, SkPaint* paint) = 0;
+            const float* positions, const SkPaint* paint) = 0;
 
 // ----------------------------------------------------------------------------
 // Canvas draw operations - special
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 3f77021..e58857c 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -40,7 +40,7 @@
 
 ResourceCache::ResourceCache() {
     Mutex::Autolock _l(mLock);
-    mCache = new KeyedVector<void*, ResourceReference*>();
+    mCache = new KeyedVector<const void*, ResourceReference*>();
 }
 
 ResourceCache::~ResourceCache() {
@@ -61,13 +61,13 @@
     incrementRefcountLocked(resource, resourceType);
 }
 
-void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
+void ResourceCache::incrementRefcount(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
 
-void ResourceCache::incrementRefcount(SkPath* pathResource) {
+void ResourceCache::incrementRefcount(const SkPath* pathResource) {
     incrementRefcount((void*) pathResource, kPath);
 }
 
@@ -81,7 +81,7 @@
     incrementRefcount((void*) filterResource, kColorFilter);
 }
 
-void ResourceCache::incrementRefcount(Res_png_9patch* patchResource) {
+void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) {
     incrementRefcount((void*) patchResource, kNinePatch);
 }
 
@@ -99,13 +99,13 @@
     ref->refCount++;
 }
 
-void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
+void ResourceCache::incrementRefcountLocked(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
 
-void ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
+void ResourceCache::incrementRefcountLocked(const SkPath* pathResource) {
     incrementRefcountLocked((void*) pathResource, kPath);
 }
 
@@ -119,7 +119,7 @@
     incrementRefcountLocked((void*) filterResource, kColorFilter);
 }
 
-void ResourceCache::incrementRefcountLocked(Res_png_9patch* patchResource) {
+void ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource) {
     incrementRefcountLocked((void*) patchResource, kNinePatch);
 }
 
@@ -132,13 +132,13 @@
     decrementRefcountLocked(resource);
 }
 
-void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
+void ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
 
-void ResourceCache::decrementRefcount(SkPath* pathResource) {
+void ResourceCache::decrementRefcount(const SkPath* pathResource) {
     decrementRefcount((void*) pathResource);
 }
 
@@ -152,7 +152,7 @@
     decrementRefcount((void*) filterResource);
 }
 
-void ResourceCache::decrementRefcount(Res_png_9patch* patchResource) {
+void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
     decrementRefcount((void*) patchResource);
 }
 
@@ -173,13 +173,13 @@
     }
 }
 
-void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
+void ResourceCache::decrementRefcountLocked(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
 
-void ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
+void ResourceCache::decrementRefcountLocked(const SkPath* pathResource) {
     decrementRefcountLocked((void*) pathResource);
 }
 
@@ -193,7 +193,7 @@
     decrementRefcountLocked((void*) filterResource);
 }
 
-void ResourceCache::decrementRefcountLocked(Res_png_9patch* patchResource) {
+void ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource) {
     decrementRefcountLocked((void*) patchResource);
 }
 
@@ -223,12 +223,12 @@
     }
 }
 
-void ResourceCache::destructor(SkBitmap* resource) {
+void ResourceCache::destructor(const SkBitmap* resource) {
     Mutex::Autolock _l(mLock);
     destructorLocked(resource);
 }
 
-void ResourceCache::destructorLocked(SkBitmap* resource) {
+void ResourceCache::destructorLocked(const SkBitmap* resource) {
     ssize_t index = mCache->indexOfKey(resource);
     ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
@@ -345,7 +345,7 @@
  * This method should only be called while the mLock mutex is held (that mutex is grabbed
  * by the various destructor() and recycle() methods which call this method).
  */
-void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
+void ResourceCache::deleteResourceReferenceLocked(const void* resource, ResourceReference* ref) {
     if (ref->recycled && ref->resourceType == kBitmap) {
         ((SkBitmap*) resource)->setPixels(NULL, NULL);
     }
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index ea0c1b5..c06b09b 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -70,42 +70,42 @@
     void lock();
     void unlock();
 
-    void incrementRefcount(SkPath* resource);
-    void incrementRefcount(SkBitmap* resource);
+    void incrementRefcount(const SkPath* resource);
+    void incrementRefcount(const SkBitmap* resource);
     void incrementRefcount(SkiaShader* resource);
     void incrementRefcount(SkiaColorFilter* resource);
-    void incrementRefcount(Res_png_9patch* resource);
+    void incrementRefcount(const Res_png_9patch* resource);
     void incrementRefcount(Layer* resource);
 
-    void incrementRefcountLocked(SkPath* resource);
-    void incrementRefcountLocked(SkBitmap* resource);
+    void incrementRefcountLocked(const SkPath* resource);
+    void incrementRefcountLocked(const SkBitmap* resource);
     void incrementRefcountLocked(SkiaShader* resource);
     void incrementRefcountLocked(SkiaColorFilter* resource);
-    void incrementRefcountLocked(Res_png_9patch* resource);
+    void incrementRefcountLocked(const Res_png_9patch* resource);
     void incrementRefcountLocked(Layer* resource);
 
-    void decrementRefcount(SkBitmap* resource);
-    void decrementRefcount(SkPath* resource);
+    void decrementRefcount(const SkBitmap* resource);
+    void decrementRefcount(const SkPath* resource);
     void decrementRefcount(SkiaShader* resource);
     void decrementRefcount(SkiaColorFilter* resource);
-    void decrementRefcount(Res_png_9patch* resource);
+    void decrementRefcount(const Res_png_9patch* resource);
     void decrementRefcount(Layer* resource);
 
-    void decrementRefcountLocked(SkBitmap* resource);
-    void decrementRefcountLocked(SkPath* resource);
+    void decrementRefcountLocked(const SkBitmap* resource);
+    void decrementRefcountLocked(const SkPath* resource);
     void decrementRefcountLocked(SkiaShader* resource);
     void decrementRefcountLocked(SkiaColorFilter* resource);
-    void decrementRefcountLocked(Res_png_9patch* resource);
+    void decrementRefcountLocked(const Res_png_9patch* resource);
     void decrementRefcountLocked(Layer* resource);
 
     void destructor(SkPath* resource);
-    void destructor(SkBitmap* resource);
+    void destructor(const SkBitmap* resource);
     void destructor(SkiaShader* resource);
     void destructor(SkiaColorFilter* resource);
     void destructor(Res_png_9patch* resource);
 
     void destructorLocked(SkPath* resource);
-    void destructorLocked(SkBitmap* resource);
+    void destructorLocked(const SkBitmap* resource);
     void destructorLocked(SkiaShader* resource);
     void destructorLocked(SkiaColorFilter* resource);
     void destructorLocked(Res_png_9patch* resource);
@@ -114,7 +114,7 @@
     bool recycleLocked(SkBitmap* resource);
 
 private:
-    void deleteResourceReferenceLocked(void* resource, ResourceReference* ref);
+    void deleteResourceReferenceLocked(const void* resource, ResourceReference* ref);
 
     void incrementRefcount(void* resource, ResourceType resourceType);
     void incrementRefcountLocked(void* resource, ResourceType resourceType);
@@ -131,7 +131,7 @@
      */
     mutable Mutex mLock;
 
-    KeyedVector<void*, ResourceReference*>* mCache;
+    KeyedVector<const void*, ResourceReference*>* mCache;
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h
index 2feb834..c222a2d 100644
--- a/libs/hwui/SkiaColorFilter.h
+++ b/libs/hwui/SkiaColorFilter.h
@@ -36,7 +36,8 @@
  * Represents a Skia color filter. A color filter modifies a ProgramDescription
  * and sets uniforms on the resulting shaders.
  */
-struct SkiaColorFilter {
+class SkiaColorFilter {
+public:
     /**
      * Type of Skia color filter in use.
      */
@@ -80,7 +81,8 @@
 /**
  * A color filter that multiplies the source color with a matrix and adds a vector.
  */
-struct SkiaColorMatrixFilter: public SkiaColorFilter {
+class SkiaColorMatrixFilter: public SkiaColorFilter {
+public:
     ANDROID_API SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector);
     ~SkiaColorMatrixFilter();
 
@@ -96,7 +98,8 @@
  * A color filters that multiplies the source color with a fixed value and adds
  * another fixed value. Ignores the alpha channel of both arguments.
  */
-struct SkiaLightingFilter: public SkiaColorFilter {
+class SkiaLightingFilter: public SkiaColorFilter {
+public:
     ANDROID_API SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add);
 
     void describe(ProgramDescription& description, const Extensions& extensions);
@@ -111,7 +114,8 @@
  * A color filters that blends the source color with a specified destination color
  * and PorterDuff blending mode.
  */
-struct SkiaBlendFilter: public SkiaColorFilter {
+class SkiaBlendFilter: public SkiaColorFilter {
+public:
     ANDROID_API SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode);
 
     void describe(ProgramDescription& description, const Extensions& extensions);
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 9fc99a4..d71f8ee 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -43,7 +43,8 @@
  * Represents a Skia shader. A shader will modify the GL context and active
  * program to recreate the original effect.
  */
-struct SkiaShader {
+class SkiaShader {
+public:
     /**
      * Type of Skia shader in use.
      */
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp
index cc8b14f..05f6cf8 100644
--- a/libs/hwui/StatefulBaseRenderer.cpp
+++ b/libs/hwui/StatefulBaseRenderer.cpp
@@ -22,6 +22,7 @@
 namespace uirenderer {
 
 StatefulBaseRenderer::StatefulBaseRenderer() :
+        mDirtyClip(false), mWidth(-1), mHeight(-1),
         mSaveCount(1), mFirstSnapshot(new Snapshot), mSnapshot(mFirstSnapshot) {
 }
 
@@ -113,7 +114,7 @@
     mSnapshot->transform->skew(sx, sy);
 }
 
-void StatefulBaseRenderer::setMatrix(SkMatrix* matrix) {
+void StatefulBaseRenderer::setMatrix(const SkMatrix* matrix) {
     if (matrix) {
         mSnapshot->transform->load(*matrix);
     } else {
@@ -125,7 +126,7 @@
     mSnapshot->transform->load(matrix);
 }
 
-void StatefulBaseRenderer::concatMatrix(SkMatrix* matrix) {
+void StatefulBaseRenderer::concatMatrix(const SkMatrix* matrix) {
     mat4 transform(*matrix);
     mSnapshot->transform->multiply(transform);
 }
@@ -138,6 +139,48 @@
 // Clip
 ///////////////////////////////////////////////////////////////////////////////
 
+bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+    if (CC_LIKELY(currentTransform()->rectToRect())) {
+        mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op);
+        return !mSnapshot->clipRect->isEmpty();
+    }
+
+    SkPath path;
+    path.addRect(left, top, right, bottom);
+
+    return StatefulBaseRenderer::clipPath(&path, op);
+}
+
+bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
+    SkMatrix transform;
+    currentTransform()->copyTo(transform);
+
+    SkPath transformed;
+    path->transform(transform, &transformed);
+
+    SkRegion clip;
+    if (!mSnapshot->previous->clipRegion->isEmpty()) {
+        clip.setRegion(*mSnapshot->previous->clipRegion);
+    } else {
+        if (mSnapshot->previous == firstSnapshot()) {
+            clip.setRect(0, 0, getWidth(), getHeight());
+        } else {
+            Rect* bounds = mSnapshot->previous->clipRect;
+            clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom);
+        }
+    }
+
+    SkRegion region;
+    region.setPath(transformed, clip);
+
+    mDirtyClip |= mSnapshot->clipRegionTransformed(region, op);
+    return !mSnapshot->clipRect->isEmpty();
+}
+
+bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
+    mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op);
+    return !mSnapshot->clipRect->isEmpty();
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 // Quick Rejection
@@ -160,10 +203,10 @@
     }
 
     Rect r(left, top, right, bottom);
-    currentTransform().mapRect(r);
+    currentTransform()->mapRect(r);
     r.snapGeometryToPixelBoundaries(snapOut);
 
-    Rect clipRect(currentClipRect());
+    Rect clipRect(*currentClipRect());
     clipRect.snapToPixelBoundaries();
 
     if (!clipRect.intersects(r)) return true;
@@ -191,10 +234,10 @@
     }
 
     Rect r(left, top, right, bottom);
-    currentTransform().mapRect(r);
+    currentTransform()->mapRect(r);
     r.roundOut(); // rounded out to be conservative
 
-    Rect clipRect(currentClipRect());
+    Rect clipRect(*currentClipRect());
     clipRect.snapToPixelBoundaries();
 
     if (!clipRect.intersects(r)) return true;
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
index 2bd196e..bf34bec 100644
--- a/libs/hwui/StatefulBaseRenderer.h
+++ b/libs/hwui/StatefulBaseRenderer.h
@@ -26,10 +26,18 @@
 namespace uirenderer {
 
 /**
- * Implementation for Renderer state methods
+ * Abstract Renderer subclass, which implements Canvas state methods.
  *
- * Eventually, this class should have abstract protected methods
- * for allowing subclasses to hook into save/saveLayer and restore
+ * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
+ * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer will have
+ * different use cases:
+ *
+ * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into
+ * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself.
+ *
+ * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations
+ * to StatefulBaseRenderer, so that not only will querying operations work (getClip/Matrix), but so
+ * that quickRejection can also be used.
  */
 class StatefulBaseRenderer : public Renderer {
 public:
@@ -43,7 +51,7 @@
 
     // getters
     bool hasRectToRectTransform() const {
-        return CC_LIKELY(currentTransform().rectToRect());
+        return CC_LIKELY(currentTransform()->rectToRect());
     }
 
     // Save (layer)
@@ -61,19 +69,18 @@
     virtual void scale(float sx, float sy);
     virtual void skew(float sx, float sy);
 
-    virtual void setMatrix(SkMatrix* matrix);
+    virtual void setMatrix(const SkMatrix* matrix);
     void setMatrix(const Matrix4& matrix); // internal only convenience method
-    virtual void concatMatrix(SkMatrix* matrix);
+    virtual void concatMatrix(const SkMatrix* matrix);
     void concatMatrix(const Matrix4& matrix); // internal only convenience method
 
     // Clip
     const Rect& getClipBounds() const { return mSnapshot->getLocalClip(); }
     virtual bool quickRejectConservative(float left, float top, float right, float bottom) const;
 
-    // TODO: implement these with hooks to enable scissor/stencil usage in OpenGLRenderer
-    // virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
-    // virtual bool clipPath(SkPath* path, SkRegion::Op op);
-    // virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
+    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
+    virtual bool clipPath(const SkPath* path, SkRegion::Op op);
+    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
 
 protected:
     int getWidth() { return mWidth; }
@@ -101,20 +108,28 @@
      */
     virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {};
 
-    inline const Rect& currentClipRect() const {
-        return *(mSnapshot->clipRect);
+    inline const Rect* currentClipRect() const {
+        return mSnapshot->clipRect;
     }
 
-    inline const mat4& currentTransform() const {
-        return *(mSnapshot->transform);
+    inline const mat4* currentTransform() const {
+        return mSnapshot->transform;
     }
 
-    inline const Snapshot& currentSnapshot() const {
-        return mSnapshot != NULL ? *mSnapshot : *mFirstSnapshot;
+    inline const Snapshot* currentSnapshot() const {
+        return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get();
     }
 
-    // TODO: below should be private so that snapshot stack manipulation
-    // goes though (mostly) public methods
+    inline const Snapshot* firstSnapshot() const {
+        return mFirstSnapshot.get();
+    }
+
+    // indicites that the clip has been changed since the last time it was consumed
+    bool mDirtyClip;
+
+private:
+    // Dimensions of the drawing surface
+    int mWidth, mHeight;
 
     // Number of saved states
     int mSaveCount;
@@ -122,13 +137,11 @@
     // Base state
     sp<Snapshot> mFirstSnapshot;
 
+protected:
     // Current state
+    // TODO: should become private, once hooks needed by OpenGLRenderer are added
     sp<Snapshot> mSnapshot;
 
-private:
-    // Dimensions of the drawing surface
-    int mWidth, mHeight;
-
 }; // class StatefulBaseRenderer
 
 }; // namespace uirenderer
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 6f27b36..4eec462 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -168,7 +168,7 @@
     mCache.clear();
 }
 
-ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len,
+ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const char* text, uint32_t len,
         int numGlyphs, float radius, const float* positions) {
     ShadowText entry(paint, radius, len, text, positions);
     ShadowTexture* texture = mCache.get(entry);
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 04d7357..54b930b 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -38,7 +38,7 @@
     }
 
     // len is the number of bytes in text
-    ShadowText(SkPaint* paint, float radius, uint32_t len, const char* srcText,
+    ShadowText(const SkPaint* paint, float radius, uint32_t len, const char* srcText,
             const float* positions):
             len(len), radius(radius), positions(positions) {
         // TODO: Propagate this through the API, we should not cast here
@@ -135,7 +135,7 @@
      */
     void operator()(ShadowText& text, ShadowTexture*& texture);
 
-    ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len,
+    ShadowTexture* get(const SkPaint* paint, const char* text, uint32_t len,
             int numGlyphs, float radius, const float* positions);
 
     /**
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 1d4af7f..457ca59 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -34,7 +34,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 TextureCache::TextureCache():
-        mCache(LruCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
+        mCache(LruCache<const SkBitmap*, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
         mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
     char property[PROPERTY_VALUE_MAX];
@@ -58,7 +58,7 @@
 }
 
 TextureCache::TextureCache(uint32_t maxByteSize):
-        mCache(LruCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
+        mCache(LruCache<const SkBitmap*, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(maxByteSize) {
     init();
 }
@@ -103,7 +103,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void TextureCache::operator()(SkBitmap*&, Texture*& texture) {
+void TextureCache::operator()(const SkBitmap*&, Texture*& texture) {
     // This will be called already locked
     if (texture) {
         mSize -= texture->bitmapSize;
@@ -121,7 +121,7 @@
 // Caching
 ///////////////////////////////////////////////////////////////////////////////
 
-Texture* TextureCache::get(SkBitmap* bitmap) {
+Texture* TextureCache::get(const SkBitmap* bitmap) {
     Texture* texture = mCache.get(bitmap);
 
     if (!texture) {
@@ -161,7 +161,7 @@
     return texture;
 }
 
-Texture* TextureCache::getTransient(SkBitmap* bitmap) {
+Texture* TextureCache::getTransient(const SkBitmap* bitmap) {
     Texture* texture = new Texture();
     texture->bitmapSize = bitmap->rowBytes() * bitmap->height();
     texture->cleanup = true;
@@ -171,11 +171,11 @@
     return texture;
 }
 
-void TextureCache::remove(SkBitmap* bitmap) {
+void TextureCache::remove(const SkBitmap* bitmap) {
     mCache.remove(bitmap);
 }
 
-void TextureCache::removeDeferred(SkBitmap* bitmap) {
+void TextureCache::removeDeferred(const SkBitmap* bitmap) {
     Mutex::Autolock _l(mLock);
     mGarbage.push(bitmap);
 }
@@ -209,7 +209,7 @@
     }
 }
 
-void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
+void TextureCache::generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate) {
     SkAutoLockPixels alp(*bitmap);
 
     if (!bitmap->readyToDraw()) {
@@ -282,7 +282,7 @@
     }
 }
 
-void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
+void TextureCache::uploadLoFiTexture(bool resize, const SkBitmap* bitmap,
         uint32_t width, uint32_t height) {
     SkBitmap rgbaBitmap;
     rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 57fc19a..e33c60d 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -49,7 +49,7 @@
  * Any texture added to the cache causing the cache to grow beyond the maximum
  * allowed size will also cause the oldest texture to be kicked out.
  */
-class TextureCache: public OnEntryRemoved<SkBitmap*, Texture*> {
+class TextureCache: public OnEntryRemoved<const SkBitmap*, Texture*> {
 public:
     TextureCache();
     TextureCache(uint32_t maxByteSize);
@@ -59,28 +59,28 @@
      * Used as a callback when an entry is removed from the cache.
      * Do not invoke directly.
      */
-    void operator()(SkBitmap*& bitmap, Texture*& texture);
+    void operator()(const SkBitmap*& bitmap, Texture*& texture);
 
     /**
      * Returns the texture associated with the specified bitmap. If the texture
      * cannot be found in the cache, a new texture is generated.
      */
-    Texture* get(SkBitmap* bitmap);
+    Texture* get(const SkBitmap* bitmap);
     /**
      * Returns the texture associated with the specified bitmap. The generated
      * texture is not kept in the cache. The caller must destroy the texture.
      */
-    Texture* getTransient(SkBitmap* bitmap);
+    Texture* getTransient(const SkBitmap* bitmap);
     /**
      * Removes the texture associated with the specified bitmap.
      * Upon remove the texture is freed.
      */
-    void remove(SkBitmap* bitmap);
+    void remove(const SkBitmap* bitmap);
     /**
      * Removes the texture associated with the specified bitmap. This is meant
      * to be called from threads that are not the EGL context thread.
      */
-    void removeDeferred(SkBitmap* bitmap);
+    void removeDeferred(const SkBitmap* bitmap);
     /**
      * Process deferred removals.
      */
@@ -122,15 +122,15 @@
      * @param regenerate If true, the bitmap data is reuploaded into the texture, but
      *        no new texture is generated.
      */
-    void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false);
+    void generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate = false);
 
-    void uploadLoFiTexture(bool resize, SkBitmap* bitmap, uint32_t width, uint32_t height);
+    void uploadLoFiTexture(bool resize, const SkBitmap* bitmap, uint32_t width, uint32_t height);
     void uploadToTexture(bool resize, GLenum format, GLsizei stride,
             GLsizei width, GLsizei height, GLenum type, const GLvoid * data);
 
     void init();
 
-    LruCache<SkBitmap*, Texture*> mCache;
+    LruCache<const SkBitmap*, Texture*> mCache;
 
     uint32_t mSize;
     uint32_t mMaxSize;
@@ -140,7 +140,7 @@
 
     bool mDebugEnabled;
 
-    Vector<SkBitmap*> mGarbage;
+    Vector<const SkBitmap*> mGarbage;
     mutable Mutex mLock;
 }; // class TextureCache
 
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 351ce71..5d7a199 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -33,7 +33,8 @@
      * Program::set()), and used to make geometry damage rect calculation conservative (see
      * Rect::snapGeometryToPixelBoundaries())
      */
-    static const float gGeometryFudgeFactor = 0.0656f;
+    static float GeometryFudgeFactor() { return 0.0656f; }
+
 
     float x, y;
 
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 12a9c235..b0945c6 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -267,7 +267,7 @@
             glyph->mCacheTexture);
 }
 
-CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching) {
+CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bool precaching) {
     CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(textUnit);
     if (cachedGlyph) {
         // Is the glyph still in texture cache?
@@ -283,14 +283,14 @@
     return cachedGlyph;
 }
 
-void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, const float* positions) {
     render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
             0, 0, NULL, positions);
 }
 
-void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
-        int numGlyphs, SkPath* path, float hOffset, float vOffset) {
+void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+        int numGlyphs, const SkPath* path, float hOffset, float vOffset) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
         return;
     }
@@ -339,7 +339,7 @@
     }
 }
 
-void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+void Font::measure(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, Rect *bounds, const float* positions) {
     if (bounds == NULL) {
         ALOGE("No return rectangle provided to measure text");
@@ -349,7 +349,7 @@
     render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, positions);
 }
 
-void Font::precache(SkPaint* paint, const char* text, int numGlyphs) {
+void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) {
     ATRACE_NAME("precacheText");
 
     if (numGlyphs == 0 || text == NULL) {
@@ -370,7 +370,7 @@
     }
 }
 
-void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+void Font::render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
         uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
@@ -416,8 +416,8 @@
     }
 }
 
-void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
-        CachedGlyphInfo* glyph, bool precaching) {
+void Font::updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
+        SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching) {
     glyph->mAdvanceX = skiaGlyph.fAdvanceX;
     glyph->mAdvanceY = skiaGlyph.fAdvanceY;
     glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -460,7 +460,7 @@
     }
 }
 
-CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching) {
+CachedGlyphInfo* Font::cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching) {
     CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
     mCachedGlyphs.add(glyph, newGlyph);
 
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index f68b430..02197bc 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -77,11 +77,11 @@
 
     ~Font();
 
-    void render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+    void render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, const float* positions);
 
-    void render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
-            int numGlyphs, SkPath* path, float hOffset, float vOffset);
+    void render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+            int numGlyphs, const SkPath* path, float hOffset, float vOffset);
 
     const Font::FontDescription& getDescription() const {
         return mDescription;
@@ -106,20 +106,20 @@
         MEASURE,
     };
 
-    void precache(SkPaint* paint, const char* text, int numGlyphs);
+    void precache(const SkPaint* paint, const char* text, int numGlyphs);
 
-    void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+    void render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
             uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions);
 
-    void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+    void measure(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
             int numGlyphs, Rect *bounds, const float* positions);
 
     void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
 
-    CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
-    void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
-            CachedGlyphInfo* glyph, bool precaching);
+    CachedGlyphInfo* cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching);
+    void updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
+            SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching);
 
     void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
             uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
@@ -136,7 +136,8 @@
     void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
             SkPathMeasure& measure, SkPoint* position, SkVector* tangent);
 
-    CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching = false);
+    CachedGlyphInfo* getCachedGlyph(const SkPaint* paint, glyph_t textUnit,
+            bool precaching = false);
 
     FontRenderer* mState;
     FontDescription mDescription;
diff --git a/tests/SmokeTest/tests/AndroidManifest.xml b/tests/SmokeTest/tests/AndroidManifest.xml
index cad37c5..f1a0a4c 100644
--- a/tests/SmokeTest/tests/AndroidManifest.xml
+++ b/tests/SmokeTest/tests/AndroidManifest.xml
@@ -27,15 +27,6 @@
     </application>
 
     <!--
-    This declares that this app uses the instrumentation test runner targeting the package of
-    com.android.smoketest.  To run the tests use the command:
-    `adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner`
-    -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="com.android.smoketest"
-                     android:label="System Smoke Tests"/>
-
-    <!--
     This declares a method to run the instrumentation with a special runner, which will run each
     app as a separate testcase.  To do so, use the command:
     `adb shell am instrument -w com.android.smoketest.tests/com.android.smoketest.SmokeTestRunner`
diff --git a/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java b/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java
index 03c2923..946299b 100644
--- a/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java
+++ b/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java
@@ -154,6 +154,11 @@
 
         // launch app, and wait 7 seconds for it to start/settle
         final Intent intent = intentForActivity(app);
+        if (intent == null) {
+            Log.i(TAG, String.format("Activity %s/%s is disabled, skipping",
+                    app.activityInfo.packageName, app.activityInfo.name));
+            return Collections.EMPTY_LIST;
+        }
         getContext().startActivity(intent);
         try {
             Thread.sleep(appLaunchWait);
@@ -238,10 +243,16 @@
     /**
      * A helper function to create an {@link Intent} to run, given a {@link ResolveInfo} specifying
      * an activity to be launched.
+     * 
+     * @return the {@link Intent} or <code>null</code> if given app is disabled
      */
-    static Intent intentForActivity(ResolveInfo app) {
+    Intent intentForActivity(ResolveInfo app) {
         final ComponentName component = new ComponentName(app.activityInfo.packageName,
                 app.activityInfo.name);
+        if (getContext().getPackageManager().getComponentEnabledSetting(component) == 
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+            return null;
+        }
         final Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.setComponent(component);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);