Vishnu Nair | 9b079a2 | 2020-01-21 14:36:08 -0800 | [diff] [blame] | 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 { |
| 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 | |
| 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 && |
Lucas Dupin | d011f50 | 2020-03-22 18:34:51 -0700 | [diff] [blame] | 38 | lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow && |
| 39 | lhs.backgroundBlurRadius == rhs.backgroundBlurRadius; |
Vishnu Nair | 9b079a2 | 2020-01-21 14:36:08 -0800 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | inline bool equalIgnoringBuffer(const renderengine::Buffer& lhs, const renderengine::Buffer& rhs) { |
| 43 | return lhs.textureName == rhs.textureName && |
| 44 | lhs.useTextureFiltering == rhs.useTextureFiltering && |
| 45 | lhs.textureTransform == rhs.textureTransform && |
| 46 | lhs.usePremultipliedAlpha == rhs.usePremultipliedAlpha && |
| 47 | lhs.isOpaque == rhs.isOpaque && lhs.isY410BT2020 == rhs.isY410BT2020 && |
| 48 | lhs.maxMasteringLuminance == rhs.maxMasteringLuminance && |
| 49 | lhs.maxContentLuminance == rhs.maxContentLuminance; |
| 50 | } |
| 51 | |
| 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 | |
| 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 | |
| 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 | |
| 81 | 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 | |
| 89 | 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 | |
| 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 | |
| 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 |