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