Home | History | Annotate | Download | only in hwui
      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:
    176     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 {
    185     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 {
    206     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 {
    214     BitmapOp(BASE_PARAMS, Bitmap* bitmap) : SUPER(BitmapOp), bitmap(bitmap) {}
    215     Bitmap* bitmap;
    216 };
    217 
    218 struct BitmapMeshOp : RecordedOp {
    219     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 {
    235     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 {
    242     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
    255     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
    266     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 {
    273     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 {
    280     OvalOp(BASE_PARAMS) : SUPER(OvalOp) {}
    281 };
    282 
    283 struct PatchOp : RecordedOp {
    284     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 {
    291     PathOp(BASE_PARAMS, const SkPath* path) : SUPER(PathOp), path(path) {}
    292     const SkPath* path;
    293 };
    294 
    295 struct PointsOp : RecordedOp {
    296     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 {
    303     RectOp(BASE_PARAMS) : SUPER(RectOp) {}
    304 };
    305 
    306 struct RoundRectOp : RecordedOp {
    307     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 {
    313     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 {
    331     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 {
    345     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?)
    354     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 {
    361     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
    378     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 {
    396     TextureLayerOp(BASE_PARAMS_PAINTLESS, DeferredLayerUpdater* layer)
    397             : SUPER_PAINTLESS(TextureLayerOp), layerHandle(layer) {}
    398 
    399     // Copy an existing TextureLayerOp, replacing the underlying matrix
    400     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 {
    416     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 {
    426     EndLayerOp()
    427             : RecordedOp(RecordedOpId::EndLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {}
    428 };
    429 
    430 struct BeginUnclippedLayerOp : RecordedOp {
    431     BeginUnclippedLayerOp(BASE_PARAMS) : SUPER(BeginUnclippedLayerOp) {}
    432 };
    433 
    434 struct EndUnclippedLayerOp : RecordedOp {
    435     EndUnclippedLayerOp()
    436             : RecordedOp(RecordedOpId::EndUnclippedLayerOp, Rect(), Matrix4::identity(), nullptr,
    437                          nullptr) {}
    438 };
    439 
    440 struct CopyToLayerOp : RecordedOp {
    441     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 {
    454     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.
    473     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 
    480     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