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, bool deviceHandlesColorTransform); 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 bool hasSolidColorLayers() const; 151 152 private: 153 CachedSet() = default; 154 155 const NonBufferHash mFingerprint; 156 std::chrono::steady_clock::time_point mLastUpdate = std::chrono::steady_clock::now(); 157 std::vector<Layer> mLayers; 158 159 // Unowned. 160 const LayerState* mHolePunchLayer = nullptr; 161 const LayerState* mBlurLayer = nullptr; 162 Rect mBounds = Rect::EMPTY_RECT; 163 Region mVisibleRegion; 164 size_t mAge = 0; 165 size_t mSkipCount = 0; 166 167 // TODO(b/190411067): This is a shared pointer only because CachedSets are copied into different 168 // containers in the Flattener. Logically this should have unique ownership otherwise. 169 std::shared_ptr<TexturePool::AutoTexture> mTexture; 170 sp<Fence> mDrawFence; 171 ProjectionSpace mOutputSpace; 172 ui::Dataspace mOutputDataspace; 173 ui::Transform::RotationFlags mOrientation = ui::Transform::ROT_0; 174 175 static const bool sDebugHighlighLayers; 176 }; 177 178 } // namespace compositionengine::impl::planner 179 } // namespace android 180