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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 if (!desiredSize.isEmpty()) { | 214 if (!desiredSize.isEmpty()) { |
215 forciblyEvictedContexts().remove(0); | 215 forciblyEvictedContexts().remove(0); |
216 evictedContext->forceRestoreContext(); | 216 evictedContext->forceRestoreContext(); |
217 } | 217 } |
218 break; | 218 break; |
219 } | 219 } |
220 } | 220 } |
221 | 221 |
222 namespace { | 222 namespace { |
223 | 223 |
| 224 // ScopedDrawingBufferBinder is used for ReadPixels/CopyTexImage2D/CopySubIm
age2D to read from |
| 225 // a multisampled DrawingBuffer. In this situation, we need to blit to a sin
gle sampled buffer |
| 226 // for reading, during which the bindings could be changed and need to be re
covered. |
224 class ScopedDrawingBufferBinder { | 227 class ScopedDrawingBufferBinder { |
225 STACK_ALLOCATED(); | 228 STACK_ALLOCATED(); |
226 public: | 229 public: |
227 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer
* framebufferBinding) | 230 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer
* framebufferBinding) |
228 : m_drawingBuffer(drawingBuffer) | 231 : m_drawingBuffer(drawingBuffer) |
229 , m_framebufferBinding(framebufferBinding) | 232 , m_readFramebufferBinding(framebufferBinding) |
230 { | 233 { |
231 // Commit DrawingBuffer if needed (e.g., for multisampling) | 234 // Commit DrawingBuffer if needed (e.g., for multisampling) |
232 if (!m_framebufferBinding && m_drawingBuffer) | 235 if (!m_readFramebufferBinding && m_drawingBuffer) |
233 m_drawingBuffer->commit(); | 236 m_drawingBuffer->commit(); |
234 } | 237 } |
235 | 238 |
236 ~ScopedDrawingBufferBinder() | 239 ~ScopedDrawingBufferBinder() |
237 { | 240 { |
238 // Restore DrawingBuffer if needed | 241 // Restore DrawingBuffer if needed |
239 if (!m_framebufferBinding && m_drawingBuffer) | 242 if (!m_readFramebufferBinding && m_drawingBuffer) |
240 m_drawingBuffer->bind(); | 243 m_drawingBuffer->restoreFramebufferBindings(); |
241 } | 244 } |
242 | 245 |
243 private: | 246 private: |
244 DrawingBuffer* m_drawingBuffer; | 247 DrawingBuffer* m_drawingBuffer; |
245 RawPtrWillBeMember<WebGLFramebuffer> m_framebufferBinding; | 248 RawPtrWillBeMember<WebGLFramebuffer> m_readFramebufferBinding; |
246 }; | 249 }; |
247 | 250 |
248 GLint clamp(GLint value, GLint min, GLint max) | 251 GLint clamp(GLint value, GLint min, GLint max) |
249 { | 252 { |
250 if (value < min) | 253 if (value < min) |
251 value = min; | 254 value = min; |
252 if (value > max) | 255 if (value > max) |
253 value = max; | 256 value = max; |
254 return value; | 257 return value; |
255 } | 258 } |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims); | 647 context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims); |
645 | 648 |
646 RefPtr<DrawingBuffer> buffer = createDrawingBuffer(context); | 649 RefPtr<DrawingBuffer> buffer = createDrawingBuffer(context); |
647 if (!buffer) { | 650 if (!buffer) { |
648 m_contextLostMode = SyntheticLostContext; | 651 m_contextLostMode = SyntheticLostContext; |
649 return; | 652 return; |
650 } | 653 } |
651 | 654 |
652 m_drawingBuffer = buffer.release(); | 655 m_drawingBuffer = buffer.release(); |
653 | 656 |
654 drawingBuffer()->bind(); | 657 drawingBuffer()->bind(GL_FRAMEBUFFER); |
655 setupFlags(); | 658 setupFlags(); |
656 } | 659 } |
657 | 660 |
658 PassRefPtr<DrawingBuffer> WebGLRenderingContextBase::createDrawingBuffer(PassOwn
Ptr<WebGraphicsContext3D> context) | 661 PassRefPtr<DrawingBuffer> WebGLRenderingContextBase::createDrawingBuffer(PassOwn
Ptr<WebGraphicsContext3D> context) |
659 { | 662 { |
660 WebGraphicsContext3D::Attributes attrs; | 663 WebGraphicsContext3D::Attributes attrs; |
661 attrs.alpha = m_requestedAttributes.alpha(); | 664 attrs.alpha = m_requestedAttributes.alpha(); |
662 attrs.depth = m_requestedAttributes.depth(); | 665 attrs.depth = m_requestedAttributes.depth(); |
663 attrs.stencil = m_requestedAttributes.stencil(); | 666 attrs.stencil = m_requestedAttributes.stencil(); |
664 attrs.antialias = m_requestedAttributes.antialias(); | 667 attrs.antialias = m_requestedAttributes.antialias(); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 webContext()->clearStencil(m_clearStencil & m_stencilMask); | 908 webContext()->clearStencil(m_clearStencil & m_stencilMask); |
906 else | 909 else |
907 webContext()->clearStencil(0); | 910 webContext()->clearStencil(0); |
908 clearMask |= GL_STENCIL_BUFFER_BIT; | 911 clearMask |= GL_STENCIL_BUFFER_BIT; |
909 webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 912 webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); |
910 } | 913 } |
911 | 914 |
912 drawingBuffer()->clearFramebuffers(clearMask); | 915 drawingBuffer()->clearFramebuffers(clearMask); |
913 | 916 |
914 restoreStateAfterClear(); | 917 restoreStateAfterClear(); |
915 if (m_framebufferBinding) | 918 drawingBuffer()->restoreFramebufferBindings(); |
916 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer
Binding.get())); | |
917 drawingBuffer()->setBufferClearNeeded(false); | 919 drawingBuffer()->setBufferClearNeeded(false); |
918 | 920 |
919 return combinedClear ? CombinedClear : JustClear; | 921 return combinedClear ? CombinedClear : JustClear; |
920 } | 922 } |
921 | 923 |
922 void WebGLRenderingContextBase::restoreStateAfterClear() | 924 void WebGLRenderingContextBase::restoreStateAfterClear() |
923 { | 925 { |
924 if (isContextLost()) | 926 if (isContextLost()) |
925 return; | 927 return; |
926 | 928 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 width = clamp(width, 1, maxWidth); | 1013 width = clamp(width, 1, maxWidth); |
1012 height = clamp(height, 1, maxHeight); | 1014 height = clamp(height, 1, maxHeight); |
1013 | 1015 |
1014 // We don't have to mark the canvas as dirty, since the newly created image
buffer will also start off | 1016 // We don't have to mark the canvas as dirty, since the newly created image
buffer will also start off |
1015 // clear (and this matches what reshape will do). | 1017 // clear (and this matches what reshape will do). |
1016 drawingBuffer()->reset(IntSize(width, height)); | 1018 drawingBuffer()->reset(IntSize(width, height)); |
1017 restoreStateAfterClear(); | 1019 restoreStateAfterClear(); |
1018 | 1020 |
1019 webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activ
eTextureUnit].m_texture2DBinding.get())); | 1021 webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activ
eTextureUnit].m_texture2DBinding.get())); |
1020 webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferB
inding.get())); | 1022 webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferB
inding.get())); |
1021 if (m_framebufferBinding) | 1023 drawingBuffer()->restoreFramebufferBindings(); |
1022 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer
Binding.get())); | |
1023 } | 1024 } |
1024 | 1025 |
1025 int WebGLRenderingContextBase::drawingBufferWidth() const | 1026 int WebGLRenderingContextBase::drawingBufferWidth() const |
1026 { | 1027 { |
1027 return isContextLost() ? 0 : drawingBuffer()->size().width(); | 1028 return isContextLost() ? 0 : drawingBuffer()->size().width(); |
1028 } | 1029 } |
1029 | 1030 |
1030 int WebGLRenderingContextBase::drawingBufferHeight() const | 1031 int WebGLRenderingContextBase::drawingBufferHeight() const |
1031 { | 1032 { |
1032 return isContextLost() ? 0 : drawingBuffer()->size().height(); | 1033 return isContextLost() ? 0 : drawingBuffer()->size().height(); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 | 1364 |
1364 bool WebGLRenderingContextBase::validateFramebufferTarget(GLenum target) | 1365 bool WebGLRenderingContextBase::validateFramebufferTarget(GLenum target) |
1365 { | 1366 { |
1366 if (target == GL_FRAMEBUFFER) | 1367 if (target == GL_FRAMEBUFFER) |
1367 return true; | 1368 return true; |
1368 return false; | 1369 return false; |
1369 } | 1370 } |
1370 | 1371 |
1371 WebGLFramebuffer* WebGLRenderingContextBase::getFramebufferBinding(GLenum target
) | 1372 WebGLFramebuffer* WebGLRenderingContextBase::getFramebufferBinding(GLenum target
) |
1372 { | 1373 { |
1373 return m_framebufferBinding.get(); | 1374 if (target == GL_FRAMEBUFFER) |
| 1375 return m_framebufferBinding.get(); |
| 1376 return nullptr; |
1374 } | 1377 } |
1375 | 1378 |
1376 GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target) | 1379 GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target) |
1377 { | 1380 { |
1378 if (isContextLost()) | 1381 if (isContextLost()) |
1379 return GL_FRAMEBUFFER_UNSUPPORTED; | 1382 return GL_FRAMEBUFFER_UNSUPPORTED; |
1380 if (!validateFramebufferTarget(target)) { | 1383 if (!validateFramebufferTarget(target)) { |
1381 synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid ta
rget"); | 1384 synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid ta
rget"); |
1382 return 0; | 1385 return 0; |
1383 } | 1386 } |
1384 if (!getFramebufferBinding(target) || !getFramebufferBinding(target)->object
()) | 1387 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); |
| 1388 if (!framebufferBinding || !framebufferBinding->object()) |
1385 return GL_FRAMEBUFFER_COMPLETE; | 1389 return GL_FRAMEBUFFER_COMPLETE; |
1386 const char* reason = "framebuffer incomplete"; | 1390 const char* reason = "framebuffer incomplete"; |
1387 GLenum result = m_framebufferBinding->checkStatus(&reason); | 1391 GLenum result = framebufferBinding->checkStatus(&reason); |
1388 if (result != GL_FRAMEBUFFER_COMPLETE) { | 1392 if (result != GL_FRAMEBUFFER_COMPLETE) { |
1389 emitGLWarning("checkFramebufferStatus", reason); | 1393 emitGLWarning("checkFramebufferStatus", reason); |
1390 return result; | 1394 return result; |
1391 } | 1395 } |
1392 result = webContext()->checkFramebufferStatus(target); | 1396 result = webContext()->checkFramebufferStatus(target); |
1393 return result; | 1397 return result; |
1394 } | 1398 } |
1395 | 1399 |
1396 void WebGLRenderingContextBase::clear(GLbitfield mask) | 1400 void WebGLRenderingContextBase::clear(GLbitfield mask) |
1397 { | 1401 { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 } | 1560 } |
1557 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra
mebufferColorFormat())) { | 1561 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra
mebufferColorFormat())) { |
1558 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i
s incompatible format"); | 1562 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i
s incompatible format"); |
1559 return; | 1563 return; |
1560 } | 1564 } |
1561 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { | 1565 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { |
1562 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow
er of 2"); | 1566 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow
er of 2"); |
1563 return; | 1567 return; |
1564 } | 1568 } |
1565 const char* reason = "framebuffer incomplete"; | 1569 const char* reason = "framebuffer incomplete"; |
1566 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r
eason)) { | 1570 GLenum framebufferTarget = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRA
MEBUFFER; |
| 1571 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(framebuffer
Target); |
| 1572 if (readFramebufferBinding && !readFramebufferBinding->onAccess(webContext()
, &reason)) { |
1567 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", re
ason); | 1573 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", re
ason); |
1568 return; | 1574 return; |
1569 } | 1575 } |
1570 clearIfComposited(); | 1576 clearIfComposited(); |
1571 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get()
); | 1577 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
1572 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei
ght, border); | 1578 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei
ght, border); |
1573 // FIXME: if the framebuffer is not complete, none of the below should be ex
ecuted. | 1579 // FIXME: if the framebuffer is not complete, none of the below should be ex
ecuted. |
1574 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN
ED_BYTE); | 1580 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN
ED_BYTE); |
1575 } | 1581 } |
1576 | 1582 |
1577 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL
int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) | 1583 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL
int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) |
1578 { | 1584 { |
1579 if (isContextLost()) | 1585 if (isContextLost()) |
1580 return; | 1586 return; |
1581 if (!validateTexFuncLevel("copyTexSubImage2D", target, level)) | 1587 if (!validateTexFuncLevel("copyTexSubImage2D", target, level)) |
(...skipping 17 matching lines...) Expand all Loading... |
1599 return; | 1605 return; |
1600 } | 1606 } |
1601 GLenum internalformat = tex->getInternalFormat(target, level); | 1607 GLenum internalformat = tex->getInternalFormat(target, level); |
1602 if (!validateSettableTexFormat("copyTexSubImage2D", internalformat)) | 1608 if (!validateSettableTexFormat("copyTexSubImage2D", internalformat)) |
1603 return; | 1609 return; |
1604 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra
mebufferColorFormat())) { | 1610 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra
mebufferColorFormat())) { |
1605 synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffe
r is incompatible format"); | 1611 synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffe
r is incompatible format"); |
1606 return; | 1612 return; |
1607 } | 1613 } |
1608 const char* reason = "framebuffer incomplete"; | 1614 const char* reason = "framebuffer incomplete"; |
1609 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r
eason)) { | 1615 GLenum framebufferTarget = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRA
MEBUFFER; |
| 1616 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(framebuffer
Target); |
| 1617 if (readFramebufferBinding && !readFramebufferBinding->onAccess(webContext()
, &reason)) { |
1610 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D",
reason); | 1618 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D",
reason); |
1611 return; | 1619 return; |
1612 } | 1620 } |
1613 clearIfComposited(); | 1621 clearIfComposited(); |
1614 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get()
); | 1622 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
1615 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width
, height); | 1623 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width
, height); |
1616 } | 1624 } |
1617 | 1625 |
1618 PassRefPtrWillBeRawPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer() | 1626 PassRefPtrWillBeRawPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer() |
1619 { | 1627 { |
1620 if (isContextLost()) | 1628 if (isContextLost()) |
1621 return nullptr; | 1629 return nullptr; |
1622 RefPtrWillBeRawPtr<WebGLBuffer> o = WebGLBuffer::create(this); | 1630 RefPtrWillBeRawPtr<WebGLBuffer> o = WebGLBuffer::create(this); |
1623 addSharedObject(o.get()); | 1631 addSharedObject(o.get()); |
1624 return o.release(); | 1632 return o.release(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 return; | 1732 return; |
1725 removeBoundBuffer(buffer); | 1733 removeBoundBuffer(buffer); |
1726 } | 1734 } |
1727 | 1735 |
1728 void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer) | 1736 void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer) |
1729 { | 1737 { |
1730 if (!deleteObject(framebuffer)) | 1738 if (!deleteObject(framebuffer)) |
1731 return; | 1739 return; |
1732 if (framebuffer == m_framebufferBinding) { | 1740 if (framebuffer == m_framebufferBinding) { |
1733 m_framebufferBinding = nullptr; | 1741 m_framebufferBinding = nullptr; |
1734 drawingBuffer()->setFramebufferBinding(0); | 1742 drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0); |
1735 // Have to call bindFramebuffer here to bind back to internal fbo. | 1743 // Have to call drawingBuffer()->bind() here to bind back to internal fb
o. |
1736 drawingBuffer()->bind(); | 1744 drawingBuffer()->bind(GL_FRAMEBUFFER); |
1737 } | 1745 } |
1738 } | 1746 } |
1739 | 1747 |
1740 void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program) | 1748 void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program) |
1741 { | 1749 { |
1742 deleteObject(program); | 1750 deleteObject(program); |
1743 // We don't reset m_currentProgram to 0 here because the deletion of the | 1751 // We don't reset m_currentProgram to 0 here because the deletion of the |
1744 // current program is delayed. | 1752 // current program is delayed. |
1745 } | 1753 } |
1746 | 1754 |
1747 void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff
er) | 1755 void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff
er) |
1748 { | 1756 { |
1749 if (!deleteObject(renderbuffer)) | 1757 if (!deleteObject(renderbuffer)) |
1750 return; | 1758 return; |
1751 if (renderbuffer == m_renderbufferBinding) | 1759 if (renderbuffer == m_renderbufferBinding) |
1752 m_renderbufferBinding = nullptr; | 1760 m_renderbufferBinding = nullptr; |
1753 if (m_framebufferBinding) | 1761 if (m_framebufferBinding) |
1754 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer)
; | 1762 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFE
R, renderbuffer); |
| 1763 if (getFramebufferBinding(GL_READ_FRAMEBUFFER)) |
| 1764 getFramebufferBinding(GL_READ_FRAMEBUFFER)->removeAttachmentFromBoundFra
mebuffer(GL_READ_FRAMEBUFFER, renderbuffer); |
1755 } | 1765 } |
1756 | 1766 |
1757 void WebGLRenderingContextBase::deleteShader(WebGLShader* shader) | 1767 void WebGLRenderingContextBase::deleteShader(WebGLShader* shader) |
1758 { | 1768 { |
1759 deleteObject(shader); | 1769 deleteObject(shader); |
1760 } | 1770 } |
1761 | 1771 |
1762 void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture) | 1772 void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture) |
1763 { | 1773 { |
1764 if (!deleteObject(texture)) | 1774 if (!deleteObject(texture)) |
(...skipping 16 matching lines...) Expand all Loading... |
1781 m_textureUnits[i].m_texture3DBinding = nullptr; | 1791 m_textureUnits[i].m_texture3DBinding = nullptr; |
1782 maxBoundTextureIndex = i; | 1792 maxBoundTextureIndex = i; |
1783 } | 1793 } |
1784 if (texture == m_textureUnits[i].m_texture2DArrayBinding) { | 1794 if (texture == m_textureUnits[i].m_texture2DArrayBinding) { |
1785 m_textureUnits[i].m_texture2DArrayBinding = nullptr; | 1795 m_textureUnits[i].m_texture2DArrayBinding = nullptr; |
1786 maxBoundTextureIndex = i; | 1796 maxBoundTextureIndex = i; |
1787 } | 1797 } |
1788 } | 1798 } |
1789 } | 1799 } |
1790 if (m_framebufferBinding) | 1800 if (m_framebufferBinding) |
1791 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture); | 1801 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFE
R, texture); |
| 1802 if (getFramebufferBinding(GL_READ_FRAMEBUFFER)) |
| 1803 getFramebufferBinding(GL_READ_FRAMEBUFFER)->removeAttachmentFromBoundFra
mebuffer(GL_READ_FRAMEBUFFER, texture); |
1792 | 1804 |
1793 // If the deleted was bound to the the current maximum index, trace backward
s to find the new max texture index | 1805 // If the deleted was bound to the the current maximum index, trace backward
s to find the new max texture index |
1794 if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBound
TextureIndex + 1)) { | 1806 if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBound
TextureIndex + 1)) { |
1795 findNewMaxNonDefaultTextureUnit(); | 1807 findNewMaxNonDefaultTextureUnit(); |
1796 } | 1808 } |
1797 } | 1809 } |
1798 | 1810 |
1799 void WebGLRenderingContextBase::depthFunc(GLenum func) | 1811 void WebGLRenderingContextBase::depthFunc(GLenum func) |
1800 { | 1812 { |
1801 if (isContextLost()) | 1813 if (isContextLost()) |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid t
arget"); | 2013 synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid t
arget"); |
2002 return; | 2014 return; |
2003 } | 2015 } |
2004 if (buffer && !buffer->validate(contextGroup(), this)) { | 2016 if (buffer && !buffer->validate(contextGroup(), this)) { |
2005 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no b
uffer or buffer not from this context"); | 2017 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no b
uffer or buffer not from this context"); |
2006 return; | 2018 return; |
2007 } | 2019 } |
2008 // Don't allow the default framebuffer to be mutated; all current | 2020 // Don't allow the default framebuffer to be mutated; all current |
2009 // implementations use an FBO internally in place of the default | 2021 // implementations use an FBO internally in place of the default |
2010 // FBO. | 2022 // FBO. |
2011 if (!m_framebufferBinding || !m_framebufferBinding->object()) { | 2023 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); |
| 2024 if (!framebufferBinding || !framebufferBinding->object()) { |
2012 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no f
ramebuffer bound"); | 2025 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no f
ramebuffer bound"); |
2013 return; | 2026 return; |
2014 } | 2027 } |
2015 Platform3DObject bufferObject = objectOrZero(buffer); | 2028 Platform3DObject bufferObject = objectOrZero(buffer); |
2016 switch (attachment) { | 2029 switch (attachment) { |
2017 case GL_DEPTH_STENCIL_ATTACHMENT: | 2030 case GL_DEPTH_STENCIL_ATTACHMENT: |
2018 if (isDepthStencilSupported() || !buffer) { | 2031 if (isDepthStencilSupported() || !buffer) { |
2019 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r
enderbuffertarget, bufferObject); | 2032 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r
enderbuffertarget, bufferObject); |
2020 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,
renderbuffertarget, bufferObject); | 2033 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,
renderbuffertarget, bufferObject); |
2021 } else { | 2034 } else { |
2022 WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuff
er(renderbuffertarget, buffer); | 2035 WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuff
er(renderbuffertarget, buffer); |
2023 if (!emulatedStencilBuffer) { | 2036 if (!emulatedStencilBuffer) { |
2024 synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "
out of memory"); | 2037 synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "
out of memory"); |
2025 return; | 2038 return; |
2026 } | 2039 } |
2027 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r
enderbuffertarget, bufferObject); | 2040 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r
enderbuffertarget, bufferObject); |
2028 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,
renderbuffertarget, objectOrZero(emulatedStencilBuffer)); | 2041 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,
renderbuffertarget, objectOrZero(emulatedStencilBuffer)); |
2029 } | 2042 } |
2030 break; | 2043 break; |
2031 default: | 2044 default: |
2032 webContext()->framebufferRenderbuffer(target, attachment, renderbufferta
rget, bufferObject); | 2045 webContext()->framebufferRenderbuffer(target, attachment, renderbufferta
rget, bufferObject); |
2033 } | 2046 } |
2034 m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer); | 2047 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buf
fer); |
2035 applyStencilTest(); | 2048 applyStencilTest(); |
2036 } | 2049 } |
2037 | 2050 |
2038 void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac
hment, GLenum textarget, WebGLTexture* texture, GLint level) | 2051 void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac
hment, GLenum textarget, WebGLTexture* texture, GLint level) |
2039 { | 2052 { |
2040 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur
e2D", target, attachment)) | 2053 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur
e2D", target, attachment)) |
2041 return; | 2054 return; |
2042 if (isWebGL2OrHigher()) { | 2055 if (isWebGL2OrHigher()) { |
2043 if (!validateTexFuncLevel("framebufferTexture2D", textarget, level)) | 2056 if (!validateTexFuncLevel("framebufferTexture2D", textarget, level)) |
2044 return; | 2057 return; |
2045 } else if (level) { | 2058 } else if (level) { |
2046 synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0
"); | 2059 synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0
"); |
2047 return; | 2060 return; |
2048 } | 2061 } |
2049 if (texture && !texture->validate(contextGroup(), this)) { | 2062 if (texture && !texture->validate(contextGroup(), this)) { |
2050 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text
ure or texture not from this context"); | 2063 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text
ure or texture not from this context"); |
2051 return; | 2064 return; |
2052 } | 2065 } |
2053 // Don't allow the default framebuffer to be mutated; all current | 2066 // Don't allow the default framebuffer to be mutated; all current |
2054 // implementations use an FBO internally in place of the default | 2067 // implementations use an FBO internally in place of the default |
2055 // FBO. | 2068 // FBO. |
2056 if (!m_framebufferBinding || !m_framebufferBinding->object()) { | 2069 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); |
| 2070 if (!framebufferBinding || !framebufferBinding->object()) { |
2057 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram
ebuffer bound"); | 2071 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram
ebuffer bound"); |
2058 return; | 2072 return; |
2059 } | 2073 } |
2060 Platform3DObject textureObject = objectOrZero(texture); | 2074 Platform3DObject textureObject = objectOrZero(texture); |
2061 switch (attachment) { | 2075 switch (attachment) { |
2062 case GL_DEPTH_STENCIL_ATTACHMENT: | 2076 case GL_DEPTH_STENCIL_ATTACHMENT: |
2063 webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarge
t, textureObject, level); | 2077 webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarge
t, textureObject, level); |
2064 webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textar
get, textureObject, level); | 2078 webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textar
get, textureObject, level); |
2065 break; | 2079 break; |
2066 case GL_DEPTH_ATTACHMENT: | 2080 case GL_DEPTH_ATTACHMENT: |
2067 webContext()->framebufferTexture2D(target, attachment, textarget, textur
eObject, level); | 2081 webContext()->framebufferTexture2D(target, attachment, textarget, textur
eObject, level); |
2068 break; | 2082 break; |
2069 case GL_STENCIL_ATTACHMENT: | 2083 case GL_STENCIL_ATTACHMENT: |
2070 webContext()->framebufferTexture2D(target, attachment, textarget, textur
eObject, level); | 2084 webContext()->framebufferTexture2D(target, attachment, textarget, textur
eObject, level); |
2071 break; | 2085 break; |
2072 default: | 2086 default: |
2073 webContext()->framebufferTexture2D(target, attachment, textarget, textur
eObject, level); | 2087 webContext()->framebufferTexture2D(target, attachment, textarget, textur
eObject, level); |
2074 } | 2088 } |
2075 m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget
, texture, level); | 2089 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, tex
target, texture, level); |
2076 applyStencilTest(); | 2090 applyStencilTest(); |
2077 } | 2091 } |
2078 | 2092 |
2079 void WebGLRenderingContextBase::frontFace(GLenum mode) | 2093 void WebGLRenderingContextBase::frontFace(GLenum mode) |
2080 { | 2094 { |
2081 if (isContextLost()) | 2095 if (isContextLost()) |
2082 return; | 2096 return; |
2083 switch (mode) { | 2097 switch (mode) { |
2084 case GL_CW: | 2098 case GL_CW: |
2085 case GL_CCW: | 2099 case GL_CCW: |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3319 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type n
ot RGBA/UNSIGNED_BYTE or implementation-defined values"); | 3333 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type n
ot RGBA/UNSIGNED_BYTE or implementation-defined values"); |
3320 return; | 3334 return; |
3321 } | 3335 } |
3322 } | 3336 } |
3323 // Validate array type against pixel type. | 3337 // Validate array type against pixel type. |
3324 if (pixels->type() != expectedViewType) { | 3338 if (pixels->type() != expectedViewType) { |
3325 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w
as the wrong type for the pixel format"); | 3339 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w
as the wrong type for the pixel format"); |
3326 return; | 3340 return; |
3327 } | 3341 } |
3328 const char* reason = "framebuffer incomplete"; | 3342 const char* reason = "framebuffer incomplete"; |
3329 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r
eason)) { | 3343 GLenum target = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER; |
| 3344 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(target); |
| 3345 if (readFramebufferBinding && !readFramebufferBinding->onAccess(webContext()
, &reason)) { |
3330 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason
); | 3346 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason
); |
3331 return; | 3347 return; |
3332 } | 3348 } |
3333 // Calculate array size, taking into consideration of PACK_ALIGNMENT. | 3349 // Calculate array size, taking into consideration of PACK_ALIGNMENT. |
3334 unsigned totalBytesRequired = 0; | 3350 unsigned totalBytesRequired = 0; |
3335 unsigned padding = 0; | 3351 unsigned padding = 0; |
3336 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w
idth, height, m_packAlignment, &totalBytesRequired, &padding); | 3352 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w
idth, height, m_packAlignment, &totalBytesRequired, &padding); |
3337 if (error != GL_NO_ERROR) { | 3353 if (error != GL_NO_ERROR) { |
3338 synthesizeGLError(error, "readPixels", "invalid dimensions"); | 3354 synthesizeGLError(error, "readPixels", "invalid dimensions"); |
3339 return; | 3355 return; |
3340 } | 3356 } |
3341 if (pixels->byteLength() < totalBytesRequired) { | 3357 if (pixels->byteLength() < totalBytesRequired) { |
3342 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n
ot large enough for dimensions"); | 3358 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n
ot large enough for dimensions"); |
3343 return; | 3359 return; |
3344 } | 3360 } |
3345 | 3361 |
3346 clearIfComposited(); | 3362 clearIfComposited(); |
3347 void* data = pixels->baseAddress(); | 3363 void* data = pixels->baseAddress(); |
3348 | 3364 |
3349 { | 3365 { |
3350 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.g
et()); | 3366 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding
); |
3351 webContext()->readPixels(x, y, width, height, format, type, data); | 3367 webContext()->readPixels(x, y, width, height, format, type, data); |
3352 } | 3368 } |
3353 | 3369 |
3354 #if OS(MACOSX) | 3370 #if OS(MACOSX) |
3355 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e., | 3371 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e., |
3356 // when alpha is off, readPixels should set alpha to 255 instead of 0. | 3372 // when alpha is off, readPixels should set alpha to 255 instead of 0. |
3357 if (!m_framebufferBinding && !drawingBuffer()->getActualAttributes().alpha)
{ | 3373 if (!readFramebufferBinding && !drawingBuffer()->getActualAttributes().alpha
) { |
3358 unsigned char* pixels = reinterpret_cast<unsigned char*>(data); | 3374 unsigned char* pixels = reinterpret_cast<unsigned char*>(data); |
3359 for (GLsizei iy = 0; iy < height; ++iy) { | 3375 for (GLsizei iy = 0; iy < height; ++iy) { |
3360 for (GLsizei ix = 0; ix < width; ++ix) { | 3376 for (GLsizei ix = 0; ix < width; ++ix) { |
3361 pixels[3] = 255; | 3377 pixels[3] = 255; |
3362 pixels += 4; | 3378 pixels += 4; |
3363 } | 3379 } |
3364 pixels += padding; | 3380 pixels += padding; |
3365 } | 3381 } |
3366 } | 3382 } |
3367 #endif | 3383 #endif |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4627 | 4643 |
4628 if (mode == RealLostContext) { | 4644 if (mode == RealLostContext) { |
4629 // Inform the embedder that a lost context was received. In response, th
e embedder might | 4645 // Inform the embedder that a lost context was received. In response, th
e embedder might |
4630 // decide to take action such as asking the user for permission to use W
ebGL again. | 4646 // decide to take action such as asking the user for permission to use W
ebGL again. |
4631 if (LocalFrame* frame = canvas()->document().frame()) | 4647 if (LocalFrame* frame = canvas()->document().frame()) |
4632 frame->loader().client()->didLoseWebGLContext(webContext()->getGraph
icsResetStatusARB()); | 4648 frame->loader().client()->didLoseWebGLContext(webContext()->getGraph
icsResetStatusARB()); |
4633 } | 4649 } |
4634 | 4650 |
4635 // Make absolutely sure we do not refer to an already-deleted texture or fra
mebuffer. | 4651 // Make absolutely sure we do not refer to an already-deleted texture or fra
mebuffer. |
4636 drawingBuffer()->setTexture2DBinding(0); | 4652 drawingBuffer()->setTexture2DBinding(0); |
4637 drawingBuffer()->setFramebufferBinding(0); | 4653 drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0); |
4638 | 4654 |
4639 detachAndRemoveAllObjects(); | 4655 detachAndRemoveAllObjects(); |
4640 | 4656 |
4641 // Lose all the extensions. | 4657 // Lose all the extensions. |
4642 for (size_t i = 0; i < m_extensions.size(); ++i) { | 4658 for (size_t i = 0; i < m_extensions.size(); ++i) { |
4643 ExtensionTracker* tracker = m_extensions[i].get(); | 4659 ExtensionTracker* tracker = m_extensions[i].get(); |
4644 tracker->loseExtension(); | 4660 tracker->loseExtension(); |
4645 } | 4661 } |
4646 | 4662 |
4647 for (size_t i = 0; i < WebGLExtensionNameCount; ++i) | 4663 for (size_t i = 0; i < WebGLExtensionNameCount; ++i) |
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5940 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE
); | 5956 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE
); |
5941 } else { | 5957 } else { |
5942 // This likely shouldn't happen but is the best way to report it to
the WebGL app. | 5958 // This likely shouldn't happen but is the best way to report it to
the WebGL app. |
5943 synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context
"); | 5959 synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context
"); |
5944 } | 5960 } |
5945 return; | 5961 return; |
5946 } | 5962 } |
5947 | 5963 |
5948 m_drawingBuffer = buffer.release(); | 5964 m_drawingBuffer = buffer.release(); |
5949 | 5965 |
5950 drawingBuffer()->bind(); | 5966 drawingBuffer()->bind(GL_FRAMEBUFFER); |
5951 m_lostContextErrors.clear(); | 5967 m_lostContextErrors.clear(); |
5952 m_contextLostMode = NotLostContext; | 5968 m_contextLostMode = NotLostContext; |
5953 m_autoRecoveryMethod = Manual; | 5969 m_autoRecoveryMethod = Manual; |
5954 m_restoreAllowed = false; | 5970 m_restoreAllowed = false; |
5955 removeFromEvictedList(this); | 5971 removeFromEvictedList(this); |
5956 | 5972 |
5957 setupFlags(); | 5973 setupFlags(); |
5958 initializeNewContext(); | 5974 initializeNewContext(); |
5959 markContextChanged(CanvasContextChanged); | 5975 markContextChanged(CanvasContextChanged); |
5960 canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglconte
xtrestored, false, true, "")); | 5976 canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglconte
xtrestored, false, true, "")); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6111 | 6127 |
6112 void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer*
buffer) | 6128 void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer*
buffer) |
6113 { | 6129 { |
6114 if (buffer) | 6130 if (buffer) |
6115 buffer->setHasEverBeenBound(); | 6131 buffer->setHasEverBeenBound(); |
6116 | 6132 |
6117 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) { | 6133 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) { |
6118 m_framebufferBinding = buffer; | 6134 m_framebufferBinding = buffer; |
6119 applyStencilTest(); | 6135 applyStencilTest(); |
6120 } | 6136 } |
6121 drawingBuffer()->setFramebufferBinding(objectOrZero(m_framebufferBinding.get
())); | 6137 drawingBuffer()->setFramebufferBinding(target, objectOrZero(getFramebufferBi
nding(target))); |
6122 | 6138 |
6123 if (!buffer) { | 6139 if (!buffer) { |
6124 // Instead of binding fb 0, bind the drawing buffer. | 6140 // Instead of binding fb 0, bind the drawing buffer. |
6125 drawingBuffer()->bind(target); | 6141 drawingBuffer()->bind(target); |
6126 } else { | 6142 } else { |
6127 webContext()->bindFramebuffer(target, buffer->object()); | 6143 webContext()->bindFramebuffer(target, buffer->object()); |
6128 } | 6144 } |
6129 } | 6145 } |
6130 | 6146 |
6131 void WebGLRenderingContextBase::restoreCurrentFramebuffer() | 6147 void WebGLRenderingContextBase::restoreCurrentFramebuffer() |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6216 | 6232 |
6217 return totalBytesPerPixel; | 6233 return totalBytesPerPixel; |
6218 } | 6234 } |
6219 | 6235 |
6220 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const | 6236 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const |
6221 { | 6237 { |
6222 return m_drawingBuffer.get(); | 6238 return m_drawingBuffer.get(); |
6223 } | 6239 } |
6224 | 6240 |
6225 } // namespace blink | 6241 } // namespace blink |
OLD | NEW |