Only copy paths, paints and shaders when we need to.

Change-Id: Iba7a9c92c865f698821b6ff7bc4f502659642ac1
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 6dd47be..90a7145 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -462,7 +462,8 @@
         SkPath* pathCopy = mPathMap.valueFor(path);
         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
             pathCopy = new SkPath(*path);
-            mPathMap.add(path, pathCopy);
+            // replaceValueFor() performs an add if the entry doesn't exist
+            mPathMap.replaceValueFor(path, pathCopy);
             mPaths.add(pathCopy);
         }
 
@@ -478,7 +479,8 @@
         SkPaint* paintCopy = mPaintMap.valueFor(paint);
         if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
             paintCopy = new SkPaint(*paint);
-            mPaintMap.add(paint, paintCopy);
+            // replaceValueFor() performs an add if the entry doesn't exist
+            mPaintMap.replaceValueFor(paint, paintCopy);
             mPaints.add(paintCopy);
         }
 
@@ -520,7 +522,8 @@
         // TODO: We also need to handle generation ID changes in compose shaders
         if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
             shaderCopy = shader->copy();
-            mShaderMap.add(shader, shaderCopy);
+            // replaceValueFor() performs an add if the entry doesn't exist
+            mShaderMap.replaceValueFor(shader, shaderCopy);
             mShaders.add(shaderCopy);
             Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
         }
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 3904c21..ed78daa3 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -568,6 +568,15 @@
         </activity>
 
         <activity
+                android:name="PathsCacheActivity"
+                android:label="_PathsCache">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="PointsActivity"
                 android:label="_Points">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
new file mode 100644
index 0000000..b8ad823
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class PathsCacheActivity extends Activity {
+    private Path mPath;
+
+    private final Random mRandom = new Random();
+    private final ArrayList<Path> mPathList = new ArrayList<Path>();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mPath = makePath();
+
+        final PathsView view = new PathsView(this);
+        setContentView(view);
+    }
+
+    private Path makePath() {
+        Path path = new Path();
+        buildPath(path);
+        return path;
+    }
+
+    private void buildPath(Path path) {
+        path.moveTo(0.0f, 0.0f);
+        path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f);
+        path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f);
+        path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f);
+    }
+
+    public class PathsView extends View {
+        private final Paint mMediumPaint;
+
+        public PathsView(Context c) {
+            super(c);
+
+            mMediumPaint = new Paint();
+            mMediumPaint.setAntiAlias(true);
+            mMediumPaint.setColor(0xe00000ff);
+            mMediumPaint.setStrokeWidth(10.0f);
+            mMediumPaint.setStyle(Paint.Style.STROKE);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            
+            Log.d("OpenGLRenderer", "Start frame");
+
+            canvas.drawARGB(255, 255, 255, 255);
+
+            canvas.save();
+            canvas.translate(550.0f, 60.0f);
+            canvas.drawPath(mPath, mMediumPaint);
+
+            mPath.reset();
+            buildPath(mPath);
+
+            canvas.translate(30.0f, 30.0f);
+            canvas.drawPath(mPath, mMediumPaint);
+            canvas.drawPath(mPath, mMediumPaint);
+
+            canvas.restore();
+
+//            Path path = makePath();
+//            int r = mRandom.nextInt(10);
+//            if (r == 5 || r == 3) {
+//                mPathList.add(path);
+//            } else if (r == 9) {
+//                mPathList.clear();
+//            }
+//
+//            canvas.save();
+//            canvas.translate(550.0f + mRandom.nextInt(50), 60.0f + mRandom.nextInt(50));
+//            canvas.drawPath(path, mMediumPaint);
+//            canvas.restore();
+//            
+            invalidate();
+        }
+    }
+}