RecordedOp.h revision 5854b34881b1a747ac80b5077869ef270a92b1f4
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
24#include "SkXfermode.h"
25
26class SkBitmap;
27class SkPaint;
28
29namespace android {
30namespace uirenderer {
31
32class OffscreenBuffer;
33class RenderNode;
34struct Vertex;
35
36/**
37 * The provided macro is executed for each op type in order, with the results separated by commas.
38 *
39 * This serves as the authoritative list of ops, used for generating ID enum, and ID based LUTs.
40 */
41#define MAP_OPS(OP_FN) \
42        OP_FN(BitmapOp) \
43        OP_FN(RectOp) \
44        OP_FN(RenderNodeOp) \
45        OP_FN(SimpleRectsOp) \
46        OP_FN(BeginLayerOp) \
47        OP_FN(EndLayerOp) \
48        OP_FN(LayerOp)
49
50// Generate OpId enum
51#define IDENTITY_FN(Type) Type,
52namespace RecordedOpId {
53    enum {
54        MAP_OPS(IDENTITY_FN)
55        Count,
56    };
57}
58static_assert(RecordedOpId::BitmapOp == 0,
59        "First index must be zero for LUTs to work");
60
61#define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint
62#define BASE_PARAMS_PAINTLESS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect
63#define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClipRect, paint)
64#define SUPER_PAINTLESS(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClipRect, nullptr)
65
66struct RecordedOp {
67    /* ID from RecordedOpId - generally used for jumping into function tables */
68    const int opId;
69
70    /* bounds in *local* space, without accounting for DisplayList transformation */
71    const Rect unmappedBounds;
72
73    /* transform in recording space (vs DisplayList origin) */
74    const Matrix4 localMatrix;
75
76    /* clip in recording space */
77    const Rect localClipRect;
78
79    /* optional paint, stored in base object to simplify merging logic */
80    const SkPaint* paint;
81protected:
82    RecordedOp(unsigned int opId, BASE_PARAMS)
83            : opId(opId)
84            , unmappedBounds(unmappedBounds)
85            , localMatrix(localMatrix)
86            , localClipRect(localClipRect)
87            , paint(paint) {}
88};
89
90struct RenderNodeOp : RecordedOp {
91    RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode)
92            : SUPER_PAINTLESS(RenderNodeOp)
93            , renderNode(renderNode) {}
94    RenderNode * renderNode; // not const, since drawing modifies it (somehow...)
95};
96
97struct BitmapOp : RecordedOp {
98    BitmapOp(BASE_PARAMS, const SkBitmap* bitmap)
99            : SUPER(BitmapOp)
100            , bitmap(bitmap) {}
101    const SkBitmap* bitmap;
102    // TODO: asset atlas/texture id lookup?
103};
104
105struct RectOp : RecordedOp {
106    RectOp(BASE_PARAMS)
107            : SUPER(RectOp) {}
108};
109
110struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?)
111    SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
112            : SUPER(SimpleRectsOp)
113            , vertices(vertices)
114            , vertexCount(vertexCount) {}
115    Vertex* vertices;
116    const size_t vertexCount;
117};
118
119/**
120 * Stateful operation! denotes the creation of an off-screen layer,
121 * and that commands following will render into it.
122 */
123struct BeginLayerOp : RecordedOp {
124    BeginLayerOp(BASE_PARAMS)
125            : SUPER(BeginLayerOp) {}
126};
127
128/**
129 * Stateful operation! Denotes end of off-screen layer, and that
130 * commands since last BeginLayerOp should be drawn into parent FBO.
131 *
132 * State in this op is empty, it just serves to signal that a layer has been finished.
133 */
134struct EndLayerOp : RecordedOp {
135    EndLayerOp()
136            : RecordedOp(RecordedOpId::EndLayerOp, Rect(0, 0), Matrix4::identity(), Rect(0, 0), nullptr) {}
137};
138
139struct LayerOp : RecordedOp {
140    LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle)
141            : SUPER(LayerOp)
142            , layerHandle(layerHandle) {}
143    // Records a handle to the Layer object, since the Layer itself won't be
144    // constructed until after this operation is constructed.
145    OffscreenBuffer** layerHandle;
146};
147
148}; // namespace uirenderer
149}; // namespace android
150
151#endif // ANDROID_HWUI_RECORDED_OP_H
152