Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(574)

Side by Side Diff: sky/engine/core/html/canvas/WebGLFramebuffer.cpp

Issue 1001913003: Remove <canvas> (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "sky/engine/config.h"
27
28 #include "sky/engine/core/html/canvas/WebGLFramebuffer.h"
29
30 #include "sky/engine/core/html/canvas/WebGLRenderingContextBase.h"
31 #include "sky/engine/platform/NotImplemented.h"
32 #include "sky/engine/wtf/Vector.h"
33
34 namespace blink {
35
36 namespace {
37
38 Platform3DObject objectOrZero(WebGLObject* object)
39 {
40 return object ? object->object() : 0;
41 }
42
43 class WebGLRenderbufferAttachment final : public WebGLFramebuffer::WebGLAtta chment {
44 public:
45 static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderb uffer*);
46
47 private:
48 explicit WebGLRenderbufferAttachment(WebGLRenderbuffer*);
49 WebGLRenderbufferAttachment() { }
50
51 virtual GLsizei width() const override;
52 virtual GLsizei height() const override;
53 virtual GLenum format() const override;
54 virtual GLenum type() const override;
55 virtual WebGLSharedObject* object() const override;
56 virtual bool isSharedObject(WebGLSharedObject*) const override;
57 virtual bool valid() const override;
58 virtual void onDetached(blink::WebGraphicsContext3D*) override;
59 virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) ove rride;
60 virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) o verride;
61
62 RefPtr<WebGLRenderbuffer> m_renderbuffer;
63 };
64
65 PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLRenderbufferAttachment::c reate(WebGLRenderbuffer* renderbuffer)
66 {
67 return adoptRef(new WebGLRenderbufferAttachment(renderbuffer));
68 }
69
70 WebGLRenderbufferAttachment::WebGLRenderbufferAttachment(WebGLRenderbuffer* renderbuffer)
71 : m_renderbuffer(renderbuffer)
72 {
73 }
74
75 GLsizei WebGLRenderbufferAttachment::width() const
76 {
77 return m_renderbuffer->width();
78 }
79
80 GLsizei WebGLRenderbufferAttachment::height() const
81 {
82 return m_renderbuffer->height();
83 }
84
85 GLenum WebGLRenderbufferAttachment::format() const
86 {
87 GLenum format = m_renderbuffer->internalFormat();
88 if (format == GL_DEPTH_STENCIL_OES
89 && m_renderbuffer->emulatedStencilBuffer()
90 && m_renderbuffer->emulatedStencilBuffer()->internalFormat() != GL_S TENCIL_INDEX8) {
91 return 0;
92 }
93 return format;
94 }
95
96 WebGLSharedObject* WebGLRenderbufferAttachment::object() const
97 {
98 return m_renderbuffer->object() ? m_renderbuffer.get() : 0;
99 }
100
101 bool WebGLRenderbufferAttachment::isSharedObject(WebGLSharedObject* object) const
102 {
103 return object == m_renderbuffer;
104 }
105
106 bool WebGLRenderbufferAttachment::valid() const
107 {
108 return m_renderbuffer->object();
109 }
110
111 void WebGLRenderbufferAttachment::onDetached(blink::WebGraphicsContext3D* co ntext)
112 {
113 m_renderbuffer->onDetached(context);
114 }
115
116 void WebGLRenderbufferAttachment::attach(blink::WebGraphicsContext3D* contex t, GLenum attachment)
117 {
118 Platform3DObject object = objectOrZero(m_renderbuffer.get());
119 if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL && m_renderbuffer- >emulatedStencilBuffer()) {
120 context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, object);
121 context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHME NT, GL_RENDERBUFFER, objectOrZero(m_renderbuffer->emulatedStencilBuffer()));
122 } else {
123 context->framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_REND ERBUFFER, object);
124 }
125 }
126
127 void WebGLRenderbufferAttachment::unattach(blink::WebGraphicsContext3D* cont ext, GLenum attachment)
128 {
129 if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
130 context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, 0);
131 context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHME NT, GL_RENDERBUFFER, 0);
132 } else {
133 context->framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_REND ERBUFFER, 0);
134 }
135 }
136
137 GLenum WebGLRenderbufferAttachment::type() const
138 {
139 notImplemented();
140 return 0;
141 }
142
143 class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachmen t {
144 public:
145 static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture *, GLenum target, GLint level);
146
147 private:
148 WebGLTextureAttachment(WebGLTexture*, GLenum target, GLint level);
149 WebGLTextureAttachment() { }
150
151 virtual GLsizei width() const override;
152 virtual GLsizei height() const override;
153 virtual GLenum format() const override;
154 virtual GLenum type() const override;
155 virtual WebGLSharedObject* object() const override;
156 virtual bool isSharedObject(WebGLSharedObject*) const override;
157 virtual bool valid() const override;
158 virtual void onDetached(blink::WebGraphicsContext3D*) override;
159 virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) ove rride;
160 virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) o verride;
161
162 RefPtr<WebGLTexture> m_texture;
163 GLenum m_target;
164 GLint m_level;
165 };
166
167 PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create (WebGLTexture* texture, GLenum target, GLint level)
168 {
169 return adoptRef(new WebGLTextureAttachment(texture, target, level));
170 }
171
172 WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GLenum target, GLint level)
173 : m_texture(texture)
174 , m_target(target)
175 , m_level(level)
176 {
177 }
178
179 GLsizei WebGLTextureAttachment::width() const
180 {
181 return m_texture->getWidth(m_target, m_level);
182 }
183
184 GLsizei WebGLTextureAttachment::height() const
185 {
186 return m_texture->getHeight(m_target, m_level);
187 }
188
189 GLenum WebGLTextureAttachment::format() const
190 {
191 return m_texture->getInternalFormat(m_target, m_level);
192 }
193
194 WebGLSharedObject* WebGLTextureAttachment::object() const
195 {
196 return m_texture->object() ? m_texture.get() : 0;
197 }
198
199 bool WebGLTextureAttachment::isSharedObject(WebGLSharedObject* object) const
200 {
201 return object == m_texture;
202 }
203
204 bool WebGLTextureAttachment::valid() const
205 {
206 return m_texture->object();
207 }
208
209 void WebGLTextureAttachment::onDetached(blink::WebGraphicsContext3D* context )
210 {
211 m_texture->onDetached(context);
212 }
213
214 void WebGLTextureAttachment::attach(blink::WebGraphicsContext3D* context, GL enum attachment)
215 {
216 Platform3DObject object = objectOrZero(m_texture.get());
217 context->framebufferTexture2D(GL_FRAMEBUFFER, attachment, m_target, obje ct, m_level);
218 }
219
220 void WebGLTextureAttachment::unattach(blink::WebGraphicsContext3D* context, GLenum attachment)
221 {
222 if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
223 context->framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m _target, 0, m_level);
224 context->framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, m_target, 0, m_level);
225 } else {
226 context->framebufferTexture2D(GL_FRAMEBUFFER, attachment, m_target, 0, m_level);
227 }
228 }
229
230 GLenum WebGLTextureAttachment::type() const
231 {
232 return m_texture->getType(m_target, m_level);
233 }
234
235 bool isColorRenderable(GLenum internalformat)
236 {
237 switch (internalformat) {
238 case GL_RGBA4:
239 case GL_RGB5_A1:
240 case GL_RGB565:
241 return true;
242 default:
243 return false;
244 }
245 }
246
247 } // anonymous namespace
248
249 WebGLFramebuffer::WebGLAttachment::WebGLAttachment()
250 {
251 }
252
253 WebGLFramebuffer::WebGLAttachment::~WebGLAttachment()
254 {
255 }
256
257 PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContextBase* ctx)
258 {
259 return adoptRef(new WebGLFramebuffer(ctx));
260 }
261
262 WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx)
263 : WebGLContextObject(ctx)
264 , m_hasEverBeenBound(false)
265 {
266 setObject(ctx->webContext()->createFramebuffer());
267 }
268
269 WebGLFramebuffer::~WebGLFramebuffer()
270 {
271 // Delete the platform framebuffer resource. Explicit detachment
272 // is for the benefit of Oilpan, where the framebuffer object
273 // isn't detached when it and the WebGLRenderingContextBase object
274 // it is registered with are both finalized. Without Oilpan, the
275 // object will have been detached.
276 //
277 // To keep the code regular, the trivial detach()ment is always
278 // performed.
279 detachAndDeleteObject();
280 }
281
282 void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, GLenu m texTarget, WebGLTexture* texture, GLint level)
283 {
284 ASSERT(isBound());
285 removeAttachmentFromBoundFramebuffer(attachment);
286 if (!object())
287 return;
288 if (texture && texture->object()) {
289 m_attachments.add(attachment, WebGLTextureAttachment::create(texture, te xTarget, level));
290 drawBuffersIfNecessary(false);
291 texture->onAttached();
292 }
293 }
294
295 void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, WebGL Renderbuffer* renderbuffer)
296 {
297 ASSERT(isBound());
298 removeAttachmentFromBoundFramebuffer(attachment);
299 if (!object())
300 return;
301 if (renderbuffer && renderbuffer->object()) {
302 m_attachments.add(attachment, WebGLRenderbufferAttachment::create(render buffer));
303 drawBuffersIfNecessary(false);
304 renderbuffer->onAttached();
305 }
306 }
307
308 void WebGLFramebuffer::attach(GLenum attachment, GLenum attachmentPoint)
309 {
310 ASSERT(isBound());
311 WebGLAttachment* attachmentObject = getAttachment(attachment);
312 if (attachmentObject)
313 attachmentObject->attach(context()->webContext(), attachmentPoint);
314 }
315
316 WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) cons t
317 {
318 if (!object())
319 return 0;
320 WebGLAttachment* attachmentObject = getAttachment(attachment);
321 return attachmentObject ? attachmentObject->object() : 0;
322 }
323
324 bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLe num attachment, const char** reason) const
325 {
326 ASSERT(attachedObject && attachedObject->valid());
327 ASSERT(reason);
328
329 GLenum internalformat = attachedObject->format();
330 WebGLSharedObject* object = attachedObject->object();
331 ASSERT(object && (object->isTexture() || object->isRenderbuffer()));
332
333 if (attachment == GL_DEPTH_ATTACHMENT) {
334 if (object->isRenderbuffer()) {
335 if (internalformat != GL_DEPTH_COMPONENT16) {
336 *reason = "the internalformat of the attached renderbuffer is no t DEPTH_COMPONENT16";
337 return false;
338 }
339 } else if (object->isTexture()) {
340 GLenum type = attachedObject->type();
341 if (!(context()->extensionEnabled(WebGLDepthTextureName) && internal format == GL_DEPTH_COMPONENT
342 && (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT))) {
343 *reason = "the attached texture is not a depth texture";
344 return false;
345 }
346 }
347 } else if (attachment == GL_STENCIL_ATTACHMENT) {
348 // Depend on the underlying GL drivers to check stencil textures
349 // and check renderbuffer type here only.
350 if (object->isRenderbuffer()) {
351 if (internalformat != GL_STENCIL_INDEX8) {
352 *reason = "the internalformat of the attached renderbuffer is no t STENCIL_INDEX8";
353 return false;
354 }
355 }
356 } else if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
357 if (object->isRenderbuffer()) {
358 if (internalformat != GL_DEPTH_STENCIL_OES) {
359 *reason = "the internalformat of the attached renderbuffer is no t DEPTH_STENCIL";
360 return false;
361 }
362 } else if (object->isTexture()) {
363 GLenum type = attachedObject->type();
364 if (!(context()->extensionEnabled(WebGLDepthTextureName) && internal format == GL_DEPTH_STENCIL_OES
365 && type == GL_UNSIGNED_INT_24_8_OES)) {
366 *reason = "the attached texture is not a DEPTH_STENCIL texture";
367 return false;
368 }
369 }
370 } else if (attachment == GL_COLOR_ATTACHMENT0
371 || (context()->extensionEnabled(WebGLDrawBuffersName) && attachment > GL _COLOR_ATTACHMENT0
372 && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context() ->maxColorAttachments()))) {
373 if (object->isRenderbuffer()) {
374 if (!isColorRenderable(internalformat)) {
375 *reason = "the internalformat of the attached renderbuffer is no t color-renderable";
376 return false;
377 }
378 } else if (object->isTexture()) {
379 GLenum type = attachedObject->type();
380 if (internalformat != GL_RGBA && internalformat != GL_RGB) {
381 *reason = "the internalformat of the attached texture is not col or-renderable";
382 return false;
383 }
384 // TODO: WEBGL_color_buffer_float and EXT_color_buffer_half_float ex tensions have not been implemented in
385 // WebGL yet. It would be better to depend on the underlying GL driv ers to check on rendering to floating point textures
386 // and add the check back to WebGL when above two extensions are imp lemented.
387 // Assume UNSIGNED_BYTE is renderable here without the need to expli citly check if GL_OES_rgb8_rgba8 extension is supported.
388 if (type != GL_UNSIGNED_BYTE
389 && type != GL_UNSIGNED_SHORT_5_6_5
390 && type != GL_UNSIGNED_SHORT_4_4_4_4
391 && type != GL_UNSIGNED_SHORT_5_5_5_1
392 && !(type == GL_FLOAT && context()->extensionEnabled(OESTextureF loatName))
393 && !(type == GL_HALF_FLOAT_OES && context()->extensionEnabled(OE STextureHalfFloatName))) {
394 *reason = "unsupported type: The attached texture is not support ed to be rendered to";
395 return false;
396 }
397 }
398 } else {
399 *reason = "unknown framebuffer attachment point";
400 return false;
401 }
402
403 if (!attachedObject->width() || !attachedObject->height()) {
404 *reason = "attachment has a 0 dimension";
405 return false;
406 }
407 return true;
408 }
409
410 WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum attach ment) const
411 {
412 const AttachmentMap::const_iterator it = m_attachments.find(attachment);
413 return (it != m_attachments.end()) ? it->value.get() : 0;
414 }
415
416 void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment)
417 {
418 ASSERT(isBound());
419 if (!object())
420 return;
421
422 WebGLAttachment* attachmentObject = getAttachment(attachment);
423 if (attachmentObject) {
424 attachmentObject->onDetached(context()->webContext());
425 m_attachments.remove(attachment);
426 drawBuffersIfNecessary(false);
427 switch (attachment) {
428 case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
429 attach(GL_DEPTH_ATTACHMENT, GL_DEPTH_ATTACHMENT);
430 attach(GL_STENCIL_ATTACHMENT, GL_STENCIL_ATTACHMENT);
431 break;
432 case GL_DEPTH_ATTACHMENT:
433 attach(GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL, GL_DEPTH_ATTACHMENT);
434 break;
435 case GL_STENCIL_ATTACHMENT:
436 attach(GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL, GL_STENCIL_ATTACHMENT);
437 break;
438 }
439 }
440 }
441
442 void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a ttachment)
443 {
444 ASSERT(isBound());
445 if (!object())
446 return;
447 if (!attachment)
448 return;
449
450 bool checkMore = true;
451 while (checkMore) {
452 checkMore = false;
453 for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachm ents.end(); ++it) {
454 WebGLAttachment* attachmentObject = it->value.get();
455 if (attachmentObject->isSharedObject(attachment)) {
456 GLenum attachmentType = it->key;
457 attachmentObject->unattach(context()->webContext(), attachmentTy pe);
458 removeAttachmentFromBoundFramebuffer(attachmentType);
459 checkMore = true;
460 break;
461 }
462 }
463 }
464 }
465
466 GLenum WebGLFramebuffer::colorBufferFormat() const
467 {
468 if (!object())
469 return 0;
470 WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0);
471 if (!attachment)
472 return 0;
473 return attachment->format();
474 }
475
476 GLenum WebGLFramebuffer::checkStatus(const char** reason) const
477 {
478 unsigned count = 0;
479 GLsizei width = 0, height = 0;
480 bool haveDepth = false;
481 bool haveStencil = false;
482 bool haveDepthStencil = false;
483 for (AttachmentMap::const_iterator it = m_attachments.begin(); it != m_attac hments.end(); ++it) {
484 WebGLAttachment* attachment = it->value.get();
485 if (!isAttachmentComplete(attachment, it->key, reason))
486 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
487 if (!attachment->valid()) {
488 *reason = "attachment is not valid";
489 return GL_FRAMEBUFFER_UNSUPPORTED;
490 }
491 if (!attachment->format()) {
492 *reason = "attachment is an unsupported format";
493 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
494 }
495 switch (it->key) {
496 case GL_DEPTH_ATTACHMENT:
497 haveDepth = true;
498 break;
499 case GL_STENCIL_ATTACHMENT:
500 haveStencil = true;
501 break;
502 case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
503 haveDepthStencil = true;
504 break;
505 }
506 if (!count) {
507 width = attachment->width();
508 height = attachment->height();
509 } else {
510 if (width != attachment->width() || height != attachment->height()) {
511 *reason = "attachments do not have the same dimensions";
512 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
513 }
514 }
515 ++count;
516 }
517 if (!count) {
518 *reason = "no attachments";
519 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
520 }
521 if (!width || !height) {
522 *reason = "framebuffer has a 0 dimension";
523 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
524 }
525 // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments.
526 if ((haveDepthStencil && (haveDepth || haveStencil)) || (haveDepth && haveSt encil)) {
527 *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments";
528 return GL_FRAMEBUFFER_UNSUPPORTED;
529 }
530 return GL_FRAMEBUFFER_COMPLETE;
531 }
532
533 bool WebGLFramebuffer::onAccess(blink::WebGraphicsContext3D* context3d, const ch ar** reason)
534 {
535 if (checkStatus(reason) != GL_FRAMEBUFFER_COMPLETE)
536 return false;
537 return true;
538 }
539
540 bool WebGLFramebuffer::hasStencilBuffer() const
541 {
542 WebGLAttachment* attachment = getAttachment(GL_STENCIL_ATTACHMENT);
543 if (!attachment)
544 attachment = getAttachment(GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL);
545 return attachment && attachment->valid();
546 }
547
548 void WebGLFramebuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
549 {
550 #if !ENABLE(OILPAN)
551 // With Oilpan, both the AttachmentMap and its WebGLAttachment objects are
552 // GCed objects and cannot be accessed, as they may have been finalized
553 // already during the same GC sweep.
554 //
555 // The WebGLAttachment-derived classes instead handle detachment
556 // on their own when finalizing, so the explicit notification is
557 // not needed.
558 for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments .end(); ++it)
559 it->value->onDetached(context3d);
560 #endif
561
562 context3d->deleteFramebuffer(object);
563 }
564
565 bool WebGLFramebuffer::isBound() const
566 {
567 return (context()->m_framebufferBinding.get() == this);
568 }
569
570 void WebGLFramebuffer::drawBuffers(const Vector<GLenum>& bufs)
571 {
572 m_drawBuffers = bufs;
573 m_filteredDrawBuffers.resize(m_drawBuffers.size());
574 for (size_t i = 0; i < m_filteredDrawBuffers.size(); ++i)
575 m_filteredDrawBuffers[i] = GL_NONE;
576 drawBuffersIfNecessary(true);
577 }
578
579 void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
580 {
581 if (!context()->extensionEnabled(WebGLDrawBuffersName))
582 return;
583 bool reset = force;
584 // This filtering works around graphics driver bugs on Mac OS X.
585 for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
586 if (m_drawBuffers[i] != GL_NONE && getAttachment(m_drawBuffers[i])) {
587 if (m_filteredDrawBuffers[i] != m_drawBuffers[i]) {
588 m_filteredDrawBuffers[i] = m_drawBuffers[i];
589 reset = true;
590 }
591 } else {
592 if (m_filteredDrawBuffers[i] != GL_NONE) {
593 m_filteredDrawBuffers[i] = GL_NONE;
594 reset = true;
595 }
596 }
597 }
598 if (reset) {
599 context()->webContext()->drawBuffersEXT(
600 m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
601 }
602 }
603
604 GLenum WebGLFramebuffer::getDrawBuffer(GLenum drawBuffer)
605 {
606 int index = static_cast<int>(drawBuffer - GL_DRAW_BUFFER0_EXT);
607 ASSERT(index >= 0);
608 if (index < static_cast<int>(m_drawBuffers.size()))
609 return m_drawBuffers[index];
610 if (drawBuffer == GL_DRAW_BUFFER0_EXT)
611 return GL_COLOR_ATTACHMENT0;
612 return GL_NONE;
613 }
614
615 }
OLDNEW
« no previous file with comments | « sky/engine/core/html/canvas/WebGLFramebuffer.h ('k') | sky/engine/core/html/canvas/WebGLFramebuffer.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698