1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "GlLayer.h"
20 #include "Matrix.h"
21 #include "Rect.h"
22 #include "RenderNode.h"
23 #include "TessellationCache.h"
24 #include "Vector.h"
25 #include "font/FontUtil.h"
26 #include "utils/LinearAllocator.h"
27 #include "utils/PaintUtils.h"
28 
29 #include <androidfw/ResourceTypes.h>
30 
31 class SkBitmap;
32 class SkPaint;
33 
34 namespace android {
35 namespace uirenderer {
36 
37 struct ClipBase;
38 class OffscreenBuffer;
39 class RenderNode;
40 class DeferredLayerUpdater;
41 
42 struct Vertex;
43 
44 namespace VectorDrawable {
45 class Tree;
46 }
47 
48 /**
49  * Authoritative op list, used for generating the op ID enum, ID based LUTS, and
50  * the functions to which they dispatch. Parameter macros are executed for each op,
51  * in order, based on the op's type.
52  *
53  * There are 4 types of op, which defines dispatch/LUT capability:
54  *
55  *              | DisplayList |   Render    |    Merge    |
56  * -------------|-------------|-------------|-------------|
57  * PRE RENDER   |     Yes     |             |             |
58  * RENDER ONLY  |             |     Yes     |             |
59  * UNMERGEABLE  |     Yes     |     Yes     |             |
60  * MERGEABLE    |     Yes     |     Yes     |     Yes     |
61  *
62  * PRE RENDER - These ops are recorded into DisplayLists, but can't be directly rendered. This
63  *      may be because they need to be transformed into other op types (e.g. CirclePropsOp),
64  *      be traversed to access multiple renderable ops within (e.g. RenderNodeOp), or because they
65  *      modify renderbuffer lifecycle, instead of directly rendering content (the various LayerOps).
66  *
67  * RENDER ONLY - These ops cannot be recorded into DisplayLists, and are instead implicitly
68  *      constructed from other commands/RenderNode properties. They cannot be merged.
69  *
70  * UNMERGEABLE - These ops can be recorded into DisplayLists and rendered directly, but do not
71  *      support merged rendering.
72  *
73  * MERGEABLE - These ops can be recorded into DisplayLists and rendered individually, or merged
74  *      under certain circumstances.
75  */
76 #define MAP_OPS_BASED_ON_TYPE(PRE_RENDER_OP_FN, RENDER_ONLY_OP_FN, UNMERGEABLE_OP_FN, \
77                               MERGEABLE_OP_FN)                                        \
78     PRE_RENDER_OP_FN(RenderNodeOp)                                                    \
79     PRE_RENDER_OP_FN(CirclePropsOp)                                                   \
80     PRE_RENDER_OP_FN(RoundRectPropsOp)                                                \
81     PRE_RENDER_OP_FN(BeginLayerOp)                                                    \
82     PRE_RENDER_OP_FN(EndLayerOp)                                                      \
83     PRE_RENDER_OP_FN(BeginUnclippedLayerOp)                                           \
84     PRE_RENDER_OP_FN(EndUnclippedLayerOp)                                             \
85     PRE_RENDER_OP_FN(VectorDrawableOp)                                                \
86                                                                                       \
87     RENDER_ONLY_OP_FN(ShadowOp)                                                       \
88     RENDER_ONLY_OP_FN(LayerOp)                                                        \
89     RENDER_ONLY_OP_FN(CopyToLayerOp)                                                  \
90     RENDER_ONLY_OP_FN(CopyFromLayerOp)                                                \
91                                                                                       \
92     UNMERGEABLE_OP_FN(ArcOp)                                                          \
93     UNMERGEABLE_OP_FN(BitmapMeshOp)                                                   \
94     UNMERGEABLE_OP_FN(BitmapRectOp)                                                   \
95     UNMERGEABLE_OP_FN(ColorOp)                                                        \
96     UNMERGEABLE_OP_FN(FunctorOp)                                                      \
97     UNMERGEABLE_OP_FN(LinesOp)                                                        \
98     UNMERGEABLE_OP_FN(OvalOp)                                                         \
99     UNMERGEABLE_OP_FN(PathOp)                                                         \
100     UNMERGEABLE_OP_FN(PointsOp)                                                       \
101     UNMERGEABLE_OP_FN(RectOp)                                                         \
102     UNMERGEABLE_OP_FN(RoundRectOp)                                                    \
103     UNMERGEABLE_OP_FN(SimpleRectsOp)                                                  \
104     UNMERGEABLE_OP_FN(TextOnPathOp)                                                   \
105     UNMERGEABLE_OP_FN(TextureLayerOp)                                                 \
106                                                                                       \
107     MERGEABLE_OP_FN(BitmapOp)                                                         \
108     MERGEABLE_OP_FN(PatchOp)                                                          \
109     MERGEABLE_OP_FN(TextOp)
110 
111 /**
112  * LUT generators, which will insert nullptr for unsupported ops
113  */
114 #define NULLPTR_OP_FN(Type) nullptr,
115 
116 #define BUILD_DEFERRABLE_OP_LUT(OP_FN) \
117     { MAP_OPS_BASED_ON_TYPE(OP_FN, NULLPTR_OP_FN, OP_FN, OP_FN) }
118 
119 #define BUILD_MERGEABLE_OP_LUT(OP_FN) \
120     { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, NULLPTR_OP_FN, NULLPTR_OP_FN, OP_FN) }
121 
122 #define BUILD_RENDERABLE_OP_LUT(OP_FN) \
123     { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, OP_FN, OP_FN, OP_FN) }
124 
125 #define BUILD_FULL_OP_LUT(OP_FN) \
126     { MAP_OPS_BASED_ON_TYPE(OP_FN, OP_FN, OP_FN, OP_FN) }
127 
128 /**
129  * Op mapping functions, which skip unsupported ops.
130  *
131  * Note: Do not use for LUTS, since these do not preserve ID order.
132  */
133 #define NULL_OP_FN(Type)
134 
135 #define MAP_DEFERRABLE_OPS(OP_FN) MAP_OPS_BASED_ON_TYPE(OP_FN, NULL_OP_FN, OP_FN, OP_FN)
136 
137 #define MAP_MERGEABLE_OPS(OP_FN) MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, NULL_OP_FN, NULL_OP_FN, OP_FN)
138 
139 #define MAP_RENDERABLE_OPS(OP_FN) MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, OP_FN, OP_FN, OP_FN)
140 
141 // Generate OpId enum
142 #define IDENTITY_FN(Type) Type,
143 namespace RecordedOpId {
144 enum {
145     MAP_OPS_BASED_ON_TYPE(IDENTITY_FN, IDENTITY_FN, IDENTITY_FN, IDENTITY_FN) Count,
146 };
147 }
148 static_assert(RecordedOpId::RenderNodeOp == 0, "First index must be zero for LUTs to work");
149 
150 #define BASE_PARAMS                                                                    \
151     const Rect &unmappedBounds, const Matrix4 &localMatrix, const ClipBase *localClip, \
152             const SkPaint *paint
153 #define BASE_PARAMS_PAINTLESS \
154     const Rect &unmappedBounds, const Matrix4 &localMatrix, const ClipBase *localClip
155 #define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, paint)
156 #define SUPER_PAINTLESS(Type) \
157     RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, nullptr)
158 
159 struct RecordedOp {
160     /* ID from RecordedOpId - generally used for jumping into function tables */
161     const int opId;
162 
163     /* bounds in *local* space, without accounting for DisplayList transformation, or stroke */
164     const Rect unmappedBounds;
165 
166     /* transform in recording space (vs DisplayList origin) */
167     const Matrix4 localMatrix;
168 
169     /* clip in recording space - nullptr if not clipped */
170     const ClipBase* localClip;
171 
172     /* optional paint, stored in base object to simplify merging logic */
173     const SkPaint* paint;
174 
175 protected:
RecordedOpRecordedOp176     RecordedOp(unsigned int opId, BASE_PARAMS)
177             : opId(opId)
178             , unmappedBounds(unmappedBounds)
179             , localMatrix(localMatrix)
180             , localClip(localClip)
181             , paint(paint) {}
182 };
183 
184 struct RenderNodeOp : RecordedOp {
RenderNodeOpRenderNodeOp185     RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode)
186             : SUPER_PAINTLESS(RenderNodeOp), renderNode(renderNode) {}
187     RenderNode* renderNode;  // not const, since drawing modifies it
188 
189     /**
190      * Holds the transformation between the projection surface ViewGroup and this RenderNode
191      * drawing instance. Represents any translations / transformations done within the drawing of
192      * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this
193      * DisplayList draw instance.
194      *
195      * Note: doesn't include transformation within the RenderNode, or its properties.
196      */
197     Matrix4 transformFromCompositingAncestor;
198     bool skipInOrderDraw = false;
199 };
200 
201 ////////////////////////////////////////////////////////////////////////////////////////////////////
202 // Standard Ops
203 ////////////////////////////////////////////////////////////////////////////////////////////////////
204 
205 struct ArcOp : RecordedOp {
ArcOpArcOp206     ArcOp(BASE_PARAMS, float startAngle, float sweepAngle, bool useCenter)
207             : SUPER(ArcOp), startAngle(startAngle), sweepAngle(sweepAngle), useCenter(useCenter) {}
208     const float startAngle;
209     const float sweepAngle;
210     const bool useCenter;
211 };
212 
213 struct BitmapOp : RecordedOp {
BitmapOpBitmapOp214     BitmapOp(BASE_PARAMS, Bitmap* bitmap) : SUPER(BitmapOp), bitmap(bitmap) {}
215     Bitmap* bitmap;
216 };
217 
218 struct BitmapMeshOp : RecordedOp {
BitmapMeshOpBitmapMeshOp219     BitmapMeshOp(BASE_PARAMS, Bitmap* bitmap, int meshWidth, int meshHeight, const float* vertices,
220                  const int* colors)
221             : SUPER(BitmapMeshOp)
222             , bitmap(bitmap)
223             , meshWidth(meshWidth)
224             , meshHeight(meshHeight)
225             , vertices(vertices)
226             , colors(colors) {}
227     Bitmap* bitmap;
228     const int meshWidth;
229     const int meshHeight;
230     const float* vertices;
231     const int* colors;
232 };
233 
234 struct BitmapRectOp : RecordedOp {
BitmapRectOpBitmapRectOp235     BitmapRectOp(BASE_PARAMS, Bitmap* bitmap, const Rect& src)
236             : SUPER(BitmapRectOp), bitmap(bitmap), src(src) {}
237     Bitmap* bitmap;
238     const Rect src;
239 };
240 
241 struct CirclePropsOp : RecordedOp {
CirclePropsOpCirclePropsOp242     CirclePropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
243                   float* x, float* y, float* radius)
244             : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClip, paint)
245             , x(x)
246             , y(y)
247             , radius(radius) {}
248     const float* x;
249     const float* y;
250     const float* radius;
251 };
252 
253 struct ColorOp : RecordedOp {
254     // Note: unbounded op that will fillclip, so no bounds/matrix needed
ColorOpColorOp255     ColorOp(const ClipBase* localClip, int color, SkBlendMode mode)
256             : RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr)
257             , color(color)
258             , mode(mode) {}
259     const int color;
260     const SkBlendMode mode;
261 };
262 
263 struct FunctorOp : RecordedOp {
264     // Note: undefined record-time bounds, since this op fills the clip
265     // TODO: explicitly define bounds
FunctorOpFunctorOp266     FunctorOp(const Matrix4& localMatrix, const ClipBase* localClip, Functor* functor)
267             : RecordedOp(RecordedOpId::FunctorOp, Rect(), localMatrix, localClip, nullptr)
268             , functor(functor) {}
269     Functor* functor;
270 };
271 
272 struct LinesOp : RecordedOp {
LinesOpLinesOp273     LinesOp(BASE_PARAMS, const float* points, const int floatCount)
274             : SUPER(LinesOp), points(points), floatCount(floatCount) {}
275     const float* points;
276     const int floatCount;
277 };
278 
279 struct OvalOp : RecordedOp {
OvalOpOvalOp280     OvalOp(BASE_PARAMS) : SUPER(OvalOp) {}
281 };
282 
283 struct PatchOp : RecordedOp {
PatchOpPatchOp284     PatchOp(BASE_PARAMS, Bitmap* bitmap, const Res_png_9patch* patch)
285             : SUPER(PatchOp), bitmap(bitmap), patch(patch) {}
286     Bitmap* bitmap;
287     const Res_png_9patch* patch;
288 };
289 
290 struct PathOp : RecordedOp {
PathOpPathOp291     PathOp(BASE_PARAMS, const SkPath* path) : SUPER(PathOp), path(path) {}
292     const SkPath* path;
293 };
294 
295 struct PointsOp : RecordedOp {
PointsOpPointsOp296     PointsOp(BASE_PARAMS, const float* points, const int floatCount)
297             : SUPER(PointsOp), points(points), floatCount(floatCount) {}
298     const float* points;
299     const int floatCount;
300 };
301 
302 struct RectOp : RecordedOp {
RectOpRectOp303     RectOp(BASE_PARAMS) : SUPER(RectOp) {}
304 };
305 
306 struct RoundRectOp : RecordedOp {
RoundRectOpRoundRectOp307     RoundRectOp(BASE_PARAMS, float rx, float ry) : SUPER(RoundRectOp), rx(rx), ry(ry) {}
308     const float rx;
309     const float ry;
310 };
311 
312 struct RoundRectPropsOp : RecordedOp {
RoundRectPropsOpRoundRectPropsOp313     RoundRectPropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
314                      float* left, float* top, float* right, float* bottom, float* rx, float* ry)
315             : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClip, paint)
316             , left(left)
317             , top(top)
318             , right(right)
319             , bottom(bottom)
320             , rx(rx)
321             , ry(ry) {}
322     const float* left;
323     const float* top;
324     const float* right;
325     const float* bottom;
326     const float* rx;
327     const float* ry;
328 };
329 
330 struct VectorDrawableOp : RecordedOp {
VectorDrawableOpVectorDrawableOp331     VectorDrawableOp(VectorDrawable::Tree* tree, BASE_PARAMS_PAINTLESS)
332             : SUPER_PAINTLESS(VectorDrawableOp), vectorDrawable(tree) {}
333     VectorDrawable::Tree* vectorDrawable;
334 };
335 
336 /**
337  * Real-time, dynamic-lit shadow.
338  *
339  * Uses invalid/empty bounds and matrix since ShadowOp bounds aren't known at defer time,
340  * and are resolved dynamically, and transform isn't needed.
341  *
342  * State construction handles these properties specially, ignoring matrix/bounds.
343  */
344 struct ShadowOp : RecordedOp {
ShadowOpShadowOp345     ShadowOp(sp<TessellationCache::ShadowTask>& shadowTask, float casterAlpha)
346             : RecordedOp(RecordedOpId::ShadowOp, Rect(), Matrix4::identity(), nullptr, nullptr)
347             , shadowTask(shadowTask)
348             , casterAlpha(casterAlpha){};
349     sp<TessellationCache::ShadowTask> shadowTask;
350     const float casterAlpha;
351 };
352 
353 struct SimpleRectsOp : RecordedOp {  // Filled, no AA (TODO: better name?)
SimpleRectsOpSimpleRectsOp354     SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
355             : SUPER(SimpleRectsOp), vertices(vertices), vertexCount(vertexCount) {}
356     Vertex* vertices;
357     const size_t vertexCount;
358 };
359 
360 struct TextOp : RecordedOp {
TextOpTextOp361     TextOp(BASE_PARAMS, const glyph_t* glyphs, const float* positions, int glyphCount, float x,
362            float y)
363             : SUPER(TextOp)
364             , glyphs(glyphs)
365             , positions(positions)
366             , glyphCount(glyphCount)
367             , x(x)
368             , y(y) {}
369     const glyph_t* glyphs;
370     const float* positions;
371     const int glyphCount;
372     const float x;
373     const float y;
374 };
375 
376 struct TextOnPathOp : RecordedOp {
377     // TODO: explicitly define bounds
TextOnPathOpTextOnPathOp378     TextOnPathOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
379                  const glyph_t* glyphs, int glyphCount, const SkPath* path, float hOffset,
380                  float vOffset)
381             : RecordedOp(RecordedOpId::TextOnPathOp, Rect(), localMatrix, localClip, paint)
382             , glyphs(glyphs)
383             , glyphCount(glyphCount)
384             , path(path)
385             , hOffset(hOffset)
386             , vOffset(vOffset) {}
387     const glyph_t* glyphs;
388     const int glyphCount;
389 
390     const SkPath* path;
391     const float hOffset;
392     const float vOffset;
393 };
394 
395 struct TextureLayerOp : RecordedOp {
TextureLayerOpTextureLayerOp396     TextureLayerOp(BASE_PARAMS_PAINTLESS, DeferredLayerUpdater* layer)
397             : SUPER_PAINTLESS(TextureLayerOp), layerHandle(layer) {}
398 
399     // Copy an existing TextureLayerOp, replacing the underlying matrix
TextureLayerOpTextureLayerOp400     TextureLayerOp(const TextureLayerOp& op, const Matrix4& replacementMatrix)
401             : RecordedOp(RecordedOpId::TextureLayerOp, op.unmappedBounds, replacementMatrix,
402                          op.localClip, op.paint)
403             , layerHandle(op.layerHandle) {}
404     DeferredLayerUpdater* layerHandle;
405 };
406 
407 ////////////////////////////////////////////////////////////////////////////////////////////////////
408 // Layers
409 ////////////////////////////////////////////////////////////////////////////////////////////////////
410 
411 /**
412  * Stateful operation! denotes the creation of an off-screen layer,
413  * and that commands following will render into it.
414  */
415 struct BeginLayerOp : RecordedOp {
BeginLayerOpBeginLayerOp416     BeginLayerOp(BASE_PARAMS) : SUPER(BeginLayerOp) {}
417 };
418 
419 /**
420  * Stateful operation! Denotes end of off-screen layer, and that
421  * commands since last BeginLayerOp should be drawn into parent FBO.
422  *
423  * State in this op is empty, it just serves to signal that a layer has been finished.
424  */
425 struct EndLayerOp : RecordedOp {
EndLayerOpEndLayerOp426     EndLayerOp()
427             : RecordedOp(RecordedOpId::EndLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {}
428 };
429 
430 struct BeginUnclippedLayerOp : RecordedOp {
BeginUnclippedLayerOpBeginUnclippedLayerOp431     BeginUnclippedLayerOp(BASE_PARAMS) : SUPER(BeginUnclippedLayerOp) {}
432 };
433 
434 struct EndUnclippedLayerOp : RecordedOp {
EndUnclippedLayerOpEndUnclippedLayerOp435     EndUnclippedLayerOp()
436             : RecordedOp(RecordedOpId::EndUnclippedLayerOp, Rect(), Matrix4::identity(), nullptr,
437                          nullptr) {}
438 };
439 
440 struct CopyToLayerOp : RecordedOp {
CopyToLayerOpCopyToLayerOp441     CopyToLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle)
442             : RecordedOp(RecordedOpId::CopyToLayerOp, op.unmappedBounds, op.localMatrix,
443                          nullptr,  // clip intentionally ignored
444                          op.paint)
445             , layerHandle(layerHandle) {}
446 
447     // Records a handle to the Layer object, since the Layer itself won't be
448     // constructed until after this operation is constructed.
449     OffscreenBuffer** layerHandle;
450 };
451 
452 // draw the parameter layer underneath
453 struct CopyFromLayerOp : RecordedOp {
CopyFromLayerOpCopyFromLayerOp454     CopyFromLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle)
455             : RecordedOp(RecordedOpId::CopyFromLayerOp, op.unmappedBounds, op.localMatrix,
456                          nullptr,  // clip intentionally ignored
457                          op.paint)
458             , layerHandle(layerHandle) {}
459 
460     // Records a handle to the Layer object, since the Layer itself won't be
461     // constructed until after this operation is constructed.
462     OffscreenBuffer** layerHandle;
463 };
464 
465 /**
466  * Draws an OffscreenBuffer.
467  *
468  * Alpha, mode, and colorfilter are embedded, since LayerOps are always dynamically generated,
469  * when creating/tracking a SkPaint* during defer isn't worth the bother.
470  */
471 struct LayerOp : RecordedOp {
472     // Records a one-use (saveLayer) layer for drawing.
LayerOpLayerOp473     LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle)
474             : SUPER_PAINTLESS(LayerOp)
475             , layerHandle(layerHandle)
476             , alpha(paint ? paint->getAlpha() / 255.0f : 1.0f)
477             , mode(PaintUtils::getBlendModeDirect(paint))
478             , colorFilter(paint ? paint->getColorFilter() : nullptr) {}
479 
LayerOpLayerOp480     explicit LayerOp(RenderNode& node)
481             : RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()),
482                          Matrix4::identity(), nullptr, nullptr)
483             , layerHandle(node.getLayerHandle())
484             , alpha(node.properties().layerProperties().alpha() / 255.0f)
485             , mode(node.properties().layerProperties().xferMode())
486             , colorFilter(node.properties().layerProperties().colorFilter()) {}
487 
488     // Records a handle to the Layer object, since the Layer itself won't be
489     // constructed until after this operation is constructed.
490     OffscreenBuffer** layerHandle;
491     const float alpha;
492     const SkBlendMode mode;
493 
494     // pointer to object owned by either LayerProperties, or a recorded Paint object in a
495     // BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used.
496     SkColorFilter* colorFilter;
497 };
498 
499 };  // namespace uirenderer
500 };  // namespace android
501