• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #include <algorithm>
18 
19 #include <compositionengine/impl/ClientCompositionRequestCache.h>
20 #include <renderengine/DisplaySettings.h>
21 #include <renderengine/LayerSettings.h>
22 
23 namespace android::compositionengine::impl {
24 
25 namespace {
getLayerSettingsSnapshot(const LayerFE::LayerSettings & settings)26 LayerFE::LayerSettings getLayerSettingsSnapshot(const LayerFE::LayerSettings& settings) {
27     LayerFE::LayerSettings snapshot = settings;
28     snapshot.source.buffer.buffer = nullptr;
29     snapshot.source.buffer.fence = nullptr;
30     return snapshot;
31 }
32 
equalIgnoringSource(const renderengine::LayerSettings & lhs,const renderengine::LayerSettings & rhs)33 inline bool equalIgnoringSource(const renderengine::LayerSettings& lhs,
34                                 const renderengine::LayerSettings& rhs) {
35     return lhs.geometry == rhs.geometry && lhs.alpha == rhs.alpha &&
36             lhs.sourceDataspace == rhs.sourceDataspace &&
37             lhs.colorTransform == rhs.colorTransform &&
38             lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow &&
39             lhs.backgroundBlurRadius == rhs.backgroundBlurRadius &&
40             lhs.stretchEffect == rhs.stretchEffect;
41 }
42 
equalIgnoringBuffer(const renderengine::Buffer & lhs,const renderengine::Buffer & rhs)43 inline bool equalIgnoringBuffer(const renderengine::Buffer& lhs, const renderengine::Buffer& rhs) {
44     return lhs.textureName == rhs.textureName &&
45             lhs.useTextureFiltering == rhs.useTextureFiltering &&
46             lhs.textureTransform == rhs.textureTransform &&
47             lhs.usePremultipliedAlpha == rhs.usePremultipliedAlpha &&
48             lhs.isOpaque == rhs.isOpaque && lhs.isY410BT2020 == rhs.isY410BT2020 &&
49             lhs.maxLuminanceNits == rhs.maxLuminanceNits;
50 }
51 
equalIgnoringBuffer(const renderengine::LayerSettings & lhs,const renderengine::LayerSettings & rhs)52 inline bool equalIgnoringBuffer(const renderengine::LayerSettings& lhs,
53                                 const renderengine::LayerSettings& rhs) {
54     // compare LayerSettings without LayerSettings.PixelSource
55     return equalIgnoringSource(lhs, rhs) &&
56 
57             // compare LayerSettings.PixelSource without buffer
58             lhs.source.solidColor == rhs.source.solidColor &&
59 
60             // compare LayerSettings.PixelSource.Buffer without buffer & fence
61             equalIgnoringBuffer(lhs.source.buffer, rhs.source.buffer);
62 }
63 
layerSettingsAreEqual(const LayerFE::LayerSettings & lhs,const LayerFE::LayerSettings & rhs)64 bool layerSettingsAreEqual(const LayerFE::LayerSettings& lhs, const LayerFE::LayerSettings& rhs) {
65     return lhs.bufferId == rhs.bufferId && lhs.frameNumber == rhs.frameNumber &&
66             equalIgnoringBuffer(lhs, rhs);
67 }
68 
69 } // namespace
70 
ClientCompositionRequest(const renderengine::DisplaySettings & initDisplay,const std::vector<LayerFE::LayerSettings> & initLayerSettings)71 ClientCompositionRequestCache::ClientCompositionRequest::ClientCompositionRequest(
72         const renderengine::DisplaySettings& initDisplay,
73         const std::vector<LayerFE::LayerSettings>& initLayerSettings)
74       : display(initDisplay) {
75     layerSettings.reserve(initLayerSettings.size());
76     for (const LayerFE::LayerSettings& settings : initLayerSettings) {
77         layerSettings.push_back(getLayerSettingsSnapshot(settings));
78     }
79 }
80 
equals(const renderengine::DisplaySettings & newDisplay,const std::vector<LayerFE::LayerSettings> & newLayerSettings) const81 bool ClientCompositionRequestCache::ClientCompositionRequest::equals(
82         const renderengine::DisplaySettings& newDisplay,
83         const std::vector<LayerFE::LayerSettings>& newLayerSettings) const {
84     return newDisplay == display &&
85             std::equal(layerSettings.begin(), layerSettings.end(), newLayerSettings.begin(),
86                        newLayerSettings.end(), layerSettingsAreEqual);
87 }
88 
exists(uint64_t bufferId,const renderengine::DisplaySettings & display,const std::vector<LayerFE::LayerSettings> & layerSettings) const89 bool ClientCompositionRequestCache::exists(
90         uint64_t bufferId, const renderengine::DisplaySettings& display,
91         const std::vector<LayerFE::LayerSettings>& layerSettings) const {
92     for (const auto& [cachedBufferId, cachedRequest] : mCache) {
93         if (cachedBufferId == bufferId) {
94             return cachedRequest.equals(display, layerSettings);
95         }
96     }
97     return false;
98 }
99 
add(uint64_t bufferId,const renderengine::DisplaySettings & display,const std::vector<LayerFE::LayerSettings> & layerSettings)100 void ClientCompositionRequestCache::add(uint64_t bufferId,
101                                         const renderengine::DisplaySettings& display,
102                                         const std::vector<LayerFE::LayerSettings>& layerSettings) {
103     const ClientCompositionRequest request(display, layerSettings);
104     for (auto& [cachedBufferId, cachedRequest] : mCache) {
105         if (cachedBufferId == bufferId) {
106             cachedRequest = std::move(request);
107             return;
108         }
109     }
110 
111     if (mCache.size() >= mMaxCacheSize) {
112         mCache.pop_front();
113     }
114 
115     mCache.emplace_back(bufferId, std::move(request));
116 }
117 
remove(uint64_t bufferId)118 void ClientCompositionRequestCache::remove(uint64_t bufferId) {
119     for (auto it = mCache.begin(); it != mCache.end(); it++) {
120         if (it->first == bufferId) {
121             mCache.erase(it);
122             return;
123         }
124     }
125 }
126 
127 } // namespace android::compositionengine::impl
128