Fix bad field type in ScriptRequestIncident.
[chromium-blink-merge.git] / gpu / command_buffer / service / renderbuffer_manager.cc
blob4b4337ef144e6e7fdf137126901ff6f884f7bf06
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/gles2_cmd_decoder.h"
12 #include "gpu/command_buffer/service/memory_tracking.h"
13 #include "ui/gl/gl_implementation.h"
15 namespace gpu {
16 namespace gles2 {
18 // This should contain everything to uniquely identify a Renderbuffer.
19 static const char RenderbufferTag[] = "|Renderbuffer|";
20 struct RenderbufferSignature {
21 GLenum internal_format_;
22 GLsizei samples_;
23 GLsizei width_;
24 GLsizei height_;
26 // Since we will be hashing this signature structure, the padding must be
27 // zero initialized. Although the C++11 specifications specify that this is
28 // true, we will use a constructor with a memset to further enforce it instead
29 // of relying on compilers adhering to this deep dark corner specification.
30 RenderbufferSignature(GLenum internal_format,
31 GLsizei samples,
32 GLsizei width,
33 GLsizei height) {
34 memset(this, 0, sizeof(RenderbufferSignature));
35 internal_format_ = internal_format;
36 samples_ = samples;
37 width_ = width;
38 height_ = height;
42 RenderbufferManager::RenderbufferManager(
43 MemoryTracker* memory_tracker,
44 GLint max_renderbuffer_size,
45 GLint max_samples,
46 bool depth24_supported)
47 : memory_tracker_(
48 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
49 max_renderbuffer_size_(max_renderbuffer_size),
50 max_samples_(max_samples),
51 depth24_supported_(depth24_supported),
52 num_uncleared_renderbuffers_(0),
53 renderbuffer_count_(0),
54 have_context_(true) {
57 RenderbufferManager::~RenderbufferManager() {
58 DCHECK(renderbuffers_.empty());
59 // If this triggers, that means something is keeping a reference to
60 // a Renderbuffer belonging to this.
61 CHECK_EQ(renderbuffer_count_, 0u);
63 DCHECK_EQ(0, num_uncleared_renderbuffers_);
66 size_t Renderbuffer::EstimatedSize() {
67 uint32 size = 0;
68 manager_->ComputeEstimatedRenderbufferSize(
69 width_, height_, samples_, internal_format_, &size);
70 return size;
74 size_t Renderbuffer::GetSignatureSize() const {
75 return sizeof(RenderbufferTag) + sizeof(RenderbufferSignature);
78 void Renderbuffer::AddToSignature(std::string* signature) const {
79 DCHECK(signature);
80 RenderbufferSignature signature_data(internal_format_,
81 samples_,
82 width_,
83 height_);
85 signature->append(RenderbufferTag, sizeof(RenderbufferTag));
86 signature->append(reinterpret_cast<const char*>(&signature_data),
87 sizeof(signature_data));
90 Renderbuffer::Renderbuffer(RenderbufferManager* manager,
91 GLuint client_id,
92 GLuint service_id)
93 : manager_(manager),
94 client_id_(client_id),
95 service_id_(service_id),
96 cleared_(true),
97 has_been_bound_(false),
98 samples_(0),
99 internal_format_(GL_RGBA4),
100 width_(0),
101 height_(0) {
102 manager_->StartTracking(this);
105 Renderbuffer::~Renderbuffer() {
106 if (manager_) {
107 if (manager_->have_context_) {
108 GLuint id = service_id();
109 glDeleteRenderbuffersEXT(1, &id);
111 manager_->StopTracking(this);
112 manager_ = NULL;
116 void RenderbufferManager::Destroy(bool have_context) {
117 have_context_ = have_context;
118 renderbuffers_.clear();
119 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented());
122 void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) {
123 ++renderbuffer_count_;
126 void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) {
127 --renderbuffer_count_;
128 if (!renderbuffer->cleared()) {
129 --num_uncleared_renderbuffers_;
131 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
134 void RenderbufferManager::SetInfo(
135 Renderbuffer* renderbuffer,
136 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
137 DCHECK(renderbuffer);
138 if (!renderbuffer->cleared()) {
139 --num_uncleared_renderbuffers_;
141 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
142 renderbuffer->SetInfo(samples, internalformat, width, height);
143 memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize());
144 if (!renderbuffer->cleared()) {
145 ++num_uncleared_renderbuffers_;
149 void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer,
150 bool cleared) {
151 DCHECK(renderbuffer);
152 if (!renderbuffer->cleared()) {
153 --num_uncleared_renderbuffers_;
155 renderbuffer->set_cleared(cleared);
156 if (!renderbuffer->cleared()) {
157 ++num_uncleared_renderbuffers_;
161 void RenderbufferManager::CreateRenderbuffer(
162 GLuint client_id, GLuint service_id) {
163 scoped_refptr<Renderbuffer> renderbuffer(
164 new Renderbuffer(this, client_id, service_id));
165 std::pair<RenderbufferMap::iterator, bool> result =
166 renderbuffers_.insert(std::make_pair(client_id, renderbuffer));
167 DCHECK(result.second);
168 if (!renderbuffer->cleared()) {
169 ++num_uncleared_renderbuffers_;
173 Renderbuffer* RenderbufferManager::GetRenderbuffer(
174 GLuint client_id) {
175 RenderbufferMap::iterator it = renderbuffers_.find(client_id);
176 return it != renderbuffers_.end() ? it->second.get() : NULL;
179 void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) {
180 RenderbufferMap::iterator it = renderbuffers_.find(client_id);
181 if (it != renderbuffers_.end()) {
182 Renderbuffer* renderbuffer = it->second.get();
183 renderbuffer->MarkAsDeleted();
184 renderbuffers_.erase(it);
188 bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width,
189 int height,
190 int samples,
191 int internal_format,
192 uint32* size) const {
193 DCHECK(size);
195 uint32 temp = 0;
196 if (!SafeMultiplyUint32(width, height, &temp)) {
197 return false;
199 if (!SafeMultiplyUint32(temp, samples, &temp)) {
200 return false;
202 GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format);
203 if (!SafeMultiplyUint32(
204 temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) {
205 return false;
207 *size = temp;
208 return true;
211 GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat(
212 GLenum impl_format) const {
213 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
214 switch (impl_format) {
215 case GL_DEPTH_COMPONENT16:
216 return GL_DEPTH_COMPONENT;
217 case GL_RGBA4:
218 case GL_RGB5_A1:
219 return GL_RGBA;
220 case GL_RGB565:
221 return GL_RGB;
223 } else {
224 // Upgrade 16-bit depth to 24-bit if possible.
225 if (impl_format == GL_DEPTH_COMPONENT16 && depth24_supported_)
226 return GL_DEPTH_COMPONENT24;
228 return impl_format;
231 } // namespace gles2
232 } // namespace gpu