blob: 1ac57cdbac0cc882fb94d77fff7466d42b90d3fa [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
Chris Craik48a8f432016-02-05 15:59:29 -080043RenderBufferCache::RenderBufferCache()
44 : mSize(0)
45 , mMaxSize(Properties::renderBufferCacheSize) {}
Romain Guy8d4aeb72013-02-12 16:08:55 -080046
47RenderBufferCache::~RenderBufferCache() {
48 clear();
49}
50
51///////////////////////////////////////////////////////////////////////////////
52// Size management
53///////////////////////////////////////////////////////////////////////////////
54
55uint32_t RenderBufferCache::getSize() {
56 return mSize;
57}
58
59uint32_t RenderBufferCache::getMaxSize() {
60 return mMaxSize;
61}
62
Romain Guy8d4aeb72013-02-12 16:08:55 -080063///////////////////////////////////////////////////////////////////////////////
64// Caching
65///////////////////////////////////////////////////////////////////////////////
66
67int RenderBufferCache::RenderBufferEntry::compare(
68 const RenderBufferCache::RenderBufferEntry& lhs,
69 const RenderBufferCache::RenderBufferEntry& rhs) {
70 int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
71 if (deltaInt != 0) return deltaInt;
72
73 deltaInt = int(lhs.mHeight) - int(rhs.mHeight);
74 if (deltaInt != 0) return deltaInt;
75
76 return int(lhs.mFormat) - int(rhs.mFormat);
77}
78
79void RenderBufferCache::deleteBuffer(RenderBuffer* buffer) {
80 if (buffer) {
81 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)",
82 RenderBuffer::formatName(buffer->getFormat()),
83 buffer->getWidth(), buffer->getHeight());
84
85 mSize -= buffer->getSize();
86 delete buffer;
87 }
88}
89
90void RenderBufferCache::clear() {
John Reckbef837d2015-07-29 16:51:05 -070091 for (auto entry : mCache) {
92 deleteBuffer(entry.mBuffer);
Romain Guy8d4aeb72013-02-12 16:08:55 -080093 }
94 mCache.clear();
95}
96
97RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) {
Chris Craikd41c4d82015-01-05 15:51:13 -080098 RenderBuffer* buffer = nullptr;
Romain Guy8d4aeb72013-02-12 16:08:55 -080099
100 RenderBufferEntry entry(format, width, height);
John Reckbef837d2015-07-29 16:51:05 -0700101 auto iter = mCache.find(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800102
John Reckbef837d2015-07-29 16:51:05 -0700103 if (iter != mCache.end()) {
104 entry = *iter;
105 mCache.erase(iter);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800106
107 buffer = entry.mBuffer;
108 mSize -= buffer->getSize();
109
110 RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)",
111 RenderBuffer::formatName(format), width, height);
112 } else {
113 buffer = new RenderBuffer(format, width, height);
114
115 RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)",
116 RenderBuffer::formatName(format), width, height);
117 }
118
119 buffer->bind();
120 buffer->allocate();
121
122 return buffer;
123}
124
125bool RenderBufferCache::put(RenderBuffer* buffer) {
126 if (!buffer) return false;
127
128 const uint32_t size = buffer->getSize();
129 if (size < mMaxSize) {
130 while (mSize + size > mMaxSize) {
John Reckbef837d2015-07-29 16:51:05 -0700131 RenderBuffer* victim = mCache.begin()->mBuffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800132 deleteBuffer(victim);
John Reckbef837d2015-07-29 16:51:05 -0700133 mCache.erase(mCache.begin());
Romain Guy8d4aeb72013-02-12 16:08:55 -0800134 }
135
136 RenderBufferEntry entry(buffer);
137
John Reckbef837d2015-07-29 16:51:05 -0700138 mCache.insert(entry);
Romain Guy8d4aeb72013-02-12 16:08:55 -0800139 mSize += size;
140
141 RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
142 RenderBuffer::formatName(buffer->getFormat()),
143 buffer->getWidth(), buffer->getHeight());
144
145 return true;
Samsunge11f3ab2014-09-24 10:52:13 -0700146 } else {
147 RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d",
148 RenderBuffer::formatName(buffer->getFormat()),
149 buffer->getWidth(), buffer->getHeight(), size, mMaxSize);
150 delete buffer;
Romain Guy8d4aeb72013-02-12 16:08:55 -0800151 }
152 return false;
153}
154
155}; // namespace uirenderer
156}; // namespace android