renderbuffer_manager.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "gpu/command_buffer/service/renderbuffer_manager.h" 6#include "base/debug/trace_event.h" 7#include "base/logging.h" 8#include "base/strings/stringprintf.h" 9#include "gpu/command_buffer/common/gles2_cmd_utils.h" 10#include "gpu/command_buffer/service/gles2_cmd_decoder.h" 11#include "gpu/command_buffer/service/memory_tracking.h" 12#include "ui/gl/gl_implementation.h" 13 14namespace gpu { 15namespace gles2 { 16 17RenderbufferManager::RenderbufferManager( 18 MemoryTracker* memory_tracker, 19 GLint max_renderbuffer_size, 20 GLint max_samples) 21 : memory_tracker_( 22 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), 23 max_renderbuffer_size_(max_renderbuffer_size), 24 max_samples_(max_samples), 25 num_uncleared_renderbuffers_(0), 26 renderbuffer_count_(0), 27 have_context_(true) { 28} 29 30RenderbufferManager::~RenderbufferManager() { 31 DCHECK(renderbuffers_.empty()); 32 // If this triggers, that means something is keeping a reference to 33 // a Renderbuffer belonging to this. 34 CHECK_EQ(renderbuffer_count_, 0u); 35 36 DCHECK_EQ(0, num_uncleared_renderbuffers_); 37} 38 39size_t Renderbuffer::EstimatedSize() { 40 uint32 size = 0; 41 RenderbufferManager::ComputeEstimatedRenderbufferSize( 42 width_, height_, samples_, internal_format_, &size); 43 return size; 44} 45 46void Renderbuffer::AddToSignature( 47 std::string* signature) const { 48 DCHECK(signature); 49 *signature += base::StringPrintf( 50 "|Renderbuffer|internal_format=%04x|samples=%d|width=%d|height=%d", 51 internal_format_, samples_, width_, height_); 52} 53 54Renderbuffer::Renderbuffer(RenderbufferManager* manager, 55 GLuint client_id, 56 GLuint service_id) 57 : manager_(manager), 58 client_id_(client_id), 59 service_id_(service_id), 60 cleared_(true), 61 has_been_bound_(false), 62 samples_(0), 63 internal_format_(GL_RGBA4), 64 width_(0), 65 height_(0) { 66 manager_->StartTracking(this); 67} 68 69Renderbuffer::~Renderbuffer() { 70 if (manager_) { 71 if (manager_->have_context_) { 72 GLuint id = service_id(); 73 glDeleteRenderbuffersEXT(1, &id); 74 } 75 manager_->StopTracking(this); 76 manager_ = NULL; 77 } 78} 79 80void RenderbufferManager::Destroy(bool have_context) { 81 have_context_ = have_context; 82 renderbuffers_.clear(); 83 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); 84} 85 86void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) { 87 ++renderbuffer_count_; 88} 89 90void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) { 91 --renderbuffer_count_; 92 if (!renderbuffer->cleared()) { 93 --num_uncleared_renderbuffers_; 94 } 95 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize()); 96} 97 98void RenderbufferManager::SetInfo( 99 Renderbuffer* renderbuffer, 100 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { 101 DCHECK(renderbuffer); 102 if (!renderbuffer->cleared()) { 103 --num_uncleared_renderbuffers_; 104 } 105 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize()); 106 renderbuffer->SetInfo(samples, internalformat, width, height); 107 memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize()); 108 if (!renderbuffer->cleared()) { 109 ++num_uncleared_renderbuffers_; 110 } 111} 112 113void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer, 114 bool cleared) { 115 DCHECK(renderbuffer); 116 if (!renderbuffer->cleared()) { 117 --num_uncleared_renderbuffers_; 118 } 119 renderbuffer->set_cleared(cleared); 120 if (!renderbuffer->cleared()) { 121 ++num_uncleared_renderbuffers_; 122 } 123} 124 125void RenderbufferManager::CreateRenderbuffer( 126 GLuint client_id, GLuint service_id) { 127 scoped_refptr<Renderbuffer> renderbuffer( 128 new Renderbuffer(this, client_id, service_id)); 129 std::pair<RenderbufferMap::iterator, bool> result = 130 renderbuffers_.insert(std::make_pair(client_id, renderbuffer)); 131 DCHECK(result.second); 132 if (!renderbuffer->cleared()) { 133 ++num_uncleared_renderbuffers_; 134 } 135} 136 137Renderbuffer* RenderbufferManager::GetRenderbuffer( 138 GLuint client_id) { 139 RenderbufferMap::iterator it = renderbuffers_.find(client_id); 140 return it != renderbuffers_.end() ? it->second.get() : NULL; 141} 142 143void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) { 144 RenderbufferMap::iterator it = renderbuffers_.find(client_id); 145 if (it != renderbuffers_.end()) { 146 Renderbuffer* renderbuffer = it->second.get(); 147 renderbuffer->MarkAsDeleted(); 148 renderbuffers_.erase(it); 149 } 150} 151 152bool RenderbufferManager::ComputeEstimatedRenderbufferSize( 153 int width, int height, int samples, int internal_format, uint32* size) { 154 DCHECK(size); 155 156 uint32 temp = 0; 157 if (!SafeMultiplyUint32(width, height, &temp)) { 158 return false; 159 } 160 if (!SafeMultiplyUint32(temp, samples, &temp)) { 161 return false; 162 } 163 GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format); 164 if (!SafeMultiplyUint32( 165 temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) { 166 return false; 167 } 168 *size = temp; 169 return true; 170} 171 172GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( 173 GLenum impl_format) { 174 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 175 switch (impl_format) { 176 case GL_DEPTH_COMPONENT16: 177 return GL_DEPTH_COMPONENT; 178 case GL_RGBA4: 179 case GL_RGB5_A1: 180 return GL_RGBA; 181 case GL_RGB565: 182 return GL_RGB; 183 } 184 } 185 return impl_format; 186} 187 188} // namespace gles2 189} // namespace gpu 190 191 192