OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/framebuffer_manager.h" | 5 #include "gpu/command_buffer/service/framebuffer_manager.h" |
6 #include "base/logging.h" | 6 #include "base/logging.h" |
7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
8 | 8 |
9 namespace gpu { | 9 namespace gpu { |
10 namespace gles2 { | 10 namespace gles2 { |
11 | 11 |
12 class RenderbufferAttachment | 12 class RenderbufferAttachment |
13 : public FramebufferManager::FramebufferInfo::Attachment { | 13 : public FramebufferManager::FramebufferInfo::Attachment { |
14 public: | 14 public: |
15 explicit RenderbufferAttachment( | 15 explicit RenderbufferAttachment( |
16 RenderbufferManager::RenderbufferInfo* render_buffer) | 16 RenderbufferManager::RenderbufferInfo* renderbuffer) |
17 : render_buffer_(render_buffer) { | 17 : renderbuffer_(renderbuffer) { |
18 } | 18 } |
19 | 19 |
20 virtual ~RenderbufferAttachment() { } | 20 virtual ~RenderbufferAttachment() { } |
21 | 21 |
22 virtual GLsizei width() const { | 22 virtual GLsizei width() const { |
23 return render_buffer_->width(); | 23 return renderbuffer_->width(); |
24 } | 24 } |
25 | 25 |
26 virtual GLsizei height() const { | 26 virtual GLsizei height() const { |
27 return render_buffer_->height(); | 27 return renderbuffer_->height(); |
28 } | 28 } |
29 | 29 |
30 virtual GLenum internal_format() const { | 30 virtual GLenum internal_format() const { |
31 return render_buffer_->internal_format(); | 31 return renderbuffer_->internal_format(); |
32 } | 32 } |
33 | 33 |
34 virtual GLsizei samples() const { | 34 virtual GLsizei samples() const { |
35 return render_buffer_->samples(); | 35 return renderbuffer_->samples(); |
36 } | 36 } |
37 | 37 |
38 virtual bool cleared() const { | 38 virtual bool cleared() const { |
39 return render_buffer_->cleared(); | 39 return renderbuffer_->cleared(); |
40 } | 40 } |
41 | 41 |
42 virtual void set_cleared() { | 42 virtual void SetCleared( |
43 render_buffer_->set_cleared(); | 43 RenderbufferManager* renderbuffer_manager, |
| 44 TextureManager* /* texture_manager */) { |
| 45 renderbuffer_manager->SetCleared(renderbuffer_); |
44 } | 46 } |
45 | 47 |
46 virtual bool IsTexture(TextureManager::TextureInfo* /* texture */) const { | 48 virtual bool IsTexture(TextureManager::TextureInfo* /* texture */) const { |
47 return false; | 49 return false; |
48 } | 50 } |
49 | 51 |
50 virtual bool CanRenderTo() const { | 52 virtual bool CanRenderTo() const { |
51 return true; | 53 return true; |
52 } | 54 } |
53 | 55 |
54 RenderbufferManager::RenderbufferInfo* render_buffer() const { | 56 virtual void DetachFromFramebuffer() { |
55 return render_buffer_.get(); | 57 // Nothing to do for renderbuffers. |
| 58 } |
| 59 |
| 60 virtual bool ValidForAttachmentType(GLenum attachment_type) { |
| 61 // TODO(gman): Fill this out. |
| 62 return true; |
| 63 } |
| 64 |
| 65 RenderbufferManager::RenderbufferInfo* renderbuffer() const { |
| 66 return renderbuffer_.get(); |
56 } | 67 } |
57 | 68 |
58 private: | 69 private: |
59 RenderbufferManager::RenderbufferInfo::Ref render_buffer_; | 70 RenderbufferManager::RenderbufferInfo::Ref renderbuffer_; |
60 | 71 |
61 DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment); | 72 DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment); |
62 }; | 73 }; |
63 | 74 |
64 class TextureAttachment | 75 class TextureAttachment |
65 : public FramebufferManager::FramebufferInfo::Attachment { | 76 : public FramebufferManager::FramebufferInfo::Attachment { |
66 public: | 77 public: |
67 TextureAttachment( | 78 TextureAttachment( |
68 TextureManager::TextureInfo* texture, GLenum target, GLint level) | 79 TextureManager::TextureInfo* texture, GLenum target, GLint level) |
69 : texture_(texture), | 80 : texture_(texture), |
(...skipping 22 matching lines...) Expand all Loading... |
92 GLenum temp_internal_format = 0; | 103 GLenum temp_internal_format = 0; |
93 texture_->GetLevelType(target_, level_, &temp_type, &temp_internal_format); | 104 texture_->GetLevelType(target_, level_, &temp_type, &temp_internal_format); |
94 return temp_internal_format; | 105 return temp_internal_format; |
95 } | 106 } |
96 | 107 |
97 virtual GLsizei samples() const { | 108 virtual GLsizei samples() const { |
98 return 0; | 109 return 0; |
99 } | 110 } |
100 | 111 |
101 virtual bool cleared() const { | 112 virtual bool cleared() const { |
102 // Textures are cleared on creation. | 113 return texture_->IsLevelCleared(target_, level_); |
103 return true; | |
104 } | 114 } |
105 | 115 |
106 virtual void set_cleared() { | 116 virtual void SetCleared( |
107 NOTREACHED(); | 117 RenderbufferManager* /* renderbuffer_manager */, |
| 118 TextureManager* texture_manager) { |
| 119 texture_manager->SetLevelCleared(texture_, target_, level_); |
108 } | 120 } |
109 | 121 |
110 virtual bool IsTexture(TextureManager::TextureInfo* texture) const { | 122 virtual bool IsTexture(TextureManager::TextureInfo* texture) const { |
111 return texture == texture_.get(); | 123 return texture == texture_.get(); |
112 } | 124 } |
113 | 125 |
114 TextureManager::TextureInfo* texture() const { | 126 TextureManager::TextureInfo* texture() const { |
115 return texture_.get(); | 127 return texture_.get(); |
116 } | 128 } |
117 | 129 |
118 virtual bool CanRenderTo() const { | 130 virtual bool CanRenderTo() const { |
119 return texture_->CanRenderTo(); | 131 return texture_->CanRenderTo(); |
120 } | 132 } |
121 | 133 |
| 134 virtual void DetachFromFramebuffer() { |
| 135 texture_->DetachFromFramebuffer(); |
| 136 } |
| 137 |
| 138 virtual bool ValidForAttachmentType(GLenum attachment_type) { |
| 139 // TODO(gman): Fill this out. |
| 140 return true; |
| 141 } |
| 142 |
122 private: | 143 private: |
123 TextureManager::TextureInfo::Ref texture_; | 144 TextureManager::TextureInfo::Ref texture_; |
124 GLenum target_; | 145 GLenum target_; |
125 GLint level_; | 146 GLint level_; |
126 | 147 |
127 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); | 148 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); |
128 }; | 149 }; |
129 | 150 |
130 FramebufferManager::FramebufferManager() {} | 151 FramebufferManager::FramebufferManager() {} |
131 | 152 |
132 FramebufferManager::~FramebufferManager() { | 153 FramebufferManager::~FramebufferManager() { |
133 DCHECK(framebuffer_infos_.empty()); | 154 DCHECK(framebuffer_infos_.empty()); |
134 } | 155 } |
135 | 156 |
| 157 void FramebufferManager::FramebufferInfo::MarkAsDeleted() { |
| 158 service_id_ = 0; |
| 159 while (!attachments_.empty()) { |
| 160 Attachment* attachment = attachments_.begin()->second.get(); |
| 161 attachment->DetachFromFramebuffer(); |
| 162 attachments_.erase(attachments_.begin()); |
| 163 } |
| 164 } |
| 165 |
136 void FramebufferManager::Destroy(bool have_context) { | 166 void FramebufferManager::Destroy(bool have_context) { |
137 while (!framebuffer_infos_.empty()) { | 167 while (!framebuffer_infos_.empty()) { |
138 if (have_context) { | 168 FramebufferInfo* info = framebuffer_infos_.begin()->second; |
139 FramebufferInfo* info = framebuffer_infos_.begin()->second; | 169 if (!info->IsDeleted()) { |
140 if (!info->IsDeleted()) { | 170 if (have_context) { |
141 GLuint service_id = info->service_id(); | 171 GLuint service_id = info->service_id(); |
142 glDeleteFramebuffersEXT(1, &service_id); | 172 glDeleteFramebuffersEXT(1, &service_id); |
143 info->MarkAsDeleted(); | |
144 } | 173 } |
| 174 info->MarkAsDeleted(); |
145 } | 175 } |
146 framebuffer_infos_.erase(framebuffer_infos_.begin()); | 176 framebuffer_infos_.erase(framebuffer_infos_.begin()); |
147 } | 177 } |
148 } | 178 } |
149 | 179 |
150 void FramebufferManager::CreateFramebufferInfo( | 180 void FramebufferManager::CreateFramebufferInfo( |
151 GLuint client_id, GLuint service_id) { | 181 GLuint client_id, GLuint service_id) { |
152 std::pair<FramebufferInfoMap::iterator, bool> result = | 182 std::pair<FramebufferInfoMap::iterator, bool> result = |
153 framebuffer_infos_.insert( | 183 framebuffer_infos_.insert( |
154 std::make_pair( | 184 std::make_pair( |
155 client_id, | 185 client_id, |
156 FramebufferInfo::Ref(new FramebufferInfo(service_id)))); | 186 FramebufferInfo::Ref(new FramebufferInfo(service_id)))); |
157 DCHECK(result.second); | 187 DCHECK(result.second); |
158 } | 188 } |
159 | 189 |
160 FramebufferManager::FramebufferInfo::FramebufferInfo(GLuint service_id) | 190 FramebufferManager::FramebufferInfo::FramebufferInfo(GLuint service_id) |
161 : service_id_(service_id) | 191 : service_id_(service_id), |
162 , has_been_bound_(false) { | 192 has_been_bound_(false) { |
163 } | 193 } |
164 | 194 |
165 FramebufferManager::FramebufferInfo::~FramebufferInfo() {} | 195 FramebufferManager::FramebufferInfo::~FramebufferInfo() {} |
166 | 196 |
167 bool FramebufferManager::FramebufferInfo::HasUnclearedAttachment( | 197 bool FramebufferManager::FramebufferInfo::HasUnclearedAttachment( |
168 GLenum attachment) const { | 198 GLenum attachment) const { |
169 AttachmentMap::const_iterator it = | 199 AttachmentMap::const_iterator it = |
170 attachments_.find(attachment); | 200 attachments_.find(attachment); |
171 if (it != attachments_.end()) { | 201 if (it != attachments_.end()) { |
172 const Attachment* attachment = it->second; | 202 const Attachment* attachment = it->second; |
173 return !attachment->cleared(); | 203 return !attachment->cleared(); |
174 } | 204 } |
175 return false; | 205 return false; |
176 } | 206 } |
177 | 207 |
178 void FramebufferManager::FramebufferInfo::MarkAttachedRenderbuffersAsCleared() { | 208 void FramebufferManager::FramebufferInfo::MarkAttachmentsAsCleared( |
| 209 RenderbufferManager* renderbuffer_manager, |
| 210 TextureManager* texture_manager) { |
179 for (AttachmentMap::iterator it = attachments_.begin(); | 211 for (AttachmentMap::iterator it = attachments_.begin(); |
180 it != attachments_.end(); ++it) { | 212 it != attachments_.end(); ++it) { |
181 Attachment* attachment = it->second; | 213 Attachment* attachment = it->second; |
182 if (!attachment->cleared()) { | 214 if (!attachment->cleared()) { |
183 attachment->set_cleared(); | 215 attachment->SetCleared(renderbuffer_manager, texture_manager); |
184 } | 216 } |
185 } | 217 } |
186 } | 218 } |
187 | 219 |
188 bool FramebufferManager::FramebufferInfo::HasDepthAttachment() const { | 220 bool FramebufferManager::FramebufferInfo::HasDepthAttachment() const { |
189 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 221 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || |
190 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); | 222 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); |
191 } | 223 } |
192 | 224 |
193 bool FramebufferManager::FramebufferInfo::HasStencilAttachment() const { | 225 bool FramebufferManager::FramebufferInfo::HasStencilAttachment() const { |
194 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 226 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || |
195 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); | 227 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); |
196 } | 228 } |
197 | 229 |
198 GLenum FramebufferManager::FramebufferInfo::GetColorAttachmentFormat() const { | 230 GLenum FramebufferManager::FramebufferInfo::GetColorAttachmentFormat() const { |
199 AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); | 231 AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); |
200 if (it == attachments_.end()) { | 232 if (it == attachments_.end()) { |
201 return 0; | 233 return 0; |
202 } | 234 } |
203 const Attachment* attachment = it->second; | 235 const Attachment* attachment = it->second; |
204 return attachment->internal_format(); | 236 return attachment->internal_format(); |
205 } | 237 } |
206 | 238 |
207 bool FramebufferManager::FramebufferInfo::IsNotComplete() const { | 239 GLenum FramebufferManager::FramebufferInfo::IsPossiblyComplete() const { |
| 240 if (attachments_.empty()) { |
| 241 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; |
| 242 } |
| 243 |
| 244 GLsizei width = -1; |
| 245 GLsizei height = -1; |
| 246 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 247 it != attachments_.end(); ++it) { |
| 248 GLenum attachment_type = it->first; |
| 249 Attachment* attachment = it->second; |
| 250 if (!attachment->ValidForAttachmentType(attachment_type)) { |
| 251 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
| 252 } |
| 253 if (width < 0) { |
| 254 width = attachment->width(); |
| 255 height = attachment->height(); |
| 256 if (width == 0 || height == 0) { |
| 257 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
| 258 } |
| 259 } else { |
| 260 if (attachment->width() != width || attachment->height() != height) { |
| 261 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT; |
| 262 } |
| 263 } |
| 264 |
| 265 if (!attachment->CanRenderTo()) { |
| 266 return GL_FRAMEBUFFER_UNSUPPORTED; |
| 267 } |
| 268 } |
| 269 |
| 270 // This does not mean the framebuffer is actually complete. It just means our |
| 271 // checks passed. |
| 272 return GL_FRAMEBUFFER_COMPLETE; |
| 273 } |
| 274 |
| 275 bool FramebufferManager::FramebufferInfo::IsCleared() const { |
| 276 // are all the attachments cleaared? |
208 for (AttachmentMap::const_iterator it = attachments_.begin(); | 277 for (AttachmentMap::const_iterator it = attachments_.begin(); |
209 it != attachments_.end(); ++it) { | 278 it != attachments_.end(); ++it) { |
210 Attachment* attachment = it->second; | 279 Attachment* attachment = it->second; |
211 if (attachment->width() == 0 || attachment->height() == 0) { | 280 if (!attachment->cleared()) { |
212 return true; | 281 return false; |
213 } | |
214 if (!attachment->CanRenderTo()) { | |
215 return true; | |
216 } | 282 } |
217 } | 283 } |
218 return false; | 284 return true; |
219 } | 285 } |
220 | 286 |
221 FramebufferManager::FramebufferInfo* FramebufferManager::GetFramebufferInfo( | 287 FramebufferManager::FramebufferInfo* FramebufferManager::GetFramebufferInfo( |
222 GLuint client_id) { | 288 GLuint client_id) { |
223 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); | 289 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); |
224 return it != framebuffer_infos_.end() ? it->second : NULL; | 290 return it != framebuffer_infos_.end() ? it->second : NULL; |
225 } | 291 } |
226 | 292 |
227 void FramebufferManager::RemoveFramebufferInfo(GLuint client_id) { | 293 void FramebufferManager::RemoveFramebufferInfo(GLuint client_id) { |
228 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); | 294 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 return true; | 352 return true; |
287 } | 353 } |
288 } | 354 } |
289 return false; | 355 return false; |
290 } | 356 } |
291 | 357 |
292 } // namespace gles2 | 358 } // namespace gles2 |
293 } // namespace gpu | 359 } // namespace gpu |
294 | 360 |
295 | 361 |
OLD | NEW |