blob: 6776a3c9fc1877065d1ced2b15c90774b773a5ea [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
Chris Craikb36af872015-10-16 14:23:12 -070065 void defer(int viewportWidth, int viewportHeight, const DisplayList& displayList);
Chris Craikb565df12015-10-05 13:00:52 -070066 typedef std::function<void(void*, const RecordedOp&, const BakedOpState&)> BakedOpReceiver;
67
68 /**
69 * replayBakedOps() is templated based on what class will recieve ops being replayed.
70 *
71 * It constructs a lookup array of lambdas, which allows a recorded BakeOpState to use
72 * state->op->opId to lookup a receiver that will be called when the op is replayed.
73 *
74 * For example a BitmapOp would resolve, via the lambda lookup, to calling:
75 *
76 * StaticReceiver::onBitmapOp(Arg* arg, const BitmapOp& op, const BakedOpState& state);
77 */
78#define BAKED_OP_RECEIVER(Type) \
79 [](void* internalArg, const RecordedOp& op, const BakedOpState& state) { \
80 StaticReceiver::on##Type(static_cast<Arg*>(internalArg), static_cast<const Type&>(op), state); \
81 },
82 template <typename StaticReceiver, typename Arg>
83 void replayBakedOps(Arg* arg) {
84 static BakedOpReceiver receivers[] = {
85 MAP_OPS(BAKED_OP_RECEIVER)
86 };
87 StaticReceiver::startFrame(*arg);
88 replayBakedOpsImpl((void*)arg, receivers);
89 StaticReceiver::endFrame(*arg);
90 }
91private:
92 BakedOpState* bakeOpState(const RecordedOp& recordedOp);
93
Chris Craikb36af872015-10-16 14:23:12 -070094 void deferImpl(const DisplayList& displayList);
Chris Craikb565df12015-10-05 13:00:52 -070095
96 void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers);
97
98 /**
99 * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type.
100 *
101 * These private methods are called from within deferImpl to defer each individual op
102 * type differently.
103 */
104#define INTERNAL_OP_HANDLER(Type) \
105 void on##Type(const Type& op);
106 MAP_OPS(INTERNAL_OP_HANDLER)
107
108 // iterate back toward target to see if anything drawn since should overlap the new op
109 // if no target, merging ops still iterate to find similar batch to insert after
110 void locateInsertIndex(int batchId, const Rect& clippedBounds,
111 BatchBase** targetBatch, size_t* insertBatchIndex) const;
112
113 void deferUnmergeableOp(BakedOpState* op, batchid_t batchId);
114
115 // insertion point of a new batch, will hopefully be immediately after similar batch
116 // (generally, should be similar shader)
117 void deferMergeableOp(BakedOpState* op, batchid_t batchId, mergeid_t mergeId);
118
119 void dump();
120
121 std::vector<BatchBase*> mBatches;
122
123 /**
124 * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
125 * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
126 * collide, which avoids the need to resolve mergeid collisions.
127 */
128 std::unordered_map<mergeid_t, MergingOpBatch*> mMergingBatches[OpBatchType::Count];
129
130 // Maps batch ids to the most recent *non-merging* batch of that id
131 OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr };
132 CanvasState mCanvasState;
133
134 // contains ResolvedOps and Batches
135 LinearAllocator mAllocator;
136
Chris Craikddf22152015-10-14 17:42:47 -0700137 int mEarliestBatchIndex = 0;
Chris Craikb565df12015-10-05 13:00:52 -0700138};
139
140}; // namespace uirenderer
141}; // namespace android
142
143#endif // ANDROID_HWUI_OP_REORDERER_H