/* * 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 #include #include #include 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& 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& 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& 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& 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