diff options
Diffstat (limited to 'chromium/gpu/command_buffer/service/renderbuffer_manager.cc')
-rw-r--r-- | chromium/gpu/command_buffer/service/renderbuffer_manager.cc | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/renderbuffer_manager.cc b/chromium/gpu/command_buffer/service/renderbuffer_manager.cc new file mode 100644 index 00000000000..0190c449452 --- /dev/null +++ b/chromium/gpu/command_buffer/service/renderbuffer_manager.cc @@ -0,0 +1,191 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/renderbuffer_manager.h" +#include "base/debug/trace_event.h" +#include "base/logging.h" +#include "base/strings/stringprintf.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "gpu/command_buffer/service/memory_tracking.h" +#include "ui/gl/gl_implementation.h" + +namespace gpu { +namespace gles2 { + +RenderbufferManager::RenderbufferManager( + MemoryTracker* memory_tracker, + GLint max_renderbuffer_size, + GLint max_samples) + : memory_tracker_( + new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), + max_renderbuffer_size_(max_renderbuffer_size), + max_samples_(max_samples), + num_uncleared_renderbuffers_(0), + renderbuffer_count_(0), + have_context_(true) { +} + +RenderbufferManager::~RenderbufferManager() { + DCHECK(renderbuffers_.empty()); + // If this triggers, that means something is keeping a reference to + // a Renderbuffer belonging to this. + CHECK_EQ(renderbuffer_count_, 0u); + + DCHECK_EQ(0, num_uncleared_renderbuffers_); +} + +size_t Renderbuffer::EstimatedSize() { + uint32 size = 0; + RenderbufferManager::ComputeEstimatedRenderbufferSize( + width_, height_, samples_, internal_format_, &size); + return size; +} + +void Renderbuffer::AddToSignature( + std::string* signature) const { + DCHECK(signature); + *signature += base::StringPrintf( + "|Renderbuffer|internal_format=%04x|samples=%d|width=%d|height=%d", + internal_format_, samples_, width_, height_); +} + +Renderbuffer::Renderbuffer(RenderbufferManager* manager, + GLuint client_id, + GLuint service_id) + : manager_(manager), + client_id_(client_id), + service_id_(service_id), + cleared_(true), + has_been_bound_(false), + samples_(0), + internal_format_(GL_RGBA4), + width_(0), + height_(0) { + manager_->StartTracking(this); +} + +Renderbuffer::~Renderbuffer() { + if (manager_) { + if (manager_->have_context_) { + GLuint id = service_id(); + glDeleteRenderbuffersEXT(1, &id); + } + manager_->StopTracking(this); + manager_ = NULL; + } +} + +void RenderbufferManager::Destroy(bool have_context) { + have_context_ = have_context; + renderbuffers_.clear(); + DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); +} + +void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) { + ++renderbuffer_count_; +} + +void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) { + --renderbuffer_count_; + if (!renderbuffer->cleared()) { + --num_uncleared_renderbuffers_; + } + memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize()); +} + +void RenderbufferManager::SetInfo( + Renderbuffer* renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { + DCHECK(renderbuffer); + if (!renderbuffer->cleared()) { + --num_uncleared_renderbuffers_; + } + memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize()); + renderbuffer->SetInfo(samples, internalformat, width, height); + memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize()); + if (!renderbuffer->cleared()) { + ++num_uncleared_renderbuffers_; + } +} + +void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer, + bool cleared) { + DCHECK(renderbuffer); + if (!renderbuffer->cleared()) { + --num_uncleared_renderbuffers_; + } + renderbuffer->set_cleared(cleared); + if (!renderbuffer->cleared()) { + ++num_uncleared_renderbuffers_; + } +} + +void RenderbufferManager::CreateRenderbuffer( + GLuint client_id, GLuint service_id) { + scoped_refptr<Renderbuffer> renderbuffer( + new Renderbuffer(this, client_id, service_id)); + std::pair<RenderbufferMap::iterator, bool> result = + renderbuffers_.insert(std::make_pair(client_id, renderbuffer)); + DCHECK(result.second); + if (!renderbuffer->cleared()) { + ++num_uncleared_renderbuffers_; + } +} + +Renderbuffer* RenderbufferManager::GetRenderbuffer( + GLuint client_id) { + RenderbufferMap::iterator it = renderbuffers_.find(client_id); + return it != renderbuffers_.end() ? it->second.get() : NULL; +} + +void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) { + RenderbufferMap::iterator it = renderbuffers_.find(client_id); + if (it != renderbuffers_.end()) { + Renderbuffer* renderbuffer = it->second.get(); + renderbuffer->MarkAsDeleted(); + renderbuffers_.erase(it); + } +} + +bool RenderbufferManager::ComputeEstimatedRenderbufferSize( + int width, int height, int samples, int internal_format, uint32* size) { + DCHECK(size); + + uint32 temp = 0; + if (!SafeMultiplyUint32(width, height, &temp)) { + return false; + } + if (!SafeMultiplyUint32(temp, samples, &temp)) { + return false; + } + GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format); + if (!SafeMultiplyUint32( + temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) { + return false; + } + *size = temp; + return true; +} + +GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( + GLenum impl_format) { + if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { + switch (impl_format) { + case GL_DEPTH_COMPONENT16: + return GL_DEPTH_COMPONENT; + case GL_RGBA4: + case GL_RGB5_A1: + return GL_RGBA; + case GL_RGB565: + return GL_RGB; + } + } + return impl_format; +} + +} // namespace gles2 +} // namespace gpu + + |