blob: e2c0acfd81873fc5b2c5eb23a91c6136b5ce25fb [file] [log] [blame]
Chia-I Wuaaff73f2017-02-13 12:28:24 -08001/*
2 * Copyright (C) 2017 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
Lloyd Pique3b5a69e2020-01-16 17:51:01 -080017#include <compositionengine/impl/HwcBufferCache.h>
18
Chia-I Wuaaff73f2017-02-13 12:28:24 -080019#include <gui/BufferQueue.h>
Lloyd Pique76ed7032018-12-04 17:24:28 -080020#include <ui/GraphicBuffer.h>
Chia-I Wuaaff73f2017-02-13 12:28:24 -080021
Lloyd Pique76ed7032018-12-04 17:24:28 -080022namespace android::compositionengine::impl {
Chia-I Wuaaff73f2017-02-13 12:28:24 -080023
Lloyd Pique76ed7032018-12-04 17:24:28 -080024HwcBufferCache::HwcBufferCache() {
Brian Lindahl90553da2022-12-06 13:36:30 -070025 for (uint32_t i = kMaxLayerBufferCount; i-- > 0;) {
Brian Lindahl439afad2022-11-14 11:16:55 -070026 mFreeSlots.push(i);
27 }
Valerie Hau6f89c372019-03-02 00:13:33 +000028}
29
Brian Lindahl439afad2022-11-14 11:16:55 -070030HwcSlotAndBuffer HwcBufferCache::getHwcSlotAndBuffer(const sp<GraphicBuffer>& buffer) {
31 // TODO(b/261930578): This is for unit tests which don't mock GraphicBuffers but instead send
32 // in nullptrs.
33 if (buffer == nullptr) {
34 return {0, nullptr};
Valerie Hau13f0d1a2019-03-22 10:35:42 -070035 }
Brian Lindahl439afad2022-11-14 11:16:55 -070036 if (auto i = mCacheByBufferId.find(buffer->getId()); i != mCacheByBufferId.end()) {
37 Cache& cache = i->second;
38 // mark this cache slot as more recently used so it won't get evicted anytime soon
39 cache.lruCounter = mLeastRecentlyUsedCounter++;
40 return {cache.slot, nullptr};
Chia-I Wuaaff73f2017-02-13 12:28:24 -080041 }
Brian Lindahl439afad2022-11-14 11:16:55 -070042 return {cache(buffer), buffer};
43}
44
45HwcSlotAndBuffer HwcBufferCache::getHwcSlotAndBufferForOverride(const sp<GraphicBuffer>& buffer) {
46 if (buffer == mLastOverrideBuffer) {
47 return {kOverrideBufferSlot, nullptr};
48 }
49 mLastOverrideBuffer = buffer;
50 return {kOverrideBufferSlot, buffer};
51}
52
53uint32_t HwcBufferCache::uncache(uint64_t bufferId) {
54 if (auto i = mCacheByBufferId.find(bufferId); i != mCacheByBufferId.end()) {
55 uint32_t slot = i->second.slot;
56 mCacheByBufferId.erase(i);
57 mFreeSlots.push(slot);
58 return slot;
59 }
60 if (mLastOverrideBuffer && bufferId == mLastOverrideBuffer->getId()) {
61 mLastOverrideBuffer = nullptr;
62 return kOverrideBufferSlot;
63 }
64 return UINT32_MAX;
65}
66
67uint32_t HwcBufferCache::cache(const sp<GraphicBuffer>& buffer) {
68 Cache cache;
69 cache.slot = getLeastRecentlyUsedSlot();
70 cache.lruCounter = mLeastRecentlyUsedCounter++;
71 cache.buffer = buffer;
72 mCacheByBufferId.emplace(buffer->getId(), cache);
73 return cache.slot;
74}
75
76uint32_t HwcBufferCache::getLeastRecentlyUsedSlot() {
77 if (mFreeSlots.empty()) {
78 assert(!mCacheByBufferId.empty());
79 // evict the least recently used cache entry
80 auto cacheToErase = mCacheByBufferId.begin();
81 for (auto i = cacheToErase; i != mCacheByBufferId.end(); ++i) {
82 if (i->second.lruCounter < cacheToErase->second.lruCounter) {
83 cacheToErase = i;
84 }
85 }
86 uint32_t slot = cacheToErase->second.slot;
87 mCacheByBufferId.erase(cacheToErase);
88 mFreeSlots.push(slot);
89 }
90 uint32_t slot = mFreeSlots.top();
91 mFreeSlots.pop();
92 return slot;
Chia-I Wuaaff73f2017-02-13 12:28:24 -080093}
94
Lloyd Pique76ed7032018-12-04 17:24:28 -080095} // namespace android::compositionengine::impl