blob: 2f8ddfe6d6606d49104da459224c86d4080a88bc [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 "Debug.h"
18#include "Properties.h"
19#include "RenderBufferCache.h"
John Reck8dc02f92017-07-17 09:55:02 -070020#include "DeviceInfo.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
35 #define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__)
36#else
37 #define RENDER_BUFFER_LOGD(...)
38#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
Chris Craik48a8f432016-02-05 15:59:29 -080051RenderBufferCache::RenderBufferCache()
52 : mSize(0)
John Reck8dc02f92017-07-17 09:55:02 -070053 , mMaxSize(calculateRboCacheSize()) {}
Romain Guy8d4aeb72013-02-12 16:08:55 -080054
55RenderBufferCache::~RenderBufferCache() {
56 clear();
57}
58
59///////////////////////////////////////////////////////////////////////////////
60// Size management
61///////////////////////////////////////////////////////////////////////////////
62
63uint32_t RenderBufferCache::getSize() {
64 return mSize;
65}
66
67uint32_t RenderBufferCache::getMaxSize() {
68 return mMaxSize;
69}
70
Romain Guy8d4aeb72013-02-12 16:08:55 -080071///////////////////////////////////////////////////////////////////////////////
72// Caching
73///////////////////////////////////////////////////////////////////////////////
74
75int RenderBufferCache::RenderBufferEntry::compare(
76 const RenderBufferCache::RenderBufferEntry& lhs,
77 const RenderBufferCache::RenderBufferEntry& rhs) {
78 int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
79 if (deltaInt != 0) return deltaInt;
80
81 deltaInt = int(lhs.mHeight) - int(rhs.mHeight);
82 if (deltaInt != 0) return deltaInt;
83
84 return int(lhs.mFormat) - int(rhs.mFormat);
85}
86
87void RenderBufferCache::deleteBuffer(RenderBuffer* buffer) {
88 if (buffer) {
89 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)",
90 RenderBuffer::formatName(buffer->getFormat()),
91 buffer->getWidth(), buffer->getHeight());
92
93 mSize -= buffer->getSize();
94 delete buffer;
95 }
96}
97
98void RenderBufferCache::clear() {
John Reckbef837d2015-07-29 16:51:05 -070099 for (auto entry : mCache) {
100 deleteBuffer(entry.mBuffer);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800101 }
102 mCache.clear();
103}
104
105RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) {
Chris Craikd41c4d82015-01-05 15:51:13 -0800106 RenderBuffer* buffer = nullptr;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800107
108 RenderBufferEntry entry(format, width, height);
John Reckbef837d2015-07-29 16:51:05 -0700109 auto iter = mCache.find(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800110
John Reckbef837d2015-07-29 16:51:05 -0700111 if (iter != mCache.end()) {
112 entry = *iter;
113 mCache.erase(iter);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800114
115 buffer = entry.mBuffer;
116 mSize -= buffer->getSize();
117
118 RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)",
119 RenderBuffer::formatName(format), width, height);
120 } else {
121 buffer = new RenderBuffer(format, width, height);
122
123 RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)",
124 RenderBuffer::formatName(format), width, height);
125 }
126
127 buffer->bind();
128 buffer->allocate();
129
130 return buffer;
131}
132
133bool RenderBufferCache::put(RenderBuffer* buffer) {
134 if (!buffer) return false;
135
136 const uint32_t size = buffer->getSize();
137 if (size < mMaxSize) {
138 while (mSize + size > mMaxSize) {
John Reckbef837d2015-07-29 16:51:05 -0700139 RenderBuffer* victim = mCache.begin()->mBuffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800140 deleteBuffer(victim);
John Reckbef837d2015-07-29 16:51:05 -0700141 mCache.erase(mCache.begin());
Romain Guy8d4aeb72013-02-12 16:08:55 -0800142 }
143
144 RenderBufferEntry entry(buffer);
145
John Reckbef837d2015-07-29 16:51:05 -0700146 mCache.insert(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800147 mSize += size;
148
149 RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
150 RenderBuffer::formatName(buffer->getFormat()),
151 buffer->getWidth(), buffer->getHeight());
152
153 return true;
Samsunge11f3ab2014-09-24 10:52:13 -0700154 } else {
155 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d",
156 RenderBuffer::formatName(buffer->getFormat()),
157 buffer->getWidth(), buffer->getHeight(), size, mMaxSize);
158 delete buffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800159 }
160 return false;
161}
162
163}; // namespace uirenderer
164}; // namespace android