blob: 395a1baeebd05cd5a6b4a0da4e43ecd39f2c085a [file] [log] [blame]
Chris Craikb565df12015-10-05 13:00:52 -07001/*
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_OP_REORDERER_H
18#define ANDROID_HWUI_OP_REORDERER_H
19
20#include "BakedOpState.h"
21#include "CanvasState.h"
22#include "DisplayList.h"
23#include "RecordedOp.h"
24
25#include <vector>
26#include <unordered_map>
27
Chris Craikddf22152015-10-14 17:42:47 -070028struct SkRect;
29
Chris Craikb565df12015-10-05 13:00:52 -070030namespace android {
31namespace uirenderer {
32
33class BakedOpState;
34class BatchBase;
35class MergingOpBatch;
36class OpBatch;
37class Rect;
38
39typedef int batchid_t;
40typedef const void* mergeid_t;
41
42namespace OpBatchType {
43 enum {
44 None = 0, // Don't batch
45 Bitmap,
46 Patch,
47 AlphaVertices,
48 Vertices,
49 AlphaMaskTexture,
50 Text,
51 ColorText,
52
53 Count // must be last
54 };
55}
56
57class OpReorderer {
58public:
59 OpReorderer();
60
61 // TODO: not final, just presented this way for simplicity. Layers too?
Chris Craikddf22152015-10-14 17:42:47 -070062 void defer(const SkRect& clip, int viewportWidth, int viewportHeight,
63 const std::vector< sp<RenderNode> >& nodes);
Chris Craikb565df12015-10-05 13:00:52 -070064
65 void defer(int viewportWidth, int viewportHeight,
66 const std::vector<DisplayListData::Chunk>& chunks, const std::vector<RecordedOp*>& ops);
67 typedef std::function<void(void*, const RecordedOp&, const BakedOpState&)> BakedOpReceiver;
68
69 /**
70 * replayBakedOps() is templated based on what class will recieve ops being replayed.
71 *
72 * It constructs a lookup array of lambdas, which allows a recorded BakeOpState to use
73 * state->op->opId to lookup a receiver that will be called when the op is replayed.
74 *
75 * For example a BitmapOp would resolve, via the lambda lookup, to calling:
76 *
77 * StaticReceiver::onBitmapOp(Arg* arg, const BitmapOp& op, const BakedOpState& state);
78 */
79#define BAKED_OP_RECEIVER(Type) \
80 [](void* internalArg, const RecordedOp& op, const BakedOpState& state) { \
81 StaticReceiver::on##Type(static_cast<Arg*>(internalArg), static_cast<const Type&>(op), state); \
82 },
83 template <typename StaticReceiver, typename Arg>
84 void replayBakedOps(Arg* arg) {
85 static BakedOpReceiver receivers[] = {
86 MAP_OPS(BAKED_OP_RECEIVER)
87 };
88 StaticReceiver::startFrame(*arg);
89 replayBakedOpsImpl((void*)arg, receivers);
90 StaticReceiver::endFrame(*arg);
91 }
92private:
93 BakedOpState* bakeOpState(const RecordedOp& recordedOp);
94
95 void deferImpl(const std::vector<DisplayListData::Chunk>& chunks,
96 const std::vector<RecordedOp*>& ops);
97
98 void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers);
99
100 /**
101 * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type.
102 *
103 * These private methods are called from within deferImpl to defer each individual op
104 * type differently.
105 */
106#define INTERNAL_OP_HANDLER(Type) \
107 void on##Type(const Type& op);
108 MAP_OPS(INTERNAL_OP_HANDLER)
109
110 // iterate back toward target to see if anything drawn since should overlap the new op
111 // if no target, merging ops still iterate to find similar batch to insert after
112 void locateInsertIndex(int batchId, const Rect& clippedBounds,
113 BatchBase** targetBatch, size_t* insertBatchIndex) const;
114
115 void deferUnmergeableOp(BakedOpState* op, batchid_t batchId);
116
117 // insertion point of a new batch, will hopefully be immediately after similar batch
118 // (generally, should be similar shader)
119 void deferMergeableOp(BakedOpState* op, batchid_t batchId, mergeid_t mergeId);
120
121 void dump();
122
123 std::vector<BatchBase*> mBatches;
124
125 /**
126 * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
127 * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
128 * collide, which avoids the need to resolve mergeid collisions.
129 */
130 std::unordered_map<mergeid_t, MergingOpBatch*> mMergingBatches[OpBatchType::Count];
131
132 // Maps batch ids to the most recent *non-merging* batch of that id
133 OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr };
134 CanvasState mCanvasState;
135
136 // contains ResolvedOps and Batches
137 LinearAllocator mAllocator;
138
Chris Craikddf22152015-10-14 17:42:47 -0700139 int mEarliestBatchIndex = 0;
Chris Craikb565df12015-10-05 13:00:52 -0700140};
141
142}; // namespace uirenderer
143}; // namespace android
144
145#endif // ANDROID_HWUI_OP_REORDERER_H