renderbuffer_manager.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/renderbuffer_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gles2_cmd_decoder.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_implementation.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderbufferManager::RenderbufferManager( 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryTracker* memory_tracker, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_renderbuffer_size, 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GLint max_samples, 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool depth24_supported) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : memory_tracker_( 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_renderbuffer_size_(max_renderbuffer_size), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_samples_(max_samples), 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) depth24_supported_(depth24_supported), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_uncleared_renderbuffers_(0), 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) renderbuffer_count_(0), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) have_context_(true) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderbufferManager::~RenderbufferManager() { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(renderbuffers_.empty()); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this triggers, that means something is keeping a reference to 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a Renderbuffer belonging to this. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(renderbuffer_count_, 0u); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0, num_uncleared_renderbuffers_); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t Renderbuffer::EstimatedSize() { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size = 0; 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) manager_->ComputeEstimatedRenderbufferSize( 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width_, height_, samples_, internal_format_, &size); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return size; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Renderbuffer::AddToSignature( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* signature) const { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(signature); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *signature += base::StringPrintf( 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "|Renderbuffer|internal_format=%04x|samples=%d|width=%d|height=%d", 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal_format_, samples_, width_, height_); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Renderbuffer::Renderbuffer(RenderbufferManager* manager, 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GLuint client_id, 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GLuint service_id) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : manager_(manager), 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) client_id_(client_id), 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_id_(service_id), 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleared_(true), 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_been_bound_(false), 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) samples_(0), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal_format_(GL_RGBA4), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width_(0), 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) height_(0) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_->StartTracking(this); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Renderbuffer::~Renderbuffer() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manager_) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manager_->have_context_) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint id = service_id(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glDeleteRenderbuffersEXT(1, &id); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->StopTracking(this); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_ = NULL; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderbufferManager::Destroy(bool have_context) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) have_context_ = have_context; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) renderbuffers_.clear(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++renderbuffer_count_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --renderbuffer_count_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderbuffer->cleared()) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --num_uncleared_renderbuffers_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize()); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderbufferManager::SetInfo( 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Renderbuffer* renderbuffer, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(renderbuffer); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderbuffer->cleared()) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --num_uncleared_renderbuffers_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) renderbuffer->SetInfo(samples, internalformat, width, height); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderbuffer->cleared()) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_uncleared_renderbuffers_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer, 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool cleared) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(renderbuffer); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderbuffer->cleared()) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --num_uncleared_renderbuffers_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) renderbuffer->set_cleared(cleared); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderbuffer->cleared()) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_uncleared_renderbuffers_; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::CreateRenderbuffer( 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint client_id, GLuint service_id) { 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<Renderbuffer> renderbuffer( 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new Renderbuffer(this, client_id, service_id)); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::pair<RenderbufferMap::iterator, bool> result = 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) renderbuffers_.insert(std::make_pair(client_id, renderbuffer)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result.second); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!renderbuffer->cleared()) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_uncleared_renderbuffers_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Renderbuffer* RenderbufferManager::GetRenderbuffer( 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint client_id) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderbufferMap::iterator it = renderbuffers_.find(client_id); 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return it != renderbuffers_.end() ? it->second.get() : NULL; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderbufferMap::iterator it = renderbuffers_.find(client_id); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != renderbuffers_.end()) { 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Renderbuffer* renderbuffer = it->second.get(); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) renderbuffer->MarkAsDeleted(); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) renderbuffers_.erase(it); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width, 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int height, 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int samples, 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int internal_format, 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint32* size) const { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(size); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 temp = 0; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!SafeMultiplyUint32(width, height, &temp)) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!SafeMultiplyUint32(temp, samples, &temp)) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!SafeMultiplyUint32( 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *size = temp; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GLenum impl_format) const { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (impl_format) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_DEPTH_COMPONENT16: 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GL_DEPTH_COMPONENT; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_RGBA4: 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_RGB5_A1: 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GL_RGBA; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_RGB565: 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GL_RGB; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Upgrade 16-bit depth to 24-bit if possible. 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (impl_format == GL_DEPTH_COMPONENT16 && depth24_supported_) 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GL_DEPTH_COMPONENT24; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return impl_format; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gles2 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 201