blob: 98010d8da1bd9c8a13e2ba8ec227fc50bc5f5f25 [file] [log] [blame]
Romain Guy8d4aeb72013-02-12 16:08:55 -08001/*
2 * Copyright (C) 2013 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
Romain Guy8d4aeb72013-02-12 16:08:55 -080017#include "RenderBufferCache.h"
John Reck1bcacfd2017-11-03 10:12:19 -070018#include "Debug.h"
John Reck8dc02f92017-07-17 09:55:02 -070019#include "DeviceInfo.h"
John Reck1bcacfd2017-11-03 10:12:19 -070020#include "Properties.h"
Romain Guy8d4aeb72013-02-12 16:08:55 -080021
John Reck6b507802015-11-03 10:09:59 -080022#include <utils/Log.h>
23
24#include <cstdlib>
25
Romain Guy8d4aeb72013-02-12 16:08:55 -080026namespace android {
27namespace uirenderer {
28
29///////////////////////////////////////////////////////////////////////////////
30// Defines
31///////////////////////////////////////////////////////////////////////////////
32
33// Debug
34#if DEBUG_RENDER_BUFFERS
John Reck1bcacfd2017-11-03 10:12:19 -070035#define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__)
Romain Guy8d4aeb72013-02-12 16:08:55 -080036#else
John Reck1bcacfd2017-11-03 10:12:19 -070037#define RENDER_BUFFER_LOGD(...)
Romain Guy8d4aeb72013-02-12 16:08:55 -080038#endif
39
John Reck8dc02f92017-07-17 09:55:02 -070040static uint32_t calculateRboCacheSize() {
41 // TODO: Do we need to use extensions().has4BitStencil() here?
42 // The tuning guide recommends it, but all real devices are configured
43 // with a larger cache than necessary by 4x, so keep the 2x for now regardless
44 return DeviceInfo::multiplyByResolution(2);
45}
46
Romain Guy8d4aeb72013-02-12 16:08:55 -080047///////////////////////////////////////////////////////////////////////////////
48// Constructors/destructor
49///////////////////////////////////////////////////////////////////////////////
50
John Reck1bcacfd2017-11-03 10:12:19 -070051RenderBufferCache::RenderBufferCache() : mSize(0), mMaxSize(calculateRboCacheSize()) {}
Romain Guy8d4aeb72013-02-12 16:08:55 -080052
53RenderBufferCache::~RenderBufferCache() {
54 clear();
55}
56
57///////////////////////////////////////////////////////////////////////////////
58// Size management
59///////////////////////////////////////////////////////////////////////////////
60
61uint32_t RenderBufferCache::getSize() {
62 return mSize;
63}
64
65uint32_t RenderBufferCache::getMaxSize() {
66 return mMaxSize;
67}
68
Romain Guy8d4aeb72013-02-12 16:08:55 -080069///////////////////////////////////////////////////////////////////////////////
70// Caching
71///////////////////////////////////////////////////////////////////////////////
72
John Reck1bcacfd2017-11-03 10:12:19 -070073int RenderBufferCache::RenderBufferEntry::compare(const RenderBufferCache::RenderBufferEntry& lhs,
74 const RenderBufferCache::RenderBufferEntry& rhs) {
Romain Guy8d4aeb72013-02-12 16:08:55 -080075 int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
76 if (deltaInt != 0) return deltaInt;
77
78 deltaInt = int(lhs.mHeight) - int(rhs.mHeight);
79 if (deltaInt != 0) return deltaInt;
80
81 return int(lhs.mFormat) - int(rhs.mFormat);
82}
83
84void RenderBufferCache::deleteBuffer(RenderBuffer* buffer) {
85 if (buffer) {
86 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)",
John Reck1bcacfd2017-11-03 10:12:19 -070087 RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(),
88 buffer->getHeight());
Romain Guy8d4aeb72013-02-12 16:08:55 -080089
90 mSize -= buffer->getSize();
91 delete buffer;
92 }
93}
94
95void RenderBufferCache::clear() {
John Reckbef837d2015-07-29 16:51:05 -070096 for (auto entry : mCache) {
97 deleteBuffer(entry.mBuffer);
Romain Guy8d4aeb72013-02-12 16:08:55 -080098 }
99 mCache.clear();
100}
101
102RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) {
Chris Craikd41c4d82015-01-05 15:51:13 -0800103 RenderBuffer* buffer = nullptr;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800104
105 RenderBufferEntry entry(format, width, height);
John Reckbef837d2015-07-29 16:51:05 -0700106 auto iter = mCache.find(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800107
John Reckbef837d2015-07-29 16:51:05 -0700108 if (iter != mCache.end()) {
109 entry = *iter;
110 mCache.erase(iter);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800111
112 buffer = entry.mBuffer;
113 mSize -= buffer->getSize();
114
John Reck1bcacfd2017-11-03 10:12:19 -0700115 RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)", RenderBuffer::formatName(format),
116 width, height);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800117 } else {
118 buffer = new RenderBuffer(format, width, height);
119
John Reck1bcacfd2017-11-03 10:12:19 -0700120 RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)", RenderBuffer::formatName(format),
121 width, height);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800122 }
123
124 buffer->bind();
125 buffer->allocate();
126
127 return buffer;
128}
129
130bool RenderBufferCache::put(RenderBuffer* buffer) {
131 if (!buffer) return false;
132
133 const uint32_t size = buffer->getSize();
134 if (size < mMaxSize) {
135 while (mSize + size > mMaxSize) {
John Reckbef837d2015-07-29 16:51:05 -0700136 RenderBuffer* victim = mCache.begin()->mBuffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800137 deleteBuffer(victim);
John Reckbef837d2015-07-29 16:51:05 -0700138 mCache.erase(mCache.begin());
Romain Guy8d4aeb72013-02-12 16:08:55 -0800139 }
140
141 RenderBufferEntry entry(buffer);
142
John Reckbef837d2015-07-29 16:51:05 -0700143 mCache.insert(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800144 mSize += size;
145
146 RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
John Reck1bcacfd2017-11-03 10:12:19 -0700147 RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(),
148 buffer->getHeight());
Romain Guy8d4aeb72013-02-12 16:08:55 -0800149
150 return true;
Samsunge11f3ab2014-09-24 10:52:13 -0700151 } else {
152 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d",
John Reck1bcacfd2017-11-03 10:12:19 -0700153 RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(),
154 buffer->getHeight(), size, mMaxSize);
Samsunge11f3ab2014-09-24 10:52:13 -0700155 delete buffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800156 }
157 return false;
158}
159
John Reck1bcacfd2017-11-03 10:12:19 -0700160}; // namespace uirenderer
161}; // namespace android