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 "font/FontUtil.h"
     20 #include "GlLayer.h"
     21 #include "Matrix.h"
     22 #include "Rect.h"
     23 #include "RenderNode.h"
     24 #include "TessellationCache.h"
     25 #include "utils/LinearAllocator.h"
     26 #include "utils/PaintUtils.h"
     27 #include "Vector.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, MERGEABLE_OP_FN) \
     77         PRE_RENDER_OP_FN(RenderNodeOp) \
     78         PRE_RENDER_OP_FN(CirclePropsOp) \
     79         PRE_RENDER_OP_FN(RoundRectPropsOp) \
     80         PRE_RENDER_OP_FN(BeginLayerOp) \
     81         PRE_RENDER_OP_FN(EndLayerOp) \
     82         PRE_RENDER_OP_FN(BeginUnclippedLayerOp) \
     83         PRE_RENDER_OP_FN(EndUnclippedLayerOp) \
     84         PRE_RENDER_OP_FN(VectorDrawableOp) \
     85         \
     86         RENDER_ONLY_OP_FN(ShadowOp) \
     87         RENDER_ONLY_OP_FN(LayerOp) \
     88         RENDER_ONLY_OP_FN(CopyToLayerOp) \
     89         RENDER_ONLY_OP_FN(CopyFromLayerOp) \
     90         \
     91         UNMERGEABLE_OP_FN(ArcOp) \
     92         UNMERGEABLE_OP_FN(BitmapMeshOp) \
     93         UNMERGEABLE_OP_FN(BitmapRectOp) \
     94         UNMERGEABLE_OP_FN(ColorOp) \
     95         UNMERGEABLE_OP_FN(FunctorOp) \
     96         UNMERGEABLE_OP_FN(LinesOp) \
     97         UNMERGEABLE_OP_FN(OvalOp) \
     98         UNMERGEABLE_OP_FN(PathOp) \
     99         UNMERGEABLE_OP_FN(PointsOp) \
    100         UNMERGEABLE_OP_FN(RectOp) \
    101         UNMERGEABLE_OP_FN(RoundRectOp) \
    102         UNMERGEABLE_OP_FN(SimpleRectsOp) \
    103         UNMERGEABLE_OP_FN(TextOnPathOp) \
    104         UNMERGEABLE_OP_FN(TextureLayerOp) \
    105         \
    106         MERGEABLE_OP_FN(BitmapOp) \
    107         MERGEABLE_OP_FN(PatchOp) \
    108         MERGEABLE_OP_FN(TextOp)
    109 
    110 /**
    111  * LUT generators, which will insert nullptr for unsupported ops
    112  */
    113 #define NULLPTR_OP_FN(Type) nullptr,
    114 
    115 #define BUILD_DEFERRABLE_OP_LUT(OP_FN) \
    116         { MAP_OPS_BASED_ON_TYPE(OP_FN, NULLPTR_OP_FN, OP_FN, OP_FN) }
    117 
    118 #define BUILD_MERGEABLE_OP_LUT(OP_FN) \
    119         { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, NULLPTR_OP_FN, NULLPTR_OP_FN, OP_FN) }
    120 
    121 #define BUILD_RENDERABLE_OP_LUT(OP_FN) \
    122         { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, OP_FN, OP_FN, OP_FN) }
    123 
    124 #define BUILD_FULL_OP_LUT(OP_FN) \
    125         { MAP_OPS_BASED_ON_TYPE(OP_FN, OP_FN, OP_FN, OP_FN) }
    126 
    127 /**
    128  * Op mapping functions, which skip unsupported ops.
    129  *
    130  * Note: Do not use for LUTS, since these do not preserve ID order.
    131  */
    132 #define NULL_OP_FN(Type)
    133 
    134 #define MAP_DEFERRABLE_OPS(OP_FN) \
    135         MAP_OPS_BASED_ON_TYPE(OP_FN, NULL_OP_FN, OP_FN, OP_FN)
    136 
    137 #define MAP_MERGEABLE_OPS(OP_FN) \
    138         MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, NULL_OP_FN, NULL_OP_FN, OP_FN)
    139 
    140 #define MAP_RENDERABLE_OPS(OP_FN) \
    141         MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, OP_FN, OP_FN, OP_FN)
    142 
    143 // Generate OpId enum
    144 #define IDENTITY_FN(Type) Type,
    145 namespace RecordedOpId {
    146     enum {
    147         MAP_OPS_BASED_ON_TYPE(IDENTITY_FN, IDENTITY_FN, IDENTITY_FN, IDENTITY_FN)
    148         Count,
    149     };
    150 }
    151 static_assert(RecordedOpId::RenderNodeOp == 0,
    152         "First index must be zero for LUTs to work");
    153 
    154 #define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint
    155 #define BASE_PARAMS_PAINTLESS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip
    156 #define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, paint)
    157 #define SUPER_PAINTLESS(Type) 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 protected:
    175     RecordedOp(unsigned int opId, BASE_PARAMS)
    176             : opId(opId)
    177             , unmappedBounds(unmappedBounds)
    178             , localMatrix(localMatrix)
    179             , localClip(localClip)
    180             , paint(paint) {}
    181 };
    182 
    183 struct RenderNodeOp : RecordedOp {
    184     RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode)
    185             : SUPER_PAINTLESS(RenderNodeOp)
    186             , 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)
    208             , startAngle(startAngle)
    209             , sweepAngle(sweepAngle)
    210             , useCenter(useCenter) {}
    211     const float startAngle;
    212     const float sweepAngle;
    213     const bool useCenter;
    214 };
    215 
    216 struct BitmapOp : RecordedOp {
    217     BitmapOp(BASE_PARAMS, Bitmap* bitmap)
    218             : SUPER(BitmapOp)
    219             , bitmap(bitmap) {}
    220     Bitmap* bitmap;
    221 };
    222 
    223 struct BitmapMeshOp : RecordedOp {
    224     BitmapMeshOp(BASE_PARAMS, Bitmap* 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     Bitmap* 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, Bitmap* bitmap, const Rect& src)
    241             : SUPER(BitmapRectOp)
    242             , bitmap(bitmap)
    243             , src(src) {}
    244     Bitmap* 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, SkBlendMode mode)
    263             : RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr)
    264             , color(color)
    265             , mode(mode) {}
    266     const int color;
    267     const SkBlendMode 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, Bitmap* bitmap, const Res_png_9patch* patch)
    295             : SUPER(PatchOp)
    296             , bitmap(bitmap)
    297             , patch(patch) {}
    298     Bitmap* 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, DeferredLayerUpdater* layer)
    420             : SUPER_PAINTLESS(TextureLayerOp)
    421             , layerHandle(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             , layerHandle(op.layerHandle) {
    428 
    429     }
    430     DeferredLayerUpdater* layerHandle;
    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::getBlendModeDirect(paint))
    510             , colorFilter(paint ? paint->getColorFilter() : nullptr) {}
    511 
    512     explicit 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 SkBlendMode 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