Rework op macros

Makes it simpler to add defer-only or render-only opps.

Change-Id: I6c8ec64e76d419635429055cff6d96360d21706d
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 332a204..097675a 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -302,26 +302,6 @@
     }
 }
 
-void BakedOpDispatcher::onRenderNodeOp(BakedOpRenderer&, const RenderNodeOp&, const BakedOpState&) {
-    LOG_ALWAYS_FATAL("unsupported operation");
-}
-
-void BakedOpDispatcher::onBeginLayerOp(BakedOpRenderer&, const BeginLayerOp&, const BakedOpState&) {
-    LOG_ALWAYS_FATAL("unsupported operation");
-}
-
-void BakedOpDispatcher::onEndLayerOp(BakedOpRenderer&, const EndLayerOp&, const BakedOpState&) {
-    LOG_ALWAYS_FATAL("unsupported operation");
-}
-
-void BakedOpDispatcher::onCirclePropsOp(BakedOpRenderer&, const CirclePropsOp&, const BakedOpState&) {
-    LOG_ALWAYS_FATAL("unsupported operation");
-}
-
-void BakedOpDispatcher::onRoundRectPropsOp(BakedOpRenderer&, const RoundRectPropsOp&, const BakedOpState&) {
-    LOG_ALWAYS_FATAL("unsupported operation");
-}
-
 namespace VertexBufferRenderFlags {
     enum {
         Offset = 0x1,
diff --git a/libs/hwui/BakedOpDispatcher.h b/libs/hwui/BakedOpDispatcher.h
index ed34ada..4dfdd3f 100644
--- a/libs/hwui/BakedOpDispatcher.h
+++ b/libs/hwui/BakedOpDispatcher.h
@@ -36,13 +36,13 @@
     // Declares all "onMergedBitmapOps(...)" style methods for mergeable op types
 #define X(Type) \
         static void onMerged##Type##s(BakedOpRenderer& renderer, const MergedBakedOpList& opList);
-    MAP_MERGED_OPS(X)
+    MAP_MERGEABLE_OPS(X)
 #undef X
 
     // Declares all "onBitmapOp(...)" style methods for every op type
 #define X(Type) \
         static void on##Type(BakedOpRenderer& renderer, const Type& op, const BakedOpState& state);
-    MAP_OPS(X)
+    MAP_RENDERABLE_OPS(X)
 #undef X
 
 };
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index 11b2c8a..3f492d5 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -652,9 +652,7 @@
         [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); },
 void OpReorderer::deferNodeOps(const RenderNode& renderNode) {
     typedef void (*OpDispatcher) (OpReorderer& reorderer, const RecordedOp& op);
-    static OpDispatcher receivers[] = {
-        MAP_OPS(OP_RECEIVER)
-    };
+    static OpDispatcher receivers[] = BUILD_DEFERRABLE_OP_LUT(OP_RECEIVER);
 
     // can't be null, since DL=null node rejection happens before deferNodePropsAndOps
     const DisplayList& displayList = *(renderNode.getDisplayList());
@@ -968,13 +966,5 @@
     }
 }
 
-void OpReorderer::deferLayerOp(const LayerOp& op) {
-    LOG_ALWAYS_FATAL("unsupported");
-}
-
-void OpReorderer::deferShadowOp(const ShadowOp& op) {
-    LOG_ALWAYS_FATAL("unsupported");
-}
-
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/OpReorderer.h b/libs/hwui/OpReorderer.h
index 4e9b5e6..429913f 100644
--- a/libs/hwui/OpReorderer.h
+++ b/libs/hwui/OpReorderer.h
@@ -138,7 +138,7 @@
     template <typename StaticDispatcher, typename Renderer>
     void replayBakedOps(Renderer& renderer) {
         /**
-         * defines a LUT of lambdas which allow a recorded BakedOpState to use state->op->opId to
+         * Defines a LUT of lambdas which allow a recorded BakedOpState to use state->op->opId to
          * dispatch the op via a method on a static dispatcher when the op is replayed.
          *
          * For example a BitmapOp would resolve, via the lambda lookup, to calling:
@@ -149,29 +149,19 @@
                 [](void* renderer, const BakedOpState& state) { \
                     StaticDispatcher::on##Type(*(static_cast<Renderer*>(renderer)), static_cast<const Type&>(*(state.op)), state); \
                 },
-        static BakedOpReceiver unmergedReceivers[] = {
-            MAP_OPS(X)
-        };
+        static BakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X);
         #undef X
 
         /**
-         * defines a LUT of lambdas which allow merged arrays of BakedOpState* to be passed to a
-         * static dispatcher when the group of merged ops is replayed. Unmergeable ops trigger
-         * a LOG_ALWAYS_FATAL().
+         * Defines a LUT of lambdas which allow merged arrays of BakedOpState* to be passed to a
+         * static dispatcher when the group of merged ops is replayed.
          */
         #define X(Type) \
                 [](void* renderer, const MergedBakedOpList& opList) { \
-                    LOG_ALWAYS_FATAL("op type %d does not support merging", opList.states[0]->op->opId); \
-                },
-        #define Y(Type) \
-                [](void* renderer, const MergedBakedOpList& opList) { \
                     StaticDispatcher::onMerged##Type##s(*(static_cast<Renderer*>(renderer)), opList); \
                 },
-        static MergedOpReceiver mergedReceivers[] = {
-            MAP_OPS_BASED_ON_MERGEABILITY(X, Y)
-        };
+        static MergedOpReceiver mergedReceivers[] = BUILD_MERGEABLE_OP_LUT(X);
         #undef X
-        #undef Y
 
         // Relay through layers in reverse order, since layers
         // later in the list will be drawn by earlier ones
@@ -256,9 +246,9 @@
      * These private methods are called from within deferImpl to defer each individual op
      * type differently.
      */
-#define INTERNAL_OP_HANDLER(Type) \
-    void defer##Type(const Type& op);
-    MAP_OPS(INTERNAL_OP_HANDLER)
+#define X(Type) void defer##Type(const Type& op);
+    MAP_DEFERRABLE_OPS(X)
+#undef X
 
     std::vector<std::unique_ptr<SkPath> > mFrameAllocatedPaths;
 
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 1971530..b243f99 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -39,57 +39,84 @@
 struct Vertex;
 
 /**
- * On of the provided macros is executed for each op type in order. The first will be used for ops
- * that cannot merge, and the second for those that can.
+ * Authoritative op list, used for generating the op ID enum, ID based LUTS, and
+ * the functions to which they dispatch. Parameter macros are executed for each op,
+ * in order, based on the op's type.
  *
- * This serves as the authoritative list of ops, used for generating ID enum, and ID based LUTs.
+ * There are 4 types of op:
+ *
+ * Pre render - not directly consumed by renderer, reorder stage resolves this into renderable type
+ * Render only - generated renderable ops - never passed to a reorderer
+ * Unmergeable - reorderable, renderable (but not mergeable)
+ * Mergeable - reorderable, renderable (and mergeable)
  */
-#define MAP_OPS_BASED_ON_MERGEABILITY(U_OP_FN, M_OP_FN) \
-        U_OP_FN(ArcOp) \
-        M_OP_FN(BitmapOp) \
-        U_OP_FN(BitmapMeshOp) \
-        U_OP_FN(BitmapRectOp) \
-        U_OP_FN(CirclePropsOp) \
-        U_OP_FN(FunctorOp) \
-        U_OP_FN(LinesOp) \
-        U_OP_FN(OvalOp) \
-        M_OP_FN(PatchOp) \
-        U_OP_FN(PathOp) \
-        U_OP_FN(PointsOp) \
-        U_OP_FN(RectOp) \
-        U_OP_FN(RenderNodeOp) \
-        U_OP_FN(RoundRectOp) \
-        U_OP_FN(RoundRectPropsOp) \
-        U_OP_FN(ShadowOp) \
-        U_OP_FN(SimpleRectsOp) \
-        M_OP_FN(TextOp) \
-        U_OP_FN(TextOnPathOp) \
-        U_OP_FN(TextureLayerOp) \
-        U_OP_FN(BeginLayerOp) \
-        U_OP_FN(EndLayerOp) \
-        U_OP_FN(LayerOp)
+#define MAP_OPS_BASED_ON_TYPE(PRE_RENDER_OP_FN, RENDER_ONLY_OP_FN, UNMERGEABLE_OP_FN, MERGEABLE_OP_FN) \
+        PRE_RENDER_OP_FN(RenderNodeOp) \
+        PRE_RENDER_OP_FN(CirclePropsOp) \
+        PRE_RENDER_OP_FN(RoundRectPropsOp) \
+        PRE_RENDER_OP_FN(BeginLayerOp) \
+        PRE_RENDER_OP_FN(EndLayerOp) \
+        \
+        RENDER_ONLY_OP_FN(ShadowOp) \
+        RENDER_ONLY_OP_FN(LayerOp) \
+        \
+        UNMERGEABLE_OP_FN(ArcOp) \
+        UNMERGEABLE_OP_FN(BitmapMeshOp) \
+        UNMERGEABLE_OP_FN(BitmapRectOp) \
+        UNMERGEABLE_OP_FN(FunctorOp) \
+        UNMERGEABLE_OP_FN(LinesOp) \
+        UNMERGEABLE_OP_FN(OvalOp) \
+        UNMERGEABLE_OP_FN(PathOp) \
+        UNMERGEABLE_OP_FN(PointsOp) \
+        UNMERGEABLE_OP_FN(RectOp) \
+        UNMERGEABLE_OP_FN(RoundRectOp) \
+        UNMERGEABLE_OP_FN(SimpleRectsOp) \
+        UNMERGEABLE_OP_FN(TextOnPathOp) \
+        UNMERGEABLE_OP_FN(TextureLayerOp) \
+        \
+        MERGEABLE_OP_FN(BitmapOp) \
+        MERGEABLE_OP_FN(PatchOp) \
+        MERGEABLE_OP_FN(TextOp)
 
 /**
- * The provided macro is executed for each op type in order. This is used in cases where
- * merge-ability of ops doesn't matter.
+ * LUT generators, which will insert nullptr for unsupported ops
  */
-#define MAP_OPS(OP_FN) \
-        MAP_OPS_BASED_ON_MERGEABILITY(OP_FN, OP_FN)
+#define NULLPTR_OP_FN(Type) nullptr,
 
+#define BUILD_DEFERRABLE_OP_LUT(OP_FN) \
+        { MAP_OPS_BASED_ON_TYPE(OP_FN, NULLPTR_OP_FN, OP_FN, OP_FN) }
+
+#define BUILD_MERGEABLE_OP_LUT(OP_FN) \
+        { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, NULLPTR_OP_FN, NULLPTR_OP_FN, OP_FN) }
+
+#define BUILD_RENDERABLE_OP_LUT(OP_FN) \
+        { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, OP_FN, OP_FN, OP_FN) }
+
+/**
+ * Op mapping functions, which skip unsupported ops.
+ *
+ * Note: Do not use for LUTS, since these do not preserve ID order.
+ */
 #define NULL_OP_FN(Type)
 
-#define MAP_MERGED_OPS(OP_FN) \
-        MAP_OPS_BASED_ON_MERGEABILITY(NULL_OP_FN, OP_FN)
+#define MAP_MERGEABLE_OPS(OP_FN) \
+        MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, NULL_OP_FN, NULL_OP_FN, OP_FN)
+
+#define MAP_RENDERABLE_OPS(OP_FN) \
+        MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, OP_FN, OP_FN, OP_FN)
+
+#define MAP_DEFERRABLE_OPS(OP_FN) \
+        MAP_OPS_BASED_ON_TYPE(OP_FN, NULL_OP_FN, OP_FN, OP_FN)
 
 // Generate OpId enum
 #define IDENTITY_FN(Type) Type,
 namespace RecordedOpId {
     enum {
-        MAP_OPS(IDENTITY_FN)
+        MAP_OPS_BASED_ON_TYPE(IDENTITY_FN, IDENTITY_FN, IDENTITY_FN, IDENTITY_FN)
         Count,
     };
 }
-static_assert(RecordedOpId::ArcOp == 0,
+static_assert(RecordedOpId::RenderNodeOp == 0,
         "First index must be zero for LUTs to work");
 
 #define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint
diff --git a/libs/hwui/tests/unit/OpReordererTests.cpp b/libs/hwui/tests/unit/OpReordererTests.cpp
index 0d13118..66dccb4 100644
--- a/libs/hwui/tests/unit/OpReordererTests.cpp
+++ b/libs/hwui/tests/unit/OpReordererTests.cpp
@@ -71,7 +71,7 @@
     virtual void on##Type(const Type&, const BakedOpState&) { \
         ADD_FAILURE() << #Type " not expected in this test"; \
     }
-    MAP_OPS(X)
+    MAP_RENDERABLE_OPS(X)
 #undef X
 
     // define virtual defaults for merged draw methods
@@ -79,7 +79,7 @@
     virtual void onMerged##Type##s(const MergedBakedOpList& opList) { \
         ADD_FAILURE() << "Merged " #Type "s not expected in this test"; \
     }
-    MAP_MERGED_OPS(X)
+    MAP_MERGEABLE_OPS(X)
 #undef X
 
     int getIndex() { return mIndex; }
@@ -99,7 +99,7 @@
     static void on##Type(TestRendererBase& renderer, const Type& op, const BakedOpState& state) { \
         renderer.on##Type(op, state); \
     }
-    MAP_OPS(X);
+    MAP_RENDERABLE_OPS(X);
 #undef X
 
     // define merged op methods, which redirect to TestRendererBase
@@ -107,7 +107,7 @@
     static void onMerged##Type##s(TestRendererBase& renderer, const MergedBakedOpList& opList) { \
         renderer.onMerged##Type##s(opList); \
     }
-    MAP_MERGED_OPS(X);
+    MAP_MERGEABLE_OPS(X);
 #undef X
 };