DeferredDisplayList.h revision 499d83f21e7ffb687788bba1668b05fe38f6ebaf
1/* 2 * Copyright (C) 2013 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_DEFERRED_DISPLAY_LIST_H 18#define ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H 19 20#include <unordered_map> 21 22#include <utils/Errors.h> 23#include <utils/LinearAllocator.h> 24 25#include "Matrix.h" 26#include "OpenGLRenderer.h" 27#include "Rect.h" 28 29#include <vector> 30 31class SkBitmap; 32 33namespace android { 34namespace uirenderer { 35 36class ClipOp; 37class DrawOp; 38class SaveOp; 39class SaveLayerOp; 40class StateOp; 41 42class DeferredDisplayState; 43 44class Batch; 45class DrawBatch; 46class MergingDrawBatch; 47 48typedef const void* mergeid_t; 49 50class DeferredDisplayState { 51public: 52 static void* operator new(size_t size) = delete; 53 54 // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped 55 Rect mBounds; 56 57 // the below are set and used by the OpenGLRenderer at record and deferred playback 58 bool mClipValid; 59 Rect mClip; 60 int mClipSideFlags; // specifies which sides of the bounds are clipped, unclipped if cleared 61 mat4 mMatrix; 62 float mAlpha; 63 const RoundRectClipState* mRoundRectClipState; 64 const ProjectionPathMask* mProjectionPathMask; 65}; 66 67class OpStatePair { 68public: 69 OpStatePair() 70 : op(nullptr), state(nullptr) {} 71 OpStatePair(DrawOp* newOp, const DeferredDisplayState* newState) 72 : op(newOp), state(newState) {} 73 OpStatePair(const OpStatePair& other) 74 : op(other.op), state(other.state) {} 75 DrawOp* op; 76 const DeferredDisplayState* state; 77}; 78 79class DeferredDisplayList { 80 friend struct DeferStateStruct; // used to give access to allocator 81public: 82 DeferredDisplayList(const Rect& bounds) 83 : mBounds(bounds) { 84 clear(); 85 } 86 ~DeferredDisplayList() { clear(); } 87 88 enum OpBatchId { 89 kOpBatch_None = 0, // Don't batch 90 kOpBatch_Bitmap, 91 kOpBatch_Patch, 92 kOpBatch_AlphaVertices, 93 kOpBatch_Vertices, 94 kOpBatch_AlphaMaskTexture, 95 kOpBatch_Text, 96 kOpBatch_ColorText, 97 98 kOpBatch_Count, // Add other batch ids before this 99 }; 100 101 bool isEmpty() { return mBatches.empty(); } 102 103 /** 104 * Plays back all of the draw ops recorded into batches to the renderer. 105 * Adjusts the state of the renderer as necessary, and restores it when complete 106 */ 107 void flush(OpenGLRenderer& renderer, Rect& dirty); 108 109 void addClip(OpenGLRenderer& renderer, ClipOp* op); 110 void addSaveLayer(OpenGLRenderer& renderer, SaveLayerOp* op, int newSaveCount); 111 void addSave(OpenGLRenderer& renderer, SaveOp* op, int newSaveCount); 112 void addRestoreToCount(OpenGLRenderer& renderer, StateOp* op, int newSaveCount); 113 114 /** 115 * Add a draw op into the DeferredDisplayList, reordering as needed (for performance) if 116 * disallowReorder is false, respecting draw order when overlaps occur. 117 */ 118 void addDrawOp(OpenGLRenderer& renderer, DrawOp* op); 119 120private: 121 DeferredDisplayList(const DeferredDisplayList& other); // disallow copy 122 123 DeferredDisplayState* createState() { 124 return mAllocator.create_trivial<DeferredDisplayState>(); 125 } 126 127 void tryRecycleState(DeferredDisplayState* state) { 128 mAllocator.rewindIfLastAlloc(state); 129 } 130 131 /** 132 * Resets the batching back-pointers, creating a barrier in the operation stream so that no ops 133 * added in the future will be inserted into a batch that already exist. 134 */ 135 void resetBatchingState(); 136 137 void clear(); 138 139 void storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* op); 140 void storeRestoreToCountBarrier(OpenGLRenderer& renderer, StateOp* op, int newSaveCount); 141 142 bool recordingComplexClip() const { return mComplexClipStackStart >= 0; } 143 144 int getStateOpDeferFlags() const; 145 int getDrawOpDeferFlags() const; 146 147 void discardDrawingBatches(const unsigned int maxIndex); 148 149 // layer space bounds of rendering 150 Rect mBounds; 151 152 /** 153 * At defer time, stores the *defer time* savecount of save/saveLayer ops that were deferred, so 154 * that when an associated restoreToCount is deferred, it can be recorded as a 155 * RestoreToCountBatch 156 */ 157 std::vector<int> mSaveStack; 158 int mComplexClipStackStart; 159 160 std::vector<Batch*> mBatches; 161 162 // Maps batch ids to the most recent *non-merging* batch of that id 163 Batch* mBatchLookup[kOpBatch_Count]; 164 165 // Points to the index after the most recent barrier 166 int mEarliestBatchIndex; 167 168 // Points to the first index that may contain a pure drawing batch 169 int mEarliestUnclearedIndex; 170 171 /** 172 * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen 173 * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not 174 * collide, which avoids the need to resolve mergeid collisions. 175 */ 176 std::unordered_map<mergeid_t, DrawBatch*> mMergingBatches[kOpBatch_Count]; 177 178 LinearAllocator mAllocator; 179}; 180 181/** 182 * Struct containing information that instructs the defer 183 */ 184struct DeferInfo { 185public: 186 DeferInfo() : 187 batchId(DeferredDisplayList::kOpBatch_None), 188 mergeId((mergeid_t) -1), 189 mergeable(false), 190 opaqueOverBounds(false) { 191 }; 192 193 int batchId; 194 mergeid_t mergeId; 195 bool mergeable; 196 bool opaqueOverBounds; // opaque over bounds in DeferredDisplayState - can skip ops below 197}; 198 199}; // namespace uirenderer 200}; // namespace android 201 202#endif // ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H 203