FrameBuilder.h revision ddf2215d9807b641dbcb304779ef6b530f876ac7
1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/*
2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2015 The Android Open Source Project
3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License.
6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at
7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software
11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and
14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License.
15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */
16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#ifndef ANDROID_HWUI_OP_REORDERER_H
18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#define ANDROID_HWUI_OP_REORDERER_H
19b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "BakedOpState.h"
21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "CanvasState.h"
22b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "DisplayList.h"
23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "RecordedOp.h"
24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <vector>
26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <unordered_map>
27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
28ddf2215d9807b641dbcb304779ef6b530f876ac7Chris Craikstruct SkRect;
29ddf2215d9807b641dbcb304779ef6b530f876ac7Chris Craik
30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android {
31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer {
32b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
33b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass BakedOpState;
34b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass BatchBase;
35b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass MergingOpBatch;
36b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass OpBatch;
37b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass Rect;
38b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
39b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiktypedef int batchid_t;
40b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiktypedef const void* mergeid_t;
41b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
42b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace OpBatchType {
43b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    enum {
44b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        None = 0, // Don't batch
45b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Bitmap,
46b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Patch,
47b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        AlphaVertices,
48b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Vertices,
49b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        AlphaMaskTexture,
50b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Text,
51b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        ColorText,
52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Count // must be last
54b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    };
55b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
56b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
57b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass OpReorderer {
58b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikpublic:
59b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    OpReorderer();
60b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
61b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // TODO: not final, just presented this way for simplicity. Layers too?
62ddf2215d9807b641dbcb304779ef6b530f876ac7Chris Craik    void defer(const SkRect& clip, int viewportWidth, int viewportHeight,
63ddf2215d9807b641dbcb304779ef6b530f876ac7Chris Craik            const std::vector< sp<RenderNode> >& nodes);
64b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
65b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void defer(int viewportWidth, int viewportHeight,
66b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            const std::vector<DisplayListData::Chunk>& chunks, const std::vector<RecordedOp*>& ops);
67b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    typedef std::function<void(void*, const RecordedOp&, const BakedOpState&)> BakedOpReceiver;
68b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
69b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    /**
70b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * replayBakedOps() is templated based on what class will recieve ops being replayed.
71b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     *
72b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * It constructs a lookup array of lambdas, which allows a recorded BakeOpState to use
73b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * state->op->opId to lookup a receiver that will be called when the op is replayed.
74b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     *
75b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * For example a BitmapOp would resolve, via the lambda lookup, to calling:
76b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     *
77b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * StaticReceiver::onBitmapOp(Arg* arg, const BitmapOp& op, const BakedOpState& state);
78b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     */
79b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#define BAKED_OP_RECEIVER(Type) \
80b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    [](void* internalArg, const RecordedOp& op, const BakedOpState& state) { \
81b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        StaticReceiver::on##Type(static_cast<Arg*>(internalArg), static_cast<const Type&>(op), state); \
82b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    },
83b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    template <typename StaticReceiver, typename Arg>
84b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void replayBakedOps(Arg* arg) {
85b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        static BakedOpReceiver receivers[] = {
86b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            MAP_OPS(BAKED_OP_RECEIVER)
87b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        };
88b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        StaticReceiver::startFrame(*arg);
89b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        replayBakedOpsImpl((void*)arg, receivers);
90b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        StaticReceiver::endFrame(*arg);
91b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    }
92b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikprivate:
93b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    BakedOpState* bakeOpState(const RecordedOp& recordedOp);
94b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
95b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void deferImpl(const std::vector<DisplayListData::Chunk>& chunks,
96b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            const std::vector<RecordedOp*>& ops);
97b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
98b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers);
99b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
100b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    /**
101b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type.
102b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     *
103b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * These private methods are called from within deferImpl to defer each individual op
104b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * type differently.
105b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     */
106b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#define INTERNAL_OP_HANDLER(Type) \
107b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void on##Type(const Type& op);
108b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    MAP_OPS(INTERNAL_OP_HANDLER)
109b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
110b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // iterate back toward target to see if anything drawn since should overlap the new op
111b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // if no target, merging ops still iterate to find similar batch to insert after
112b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void locateInsertIndex(int batchId, const Rect& clippedBounds,
113b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            BatchBase** targetBatch, size_t* insertBatchIndex) const;
114b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
115b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void deferUnmergeableOp(BakedOpState* op, batchid_t batchId);
116b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
117b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // insertion point of a new batch, will hopefully be immediately after similar batch
118b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // (generally, should be similar shader)
119b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void deferMergeableOp(BakedOpState* op, batchid_t batchId, mergeid_t mergeId);
120b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
121b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    void dump();
122b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
123b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    std::vector<BatchBase*> mBatches;
124b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
125b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    /**
126b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
127b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
128b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     * collide, which avoids the need to resolve mergeid collisions.
129b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik     */
130b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    std::unordered_map<mergeid_t, MergingOpBatch*> mMergingBatches[OpBatchType::Count];
131b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
132b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // Maps batch ids to the most recent *non-merging* batch of that id
133b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr };
134b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    CanvasState mCanvasState;
135b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
136b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // contains ResolvedOps and Batches
137b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    LinearAllocator mAllocator;
138b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
139ddf2215d9807b641dbcb304779ef6b530f876ac7Chris Craik    int mEarliestBatchIndex = 0;
140b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik};
141b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
142b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}; // namespace uirenderer
143b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}; // namespace android
144b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
145b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif // ANDROID_HWUI_OP_REORDERER_H
146