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