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

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: Created 5 years, 7 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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 216 }
217 break; 217 break;
218 } 218 }
219 } 219 }
220 220
221 namespace { 221 namespace {
222 222
223 class ScopedDrawingBufferBinder { 223 class ScopedDrawingBufferBinder {
224 STACK_ALLOCATED(); 224 STACK_ALLOCATED();
225 public: 225 public:
226 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding) 226 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding, GLenum target)
227 : m_drawingBuffer(drawingBuffer) 227 : m_drawingBuffer(drawingBuffer)
228 , m_framebufferBinding(framebufferBinding) 228 , m_framebufferBinding(framebufferBinding)
229 , m_target(target)
229 { 230 {
230 // Commit DrawingBuffer if needed (e.g., for multisampling) 231 // Commit DrawingBuffer if needed (e.g., for multisampling)
231 if (!m_framebufferBinding && m_drawingBuffer) 232 if (!m_framebufferBinding && m_drawingBuffer)
232 m_drawingBuffer->commit(); 233 m_drawingBuffer->commit(m_target);
233 } 234 }
234 235
235 ~ScopedDrawingBufferBinder() 236 ~ScopedDrawingBufferBinder()
236 { 237 {
237 // Restore DrawingBuffer if needed 238 // Restore DrawingBuffer if needed
238 if (!m_framebufferBinding && m_drawingBuffer) 239 if (!m_framebufferBinding && m_drawingBuffer)
239 m_drawingBuffer->bind(); 240 m_drawingBuffer->bind(m_target);
240 } 241 }
241 242
242 private: 243 private:
243 DrawingBuffer* m_drawingBuffer; 244 DrawingBuffer* m_drawingBuffer;
244 RawPtrWillBeMember<WebGLFramebuffer> m_framebufferBinding; 245 RawPtrWillBeMember<WebGLFramebuffer> m_framebufferBinding;
246 GLenum m_target;
245 }; 247 };
246 248
247 GLint clamp(GLint value, GLint min, GLint max) 249 GLint clamp(GLint value, GLint min, GLint max)
248 { 250 {
249 if (value < min) 251 if (value < min)
250 value = min; 252 value = min;
251 if (value > max) 253 if (value > max)
252 value = max; 254 value = max;
253 return value; 255 return value;
254 } 256 }
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 } 912 }
911 if (contextAttributes.get().stencil()) { 913 if (contextAttributes.get().stencil()) {
912 if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT)) 914 if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
913 webContext()->clearStencil(m_clearStencil & m_stencilMask); 915 webContext()->clearStencil(m_clearStencil & m_stencilMask);
914 else 916 else
915 webContext()->clearStencil(0); 917 webContext()->clearStencil(0);
916 clearMask |= GL_STENCIL_BUFFER_BIT; 918 clearMask |= GL_STENCIL_BUFFER_BIT;
917 webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); 919 webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
918 } 920 }
919 921
920 drawingBuffer()->clearFramebuffers(clearMask); 922 if (!isWebGL2OrHigher())
923 drawingBuffer()->clearFramebuffers(clearMask);
924 else
925 drawingBuffer()->clearFramebuffers(clearMask, GL_DRAW_FRAMEBUFFER);
Ken Russell (switch to Gerrit) 2015/05/06 21:17:33 Please add a new virtual function that returns the
yunchao 2015/05/22 09:54:35 Done.
921 926
922 restoreStateAfterClear(); 927 restoreStateAfterClear();
923 if (m_framebufferBinding) 928 if (m_framebufferBinding) {
924 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer Binding.get())); 929 if (!isWebGL2OrHigher())
930 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebu fferBinding.get()));
931 else
932 webContext()->bindFramebuffer(GL_DRAW_FRAMEBUFFER, objectOrZero(m_fr amebufferBinding.get()));
933 }
925 drawingBuffer()->setBufferClearNeeded(false); 934 drawingBuffer()->setBufferClearNeeded(false);
926 935
927 return combinedClear ? CombinedClear : JustClear; 936 return combinedClear ? CombinedClear : JustClear;
928 } 937 }
929 938
930 void WebGLRenderingContextBase::restoreStateAfterClear() 939 void WebGLRenderingContextBase::restoreStateAfterClear()
931 { 940 {
932 if (isContextLost()) 941 if (isContextLost())
933 return; 942 return;
934 943
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 width = clamp(width, 1, maxWidth); 1028 width = clamp(width, 1, maxWidth);
1020 height = clamp(height, 1, maxHeight); 1029 height = clamp(height, 1, maxHeight);
1021 1030
1022 // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off 1031 // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
1023 // clear (and this matches what reshape will do). 1032 // clear (and this matches what reshape will do).
1024 drawingBuffer()->reset(IntSize(width, height)); 1033 drawingBuffer()->reset(IntSize(width, height));
1025 restoreStateAfterClear(); 1034 restoreStateAfterClear();
1026 1035
1027 webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activ eTextureUnit].m_texture2DBinding.get())); 1036 webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activ eTextureUnit].m_texture2DBinding.get()));
1028 webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferB inding.get())); 1037 webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferB inding.get()));
1029 if (m_framebufferBinding) 1038 if (isWebGL2OrHigher()) {
1039 // In GLES 3.0, bindFramebuffer(GL_FRAMEBUFFER, buffer1) = bindBuffer(GL_REA D_FRAMEBUFFER, buffer1) +
1040 // bindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer1)
1041 if (m_framebufferBinding)
1042 webContext()->bindFramebuffer(GL_DRAW_FRAMEBUFFER, objectOrZero(m_fr amebufferBinding.get()));
1043 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(GL_READ _FRAMEBUFFER);
1044 if (readFramebufferBinding)
1045 webContext()->bindFramebuffer(GL_READ_FRAMEBUFFER, objectOrZero(read FramebufferBinding));
1046 } else if (m_framebufferBinding) {
1030 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer Binding.get())); 1047 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer Binding.get()));
1048 }
1031 } 1049 }
1032 1050
1033 int WebGLRenderingContextBase::drawingBufferWidth() const 1051 int WebGLRenderingContextBase::drawingBufferWidth() const
1034 { 1052 {
1035 return isContextLost() ? 0 : drawingBuffer()->size().width(); 1053 return isContextLost() ? 0 : drawingBuffer()->size().width();
1036 } 1054 }
1037 1055
1038 int WebGLRenderingContextBase::drawingBufferHeight() const 1056 int WebGLRenderingContextBase::drawingBufferHeight() const
1039 { 1057 {
1040 return isContextLost() ? 0 : drawingBuffer()->size().height(); 1058 return isContextLost() ? 0 : drawingBuffer()->size().height();
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 1386
1369 bool WebGLRenderingContextBase::validateFramebufferTarget(GLenum target) 1387 bool WebGLRenderingContextBase::validateFramebufferTarget(GLenum target)
1370 { 1388 {
1371 if (target == GL_FRAMEBUFFER) 1389 if (target == GL_FRAMEBUFFER)
1372 return true; 1390 return true;
1373 return false; 1391 return false;
1374 } 1392 }
1375 1393
1376 WebGLFramebuffer* WebGLRenderingContextBase::getFramebufferBinding(GLenum target ) 1394 WebGLFramebuffer* WebGLRenderingContextBase::getFramebufferBinding(GLenum target )
1377 { 1395 {
1378 return m_framebufferBinding.get(); 1396 if (target == GL_FRAMEBUFFER)
1397 return m_framebufferBinding.get();
1398 return nullptr;
1379 } 1399 }
1380 1400
1381 GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target) 1401 GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target)
1382 { 1402 {
1383 if (isContextLost()) 1403 if (isContextLost())
1384 return GL_FRAMEBUFFER_UNSUPPORTED; 1404 return GL_FRAMEBUFFER_UNSUPPORTED;
1385 if (!validateFramebufferTarget(target)) { 1405 if (!validateFramebufferTarget(target)) {
1386 synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid ta rget"); 1406 synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid ta rget");
1387 return 0; 1407 return 0;
1388 } 1408 }
1389 if (!getFramebufferBinding(target) || !getFramebufferBinding(target)->object ()) 1409 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
1410 if (!framebufferBinding || !framebufferBinding->object())
1390 return GL_FRAMEBUFFER_COMPLETE; 1411 return GL_FRAMEBUFFER_COMPLETE;
1391 const char* reason = "framebuffer incomplete"; 1412 const char* reason = "framebuffer incomplete";
1392 GLenum result = m_framebufferBinding->checkStatus(&reason); 1413 GLenum result = framebufferBinding->checkStatus(&reason, target);
1393 if (result != GL_FRAMEBUFFER_COMPLETE) { 1414 if (result != GL_FRAMEBUFFER_COMPLETE) {
1394 emitGLWarning("checkFramebufferStatus", reason); 1415 emitGLWarning("checkFramebufferStatus", reason);
1395 return result; 1416 return result;
1396 } 1417 }
1397 result = webContext()->checkFramebufferStatus(target); 1418 result = webContext()->checkFramebufferStatus(target);
1398 return result; 1419 return result;
1399 } 1420 }
1400 1421
1401 void WebGLRenderingContextBase::clear(GLbitfield mask) 1422 void WebGLRenderingContextBase::clear(GLbitfield mask)
1402 { 1423 {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 return; 1573 return;
1553 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) { 1574 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) {
1554 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i s incompatible format"); 1575 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i s incompatible format");
1555 return; 1576 return;
1556 } 1577 }
1557 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { 1578 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
1558 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow er of 2"); 1579 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow er of 2");
1559 return; 1580 return;
1560 } 1581 }
1561 const char* reason = "framebuffer incomplete"; 1582 const char* reason = "framebuffer incomplete";
1562 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 1583 if ((m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), & reason))
1584 || (getFramebufferBinding(GL_READ_FRAMEBUFFER) && !getFramebufferBinding (GL_READ_FRAMEBUFFER)->onAccess(webContext(), &reason, GL_READ_FRAMEBUFFER))) {
1563 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", re ason); 1585 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", re ason);
1564 return; 1586 return;
1565 } 1587 }
1566 clearIfComposited(); 1588 clearIfComposited();
1567 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() ); 1589 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() , GL_FRAMEBUFFER);
1590 if (isWebGL2OrHigher())
1591 ScopedDrawingBufferBinder readBinder(drawingBuffer(), getFramebufferBind ing(GL_READ_FRAMEBUFFER), GL_READ_FRAMEBUFFER);
Ken Russell (switch to Gerrit) 2015/05/06 21:17:33 This won't work. The scoping of readBinder ends ou
yunchao 2015/05/22 09:54:35 I am very sorry, Ken. I didn't got what you said.
1568 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei ght, border); 1592 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei ght, border);
1569 // FIXME: if the framebuffer is not complete, none of the below should be ex ecuted. 1593 // FIXME: if the framebuffer is not complete, none of the below should be ex ecuted.
1570 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN ED_BYTE); 1594 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN ED_BYTE);
1571 } 1595 }
1572 1596
1573 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) 1597 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1574 { 1598 {
1575 if (isContextLost()) 1599 if (isContextLost())
1576 return; 1600 return;
1577 if (!validateTexFuncLevel("copyTexSubImage2D", target, level)) 1601 if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
(...skipping 17 matching lines...) Expand all
1595 return; 1619 return;
1596 } 1620 }
1597 GLenum internalformat = tex->getInternalFormat(target, level); 1621 GLenum internalformat = tex->getInternalFormat(target, level);
1598 if (!validateSettableTexFormat("copyTexSubImage2D", internalformat)) 1622 if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
1599 return; 1623 return;
1600 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) { 1624 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) {
1601 synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffe r is incompatible format"); 1625 synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffe r is incompatible format");
1602 return; 1626 return;
1603 } 1627 }
1604 const char* reason = "framebuffer incomplete"; 1628 const char* reason = "framebuffer incomplete";
1605 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 1629 if ((m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), & reason))
1630 || (getFramebufferBinding(GL_READ_FRAMEBUFFER) && !getFramebufferBinding (GL_READ_FRAMEBUFFER)->onAccess(webContext(), &reason, GL_READ_FRAMEBUFFER))) {
1606 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason); 1631 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
1607 return; 1632 return;
1608 } 1633 }
1609 clearIfComposited(); 1634 clearIfComposited();
1610 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() ); 1635 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() , GL_FRAMEBUFFER);
1636 if (isWebGL2OrHigher())
1637 ScopedDrawingBufferBinder readBinder(drawingBuffer(), getFramebufferBind ing(GL_READ_FRAMEBUFFER), GL_READ_FRAMEBUFFER);
Ken Russell (switch to Gerrit) 2015/05/06 21:17:33 Same problem here.
1611 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height); 1638 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height);
1612 } 1639 }
1613 1640
1614 PassRefPtrWillBeRawPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer() 1641 PassRefPtrWillBeRawPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
1615 { 1642 {
1616 if (isContextLost()) 1643 if (isContextLost())
1617 return nullptr; 1644 return nullptr;
1618 RefPtrWillBeRawPtr<WebGLBuffer> o = WebGLBuffer::create(this); 1645 RefPtrWillBeRawPtr<WebGLBuffer> o = WebGLBuffer::create(this);
1619 addSharedObject(o.get()); 1646 addSharedObject(o.get());
1620 return o.release(); 1647 return o.release();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 } 1771 }
1745 1772
1746 void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff er) 1773 void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff er)
1747 { 1774 {
1748 if (!deleteObject(renderbuffer)) 1775 if (!deleteObject(renderbuffer))
1749 return; 1776 return;
1750 if (renderbuffer == m_renderbufferBinding) 1777 if (renderbuffer == m_renderbufferBinding)
1751 m_renderbufferBinding = nullptr; 1778 m_renderbufferBinding = nullptr;
1752 if (m_framebufferBinding) 1779 if (m_framebufferBinding)
1753 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer) ; 1780 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer) ;
1781 if (getFramebufferBinding(GL_READ_FRAMEBUFFER))
1782 getFramebufferBinding(GL_READ_FRAMEBUFFER)->removeAttachmentFromBoundFra mebuffer(renderbuffer, GL_READ_FRAMEBUFFER);
1754 } 1783 }
1755 1784
1756 void WebGLRenderingContextBase::deleteShader(WebGLShader* shader) 1785 void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
1757 { 1786 {
1758 deleteObject(shader); 1787 deleteObject(shader);
1759 } 1788 }
1760 1789
1761 void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture) 1790 void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
1762 { 1791 {
1763 if (!deleteObject(texture)) 1792 if (!deleteObject(texture))
(...skipping 17 matching lines...) Expand all
1781 maxBoundTextureIndex = i; 1810 maxBoundTextureIndex = i;
1782 } 1811 }
1783 if (texture == m_textureUnits[i].m_texture2DArrayBinding) { 1812 if (texture == m_textureUnits[i].m_texture2DArrayBinding) {
1784 m_textureUnits[i].m_texture2DArrayBinding = nullptr; 1813 m_textureUnits[i].m_texture2DArrayBinding = nullptr;
1785 maxBoundTextureIndex = i; 1814 maxBoundTextureIndex = i;
1786 } 1815 }
1787 } 1816 }
1788 } 1817 }
1789 if (m_framebufferBinding) 1818 if (m_framebufferBinding)
1790 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture); 1819 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
1820 if (getFramebufferBinding(GL_READ_FRAMEBUFFER))
1821 getFramebufferBinding(GL_READ_FRAMEBUFFER)->removeAttachmentFromBoundFra mebuffer(texture, GL_READ_FRAMEBUFFER);
1791 1822
1792 // If the deleted was bound to the the current maximum index, trace backward s to find the new max texture index 1823 // If the deleted was bound to the the current maximum index, trace backward s to find the new max texture index
1793 if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBound TextureIndex + 1)) { 1824 if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBound TextureIndex + 1)) {
1794 findNewMaxNonDefaultTextureUnit(); 1825 findNewMaxNonDefaultTextureUnit();
1795 } 1826 }
1796 } 1827 }
1797 1828
1798 void WebGLRenderingContextBase::depthFunc(GLenum func) 1829 void WebGLRenderingContextBase::depthFunc(GLenum func)
1799 { 1830 {
1800 if (isContextLost()) 1831 if (isContextLost())
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2000 synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid t arget"); 2031 synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid t arget");
2001 return; 2032 return;
2002 } 2033 }
2003 if (buffer && !buffer->validate(contextGroup(), this)) { 2034 if (buffer && !buffer->validate(contextGroup(), this)) {
2004 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no b uffer or buffer not from this context"); 2035 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no b uffer or buffer not from this context");
2005 return; 2036 return;
2006 } 2037 }
2007 // Don't allow the default framebuffer to be mutated; all current 2038 // Don't allow the default framebuffer to be mutated; all current
2008 // implementations use an FBO internally in place of the default 2039 // implementations use an FBO internally in place of the default
2009 // FBO. 2040 // FBO.
2010 if (!m_framebufferBinding || !m_framebufferBinding->object()) { 2041 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
2042 if (!framebufferBinding || !framebufferBinding->object()) {
2011 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no f ramebuffer bound"); 2043 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no f ramebuffer bound");
2012 return; 2044 return;
2013 } 2045 }
2014 Platform3DObject bufferObject = objectOrZero(buffer); 2046 Platform3DObject bufferObject = objectOrZero(buffer);
2015 switch (attachment) { 2047 switch (attachment) {
2016 case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL: 2048 case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
2049 // TODO. are there any devices can support depth_stencil buffer directly , not use oes_depth_stencil extension?
2017 if (isDepthStencilSupported() || !buffer) { 2050 if (isDepthStencilSupported() || !buffer) {
2018 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject); 2051 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject);
2019 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject); 2052 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
2020 } else { 2053 } else {
2021 WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuff er(renderbuffertarget, buffer); 2054 WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuff er(renderbuffertarget, buffer);
2022 if (!emulatedStencilBuffer) { 2055 if (!emulatedStencilBuffer) {
2023 synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", " out of memory"); 2056 synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", " out of memory");
2024 return; 2057 return;
2025 } 2058 }
2026 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject); 2059 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject);
2027 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer)); 2060 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
2028 } 2061 }
2029 break; 2062 break;
2030 default: 2063 default:
2031 webContext()->framebufferRenderbuffer(target, attachment, renderbufferta rget, bufferObject); 2064 webContext()->framebufferRenderbuffer(target, attachment, renderbufferta rget, bufferObject);
2032 } 2065 }
2033 m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer); 2066 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buf fer);
2034 applyStencilTest(); 2067 applyStencilTest();
2035 } 2068 }
2036 2069
2037 void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac hment, GLenum textarget, WebGLTexture* texture, GLint level) 2070 void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac hment, GLenum textarget, WebGLTexture* texture, GLint level)
2038 { 2071 {
2039 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur e2D", target, attachment)) 2072 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur e2D", target, attachment))
2040 return; 2073 return;
2041 if (level) { 2074 if (level) {
2042 synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0 "); 2075 synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0 ");
2043 return; 2076 return;
2044 } 2077 }
2045 if (texture && !texture->validate(contextGroup(), this)) { 2078 if (texture && !texture->validate(contextGroup(), this)) {
2046 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text ure or texture not from this context"); 2079 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text ure or texture not from this context");
2047 return; 2080 return;
2048 } 2081 }
2049 // Don't allow the default framebuffer to be mutated; all current 2082 // Don't allow the default framebuffer to be mutated; all current
2050 // implementations use an FBO internally in place of the default 2083 // implementations use an FBO internally in place of the default
2051 // FBO. 2084 // FBO.
2052 if (!m_framebufferBinding || !m_framebufferBinding->object()) { 2085 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
2086 if (!framebufferBinding || !framebufferBinding->object()) {
2053 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram ebuffer bound"); 2087 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram ebuffer bound");
2054 return; 2088 return;
2055 } 2089 }
2056 Platform3DObject textureObject = objectOrZero(texture); 2090 Platform3DObject textureObject = objectOrZero(texture);
2057 switch (attachment) { 2091 switch (attachment) {
2058 case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL: 2092 case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
2059 webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarge t, textureObject, level); 2093 webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarge t, textureObject, level);
2060 webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textar get, textureObject, level); 2094 webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textar get, textureObject, level);
2061 break; 2095 break;
2062 case GL_DEPTH_ATTACHMENT:
2063 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level);
2064 break;
2065 case GL_STENCIL_ATTACHMENT:
2066 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level);
2067 break;
2068 default: 2096 default:
2069 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level); 2097 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level);
2070 } 2098 }
2071 m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget , texture, level); 2099 // TODO: Check whether this is correct
bajones 2015/05/06 17:47:54 Let's figure this out before landing the patch.
yunchao 2015/05/22 09:54:35 I think this is correct. So remove this TODO.
2100 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, tex target, texture, level);
2072 applyStencilTest(); 2101 applyStencilTest();
2073 } 2102 }
2074 2103
2075 void WebGLRenderingContextBase::frontFace(GLenum mode) 2104 void WebGLRenderingContextBase::frontFace(GLenum mode)
2076 { 2105 {
2077 if (isContextLost()) 2106 if (isContextLost())
2078 return; 2107 return;
2079 switch (mode) { 2108 switch (mode) {
2080 case GL_CW: 2109 case GL_CW:
2081 case GL_CCW: 2110 case GL_CCW:
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3315 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type n ot RGBA/UNSIGNED_BYTE or implementation-defined values"); 3344 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type n ot RGBA/UNSIGNED_BYTE or implementation-defined values");
3316 return; 3345 return;
3317 } 3346 }
3318 } 3347 }
3319 // Validate array type against pixel type. 3348 // Validate array type against pixel type.
3320 if (pixels->type() != expectedViewType) { 3349 if (pixels->type() != expectedViewType) {
3321 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format"); 3350 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format");
3322 return; 3351 return;
3323 } 3352 }
3324 const char* reason = "framebuffer incomplete"; 3353 const char* reason = "framebuffer incomplete";
3325 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 3354 GLenum target = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER;
3355 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(target);
3356 if (readFramebufferBinding && !readFramebufferBinding->onAccess(webContext() , &reason, target)) {
3326 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason ); 3357 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason );
3327 return; 3358 return;
3328 } 3359 }
3329 // Calculate array size, taking into consideration of PACK_ALIGNMENT. 3360 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
3330 unsigned totalBytesRequired = 0; 3361 unsigned totalBytesRequired = 0;
3331 unsigned padding = 0; 3362 unsigned padding = 0;
3332 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding); 3363 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding);
3333 if (error != GL_NO_ERROR) { 3364 if (error != GL_NO_ERROR) {
3334 synthesizeGLError(error, "readPixels", "invalid dimensions"); 3365 synthesizeGLError(error, "readPixels", "invalid dimensions");
3335 return; 3366 return;
3336 } 3367 }
3337 if (pixels->byteLength() < totalBytesRequired) { 3368 if (pixels->byteLength() < totalBytesRequired) {
3338 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions"); 3369 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions");
3339 return; 3370 return;
3340 } 3371 }
3341 3372
3342 clearIfComposited(); 3373 clearIfComposited();
3343 void* data = pixels->baseAddress(); 3374 void* data = pixels->baseAddress();
3344 3375
3345 { 3376 {
3346 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.g et()); 3377 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding , target);
3347 webContext()->readPixels(x, y, width, height, format, type, data); 3378 webContext()->readPixels(x, y, width, height, format, type, data);
3348 } 3379 }
3349 3380
3350 #if OS(MACOSX) 3381 #if OS(MACOSX)
3351 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e., 3382 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
3352 // when alpha is off, readPixels should set alpha to 255 instead of 0. 3383 // when alpha is off, readPixels should set alpha to 255 instead of 0.
3353 if (!m_framebufferBinding && !drawingBuffer()->getActualAttributes().alpha) { 3384 if (!readFramebufferBinding && !drawingBuffer()->getActualAttributes().alpha ) {
3354 unsigned char* pixels = reinterpret_cast<unsigned char*>(data); 3385 unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
3355 for (GLsizei iy = 0; iy < height; ++iy) { 3386 for (GLsizei iy = 0; iy < height; ++iy) {
3356 for (GLsizei ix = 0; ix < width; ++ix) { 3387 for (GLsizei ix = 0; ix < width; ++ix) {
3357 pixels[3] = 255; 3388 pixels[3] = 255;
3358 pixels += 4; 3389 pixels += 4;
3359 } 3390 }
3360 pixels += padding; 3391 pixels += padding;
3361 } 3392 }
3362 } 3393 }
3363 #endif 3394 #endif
(...skipping 2710 matching lines...) Expand 10 before | Expand all | Expand 10 after
6074 6105
6075 void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer* buffer) 6106 void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer* buffer)
6076 { 6107 {
6077 if (buffer) 6108 if (buffer)
6078 buffer->setHasEverBeenBound(); 6109 buffer->setHasEverBeenBound();
6079 6110
6080 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) { 6111 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) {
6081 m_framebufferBinding = buffer; 6112 m_framebufferBinding = buffer;
6082 applyStencilTest(); 6113 applyStencilTest();
6083 } 6114 }
6084 drawingBuffer()->setFramebufferBinding(objectOrZero(m_framebufferBinding.get ())); 6115 drawingBuffer()->setFramebufferBinding(objectOrZero(getFramebufferBinding(ta rget)), target);
6085 6116
6086 if (!buffer) { 6117 if (!buffer) {
6087 // Instead of binding fb 0, bind the drawing buffer. 6118 // Instead of binding fb 0, bind the drawing buffer.
6088 drawingBuffer()->bind(target); 6119 drawingBuffer()->bind(target);
6089 } else { 6120 } else {
6090 webContext()->bindFramebuffer(target, buffer->object()); 6121 webContext()->bindFramebuffer(target, buffer->object());
6091 } 6122 }
6092 } 6123 }
6093 6124
6094 void WebGLRenderingContextBase::restoreCurrentFramebuffer() 6125 void WebGLRenderingContextBase::restoreCurrentFramebuffer()
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
6191 return m_sharedWebGraphicsContext3D ? m_sharedWebGraphicsContext3D->drawingB uffer() : 0; 6222 return m_sharedWebGraphicsContext3D ? m_sharedWebGraphicsContext3D->drawingB uffer() : 0;
6192 } 6223 }
6193 #else 6224 #else
6194 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const 6225 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const
6195 { 6226 {
6196 return m_drawingBuffer.get(); 6227 return m_drawingBuffer.get();
6197 } 6228 }
6198 #endif 6229 #endif
6199 6230
6200 } // namespace blink 6231 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698