blob: bdaa1d0ae10c7bea6174e099c338ad56e6898867 [file] [log] [blame]
/*
* 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