DeferredDisplayList.cpp revision c3566d06421c8acc0aafb18f7e307e5725ce87e1
1c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik/* 2c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * Copyright (C) 2013 The Android Open Source Project 3c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * 4c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * you may not use this file except in compliance with the License. 6c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * You may obtain a copy of the License at 7c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * 8c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * http://www.apache.org/licenses/LICENSE-2.0 9c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * 10c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * Unless required by applicable law or agreed to in writing, software 11c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * See the License for the specific language governing permissions and 14c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * limitations under the License. 15c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik */ 16c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 17c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#define LOG_TAG "OpenGLRenderer" 18c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#define ATRACE_TAG ATRACE_TAG_VIEW 19c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 20c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include <utils/Trace.h> 21c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 22c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "Debug.h" 23c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "DisplayListOp.h" 24c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "OpenGLRenderer.h" 25c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 26c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#if DEBUG_DEFER 27c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik #define DEFER_LOGD(...) ALOGD(__VA_ARGS__) 28c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#else 29c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik #define DEFER_LOGD(...) 30c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#endif 31c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 32c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craiknamespace android { 33c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craiknamespace uirenderer { 34c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 35c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikclass DrawOpBatch { 36c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikpublic: 37c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawOpBatch() { 38c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mOps.clear(); 39c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 40c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 41c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik ~DrawOpBatch() { 42c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mOps.clear(); 43c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 44c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 45c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik void add(DrawOp* op) { 46c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik // NOTE: ignore empty bounds special case, since we don't merge across those ops 47c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBounds.unionWith(op->state.mBounds); 48c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mOps.add(op); 49c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 50c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 51c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik bool intersects(Rect& rect) { 52c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (!rect.intersects(mBounds)) return false; 53c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (unsigned int i = 0; i < mOps.size(); i++) { 54c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (rect.intersects(mOps[i]->state.mBounds)) { 55c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#if DEBUG_DEFER 56c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DEFER_LOGD("op intersects with op %p with bounds %f %f %f %f:", mOps[i], 57c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mOps[i]->state.mBounds.left, mOps[i]->state.mBounds.top, 58c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mOps[i]->state.mBounds.right, mOps[i]->state.mBounds.bottom); 59c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mOps[i]->output(2); 60c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#endif 61c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik return true; 62c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 63c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 64c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik return false; 65c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 66c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 67c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik Vector<DrawOp*> mOps; 68c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikprivate: 69c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik Rect mBounds; 70c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik}; 71c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 72c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikvoid DeferredDisplayList::clear() { 73c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (int i = 0; i < kOpBatch_Count; i++) { 74c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatchIndices[i] = -1; 75c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 76c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (unsigned int i = 0; i < mBatches.size(); i++) { 77c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik delete mBatches[i]; 78c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 79c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatches.clear(); 80c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik} 81c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 82c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikvoid DeferredDisplayList::add(DrawOp* op, bool disallowReorder) { 83c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (CC_UNLIKELY(disallowReorder)) { 84c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (!mBatches.isEmpty()) { 85c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatches[0]->add(op); 86c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik return; 87c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 88c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawOpBatch* b = new DrawOpBatch(); 89c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik b->add(op); 90c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatches.add(b); 91c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik return; 92c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 93c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 94c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik // disallowReorder isn't set, so find the latest batch of the new op's type, and try to merge 95c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik // the new op into it 96c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawOpBatch* targetBatch = NULL; 97c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik int batchId = op->getBatchId(); 98c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 99c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (!mBatches.isEmpty()) { 100c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (op->state.mBounds.isEmpty()) { 101c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik // don't know the bounds for op, so add to last batch and start from scratch on next op 102c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatches.top()->add(op); 103c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (int i = 0; i < kOpBatch_Count; i++) { 104c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatchIndices[i] = -1; 105c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 106c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#if DEBUG_DEFER 107c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DEFER_LOGD("Warning: Encountered op with empty bounds, resetting batches"); 108c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik op->output(2); 109c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#endif 110c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik return; 111c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 112c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 113c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (batchId >= 0 && mBatchIndices[batchId] != -1) { 114c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik int targetIndex = mBatchIndices[batchId]; 115c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik targetBatch = mBatches[targetIndex]; 116c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik // iterate back toward target to see if anything drawn since should overlap the new op 117c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (int i = mBatches.size() - 1; i > targetIndex; i--) { 118c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawOpBatch* overBatch = mBatches[i]; 119c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (overBatch->intersects(op->state.mBounds)) { 120c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik targetBatch = NULL; 121c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#if DEBUG_DEFER 122c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DEFER_LOGD("op couldn't join batch %d, was intersected by batch %d", 123c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik targetIndex, i); 124c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik op->output(2); 125c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#endif 126c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik break; 127c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 128c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 129c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 130c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 131c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (!targetBatch) { 132c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik targetBatch = new DrawOpBatch(); 133c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatches.add(targetBatch); 134c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (batchId >= 0) { 135c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mBatchIndices[batchId] = mBatches.size() - 1; 136c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 137c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 138c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik targetBatch->add(op); 139c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik} 140c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 141c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikstatus_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, 142c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik uint32_t level) { 143c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik ATRACE_CALL(); 144c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik status_t status = DrawGlInfo::kStatusDone; 145c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 146c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (isEmpty()) return status; // nothing to flush 147c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 148c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DEFER_LOGD("--flushing"); 149c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers(); 150c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 151c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik int opCount = 0; 152c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (unsigned int i = 0; i < mBatches.size(); i++) { 153c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawOpBatch* batch = mBatches[i]; 154c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (unsigned int j = 0; j < batch->mOps.size(); j++) { 155c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DrawOp* op = batch->mOps[j]; 156c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 157c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik renderer.restoreDisplayState(op->state); 158c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 159c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#if DEBUG_DEFER 160c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik op->output(2); 161c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#endif 162c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik status |= op->applyDraw(renderer, dirty, level, 163c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik op->state.mMultipliedAlpha >= 0, op->state.mMultipliedAlpha); 164c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik opCount++; 165c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 166c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 167c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 168c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DEFER_LOGD("--flushed, drew %d batches (total %d ops)", mBatches.size(), opCount); 169c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik renderer.restoreToCount(restoreTo); 170c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik renderer.setDrawModifiers(restoreDrawModifiers); 171c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik clear(); 172c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik return status; 173c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik} 174c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 175c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik}; // namespace uirenderer 176c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik}; // namespace android 177