1 /* 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 17 #include "Debug.h" 18 #include "Properties.h" 19 #include "RenderBufferCache.h" 20 21 #include <utils/Log.h> 22 23 #include <cstdlib> 24 25 namespace android { 26 namespace 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 43 RenderBufferCache::RenderBufferCache() 44 : mSize(0) 45 , mMaxSize(Properties::renderBufferCacheSize) {} 46 47 RenderBufferCache::~RenderBufferCache() { 48 clear(); 49 } 50 51 /////////////////////////////////////////////////////////////////////////////// 52 // Size management 53 /////////////////////////////////////////////////////////////////////////////// 54 55 uint32_t RenderBufferCache::getSize() { 56 return mSize; 57 } 58 59 uint32_t RenderBufferCache::getMaxSize() { 60 return mMaxSize; 61 } 62 63 /////////////////////////////////////////////////////////////////////////////// 64 // Caching 65 /////////////////////////////////////////////////////////////////////////////// 66 67 int 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 79 void 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 90 void RenderBufferCache::clear() { 91 for (auto entry : mCache) { 92 deleteBuffer(entry.mBuffer); 93 } 94 mCache.clear(); 95 } 96 97 RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) { 98 RenderBuffer* buffer = nullptr; 99 100 RenderBufferEntry entry(format, width, height); 101 auto iter = mCache.find(entry); 102 103 if (iter != mCache.end()) { 104 entry = *iter; 105 mCache.erase(iter); 106 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 125 bool 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) { 131 RenderBuffer* victim = mCache.begin()->mBuffer; 132 deleteBuffer(victim); 133 mCache.erase(mCache.begin()); 134 } 135 136 RenderBufferEntry entry(buffer); 137 138 mCache.insert(entry); 139 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; 146 } 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; 151 } 152 return false; 153 } 154 155 }; // namespace uirenderer 156 }; // namespace android 157