Update Canvas API with view system calls.

Refactor DisplayListCanvas, RecordingCanvas, and SkiaCanvas
to share a common API.

Change-Id: I0268ec2749ea5d13a3a72bb2784ed6a9911383d9
diff --git a/libs/hwui/Canvas.cpp b/libs/hwui/Canvas.cpp
index bc88c81..11ae1a1 100644
--- a/libs/hwui/Canvas.cpp
+++ b/libs/hwui/Canvas.cpp
@@ -16,10 +16,20 @@
 
 #include "Canvas.h"
 
+#include "DisplayListCanvas.h"
+#include "RecordingCanvas.h"
 #include <SkDrawFilter.h>
 
 namespace android {
 
+Canvas* Canvas::create_recording_canvas(int width, int height) {
+#if HWUI_NEW_OPS
+    return new uirenderer::RecordingCanvas(width, height);
+#else
+    return new uirenderer::DisplayListCanvas(width, height);
+#endif
+}
+
 void Canvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) {
     uint32_t flags;
     SkDrawFilter* drawFilter = getDrawFilter();
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index d7e2f09..27facdf 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -18,6 +18,7 @@
 #define ANDROID_GRAPHICS_CANVAS_H
 
 #include <cutils/compiler.h>
+#include <utils/Functor.h>
 
 #include "utils/NinePatch.h"
 
@@ -27,6 +28,14 @@
 
 namespace android {
 
+namespace uirenderer {
+    class CanvasPropertyPaint;
+    class CanvasPropertyPrimitive;
+    class DeferredLayerUpdater;
+    class DisplayList;
+    class RenderNode;
+}
+
 namespace SaveFlags {
 
 // These must match the corresponding Canvas API constants.
@@ -56,6 +65,8 @@
 
     static Canvas* create_canvas(const SkBitmap& bitmap);
 
+    static Canvas* create_recording_canvas(int width, int height);
+
     /**
      *  Create a new Canvas object which delegates to an SkCanvas.
      *
@@ -81,15 +92,36 @@
      */
     virtual SkCanvas* asSkCanvas() = 0;
 
+
     virtual void setBitmap(const SkBitmap& bitmap) = 0;
 
     virtual bool isOpaque() = 0;
     virtual int width() = 0;
     virtual int height() = 0;
 
+// ----------------------------------------------------------------------------
+// View System operations (not exposed in public Canvas API)
+// ----------------------------------------------------------------------------
+
+    virtual void resetRecording(int width, int height) = 0;
+    virtual uirenderer::DisplayList* finishRecording() = 0;
+    virtual void insertReorderBarrier(bool enableReorder) = 0;
+
     virtual void setHighContrastText(bool highContrastText) = 0;
     virtual bool isHighContrastText() = 0;
 
+    virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) = 0;
+    virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
+            uirenderer::CanvasPropertyPrimitive* y, uirenderer::CanvasPropertyPrimitive* radius,
+            uirenderer::CanvasPropertyPaint* paint) = 0;
+
+    virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
+    virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
+    virtual void callDrawGLFunction(Functor* functor) = 0;
+
 // ----------------------------------------------------------------------------
 // Canvas state operations
 // ----------------------------------------------------------------------------
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 5366127..3db14b5 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -42,7 +42,7 @@
     , mDeferredBarrierType(kBarrier_None)
     , mHighContrastText(false)
     , mRestoreSaveCount(-1) {
-    reset(width, height);
+    resetRecording(width, height);
 }
 
 DisplayListCanvas::~DisplayListCanvas() {
@@ -50,7 +50,7 @@
             "Destroyed a DisplayListCanvas during a record!");
 }
 
-void DisplayListCanvas::reset(int width, int height) {
+void DisplayListCanvas::resetRecording(int width, int height) {
     LOG_ALWAYS_FATAL_IF(mDisplayList,
             "prepareDirty called a second time during a recording!");
     mDisplayList = new DisplayList();
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index d41fff4..06e72a0 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -67,36 +67,33 @@
     DisplayListCanvas(int width, int height);
     virtual ~DisplayListCanvas();
 
-    void reset(int width, int height);
-    WARN_UNUSED_RESULT DisplayList* finishRecording();
+    virtual void resetRecording(int width, int height) override;
+    virtual WARN_UNUSED_RESULT DisplayList* finishRecording() override;
 
 // ----------------------------------------------------------------------------
 // HWUI Canvas state operations
 // ----------------------------------------------------------------------------
 
-    void insertReorderBarrier(bool enableReorder);
+    virtual void insertReorderBarrier(bool enableReorder) override;
 
 // ----------------------------------------------------------------------------
 // HWUI Canvas draw operations
 // ----------------------------------------------------------------------------
 
     // Shapes
-    void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+    virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
                 CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
                 CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
-                CanvasPropertyPaint* paint);
-    void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
-                CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
-
+                CanvasPropertyPaint* paint) override;
+    virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+                CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) override;
 
 // ----------------------------------------------------------------------------
 // HWUI Canvas draw operations - special
 // ----------------------------------------------------------------------------
-    void drawLayer(DeferredLayerUpdater* layerHandle);
-    void drawRenderNode(RenderNode* renderNode);
-
-    // TODO: rename for consistency
-    void callDrawGLFunction(Functor* functor);
+    virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
+    virtual void drawRenderNode(RenderNode* renderNode) override;
+    virtual void callDrawGLFunction(Functor* functor) override;
 
 // ----------------------------------------------------------------------------
 // CanvasStateClient interface
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index abbd9c3..16929b8 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -27,7 +27,7 @@
 RecordingCanvas::RecordingCanvas(size_t width, size_t height)
         : mState(*this)
         , mResourceCache(ResourceCache::getInstance()) {
-    reset(width, height);
+    resetRecording(width, height);
 }
 
 RecordingCanvas::~RecordingCanvas() {
@@ -35,7 +35,7 @@
             "Destroyed a RecordingCanvas during a record!");
 }
 
-void RecordingCanvas::reset(int width, int height) {
+void RecordingCanvas::resetRecording(int width, int height) {
     LOG_ALWAYS_FATAL_IF(mDisplayList,
             "prepareDirty called a second time during a recording!");
     mDisplayList = new DisplayList();
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 7c8ad88..cc14e61 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -50,22 +50,19 @@
     RecordingCanvas(size_t width, size_t height);
     virtual ~RecordingCanvas();
 
-    void reset(int width, int height);
-    WARN_UNUSED_RESULT DisplayList* finishRecording();
-
+    virtual void resetRecording(int width, int height) override;
+    virtual WARN_UNUSED_RESULT DisplayList* finishRecording() override;
 // ----------------------------------------------------------------------------
 // MISC HWUI OPERATIONS - TODO: CATEGORIZE
 // ----------------------------------------------------------------------------
-    void insertReorderBarrier(bool enableReorder) {
+    virtual void insertReorderBarrier(bool enableReorder) override {
         mDeferredBarrierType = enableReorder
                 ? DeferredBarrierType::OutOfOrder : DeferredBarrierType::InOrder;
     }
 
-    void drawLayer(DeferredLayerUpdater* layerHandle);
-    void drawRenderNode(RenderNode* renderNode);
-
-    // TODO: rename for consistency
-    void callDrawGLFunction(Functor* functor);
+    virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
+    virtual void drawRenderNode(RenderNode* renderNode) override;
+    virtual void callDrawGLFunction(Functor* functor) override;
 
 // ----------------------------------------------------------------------------
 // CanvasStateClient interface
@@ -78,12 +75,12 @@
 // HWUI Canvas draw operations
 // ----------------------------------------------------------------------------
 
-    void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+    virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
             CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
             CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
-            CanvasPropertyPaint* paint);
-    void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
-            CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
+            CanvasPropertyPaint* paint) override;
+    virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+            CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) override;
 
 // ----------------------------------------------------------------------------
 // android/graphics/Canvas interface
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 550995b..bd4442d 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -15,13 +15,18 @@
  */
 
 #include "Canvas.h"
+#include "CanvasProperty.h"
+#include "Layer.h"
+#include "RenderNode.h"
 
 #include <SkCanvas.h>
 #include <SkClipStack.h>
+#include <SkDrawable.h>
 #include <SkDevice.h>
 #include <SkDeque.h>
 #include <SkDrawFilter.h>
 #include <SkGraphics.h>
+#include <SkImage.h>
 #include <SkShader.h>
 #include <SkTArray.h>
 #include <SkTLazy.h>
@@ -54,6 +59,18 @@
         return mCanvas.get();
     }
 
+    virtual void resetRecording(int width, int height) override {
+        LOG_ALWAYS_FATAL("SkiaCanvas cannot be reset as a recording canvas");
+    }
+
+    virtual uirenderer::DisplayList* finishRecording() override {
+        LOG_ALWAYS_FATAL("SkiaCanvas does not produce a DisplayList");
+        return nullptr;
+    }
+    virtual void insertReorderBarrier(bool enableReorder) override {
+        LOG_ALWAYS_FATAL("SkiaCanvas does not support reordering barriers");
+    }
+
     virtual void setBitmap(const SkBitmap& bitmap) override;
 
     virtual bool isOpaque() override;
@@ -140,6 +157,18 @@
     virtual bool drawTextAbsolutePos() const  override { return true; }
     virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
 
+    virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) override;
+    virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
+            uirenderer::CanvasPropertyPrimitive* y, uirenderer::CanvasPropertyPrimitive* radius,
+            uirenderer::CanvasPropertyPaint* paint) override;
+
+    virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
+    virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
+    virtual void callDrawGLFunction(Functor* functor) override;
+
 private:
     struct SaveRec {
         int              saveCount;
@@ -748,4 +777,84 @@
     mCanvas->drawTextOnPathHV(glyphs, count << 1, path, hOffset, vOffset, paint);
 }
 
+// ----------------------------------------------------------------------------
+// Canvas draw operations: Animations
+// ----------------------------------------------------------------------------
+
+class AnimatedRoundRect : public SkDrawable {
+ public:
+    AnimatedRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* p) :
+            mLeft(left), mTop(top), mRight(right), mBottom(bottom), mRx(rx), mRy(ry), mPaint(p) {}
+
+ protected:
+     virtual SkRect onGetBounds() override {
+         return SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
+     }
+     virtual void onDraw(SkCanvas* canvas) override {
+         SkRect rect = SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
+         canvas->drawRoundRect(rect, mRx->value, mRy->value, mPaint->value);
+     }
+
+ private:
+    sp<uirenderer::CanvasPropertyPrimitive> mLeft;
+    sp<uirenderer::CanvasPropertyPrimitive> mTop;
+    sp<uirenderer::CanvasPropertyPrimitive> mRight;
+    sp<uirenderer::CanvasPropertyPrimitive> mBottom;
+    sp<uirenderer::CanvasPropertyPrimitive> mRx;
+    sp<uirenderer::CanvasPropertyPrimitive> mRy;
+    sp<uirenderer::CanvasPropertyPaint> mPaint;
+};
+
+class AnimatedCircle : public SkDrawable {
+ public:
+    AnimatedCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
+            uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint) :
+            mX(x), mY(y), mRadius(radius), mPaint(paint) {}
+
+ protected:
+     virtual SkRect onGetBounds() override {
+         const float x = mX->value;
+         const float y = mY->value;
+         const float radius = mRadius->value;
+         return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
+     }
+     virtual void onDraw(SkCanvas* canvas) override {
+         canvas->drawCircle(mX->value, mY->value, mRadius->value, mPaint->value);
+     }
+
+ private:
+    sp<uirenderer::CanvasPropertyPrimitive> mX;
+    sp<uirenderer::CanvasPropertyPrimitive> mY;
+    sp<uirenderer::CanvasPropertyPrimitive> mRadius;
+    sp<uirenderer::CanvasPropertyPaint> mPaint;
+};
+
+void SkiaCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+        uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+        uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+        uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
+    SkAutoTUnref<AnimatedRoundRect> drawable(
+            new AnimatedRoundRect(left, top, right, bottom, rx, ry, paint));
+    mCanvas->drawDrawable(drawable.get());
+}
+
+void SkiaCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
+        uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint) {
+    SkAutoTUnref<AnimatedCircle> drawable(new AnimatedCircle(x, y, radius, paint));
+    mCanvas->drawDrawable(drawable.get());
+}
+
+// ----------------------------------------------------------------------------
+// Canvas draw operations: View System
+// ----------------------------------------------------------------------------
+
+void SkiaCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layer) { }
+
+void SkiaCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) { }
+
+void SkiaCanvas::callDrawGLFunction(Functor* functor) { }
+
 } // namespace android
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index 83af148..b317c12 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -63,7 +63,7 @@
 
     StartBenchmarkTiming();
     for (int i = 0; i < iters; ++i) {
-        canvas.reset(100, 100);
+        canvas.resetRecording(100, 100);
         MicroBench::DoNotOptimize(&canvas);
         delete canvas.finishRecording();
     }
@@ -77,7 +77,7 @@
 
     StartBenchmarkTiming();
     for (int i = 0; i < iters; ++i) {
-        canvas.reset(100, 100);
+        canvas.resetRecording(100, 100);
         canvas.save(SaveFlags::MatrixClip);
         canvas.save(SaveFlags::MatrixClip);
         MicroBench::DoNotOptimize(&canvas);
@@ -95,7 +95,7 @@
 
     StartBenchmarkTiming();
     for (int i = 0; i < iters; ++i) {
-        canvas.reset(100, 100);
+        canvas.resetRecording(100, 100);
         canvas.scale(10, 10);
         MicroBench::DoNotOptimize(&canvas);
         delete canvas.finishRecording();
@@ -119,7 +119,7 @@
 
     StartBenchmarkTiming();
     for (int i = 0; i < iters; ++i) {
-        canvas.reset(100, 100);
+        canvas.resetRecording(100, 100);
         {
             canvas.save(SaveFlags::MatrixClip);
             canvas.drawRect(0, 0, 100, 100, rectPaint);