Don't add an aura tooltip to bubble close buttons on Windows.
[chromium-blink-merge.git] / gpu / command_buffer / service / renderbuffer_manager.cc
blob2af22de12c0a602335e814417ac677b27197cdcc
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"
16 namespace gpu {
17 namespace gles2 {
19 // This should contain everything to uniquely identify a Renderbuffer.
20 static const char RenderbufferTag[] = "|Renderbuffer|";
21 struct RenderbufferSignature {
22 GLenum internal_format_;
23 GLsizei samples_;
24 GLsizei width_;
25 GLsizei height_;
27 // Since we will be hashing this signature structure, the padding must be
28 // zero initialized. Although the C++11 specifications specify that this is
29 // true, we will use a constructor with a memset to further enforce it instead
30 // of relying on compilers adhering to this deep dark corner specification.
31 RenderbufferSignature(GLenum internal_format,
32 GLsizei samples,
33 GLsizei width,
34 GLsizei height) {
35 memset(this, 0, sizeof(RenderbufferSignature));
36 internal_format_ = internal_format;
37 samples_ = samples;
38 width_ = width;
39 height_ = height;
43 RenderbufferManager::RenderbufferManager(
44 MemoryTracker* memory_tracker,
45 GLint max_renderbuffer_size,
46 GLint max_samples,
47 FeatureInfo* feature_info)
48 : memory_tracker_(
49 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
50 max_renderbuffer_size_(max_renderbuffer_size),
51 max_samples_(max_samples),
52 feature_info_(feature_info),
53 num_uncleared_renderbuffers_(0),
54 renderbuffer_count_(0),
55 have_context_(true) {
58 RenderbufferManager::~RenderbufferManager() {
59 DCHECK(renderbuffers_.empty());
60 // If this triggers, that means something is keeping a reference to
61 // a Renderbuffer belonging to this.
62 CHECK_EQ(renderbuffer_count_, 0u);
64 DCHECK_EQ(0, num_uncleared_renderbuffers_);
67 size_t Renderbuffer::EstimatedSize() {
68 uint32 size = 0;
69 manager_->ComputeEstimatedRenderbufferSize(
70 width_, height_, samples_, internal_format_, &size);
71 return size;
75 size_t Renderbuffer::GetSignatureSize() const {
76 return sizeof(RenderbufferTag) + sizeof(RenderbufferSignature);
79 void Renderbuffer::AddToSignature(std::string* signature) const {
80 DCHECK(signature);
81 RenderbufferSignature signature_data(internal_format_,
82 samples_,
83 width_,
84 height_);
86 signature->append(RenderbufferTag, sizeof(RenderbufferTag));
87 signature->append(reinterpret_cast<const char*>(&signature_data),
88 sizeof(signature_data));
91 Renderbuffer::Renderbuffer(RenderbufferManager* manager,
92 GLuint client_id,
93 GLuint service_id)
94 : manager_(manager),
95 client_id_(client_id),
96 service_id_(service_id),
97 cleared_(true),
98 has_been_bound_(false),
99 samples_(0),
100 internal_format_(GL_RGBA4),
101 width_(0),
102 height_(0) {
103 manager_->StartTracking(this);
106 Renderbuffer::~Renderbuffer() {
107 if (manager_) {
108 if (manager_->have_context_) {
109 GLuint id = service_id();
110 glDeleteRenderbuffersEXT(1, &id);
112 manager_->StopTracking(this);
113 manager_ = NULL;
117 void RenderbufferManager::Destroy(bool have_context) {
118 have_context_ = have_context;
119 renderbuffers_.clear();
120 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented());
123 void RenderbufferManager::StartTracking(Renderbuffer* /* renderbuffer */) {
124 ++renderbuffer_count_;
127 void RenderbufferManager::StopTracking(Renderbuffer* renderbuffer) {
128 --renderbuffer_count_;
129 if (!renderbuffer->cleared()) {
130 --num_uncleared_renderbuffers_;
132 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
135 void RenderbufferManager::SetInfo(
136 Renderbuffer* renderbuffer,
137 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
138 DCHECK(renderbuffer);
139 if (!renderbuffer->cleared()) {
140 --num_uncleared_renderbuffers_;
142 memory_tracker_->TrackMemFree(renderbuffer->EstimatedSize());
143 renderbuffer->SetInfo(samples, internalformat, width, height);
144 memory_tracker_->TrackMemAlloc(renderbuffer->EstimatedSize());
145 if (!renderbuffer->cleared()) {
146 ++num_uncleared_renderbuffers_;
150 void RenderbufferManager::SetCleared(Renderbuffer* renderbuffer,
151 bool cleared) {
152 DCHECK(renderbuffer);
153 if (!renderbuffer->cleared()) {
154 --num_uncleared_renderbuffers_;
156 renderbuffer->set_cleared(cleared);
157 if (!renderbuffer->cleared()) {
158 ++num_uncleared_renderbuffers_;
162 void RenderbufferManager::CreateRenderbuffer(
163 GLuint client_id, GLuint service_id) {
164 scoped_refptr<Renderbuffer> renderbuffer(
165 new Renderbuffer(this, client_id, service_id));
166 std::pair<RenderbufferMap::iterator, bool> result =
167 renderbuffers_.insert(std::make_pair(client_id, renderbuffer));
168 DCHECK(result.second);
169 if (!renderbuffer->cleared()) {
170 ++num_uncleared_renderbuffers_;
174 Renderbuffer* RenderbufferManager::GetRenderbuffer(
175 GLuint client_id) {
176 RenderbufferMap::iterator it = renderbuffers_.find(client_id);
177 return it != renderbuffers_.end() ? it->second.get() : NULL;
180 void RenderbufferManager::RemoveRenderbuffer(GLuint client_id) {
181 RenderbufferMap::iterator it = renderbuffers_.find(client_id);
182 if (it != renderbuffers_.end()) {
183 Renderbuffer* renderbuffer = it->second.get();
184 renderbuffer->MarkAsDeleted();
185 renderbuffers_.erase(it);
189 bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width,
190 int height,
191 int samples,
192 int internal_format,
193 uint32* size) const {
194 DCHECK(size);
196 uint32 temp = 0;
197 if (!SafeMultiplyUint32(width, height, &temp)) {
198 return false;
200 if (!SafeMultiplyUint32(temp, samples, &temp)) {
201 return false;
203 GLenum impl_format = InternalRenderbufferFormatToImplFormat(internal_format);
204 if (!SafeMultiplyUint32(
205 temp, GLES2Util::RenderbufferBytesPerPixel(impl_format), &temp)) {
206 return false;
208 *size = temp;
209 return true;
212 GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat(
213 GLenum impl_format) const {
214 if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
215 switch (impl_format) {
216 case GL_DEPTH_COMPONENT16:
217 return GL_DEPTH_COMPONENT;
218 case GL_RGBA4:
219 case GL_RGB5_A1:
220 return GL_RGBA;
221 case GL_RGB565:
222 return GL_RGB;
224 } else {
225 // Upgrade 16-bit depth to 24-bit if possible.
226 if (impl_format == GL_DEPTH_COMPONENT16 &&
227 feature_info_->feature_flags().oes_depth24)
228 return GL_DEPTH_COMPONENT24;
230 return impl_format;
233 } // namespace gles2
234 } // namespace gpu