RecordedOp.h revision 0b7e8245db728d127ada698be63d78b33fc6e4da
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 "utils/LinearAllocator.h"
21#include "Rect.h"
22#include "Matrix.h"
23#include "RenderNode.h"
24
25#include "SkXfermode.h"
26
27class SkBitmap;
28class SkPaint;
29
30namespace android {
31namespace uirenderer {
32
33class OffscreenBuffer;
34class RenderNode;
35struct Vertex;
36
37/**
38 * The provided macro is executed for each op type in order, with the results separated by commas.
39 *
40 * This serves as the authoritative list of ops, used for generating ID enum, and ID based LUTs.
41 */
42#define MAP_OPS(OP_FN) \
43        OP_FN(BitmapOp) \
44        OP_FN(RectOp) \
45        OP_FN(RenderNodeOp) \
46        OP_FN(SimpleRectsOp) \
47        OP_FN(BeginLayerOp) \
48        OP_FN(EndLayerOp) \
49        OP_FN(LayerOp)
50
51// Generate OpId enum
52#define IDENTITY_FN(Type) Type,
53namespace RecordedOpId {
54    enum {
55        MAP_OPS(IDENTITY_FN)
56        Count,
57    };
58}
59static_assert(RecordedOpId::BitmapOp == 0,
60        "First index must be zero for LUTs to work");
61
62#define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint
63#define BASE_PARAMS_PAINTLESS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect
64#define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClipRect, paint)
65#define SUPER_PAINTLESS(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClipRect, nullptr)
66
67struct RecordedOp {
68    /* ID from RecordedOpId - generally used for jumping into function tables */
69    const int opId;
70
71    /* bounds in *local* space, without accounting for DisplayList transformation */
72    const Rect unmappedBounds;
73
74    /* transform in recording space (vs DisplayList origin) */
75    const Matrix4 localMatrix;
76
77    /* clip in recording space */
78    const Rect localClipRect;
79
80    /* optional paint, stored in base object to simplify merging logic */
81    const SkPaint* paint;
82protected:
83    RecordedOp(unsigned int opId, BASE_PARAMS)
84            : opId(opId)
85            , unmappedBounds(unmappedBounds)
86            , localMatrix(localMatrix)
87            , localClipRect(localClipRect)
88            , paint(paint) {}
89};
90
91struct RenderNodeOp : RecordedOp {
92    RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode)
93            : SUPER_PAINTLESS(RenderNodeOp)
94            , renderNode(renderNode) {}
95    RenderNode * renderNode; // not const, since drawing modifies it (somehow...)
96};
97
98struct BitmapOp : RecordedOp {
99    BitmapOp(BASE_PARAMS, const SkBitmap* bitmap)
100            : SUPER(BitmapOp)
101            , bitmap(bitmap) {}
102    const SkBitmap* bitmap;
103    // TODO: asset atlas/texture id lookup?
104};
105
106struct RectOp : RecordedOp {
107    RectOp(BASE_PARAMS)
108            : SUPER(RectOp) {}
109};
110
111struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?)
112    SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
113            : SUPER(SimpleRectsOp)
114            , vertices(vertices)
115            , vertexCount(vertexCount) {}
116    Vertex* vertices;
117    const size_t vertexCount;
118};
119
120/**
121 * Stateful operation! denotes the creation of an off-screen layer,
122 * and that commands following will render into it.
123 */
124struct BeginLayerOp : RecordedOp {
125    BeginLayerOp(BASE_PARAMS)
126            : SUPER(BeginLayerOp) {}
127};
128
129/**
130 * Stateful operation! Denotes end of off-screen layer, and that
131 * commands since last BeginLayerOp should be drawn into parent FBO.
132 *
133 * State in this op is empty, it just serves to signal that a layer has been finished.
134 */
135struct EndLayerOp : RecordedOp {
136    EndLayerOp()
137            : RecordedOp(RecordedOpId::EndLayerOp, Rect(0, 0), Matrix4::identity(), Rect(0, 0), nullptr) {}
138};
139
140/**
141 * Draws an OffscreenBuffer.
142 *
143 * Alpha, mode, and colorfilter are embedded, since LayerOps are always dynamically generated,
144 * when creating/tracking a SkPaint* during defer isn't worth the bother.
145 */
146struct LayerOp : RecordedOp {
147    // Records a one-use (saveLayer) layer for drawing. Once drawn, the layer will be destroyed.
148    LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle)
149            : SUPER_PAINTLESS(LayerOp)
150            , layerHandle(layerHandle)
151            , alpha(paint->getAlpha() / 255.0f)
152            , mode(PaintUtils::getXfermodeDirect(paint))
153            , colorFilter(paint->getColorFilter())
154            , destroy(true) {}
155
156    LayerOp(RenderNode& node)
157        : RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()), Matrix4::identity(), Rect(node.getWidth(), node.getHeight()), nullptr)
158        , layerHandle(node.getLayerHandle())
159        , alpha(node.properties().layerProperties().alpha() / 255.0f)
160        , mode(node.properties().layerProperties().xferMode())
161        , colorFilter(node.properties().layerProperties().colorFilter())
162        , destroy(false) {}
163
164    // Records a handle to the Layer object, since the Layer itself won't be
165    // constructed until after this operation is constructed.
166    OffscreenBuffer** layerHandle;
167    const float alpha;
168    const SkXfermode::Mode mode;
169
170    // pointer to object owned by either LayerProperties, or a recorded Paint object in a
171    // BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used.
172    SkColorFilter* colorFilter;
173
174    // whether to destroy the layer, once rendered
175    const bool destroy;
176};
177
178}; // namespace uirenderer
179}; // namespace android
180
181#endif // ANDROID_HWUI_RECORDED_OP_H
182