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

Side by Side Diff: Source/core/html/canvas/WebGLRenderingContextBase.cpp

Issue 1120953002: WebGL 2: add read/write framebuffer binding points to related APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: addressed kbr@'s feedback: remove an argument that is not used Created 5 years, 6 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContextBase.h ('k') | Source/platform/graphics/gpu/DrawingBuffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698