renderbuffer_manager.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint max_samples)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : memory_tracker_(
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_renderbuffer_size_(max_renderbuffer_size),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_samples_(max_samples),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_uncleared_renderbuffers_(0),
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      renderbuffer_count_(0),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      have_context_(true) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderbufferManager::~RenderbufferManager() {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(renderbuffers_.empty());
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this triggers, that means something is keeping a reference to
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a Renderbuffer belonging to this.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(renderbuffer_count_, 0u);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(0, num_uncleared_renderbuffers_);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t Renderbuffer::EstimatedSize() {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 size = 0;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderbufferManager::ComputeEstimatedRenderbufferSize(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      width_, height_, samples_, internal_format_, &size);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return size;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Renderbuffer::AddToSignature(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* signature) const {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(signature);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *signature += base::StringPrintf(
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "|Renderbuffer|internal_format=%04x|samples=%d|width=%d|height=%d",
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal_format_, samples_, width_, height_);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Renderbuffer::Renderbuffer(RenderbufferManager* manager,
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           GLuint client_id,
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           GLuint service_id)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : manager_(manager),
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      client_id_(client_id),
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service_id_(service_id),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cleared_(true),
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      has_been_bound_(false),
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      samples_(0),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal_format_(GL_RGBA4),
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      width_(0),
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      height_(0) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_->StartTracking(this);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Renderbuffer::~Renderbuffer() {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (manager_) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (manager_->have_context_) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLuint id = service_id();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      glDeleteRenderbuffersEXT(1, &id);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager_->StopTracking(this);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager_ = NULL;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderbufferManager::Destroy(bool have_context) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  have_context_ = have_context;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renderbuffers_.clear();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, memory_tracker_->GetMemRepresented());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++renderbuffer_count_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  --renderbuffer_count_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!renderbuffer->cleared()) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --num_uncleared_renderbuffers_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderbufferManager::SetInfo(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Renderbuffer* renderbuffer,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(renderbuffer);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!renderbuffer->cleared()) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --num_uncleared_renderbuffers_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  renderbuffer->SetInfo(samples, internalformat, width, height);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!renderbuffer->cleared()) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_uncleared_renderbuffers_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool cleared) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(renderbuffer);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!renderbuffer->cleared()) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --num_uncleared_renderbuffers_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renderbuffer->set_cleared(cleared);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!renderbuffer->cleared()) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_uncleared_renderbuffers_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::CreateRenderbuffer(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint client_id, GLuint service_id) {
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Renderbuffer> renderbuffer(
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new Renderbuffer(this, client_id, service_id));
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::pair<RenderbufferMap::iterator, bool> result =
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      renderbuffers_.insert(std::make_pair(client_id, renderbuffer));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(result.second);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!renderbuffer->cleared()) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_uncleared_renderbuffers_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Renderbuffer* RenderbufferManager::GetRenderbuffer(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint client_id) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderbufferMap::iterator it = renderbuffers_.find(client_id);
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return it != renderbuffers_.end() ? it->second.get() : NULL;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderbufferMap::iterator it = renderbuffers_.find(client_id);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it != renderbuffers_.end()) {
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Renderbuffer* renderbuffer = it->second.get();
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    renderbuffer->MarkAsDeleted();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    renderbuffers_.erase(it);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RenderbufferManager::ComputeEstimatedRenderbufferSize(
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int width, int height, int samples, int internal_format, uint32* size) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(size);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 temp = 0;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SafeMultiplyUint32(width, height, &temp)) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SafeMultiplyUint32(temp, samples, &temp)) {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SafeMultiplyUint32(
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *size = temp;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat(
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum impl_format) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (impl_format) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GL_DEPTH_COMPONENT16:
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_DEPTH_COMPONENT;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GL_RGBA4:
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GL_RGB5_A1:
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_RGBA;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GL_RGB565:
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_RGB;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return impl_format;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192