| /* |
| * Copyright (C) 2020 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. |
| */ |
| |
| #include <algorithm> |
| |
| #include <compositionengine/impl/ClientCompositionRequestCache.h> |
| #include <renderengine/DisplaySettings.h> |
| #include <renderengine/LayerSettings.h> |
| |
| namespace android::compositionengine::impl { |
| |
| namespace { |
| LayerFE::LayerSettings getLayerSettingsSnapshot(const LayerFE::LayerSettings& settings) { |
| LayerFE::LayerSettings snapshot = settings; |
| snapshot.source.buffer.buffer = nullptr; |
| snapshot.source.buffer.fence = nullptr; |
| return snapshot; |
| } |
| |
| inline bool equalIgnoringSource(const renderengine::LayerSettings& lhs, |
| const renderengine::LayerSettings& rhs) { |
| return lhs.geometry == rhs.geometry && lhs.alpha == rhs.alpha && |
| lhs.sourceDataspace == rhs.sourceDataspace && |
| lhs.colorTransform == rhs.colorTransform && |
| lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow && |
| lhs.backgroundBlurRadius == rhs.backgroundBlurRadius && |
| lhs.stretchEffect == rhs.stretchEffect; |
| } |
| |
| inline bool equalIgnoringBuffer(const renderengine::Buffer& lhs, const renderengine::Buffer& rhs) { |
| return lhs.useTextureFiltering == rhs.useTextureFiltering && |
| lhs.textureTransform == rhs.textureTransform && |
| lhs.usePremultipliedAlpha == rhs.usePremultipliedAlpha && |
| lhs.isOpaque == rhs.isOpaque && lhs.maxLuminanceNits == rhs.maxLuminanceNits; |
| } |
| |
| inline bool equalIgnoringBuffer(const renderengine::LayerSettings& lhs, |
| const renderengine::LayerSettings& rhs) { |
| // compare LayerSettings without LayerSettings.PixelSource |
| return equalIgnoringSource(lhs, rhs) && |
| |
| // compare LayerSettings.PixelSource without buffer |
| lhs.source.solidColor == rhs.source.solidColor && |
| |
| // compare LayerSettings.PixelSource.Buffer without buffer & fence |
| equalIgnoringBuffer(lhs.source.buffer, rhs.source.buffer); |
| } |
| |
| bool layerSettingsAreEqual(const LayerFE::LayerSettings& lhs, const LayerFE::LayerSettings& rhs) { |
| return lhs.bufferId == rhs.bufferId && lhs.frameNumber == rhs.frameNumber && |
| equalIgnoringBuffer(lhs, rhs); |
| } |
| |
| } // namespace |
| |
| ClientCompositionRequestCache::ClientCompositionRequest::ClientCompositionRequest( |
| const renderengine::DisplaySettings& initDisplay, |
| const std::vector<LayerFE::LayerSettings>& initLayerSettings) |
| : display(initDisplay) { |
| layerSettings.reserve(initLayerSettings.size()); |
| for (const LayerFE::LayerSettings& settings : initLayerSettings) { |
| layerSettings.push_back(getLayerSettingsSnapshot(settings)); |
| } |
| } |
| |
| bool ClientCompositionRequestCache::ClientCompositionRequest::equals( |
| const renderengine::DisplaySettings& newDisplay, |
| const std::vector<LayerFE::LayerSettings>& newLayerSettings) const { |
| return newDisplay == display && |
| std::equal(layerSettings.begin(), layerSettings.end(), newLayerSettings.begin(), |
| newLayerSettings.end(), layerSettingsAreEqual); |
| } |
| |
| bool ClientCompositionRequestCache::exists( |
| uint64_t bufferId, const renderengine::DisplaySettings& display, |
| const std::vector<LayerFE::LayerSettings>& layerSettings) const { |
| for (const auto& [cachedBufferId, cachedRequest] : mCache) { |
| if (cachedBufferId == bufferId) { |
| return cachedRequest.equals(display, layerSettings); |
| } |
| } |
| return false; |
| } |
| |
| void ClientCompositionRequestCache::add(uint64_t bufferId, |
| const renderengine::DisplaySettings& display, |
| const std::vector<LayerFE::LayerSettings>& layerSettings) { |
| const ClientCompositionRequest request(display, layerSettings); |
| for (auto& [cachedBufferId, cachedRequest] : mCache) { |
| if (cachedBufferId == bufferId) { |
| cachedRequest = std::move(request); |
| return; |
| } |
| } |
| |
| if (mCache.size() >= mMaxCacheSize) { |
| mCache.pop_front(); |
| } |
| |
| mCache.emplace_back(bufferId, std::move(request)); |
| } |
| |
| void ClientCompositionRequestCache::remove(uint64_t bufferId) { |
| for (auto it = mCache.begin(); it != mCache.end(); it++) { |
| if (it->first == bufferId) { |
| mCache.erase(it); |
| return; |
| } |
| } |
| } |
| |
| } // namespace android::compositionengine::impl |