[sql] Remove _HAS_EXCEPTIONS=0 from build info.
[chromium-blink-merge.git] / gpu / command_buffer / service / renderbuffer_manager.cc
blob2b57e57c955197c5118b5cb64dea5305802451a3
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.
5 #include "gpu/command_buffer/service/renderbuffer_manager.h"
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/trace_event/trace_event.h"
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
11 #include "gpu/command_buffer/service/feature_info.h"
12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
13 #include "gpu/command_buffer/service/memory_tracking.h"
14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_version_info.h"
17 namespace gpu {
18 namespace gles2 {
20 // This should contain everything to uniquely identify a Renderbuffer.
21 static const char RenderbufferTag[] = "|Renderbuffer|";
22 struct RenderbufferSignature {
23 GLenum internal_format_;
24 GLsizei samples_;
25 GLsizei width_;
26 GLsizei height_;
28 // Since we will be hashing this signature structure, the padding must be
29 // zero initialized. Although the C++11 specifications specify that this is
30 // true, we will use a constructor with a memset to further enforce it instead
31 // of relying on compilers adhering to this deep dark corner specification.
32 RenderbufferSignature(GLenum internal_format,
33 GLsizei samples,
34 GLsizei width,
35 GLsizei height) {
36 memset(this, 0, sizeof(RenderbufferSignature));
37 internal_format_ = internal_format;
38 samples_ = samples;
39 width_ = width;
40 height_ = height;
44 RenderbufferManager::RenderbufferManager(
45 MemoryTracker* memory_tracker,
46 GLint max_renderbuffer_size,
47 GLint max_samples,
48 FeatureInfo* feature_info)
49 : memory_tracker_(
50 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
51 max_renderbuffer_size_(max_renderbuffer_size),
52 max_samples_(max_samples),
53 feature_info_(feature_info),
54 num_uncleared_renderbuffers_(0),
55 renderbuffer_count_(0),
56 have_context_(true) {
59 RenderbufferManager::~RenderbufferManager() {
60 DCHECK(renderbuffers_.empty());
61 // If this triggers, that means something is keeping a reference to
62 // a Renderbuffer belonging to this.
63 CHECK_EQ(renderbuffer_count_, 0u);
65 DCHECK_EQ(0, num_uncleared_renderbuffers_);
68 size_t Renderbuffer::EstimatedSize() {
69 uint32 size = 0;
70 manager_->ComputeEstimatedRenderbufferSize(
71 width_, height_, samples_, internal_format_, &size);
72 return size;
76 size_t Renderbuffer::GetSignatureSize() const {
77 return sizeof(RenderbufferTag) + sizeof(RenderbufferSignature);
80 void Renderbuffer::AddToSignature(std::string* signature) const {
81 DCHECK(signature);
82 RenderbufferSignature signature_data(internal_format_,
83 samples_,
84 width_,
85 height_);
87 signature->append(RenderbufferTag, sizeof(RenderbufferTag));
88 signature->append(reinterpret_cast<const char*>(&signature_data),
89 sizeof(signature_data));
92 Renderbuffer::Renderbuffer(RenderbufferManager* manager,
93 GLuint client_id,
94 GLuint service_id)
95 : manager_(manager),
96 client_id_(client_id),
97 service_id_(service_id),
98 cleared_(true),
99 has_been_bound_(false),
100 samples_(0),
101 internal_format_(GL_RGBA4),
102 width_(0),
103 height_(0) {
104 manager_->StartTracking(this);
107 Renderbuffer::~Renderbuffer() {
108 if (manager_) {
109 if (manager_->have_context_) {
110 GLuint id = service_id();
111 glDeleteRenderbuffersEXT(1, &id);
113 manager_->StopTracking(this);
114 manager_ = NULL;
118 void RenderbufferManager::Destroy(bool have_context) {
119 have_context_ = have_context;
120 renderbuffers_.clear();
121 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented());
124 void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) {
125 ++renderbuffer_count_;
128 void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) {
129 --renderbuffer_count_;
130 if (!renderbuffer->cleared()) {
131 --num_uncleared_renderbuffers_;
133 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
136 void RenderbufferManager::SetInfo(
137 Renderbuffer* renderbuffer,
138 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
139 DCHECK(renderbuffer);
140 if (!renderbuffer->cleared()) {
141 --num_uncleared_renderbuffers_;
143 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
144 renderbuffer->SetInfo(samples, internalformat, width, height);
145 memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize());
146 if (!renderbuffer->cleared()) {
147 ++num_uncleared_renderbuffers_;
151 void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer,
152 bool cleared) {
153 DCHECK(renderbuffer);
154 if (!renderbuffer->cleared()) {
155 --num_uncleared_renderbuffers_;
157 renderbuffer->set_cleared(cleared);
158 if (!renderbuffer->cleared()) {
159 ++num_uncleared_renderbuffers_;
163 void RenderbufferManager::CreateRenderbuffer(
164 GLuint client_id, GLuint service_id) {
165 scoped_refptr<Renderbuffer> renderbuffer(
166 new Renderbuffer(this, client_id, service_id));
167 std::pair<RenderbufferMap::iterator, bool> result =
168 renderbuffers_.insert(std::make_pair(client_id, renderbuffer));
169 DCHECK(result.second);
170 if (!renderbuffer->cleared()) {
171 ++num_uncleared_renderbuffers_;
175 Renderbuffer* RenderbufferManager::GetRenderbuffer(
176 GLuint client_id) {
177 RenderbufferMap::iterator it = renderbuffers_.find(client_id);
178 return it != renderbuffers_.end() ? it->second.get() : NULL;
181 void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) {
182 RenderbufferMap::iterator it = renderbuffers_.find(client_id);
183 if (it != renderbuffers_.end()) {
184 Renderbuffer* renderbuffer = it->second.get();
185 renderbuffer->MarkAsDeleted();
186 renderbuffers_.erase(it);
190 bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width,
191 int height,
192 int samples,
193 int internal_format,
194 uint32* size) const {
195 DCHECK(size);
197 uint32 temp = 0;
198 if (!SafeMultiplyUint32(width, height, &temp)) {
199 return false;
201 if (!SafeMultiplyUint32(temp, samples, &temp)) {
202 return false;
204 GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format);
205 if (!SafeMultiplyUint32(
206 temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) {
207 return false;
209 *size = temp;
210 return true;
213 GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat(
214 GLenum impl_format) const {
215 if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
216 switch (impl_format) {
217 case GL_DEPTH_COMPONENT16:
218 return GL_DEPTH_COMPONENT;
219 case GL_RGBA4:
220 case GL_RGB5_A1:
221 return GL_RGBA;
222 case GL_RGB565:
223 return GL_RGB;
225 } else {
226 // Upgrade 16-bit depth to 24-bit if possible.
227 if (impl_format == GL_DEPTH_COMPONENT16 &&
228 feature_info_->feature_flags().oes_depth24)
229 return GL_DEPTH_COMPONENT24;
231 return impl_format;
234 } // namespace gles2
235 } // namespace gpu