• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #pragma once
18 
19 #include <compositionengine/Output.h>
20 #include <compositionengine/ProjectionSpace.h>
21 #include <compositionengine/impl/planner/LayerState.h>
22 #include <compositionengine/impl/planner/TexturePool.h>
23 #include <renderengine/RenderEngine.h>
24 
25 #include <chrono>
26 
27 namespace android {
28 
29 namespace compositionengine::impl::planner {
30 
31 std::string durationString(std::chrono::milliseconds duration);
32 
33 class LayerState;
34 
35 class CachedSet {
36 public:
37     class Layer {
38     public:
39         Layer(const LayerState*, std::chrono::steady_clock::time_point lastUpdate);
40 
getState()41         const LayerState* getState() const { return mState; }
getName()42         const std::string& getName() const { return mState->getName(); }
getBackgroundBlurRadius()43         int32_t getBackgroundBlurRadius() const { return mState->getBackgroundBlurRadius(); }
getDisplayFrame()44         Rect getDisplayFrame() const { return mState->getDisplayFrame(); }
getVisibleRegion()45         const Region& getVisibleRegion() const { return mState->getVisibleRegion(); }
getBuffer()46         const sp<GraphicBuffer>& getBuffer() const {
47             return mState->getOutputLayer()->getLayerFE().getCompositionState()->buffer;
48         }
getFramesSinceBufferUpdate()49         int64_t getFramesSinceBufferUpdate() const { return mState->getFramesSinceBufferUpdate(); }
getHash()50         NonBufferHash getHash() const { return mHash; }
getLastUpdate()51         std::chrono::steady_clock::time_point getLastUpdate() const { return mLastUpdate; }
52 
53     private:
54         const LayerState* mState;
55         NonBufferHash mHash;
56         std::chrono::steady_clock::time_point mLastUpdate;
57     };
58 
59     CachedSet(const LayerState*, std::chrono::steady_clock::time_point lastUpdate);
60     CachedSet(Layer layer);
61 
62     void addLayer(const LayerState*, std::chrono::steady_clock::time_point lastUpdate);
63 
getLastUpdate()64     std::chrono::steady_clock::time_point getLastUpdate() const { return mLastUpdate; }
getLayerCount()65     size_t getLayerCount() const { return mLayers.size(); }
getFirstLayer()66     const Layer& getFirstLayer() const { return mLayers[0]; }
getBounds()67     const Rect& getBounds() const { return mBounds; }
getTextureBounds()68     Rect getTextureBounds() const {
69         return mTexture ? mTexture->get()->getBuffer()->getBounds() : Rect::INVALID_RECT;
70     }
getVisibleRegion()71     const Region& getVisibleRegion() const { return mVisibleRegion; }
getAge()72     size_t getAge() const { return mAge; }
getBuffer()73     std::shared_ptr<renderengine::ExternalTexture> getBuffer() const {
74         return mTexture ? mTexture->get() : nullptr;
75     }
getDrawFence()76     const sp<Fence>& getDrawFence() const { return mDrawFence; }
getOutputSpace()77     const ProjectionSpace& getOutputSpace() const { return mOutputSpace; }
getOutputDataspace()78     ui::Dataspace getOutputDataspace() const { return mOutputDataspace; }
getConstituentLayers()79     const std::vector<Layer>& getConstituentLayers() const { return mLayers; }
80 
81     NonBufferHash getNonBufferHash() const;
82 
83     size_t getComponentDisplayCost() const;
84     size_t getCreationCost() const;
85     size_t getDisplayCost() const;
86 
87     bool hasBufferUpdate() const;
hasRenderedBuffer()88     bool hasRenderedBuffer() const { return mTexture != nullptr; }
89     bool hasReadyBuffer() const;
90 
91     // Decomposes this CachedSet into a vector of its layers as individual CachedSets
92     std::vector<CachedSet> decompose() const;
93 
94     void updateAge(std::chrono::steady_clock::time_point now);
95 
setLastUpdate(std::chrono::steady_clock::time_point now)96     void setLastUpdate(std::chrono::steady_clock::time_point now) { mLastUpdate = now; }
append(const CachedSet & other)97     void append(const CachedSet& other) {
98         mTexture.reset();
99         mOutputDataspace = ui::Dataspace::UNKNOWN;
100         mDrawFence = nullptr;
101         mBlurLayer = nullptr;
102         mHolePunchLayer = nullptr;
103         mSkipCount = 0;
104 
105         mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend());
106         Region boundingRegion;
107         boundingRegion.orSelf(mBounds);
108         boundingRegion.orSelf(other.mBounds);
109         mBounds = boundingRegion.getBounds();
110         mVisibleRegion.orSelf(other.mVisibleRegion);
111     }
incrementAge()112     void incrementAge() { ++mAge; }
incrementSkipCount()113     void incrementSkipCount() { mSkipCount++; }
getSkipCount()114     size_t getSkipCount() { return mSkipCount; }
115 
116     // Renders the cached set with the supplied output composition state.
117     void render(renderengine::RenderEngine& re, TexturePool& texturePool,
118                 const OutputCompositionState& outputState);
119 
120     void dump(std::string& result) const;
121 
122     // Whether this represents a single layer with a buffer and rounded corners.
123     // If it is, we may be able to draw it by placing it behind another
124     // CachedSet and punching a hole.
125     bool requiresHolePunch() const;
126 
127     // True if any constituent layer is configured to blur any layers behind.
128     bool hasBlurBehind() const;
129 
130     // Add a layer that will be drawn behind this one. ::render() will render a
131     // hole in this CachedSet's buffer, allowing the supplied layer to peek
132     // through. Must be called before ::render().
133     // Will do nothing if this CachedSet is not opaque where the hole punch
134     // layer is displayed.
135     // If isFirstLayer is true, this CachedSet can be considered opaque because
136     // nothing (besides the hole punch layer) will be drawn behind it.
137     void addHolePunchLayerIfFeasible(const CachedSet&, bool isFirstLayer);
138 
139     void addBackgroundBlurLayer(const CachedSet&);
140 
141     // Retrieve the layer that will be drawn behind this one.
142     compositionengine::OutputLayer* getHolePunchLayer() const;
143 
144     compositionengine::OutputLayer* getBlurLayer() const;
145 
146     bool hasUnsupportedDataspace() const;
147 
148     bool hasProtectedLayers() const;
149 
150 private:
151     CachedSet() = default;
152 
153     const NonBufferHash mFingerprint;
154     std::chrono::steady_clock::time_point mLastUpdate = std::chrono::steady_clock::now();
155     std::vector<Layer> mLayers;
156 
157     // Unowned.
158     const LayerState* mHolePunchLayer = nullptr;
159     const LayerState* mBlurLayer = nullptr;
160     Rect mBounds = Rect::EMPTY_RECT;
161     Region mVisibleRegion;
162     size_t mAge = 0;
163     size_t mSkipCount = 0;
164 
165     // TODO(b/190411067): This is a shared pointer only because CachedSets are copied into different
166     // containers in the Flattener. Logically this should have unique ownership otherwise.
167     std::shared_ptr<TexturePool::AutoTexture> mTexture;
168     sp<Fence> mDrawFence;
169     ProjectionSpace mOutputSpace;
170     ui::Dataspace mOutputDataspace;
171     ui::Transform::RotationFlags mOrientation = ui::Transform::ROT_0;
172 
173     static const bool sDebugHighlighLayers;
174 };
175 
176 } // namespace compositionengine::impl::planner
177 } // namespace android
178