blob: 11d7a6af3a6aa588d38fee98d9485498fef21f97 [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"
20
John Reck6b507802015-11-03 10:09:59 -080021#include <utils/Log.h>
22
23#include <cstdlib>
24
Romain Guy8d4aeb72013-02-12 16:08:55 -080025namespace android {
26namespace uirenderer {
27
28///////////////////////////////////////////////////////////////////////////////
29// Defines
30///////////////////////////////////////////////////////////////////////////////
31
32// Debug
33#if DEBUG_RENDER_BUFFERS
34 #define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__)
35#else
36 #define RENDER_BUFFER_LOGD(...)
37#endif
38
39///////////////////////////////////////////////////////////////////////////////
40// Constructors/destructor
41///////////////////////////////////////////////////////////////////////////////
42
43RenderBufferCache::RenderBufferCache(): mSize(0), mMaxSize(MB(DEFAULT_RENDER_BUFFER_CACHE_SIZE)) {
44 char property[PROPERTY_VALUE_MAX];
Chris Craikd41c4d82015-01-05 15:51:13 -080045 if (property_get(PROPERTY_RENDER_BUFFER_CACHE_SIZE, property, nullptr) > 0) {
Romain Guy8d4aeb72013-02-12 16:08:55 -080046 INIT_LOGD(" Setting render buffer cache size to %sMB", property);
47 setMaxSize(MB(atof(property)));
48 } else {
49 INIT_LOGD(" Using default render buffer cache size of %.2fMB",
50 DEFAULT_RENDER_BUFFER_CACHE_SIZE);
51 }
52}
53
54RenderBufferCache::~RenderBufferCache() {
55 clear();
56}
57
58///////////////////////////////////////////////////////////////////////////////
59// Size management
60///////////////////////////////////////////////////////////////////////////////
61
62uint32_t RenderBufferCache::getSize() {
63 return mSize;
64}
65
66uint32_t RenderBufferCache::getMaxSize() {
67 return mMaxSize;
68}
69
70void RenderBufferCache::setMaxSize(uint32_t maxSize) {
71 clear();
72 mMaxSize = maxSize;
73}
74
75///////////////////////////////////////////////////////////////////////////////
76// Caching
77///////////////////////////////////////////////////////////////////////////////
78
79int RenderBufferCache::RenderBufferEntry::compare(
80 const RenderBufferCache::RenderBufferEntry& lhs,
81 const RenderBufferCache::RenderBufferEntry& rhs) {
82 int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
83 if (deltaInt != 0) return deltaInt;
84
85 deltaInt = int(lhs.mHeight) - int(rhs.mHeight);
86 if (deltaInt != 0) return deltaInt;
87
88 return int(lhs.mFormat) - int(rhs.mFormat);
89}
90
91void RenderBufferCache::deleteBuffer(RenderBuffer* buffer) {
92 if (buffer) {
93 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)",
94 RenderBuffer::formatName(buffer->getFormat()),
95 buffer->getWidth(), buffer->getHeight());
96
97 mSize -= buffer->getSize();
98 delete buffer;
99 }
100}
101
102void RenderBufferCache::clear() {
John Reckbef837d2015-07-29 16:51:05 -0700103 for (auto entry : mCache) {
104 deleteBuffer(entry.mBuffer);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800105 }
106 mCache.clear();
107}
108
109RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) {
Chris Craikd41c4d82015-01-05 15:51:13 -0800110 RenderBuffer* buffer = nullptr;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800111
112 RenderBufferEntry entry(format, width, height);
John Reckbef837d2015-07-29 16:51:05 -0700113 auto iter = mCache.find(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800114
John Reckbef837d2015-07-29 16:51:05 -0700115 if (iter != mCache.end()) {
116 entry = *iter;
117 mCache.erase(iter);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800118
119 buffer = entry.mBuffer;
120 mSize -= buffer->getSize();
121
122 RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)",
123 RenderBuffer::formatName(format), width, height);
124 } else {
125 buffer = new RenderBuffer(format, width, height);
126
127 RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)",
128 RenderBuffer::formatName(format), width, height);
129 }
130
131 buffer->bind();
132 buffer->allocate();
133
134 return buffer;
135}
136
137bool RenderBufferCache::put(RenderBuffer* buffer) {
138 if (!buffer) return false;
139
140 const uint32_t size = buffer->getSize();
141 if (size < mMaxSize) {
142 while (mSize + size > mMaxSize) {
John Reckbef837d2015-07-29 16:51:05 -0700143 RenderBuffer* victim = mCache.begin()->mBuffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800144 deleteBuffer(victim);
John Reckbef837d2015-07-29 16:51:05 -0700145 mCache.erase(mCache.begin());
Romain Guy8d4aeb72013-02-12 16:08:55 -0800146 }
147
148 RenderBufferEntry entry(buffer);
149
John Reckbef837d2015-07-29 16:51:05 -0700150 mCache.insert(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800151 mSize += size;
152
153 RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
154 RenderBuffer::formatName(buffer->getFormat()),
155 buffer->getWidth(), buffer->getHeight());
156
157 return true;
Samsunge11f3ab2014-09-24 10:52:13 -0700158 } else {
159 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d",
160 RenderBuffer::formatName(buffer->getFormat()),
161 buffer->getWidth(), buffer->getHeight(), size, mMaxSize);
162 delete buffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800163 }
164 return false;
165}
166
167}; // namespace uirenderer
168}; // namespace android