| /* | |
| * 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.textureName == rhs.textureName && | |
| lhs.useTextureFiltering == rhs.useTextureFiltering && | |
| lhs.textureTransform == rhs.textureTransform && | |
| lhs.usePremultipliedAlpha == rhs.usePremultipliedAlpha && | |
| lhs.isOpaque == rhs.isOpaque && lhs.isY410BT2020 == rhs.isY410BT2020 && | |
| 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 |