| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 class WebGLRenderbufferAttachment final : public WebGLFramebuffer::WebGLAttachme
nt { | 37 class WebGLRenderbufferAttachment final : public WebGLFramebuffer::WebGLAttachme
nt { |
| 38 public: | 38 public: |
| 39 static WebGLFramebuffer::WebGLAttachment* create(WebGLRenderbuffer*); | 39 static WebGLFramebuffer::WebGLAttachment* create(WebGLRenderbuffer*); |
| 40 | 40 |
| 41 DECLARE_VIRTUAL_TRACE(); | 41 DECLARE_VIRTUAL_TRACE(); |
| 42 | 42 |
| 43 private: | 43 private: |
| 44 explicit WebGLRenderbufferAttachment(WebGLRenderbuffer*); | 44 explicit WebGLRenderbufferAttachment(WebGLRenderbuffer*); |
| 45 WebGLRenderbufferAttachment() { } | 45 WebGLRenderbufferAttachment() { } |
| 46 | 46 |
| 47 GLsizei width() const override; | |
| 48 GLsizei height() const override; | |
| 49 GLsizei depth() const override; | |
| 50 GLenum format() const override; | |
| 51 GLenum type() const override; | |
| 52 bool isCubeComplete() const override; | |
| 53 WebGLSharedObject* object() const override; | 47 WebGLSharedObject* object() const override; |
| 54 bool isSharedObject(WebGLSharedObject*) const override; | 48 bool isSharedObject(WebGLSharedObject*) const override; |
| 55 bool valid() const override; | 49 bool valid() const override; |
| 56 void onDetached(WebGraphicsContext3D*) override; | 50 void onDetached(WebGraphicsContext3D*) override; |
| 57 void attach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overrid
e; | 51 void attach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overrid
e; |
| 58 void unattach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overr
ide; | 52 void unattach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overr
ide; |
| 59 | 53 |
| 60 Member<WebGLRenderbuffer> m_renderbuffer; | 54 Member<WebGLRenderbuffer> m_renderbuffer; |
| 61 }; | 55 }; |
| 62 | 56 |
| 63 WebGLFramebuffer::WebGLAttachment* WebGLRenderbufferAttachment::create(WebGLRend
erbuffer* renderbuffer) | 57 WebGLFramebuffer::WebGLAttachment* WebGLRenderbufferAttachment::create(WebGLRend
erbuffer* renderbuffer) |
| 64 { | 58 { |
| 65 return new WebGLRenderbufferAttachment(renderbuffer); | 59 return new WebGLRenderbufferAttachment(renderbuffer); |
| 66 } | 60 } |
| 67 | 61 |
| 68 DEFINE_TRACE(WebGLRenderbufferAttachment) | 62 DEFINE_TRACE(WebGLRenderbufferAttachment) |
| 69 { | 63 { |
| 70 visitor->trace(m_renderbuffer); | 64 visitor->trace(m_renderbuffer); |
| 71 WebGLFramebuffer::WebGLAttachment::trace(visitor); | 65 WebGLFramebuffer::WebGLAttachment::trace(visitor); |
| 72 } | 66 } |
| 73 | 67 |
| 74 WebGLRenderbufferAttachment::WebGLRenderbufferAttachment(WebGLRenderbuffer* rend
erbuffer) | 68 WebGLRenderbufferAttachment::WebGLRenderbufferAttachment(WebGLRenderbuffer* rend
erbuffer) |
| 75 : m_renderbuffer(renderbuffer) | 69 : m_renderbuffer(renderbuffer) |
| 76 { | 70 { |
| 77 } | 71 } |
| 78 | 72 |
| 79 GLsizei WebGLRenderbufferAttachment::width() const | |
| 80 { | |
| 81 return m_renderbuffer->width(); | |
| 82 } | |
| 83 | |
| 84 GLsizei WebGLRenderbufferAttachment::height() const | |
| 85 { | |
| 86 return m_renderbuffer->height(); | |
| 87 } | |
| 88 | |
| 89 GLsizei WebGLRenderbufferAttachment::depth() const | |
| 90 { | |
| 91 return 1; | |
| 92 } | |
| 93 | |
| 94 GLenum WebGLRenderbufferAttachment::format() const | |
| 95 { | |
| 96 return m_renderbuffer->internalFormat(); | |
| 97 } | |
| 98 | |
| 99 WebGLSharedObject* WebGLRenderbufferAttachment::object() const | 73 WebGLSharedObject* WebGLRenderbufferAttachment::object() const |
| 100 { | 74 { |
| 101 return m_renderbuffer->object() ? m_renderbuffer.get() : 0; | 75 return m_renderbuffer->object() ? m_renderbuffer.get() : 0; |
| 102 } | 76 } |
| 103 | 77 |
| 104 bool WebGLRenderbufferAttachment::isSharedObject(WebGLSharedObject* object) cons
t | 78 bool WebGLRenderbufferAttachment::isSharedObject(WebGLSharedObject* object) cons
t |
| 105 { | 79 { |
| 106 return object == m_renderbuffer; | 80 return object == m_renderbuffer; |
| 107 } | 81 } |
| 108 | 82 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 120 { | 94 { |
| 121 Platform3DObject object = objectOrZero(m_renderbuffer.get()); | 95 Platform3DObject object = objectOrZero(m_renderbuffer.get()); |
| 122 context->framebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, object
); | 96 context->framebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, object
); |
| 123 } | 97 } |
| 124 | 98 |
| 125 void WebGLRenderbufferAttachment::unattach(WebGraphicsContext3D* context, GLenum
target, GLenum attachment) | 99 void WebGLRenderbufferAttachment::unattach(WebGraphicsContext3D* context, GLenum
target, GLenum attachment) |
| 126 { | 100 { |
| 127 context->framebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, 0); | 101 context->framebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, 0); |
| 128 } | 102 } |
| 129 | 103 |
| 130 GLenum WebGLRenderbufferAttachment::type() const | |
| 131 { | |
| 132 return WebGLTexture::getValidTypeForInternalFormat(m_renderbuffer->internalF
ormat()); | |
| 133 } | |
| 134 | |
| 135 bool WebGLRenderbufferAttachment::isCubeComplete() const | |
| 136 { | |
| 137 ASSERT_NOT_REACHED(); | |
| 138 return false; | |
| 139 } | |
| 140 | |
| 141 class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment { | 104 class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment { |
| 142 public: | 105 public: |
| 143 static WebGLFramebuffer::WebGLAttachment* create(WebGLTexture*, GLenum targe
t, GLint level, GLint layer); | 106 static WebGLFramebuffer::WebGLAttachment* create(WebGLTexture*, GLenum targe
t, GLint level, GLint layer); |
| 144 | 107 |
| 145 DECLARE_VIRTUAL_TRACE(); | 108 DECLARE_VIRTUAL_TRACE(); |
| 146 | 109 |
| 147 private: | 110 private: |
| 148 WebGLTextureAttachment(WebGLTexture*, GLenum target, GLint level, GLint laye
r); | 111 WebGLTextureAttachment(WebGLTexture*, GLenum target, GLint level, GLint laye
r); |
| 149 WebGLTextureAttachment() { } | 112 WebGLTextureAttachment() { } |
| 150 | 113 |
| 151 GLsizei width() const override; | |
| 152 GLsizei height() const override; | |
| 153 GLsizei depth() const override; | |
| 154 GLenum format() const override; | |
| 155 GLenum type() const override; | |
| 156 bool isCubeComplete() const override; | |
| 157 WebGLSharedObject* object() const override; | 114 WebGLSharedObject* object() const override; |
| 158 bool isSharedObject(WebGLSharedObject*) const override; | 115 bool isSharedObject(WebGLSharedObject*) const override; |
| 159 bool valid() const override; | 116 bool valid() const override; |
| 160 void onDetached(WebGraphicsContext3D*) override; | 117 void onDetached(WebGraphicsContext3D*) override; |
| 161 void attach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overrid
e; | 118 void attach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overrid
e; |
| 162 void unattach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overr
ide; | 119 void unattach(WebGraphicsContext3D*, GLenum target, GLenum attachment) overr
ide; |
| 163 | 120 |
| 164 Member<WebGLTexture> m_texture; | 121 Member<WebGLTexture> m_texture; |
| 165 GLenum m_target; | 122 GLenum m_target; |
| 166 GLint m_level; | 123 GLint m_level; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 179 } | 136 } |
| 180 | 137 |
| 181 WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GLenum tar
get, GLint level, GLint layer) | 138 WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GLenum tar
get, GLint level, GLint layer) |
| 182 : m_texture(texture) | 139 : m_texture(texture) |
| 183 , m_target(target) | 140 , m_target(target) |
| 184 , m_level(level) | 141 , m_level(level) |
| 185 , m_layer(layer) | 142 , m_layer(layer) |
| 186 { | 143 { |
| 187 } | 144 } |
| 188 | 145 |
| 189 GLsizei WebGLTextureAttachment::width() const | |
| 190 { | |
| 191 return m_texture->getWidth(m_target, m_level); | |
| 192 } | |
| 193 | |
| 194 GLsizei WebGLTextureAttachment::height() const | |
| 195 { | |
| 196 return m_texture->getHeight(m_target, m_level); | |
| 197 } | |
| 198 | |
| 199 GLsizei WebGLTextureAttachment::depth() const | |
| 200 { | |
| 201 return m_texture->getDepth(m_target, m_level); | |
| 202 } | |
| 203 | |
| 204 GLenum WebGLTextureAttachment::format() const | |
| 205 { | |
| 206 return m_texture->getInternalFormat(m_target, m_level); | |
| 207 } | |
| 208 | |
| 209 WebGLSharedObject* WebGLTextureAttachment::object() const | 146 WebGLSharedObject* WebGLTextureAttachment::object() const |
| 210 { | 147 { |
| 211 return m_texture->object() ? m_texture.get() : 0; | 148 return m_texture->object() ? m_texture.get() : 0; |
| 212 } | 149 } |
| 213 | 150 |
| 214 bool WebGLTextureAttachment::isSharedObject(WebGLSharedObject* object) const | 151 bool WebGLTextureAttachment::isSharedObject(WebGLSharedObject* object) const |
| 215 { | 152 { |
| 216 return object == m_texture; | 153 return object == m_texture; |
| 217 } | 154 } |
| 218 | 155 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 239 void WebGLTextureAttachment::unattach(WebGraphicsContext3D* context, GLenum targ
et, GLenum attachment) | 176 void WebGLTextureAttachment::unattach(WebGraphicsContext3D* context, GLenum targ
et, GLenum attachment) |
| 240 { | 177 { |
| 241 // GL_DEPTH_STENCIL_ATTACHMENT attachment is valid in ES3. | 178 // GL_DEPTH_STENCIL_ATTACHMENT attachment is valid in ES3. |
| 242 if (m_target == GL_TEXTURE_3D || m_target == GL_TEXTURE_2D_ARRAY) { | 179 if (m_target == GL_TEXTURE_3D || m_target == GL_TEXTURE_2D_ARRAY) { |
| 243 context->framebufferTextureLayer(target, attachment, 0, m_level, m_layer
); | 180 context->framebufferTextureLayer(target, attachment, 0, m_level, m_layer
); |
| 244 } else { | 181 } else { |
| 245 context->framebufferTexture2D(target, attachment, m_target, 0, m_level); | 182 context->framebufferTexture2D(target, attachment, m_target, 0, m_level); |
| 246 } | 183 } |
| 247 } | 184 } |
| 248 | 185 |
| 249 GLenum WebGLTextureAttachment::type() const | |
| 250 { | |
| 251 return m_texture->getType(m_target, m_level); | |
| 252 } | |
| 253 | |
| 254 bool WebGLTextureAttachment::isCubeComplete() const | |
| 255 { | |
| 256 return m_texture->isCubeComplete(); | |
| 257 } | |
| 258 | |
| 259 bool isColorRenderable(GLenum internalformat, bool includesFloat) | |
| 260 { | |
| 261 switch (internalformat) { | |
| 262 case GL_RGB: | |
| 263 case GL_RGBA: | |
| 264 case GL_SRGB_ALPHA_EXT: | |
| 265 case GL_R8: | |
| 266 case GL_R8UI: | |
| 267 case GL_R8I: | |
| 268 case GL_R16UI: | |
| 269 case GL_R16I: | |
| 270 case GL_R32UI: | |
| 271 case GL_R32I: | |
| 272 case GL_RG8: | |
| 273 case GL_RG8UI: | |
| 274 case GL_RG8I: | |
| 275 case GL_RG16UI: | |
| 276 case GL_RG16I: | |
| 277 case GL_RG32UI: | |
| 278 case GL_RG32I: | |
| 279 case GL_RGB8: | |
| 280 case GL_RGB565: | |
| 281 case GL_RGBA8: | |
| 282 case GL_SRGB8_ALPHA8: | |
| 283 case GL_RGB5_A1: | |
| 284 case GL_RGBA4: | |
| 285 case GL_RGB10_A2: | |
| 286 case GL_RGBA8UI: | |
| 287 case GL_RGBA8I: | |
| 288 case GL_RGB10_A2UI: | |
| 289 case GL_RGBA16UI: | |
| 290 case GL_RGBA16I: | |
| 291 case GL_RGBA32UI: | |
| 292 case GL_RGBA32I: | |
| 293 return true; | |
| 294 case GL_R16F: | |
| 295 case GL_RG16F: | |
| 296 case GL_RGBA16F: | |
| 297 case GL_R32F: | |
| 298 case GL_RG32F: | |
| 299 case GL_RGBA32F: | |
| 300 case GL_R11F_G11F_B10F: | |
| 301 return includesFloat; | |
| 302 default: | |
| 303 return false; | |
| 304 } | |
| 305 } | |
| 306 | |
| 307 bool isDepthRenderable(GLenum internalformat, bool includesDepthStencil) | |
| 308 { | |
| 309 switch (internalformat) { | |
| 310 case GL_DEPTH_COMPONENT: | |
| 311 case GL_DEPTH_COMPONENT16: | |
| 312 case GL_DEPTH_COMPONENT24: | |
| 313 case GL_DEPTH_COMPONENT32F: | |
| 314 return true; | |
| 315 case GL_DEPTH_STENCIL: | |
| 316 case GL_DEPTH24_STENCIL8: | |
| 317 case GL_DEPTH32F_STENCIL8: | |
| 318 return includesDepthStencil; | |
| 319 default: | |
| 320 return false; | |
| 321 } | |
| 322 } | |
| 323 | |
| 324 bool isStencilRenderable(GLenum internalformat, bool includesDepthStencil) | |
| 325 { | |
| 326 switch (internalformat) { | |
| 327 case GL_STENCIL_INDEX8: | |
| 328 return true; | |
| 329 case GL_DEPTH_STENCIL: | |
| 330 case GL_DEPTH24_STENCIL8: | |
| 331 case GL_DEPTH32F_STENCIL8: | |
| 332 return includesDepthStencil; | |
| 333 default: | |
| 334 return false; | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 } // anonymous namespace | 186 } // anonymous namespace |
| 339 | 187 |
| 340 WebGLFramebuffer::WebGLAttachment::WebGLAttachment() | 188 WebGLFramebuffer::WebGLAttachment::WebGLAttachment() |
| 341 { | 189 { |
| 342 } | 190 } |
| 343 | 191 |
| 344 WebGLFramebuffer::WebGLAttachment::~WebGLAttachment() | 192 WebGLFramebuffer::WebGLAttachment::~WebGLAttachment() |
| 345 { | 193 { |
| 346 } | 194 } |
| 347 | 195 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 } | 253 } |
| 406 | 254 |
| 407 WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) cons
t | 255 WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) cons
t |
| 408 { | 256 { |
| 409 if (!m_object) | 257 if (!m_object) |
| 410 return nullptr; | 258 return nullptr; |
| 411 WebGLAttachment* attachmentObject = getAttachment(attachment); | 259 WebGLAttachment* attachmentObject = getAttachment(attachment); |
| 412 return attachmentObject ? attachmentObject->object() : nullptr; | 260 return attachmentObject ? attachmentObject->object() : nullptr; |
| 413 } | 261 } |
| 414 | 262 |
| 415 bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLe
num attachment, const char** reason) const | |
| 416 { | |
| 417 ASSERT(attachedObject && attachedObject->valid()); | |
| 418 ASSERT(reason); | |
| 419 | |
| 420 GLenum internalformat = attachedObject->format(); | |
| 421 | |
| 422 switch (attachment) { | |
| 423 case GL_DEPTH_ATTACHMENT: | |
| 424 if (!isDepthRenderable(internalformat, context()->isWebGL2OrHigher())) { | |
| 425 *reason = "the internalformat of the attached image is not depth-ren
derable"; | |
| 426 return false; | |
| 427 } | |
| 428 break; | |
| 429 case GL_STENCIL_ATTACHMENT: | |
| 430 if (!isStencilRenderable(internalformat, context()->isWebGL2OrHigher()))
{ | |
| 431 *reason = "the internalformat of the attached image is not stencil-r
enderable"; | |
| 432 return false; | |
| 433 } | |
| 434 break; | |
| 435 case GL_DEPTH_STENCIL_ATTACHMENT: | |
| 436 ASSERT(!context()->isWebGL2OrHigher()); | |
| 437 if (internalformat != GL_DEPTH_STENCIL_OES) { | |
| 438 *reason = "the internalformat of the attached image is not DEPTH_STE
NCIL"; | |
| 439 return false; | |
| 440 } | |
| 441 break; | |
| 442 default: | |
| 443 ASSERT(attachment == GL_COLOR_ATTACHMENT0 || (attachment > GL_COLOR_ATTA
CHMENT0 && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context()->ma
xColorAttachments()))); | |
| 444 if (!isColorRenderable(internalformat, context()->extensionEnabled(EXTCo
lorBufferFloatName))) { | |
| 445 *reason = "the internalformat of the attached image is not color-ren
derable"; | |
| 446 return false; | |
| 447 } | |
| 448 break; | |
| 449 } | |
| 450 | |
| 451 if (!attachedObject->width() || !attachedObject->height()) { | |
| 452 *reason = "attachment has a 0 dimension"; | |
| 453 return false; | |
| 454 } | |
| 455 | |
| 456 if (attachedObject->object()->isTexture() && !attachedObject->isCubeComplete
()) { | |
| 457 *reason = "attachment is not cube complete"; | |
| 458 return false; | |
| 459 } | |
| 460 | |
| 461 return true; | |
| 462 } | |
| 463 | |
| 464 WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum attach
ment) const | 263 WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum attach
ment) const |
| 465 { | 264 { |
| 466 const AttachmentMap::const_iterator it = m_attachments.find(attachment); | 265 const AttachmentMap::const_iterator it = m_attachments.find(attachment); |
| 467 return (it != m_attachments.end()) ? it->value.get() : 0; | 266 return (it != m_attachments.end()) ? it->value.get() : 0; |
| 468 } | 267 } |
| 469 | 268 |
| 470 void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum target, GLenu
m attachment) | 269 void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum target, GLenu
m attachment) |
| 471 { | 270 { |
| 472 ASSERT(isBound(target)); | 271 ASSERT(isBound(target)); |
| 473 if (!m_object) | 272 if (!m_object) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 GLenum attachmentType = it.key; | 307 GLenum attachmentType = it.key; |
| 509 attachmentObject->unattach(context()->webContext(), target, atta
chmentType); | 308 attachmentObject->unattach(context()->webContext(), target, atta
chmentType); |
| 510 removeAttachmentFromBoundFramebuffer(target, attachmentType); | 309 removeAttachmentFromBoundFramebuffer(target, attachmentType); |
| 511 checkMore = true; | 310 checkMore = true; |
| 512 break; | 311 break; |
| 513 } | 312 } |
| 514 } | 313 } |
| 515 } | 314 } |
| 516 } | 315 } |
| 517 | 316 |
| 518 GLenum WebGLFramebuffer::colorBufferFormat() const | |
| 519 { | |
| 520 if (!m_object) | |
| 521 return 0; | |
| 522 WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0); | |
| 523 if (!attachment) | |
| 524 return 0; | |
| 525 return attachment->format(); | |
| 526 } | |
| 527 | |
| 528 GLenum WebGLFramebuffer::checkStatus(const char** reason) const | |
| 529 { | |
| 530 unsigned count = 0; | |
| 531 GLsizei width = 0, height = 0, depth = 0; | |
| 532 WebGLAttachment* depthAttachment = nullptr; | |
| 533 WebGLAttachment* stencilAttachment = nullptr; | |
| 534 WebGLAttachment* depthStencilAttachment = nullptr; | |
| 535 bool isWebGL2OrHigher = context()->isWebGL2OrHigher(); | |
| 536 for (const auto& it : m_attachments) { | |
| 537 WebGLAttachment* attachment = it.value.get(); | |
| 538 if (!isAttachmentComplete(attachment, it.key, reason)) | |
| 539 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | |
| 540 if (!attachment->valid()) { | |
| 541 *reason = "attachment is not valid"; | |
| 542 return GL_FRAMEBUFFER_UNSUPPORTED; | |
| 543 } | |
| 544 if (!attachment->format()) { | |
| 545 *reason = "attachment is an unsupported format"; | |
| 546 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | |
| 547 } | |
| 548 switch (it.key) { | |
| 549 case GL_DEPTH_ATTACHMENT: | |
| 550 depthAttachment = attachment; | |
| 551 break; | |
| 552 case GL_STENCIL_ATTACHMENT: | |
| 553 stencilAttachment = attachment; | |
| 554 break; | |
| 555 case GL_DEPTH_STENCIL_ATTACHMENT: | |
| 556 depthStencilAttachment = attachment; | |
| 557 break; | |
| 558 } | |
| 559 // Note: In GLES 3, images for a framebuffer need not to have the same d
imensions to be framebuffer complete. | |
| 560 // However, in Direct3D 11, on top of which OpenGL ES 3 behavior is emul
ated in Windows, all render targets | |
| 561 // must have the same size in all dimensions. In order to have consisten
t WebGL 2 behaviors across platforms, | |
| 562 // we generate FRAMEBUFFER_INCOMPLETE_DIMENSIONS in this situation. | |
| 563 if (!count) { | |
| 564 width = attachment->width(); | |
| 565 height = attachment->height(); | |
| 566 depth = attachment->depth(); | |
| 567 } else { | |
| 568 if (width != attachment->width() || height != attachment->height() |
| depth != attachment->depth()) { | |
| 569 *reason = "attachments do not have the same dimensions"; | |
| 570 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; | |
| 571 } | |
| 572 } | |
| 573 ++count; | |
| 574 } | |
| 575 if (!count) { | |
| 576 *reason = "no attachments"; | |
| 577 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; | |
| 578 } | |
| 579 // WebGL 1 specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. | |
| 580 if (!isWebGL2OrHigher | |
| 581 && ((depthStencilAttachment && (depthAttachment || stencilAttachment)) | |
| 582 || (depthAttachment && stencilAttachment))) { | |
| 583 *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments"; | |
| 584 return GL_FRAMEBUFFER_UNSUPPORTED; | |
| 585 } | |
| 586 if (isWebGL2OrHigher | |
| 587 && (depthAttachment && stencilAttachment && depthAttachment->object() !=
stencilAttachment->object())) { | |
| 588 *reason = "both DEPTH/STENCIL attachments are present and not the same i
mage"; | |
| 589 return GL_FRAMEBUFFER_UNSUPPORTED; | |
| 590 } | |
| 591 return GL_FRAMEBUFFER_COMPLETE; | |
| 592 } | |
| 593 | |
| 594 GLenum WebGLFramebuffer::checkDepthStencilStatus(const char** reason) const | 317 GLenum WebGLFramebuffer::checkDepthStencilStatus(const char** reason) const |
| 595 { | 318 { |
| 596 if (context()->isWebGL2OrHigher()) | 319 if (context()->isWebGL2OrHigher()) |
| 597 return GL_FRAMEBUFFER_COMPLETE; | 320 return GL_FRAMEBUFFER_COMPLETE; |
| 598 WebGLAttachment* depthAttachment = nullptr; | 321 WebGLAttachment* depthAttachment = nullptr; |
| 599 WebGLAttachment* stencilAttachment = nullptr; | 322 WebGLAttachment* stencilAttachment = nullptr; |
| 600 WebGLAttachment* depthStencilAttachment = nullptr; | 323 WebGLAttachment* depthStencilAttachment = nullptr; |
| 601 for (const auto& it : m_attachments) { | 324 for (const auto& it : m_attachments) { |
| 602 WebGLAttachment* attachment = it.value.get(); | 325 WebGLAttachment* attachment = it.value.get(); |
| 603 ASSERT(attachment); | 326 ASSERT(attachment); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 { | 414 { |
| 692 int index = static_cast<int>(drawBuffer - GL_DRAW_BUFFER0_EXT); | 415 int index = static_cast<int>(drawBuffer - GL_DRAW_BUFFER0_EXT); |
| 693 ASSERT(index >= 0); | 416 ASSERT(index >= 0); |
| 694 if (index < static_cast<int>(m_drawBuffers.size())) | 417 if (index < static_cast<int>(m_drawBuffers.size())) |
| 695 return m_drawBuffers[index]; | 418 return m_drawBuffers[index]; |
| 696 if (drawBuffer == GL_DRAW_BUFFER0_EXT) | 419 if (drawBuffer == GL_DRAW_BUFFER0_EXT) |
| 697 return GL_COLOR_ATTACHMENT0; | 420 return GL_COLOR_ATTACHMENT0; |
| 698 return GL_NONE; | 421 return GL_NONE; |
| 699 } | 422 } |
| 700 | 423 |
| 701 bool WebGLFramebuffer::getReadBufferFormatAndType(GLenum* format, GLenum* type)
const | |
| 702 { | |
| 703 if (m_readBuffer == GL_NONE) | |
| 704 return false; | |
| 705 WebGLAttachment* image = getAttachment(m_readBuffer); | |
| 706 if (!image) | |
| 707 return false; | |
| 708 if (format) | |
| 709 *format = image->format(); | |
| 710 if (type) | |
| 711 *type = image->type(); | |
| 712 return true; | |
| 713 } | |
| 714 | |
| 715 DEFINE_TRACE(WebGLFramebuffer) | 424 DEFINE_TRACE(WebGLFramebuffer) |
| 716 { | 425 { |
| 717 visitor->trace(m_attachments); | 426 visitor->trace(m_attachments); |
| 718 WebGLContextObject::trace(visitor); | 427 WebGLContextObject::trace(visitor); |
| 719 } | 428 } |
| 720 | 429 |
| 721 } // namespace blink | 430 } // namespace blink |
| OLD | NEW |