/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "ClipArea.h" #include "Rect.h" #include "utils/Macros.h" #include #include struct SkRect; namespace android { namespace uirenderer { class BakedOpState; struct BeginLayerOp; class BatchBase; class LinearAllocator; struct MergedBakedOpList; class MergingOpBatch; class OffscreenBuffer; class OpBatch; class RenderNode; typedef int batchid_t; typedef const void* mergeid_t; namespace OpBatchType { enum { Bitmap, MergedPatch, AlphaVertices, Vertices, AlphaMaskTexture, Text, ColorText, Shadow, TextureLayer, Functor, CopyToLayer, CopyFromLayer, Count // must be last }; } typedef void (*BakedOpReceiver)(void*, const BakedOpState&); typedef void (*MergedOpReceiver)(void*, const MergedBakedOpList& opList); /** * Stores the deferred render operations and state used to compute ordering * for a single FBO/layer. */ class LayerBuilder { // Prevent copy/assign because users may stash pointer to offscreenBuffer and viewportClip PREVENT_COPY_AND_ASSIGN(LayerBuilder); public: // Create LayerBuilder for Fbo0 LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerBuilder(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerBuilder for an offscreen layer, where beginLayerOp is present for a // saveLayer, renderNode is present for a HW layer. LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); // iterate back toward target to see if anything drawn since should overlap the new op // if no target, merging ops still iterate to find similar batch to insert after void locateInsertIndex(int batchId, const Rect& clippedBounds, BatchBase** targetBatch, size_t* insertBatchIndex) const; void deferUnmergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId); // insertion point of a new batch, will hopefully be immediately after similar batch // (generally, should be similar shader) void deferMergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId, mergeid_t mergeId); void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers, MergedOpReceiver*) const; void deferLayerClear(const Rect& dstRect); bool empty() const { return mBatches.empty(); } void clear(); void dump() const; const uint32_t width; const uint32_t height; const Rect repaintRect; const ClipRect repaintClip; OffscreenBuffer* offscreenBuffer; const BeginLayerOp* beginLayerOp; const RenderNode* renderNode; // list of deferred CopyFromLayer ops, to be deferred upon encountering EndUnclippedLayerOps std::vector activeUnclippedSaveLayers; private: void onDeferOp(LinearAllocator& allocator, const BakedOpState* bakedState); void flushLayerClears(LinearAllocator& allocator); std::vector mBatches; /** * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not * collide, which avoids the need to resolve mergeid collisions. */ std::unordered_map mMergingBatchLookup[OpBatchType::Count]; // Maps batch ids to the most recent *non-merging* batch of that id OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr }; std::vector mClearRects; }; }; // namespace uirenderer }; // namespace android