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

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 zmo@'s and kbr@'s feedback 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 } 217 }
218 break; 218 break;
219 } 219 }
220 } 220 }
221 221
222 namespace { 222 namespace {
223 223
224 class ScopedDrawingBufferBinder { 224 class ScopedDrawingBufferBinder {
225 STACK_ALLOCATED(); 225 STACK_ALLOCATED();
226 public: 226 public:
227 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding) 227 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding, GLenum target)
Zhenyao Mo 2015/06/09 20:29:51 That's why I suggest you have an idea of drawFrame
yunchao 2015/06/10 08:21:25 I got it. But I think it is not a must. see the la
228 : m_drawingBuffer(drawingBuffer) 228 : m_drawingBuffer(drawingBuffer)
229 , m_framebufferBinding(framebufferBinding) 229 , m_framebufferBinding(framebufferBinding)
230 , m_target(target)
230 { 231 {
231 // Commit DrawingBuffer if needed (e.g., for multisampling) 232 // Commit DrawingBuffer if needed (e.g., for multisampling)
232 if (!m_framebufferBinding && m_drawingBuffer) 233 if (!m_framebufferBinding && m_drawingBuffer)
Zhenyao Mo 2015/06/09 20:29:51 This should be readFramebufferBinding
yunchao 2015/06/10 08:21:25 Agree. I rename this variable to m_readFramebuffer
233 m_drawingBuffer->commit(); 234 m_drawingBuffer->commit();
234 } 235 }
235 236
236 ~ScopedDrawingBufferBinder() 237 ~ScopedDrawingBufferBinder()
237 { 238 {
238 // Restore DrawingBuffer if needed 239 // Restore DrawingBuffer if needed
239 if (!m_framebufferBinding && m_drawingBuffer) 240 if (!m_framebufferBinding && m_drawingBuffer)
Zhenyao Mo 2015/06/09 20:29:50 This actually should be drawFramebufferBinding.
Zhenyao Mo 2015/06/10 05:01:45 This should also be readFramebufferBinding. Becaus
yunchao 2015/06/10 08:21:25 To make it clear, I add a comment for the class Sc
240 m_drawingBuffer->bind(); 241 m_drawingBuffer->bind(m_target);
241 } 242 }
242 243
243 private: 244 private:
244 DrawingBuffer* m_drawingBuffer; 245 DrawingBuffer* m_drawingBuffer;
245 RawPtrWillBeMember<WebGLFramebuffer> m_framebufferBinding; 246 RawPtrWillBeMember<WebGLFramebuffer> m_framebufferBinding;
247 GLenum m_target;
246 }; 248 };
247 249
248 GLint clamp(GLint value, GLint min, GLint max) 250 GLint clamp(GLint value, GLint min, GLint max)
249 { 251 {
250 if (value < min) 252 if (value < min)
251 value = min; 253 value = min;
252 if (value > max) 254 if (value > max)
253 value = max; 255 value = max;
254 return value; 256 return value;
255 } 257 }
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 webContext()->clearStencil(m_clearStencil & m_stencilMask); 907 webContext()->clearStencil(m_clearStencil & m_stencilMask);
906 else 908 else
907 webContext()->clearStencil(0); 909 webContext()->clearStencil(0);
908 clearMask |= GL_STENCIL_BUFFER_BIT; 910 clearMask |= GL_STENCIL_BUFFER_BIT;
909 webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); 911 webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
910 } 912 }
911 913
912 drawingBuffer()->clearFramebuffers(clearMask); 914 drawingBuffer()->clearFramebuffers(clearMask);
913 915
914 restoreStateAfterClear(); 916 restoreStateAfterClear();
915 if (m_framebufferBinding) 917 drawingBuffer()->restoreFramebufferBindings();
916 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer Binding.get()));
917 drawingBuffer()->setBufferClearNeeded(false); 918 drawingBuffer()->setBufferClearNeeded(false);
918 919
919 return combinedClear ? CombinedClear : JustClear; 920 return combinedClear ? CombinedClear : JustClear;
920 } 921 }
921 922
922 void WebGLRenderingContextBase::restoreStateAfterClear() 923 void WebGLRenderingContextBase::restoreStateAfterClear()
923 { 924 {
924 if (isContextLost()) 925 if (isContextLost())
925 return; 926 return;
926 927
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 width = clamp(width, 1, maxWidth); 1012 width = clamp(width, 1, maxWidth);
1012 height = clamp(height, 1, maxHeight); 1013 height = clamp(height, 1, maxHeight);
1013 1014
1014 // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off 1015 // 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). 1016 // clear (and this matches what reshape will do).
1016 drawingBuffer()->reset(IntSize(width, height)); 1017 drawingBuffer()->reset(IntSize(width, height));
1017 restoreStateAfterClear(); 1018 restoreStateAfterClear();
1018 1019
1019 webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activ eTextureUnit].m_texture2DBinding.get())); 1020 webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activ eTextureUnit].m_texture2DBinding.get()));
1020 webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferB inding.get())); 1021 webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferB inding.get()));
1021 if (m_framebufferBinding) 1022 drawingBuffer()->restoreFramebufferBindings();
1022 webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebuffer Binding.get()));
1023 } 1023 }
1024 1024
1025 int WebGLRenderingContextBase::drawingBufferWidth() const 1025 int WebGLRenderingContextBase::drawingBufferWidth() const
1026 { 1026 {
1027 return isContextLost() ? 0 : drawingBuffer()->size().width(); 1027 return isContextLost() ? 0 : drawingBuffer()->size().width();
1028 } 1028 }
1029 1029
1030 int WebGLRenderingContextBase::drawingBufferHeight() const 1030 int WebGLRenderingContextBase::drawingBufferHeight() const
1031 { 1031 {
1032 return isContextLost() ? 0 : drawingBuffer()->size().height(); 1032 return isContextLost() ? 0 : drawingBuffer()->size().height();
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 1363
1364 bool WebGLRenderingContextBase::validateFramebufferTarget(GLenum target) 1364 bool WebGLRenderingContextBase::validateFramebufferTarget(GLenum target)
1365 { 1365 {
1366 if (target == GL_FRAMEBUFFER) 1366 if (target == GL_FRAMEBUFFER)
1367 return true; 1367 return true;
1368 return false; 1368 return false;
1369 } 1369 }
1370 1370
1371 WebGLFramebuffer* WebGLRenderingContextBase::getFramebufferBinding(GLenum target ) 1371 WebGLFramebuffer* WebGLRenderingContextBase::getFramebufferBinding(GLenum target )
1372 { 1372 {
1373 return m_framebufferBinding.get(); 1373 if (target == GL_FRAMEBUFFER)
1374 return m_framebufferBinding.get();
1375 return nullptr;
1374 } 1376 }
1375 1377
1376 GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target) 1378 GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target)
1377 { 1379 {
1378 if (isContextLost()) 1380 if (isContextLost())
1379 return GL_FRAMEBUFFER_UNSUPPORTED; 1381 return GL_FRAMEBUFFER_UNSUPPORTED;
1380 if (!validateFramebufferTarget(target)) { 1382 if (!validateFramebufferTarget(target)) {
1381 synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid ta rget"); 1383 synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid ta rget");
1382 return 0; 1384 return 0;
1383 } 1385 }
1384 if (!getFramebufferBinding(target) || !getFramebufferBinding(target)->object ()) 1386 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
1387 if (!framebufferBinding || !framebufferBinding->object())
1385 return GL_FRAMEBUFFER_COMPLETE; 1388 return GL_FRAMEBUFFER_COMPLETE;
1386 const char* reason = "framebuffer incomplete"; 1389 const char* reason = "framebuffer incomplete";
1387 GLenum result = m_framebufferBinding->checkStatus(&reason); 1390 GLenum result = framebufferBinding->checkStatus(&reason);
1388 if (result != GL_FRAMEBUFFER_COMPLETE) { 1391 if (result != GL_FRAMEBUFFER_COMPLETE) {
1389 emitGLWarning("checkFramebufferStatus", reason); 1392 emitGLWarning("checkFramebufferStatus", reason);
1390 return result; 1393 return result;
1391 } 1394 }
1392 result = webContext()->checkFramebufferStatus(target); 1395 result = webContext()->checkFramebufferStatus(target);
1393 return result; 1396 return result;
1394 } 1397 }
1395 1398
1396 void WebGLRenderingContextBase::clear(GLbitfield mask) 1399 void WebGLRenderingContextBase::clear(GLbitfield mask)
1397 { 1400 {
1398 if (isContextLost()) 1401 if (isContextLost())
1399 return; 1402 return;
1400 if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_B IT)) { 1403 if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_B IT)) {
1401 synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask"); 1404 synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
1402 return; 1405 return;
1403 } 1406 }
1404 const char* reason = "framebuffer incomplete"; 1407 const char* reason = "framebuffer incomplete";
1405 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 1408 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), GL _FRAMEBUFFER, &reason)) {
1406 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason); 1409 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
1407 return; 1410 return;
1408 } 1411 }
1409 if (clearIfComposited(mask) != CombinedClear) 1412 if (clearIfComposited(mask) != CombinedClear)
1410 webContext()->clear(mask); 1413 webContext()->clear(mask);
1411 markContextChanged(CanvasChanged); 1414 markContextChanged(CanvasChanged);
1412 } 1415 }
1413 1416
1414 void WebGLRenderingContextBase::clearColor(GLfloat r, GLfloat g, GLfloat b, GLfl oat a) 1417 void WebGLRenderingContextBase::clearColor(GLfloat r, GLfloat g, GLfloat b, GLfl oat a)
1415 { 1418 {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 } 1559 }
1557 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) { 1560 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) {
1558 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i s incompatible format"); 1561 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i s incompatible format");
1559 return; 1562 return;
1560 } 1563 }
1561 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { 1564 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
1562 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow er of 2"); 1565 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow er of 2");
1563 return; 1566 return;
1564 } 1567 }
1565 const char* reason = "framebuffer incomplete"; 1568 const char* reason = "framebuffer incomplete";
1566 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 1569 if ((m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), G L_FRAMEBUFFER, &reason))
1570 || (getFramebufferBinding(GL_READ_FRAMEBUFFER) && !getFramebufferBinding (GL_READ_FRAMEBUFFER)->onAccess(webContext(), GL_READ_FRAMEBUFFER, &reason))) {
1567 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", re ason); 1571 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", re ason);
1568 return; 1572 return;
1569 } 1573 }
1570 clearIfComposited(); 1574 clearIfComposited();
1571 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() ); 1575 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() , GL_FRAMEBUFFER);
1576 if (isWebGL2OrHigher())
1577 ScopedDrawingBufferBinder readBinder(drawingBuffer(), getFramebufferBind ing(GL_READ_FRAMEBUFFER), GL_READ_FRAMEBUFFER);
Zhenyao Mo 2015/06/09 20:29:50 This is incorrect. readBinder is only alive with
Zhenyao Mo 2015/06/10 05:01:46 See my second comments in ScopedDrawingBufferBinde
yunchao 2015/06/10 08:21:25 I got it. The think the latest code set the correc
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 if ((m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), G L_FRAMEBUFFER, &reason))
1616 || (getFramebufferBinding(GL_READ_FRAMEBUFFER) && !getFramebufferBinding (GL_READ_FRAMEBUFFER)->onAccess(webContext(), GL_READ_FRAMEBUFFER, &reason))) {
1610 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason); 1617 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
1611 return; 1618 return;
1612 } 1619 }
1613 clearIfComposited(); 1620 clearIfComposited();
1614 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() ); 1621 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.get() , GL_FRAMEBUFFER);
1622 if (isWebGL2OrHigher())
1623 ScopedDrawingBufferBinder readBinder(drawingBuffer(), getFramebufferBind ing(GL_READ_FRAMEBUFFER), GL_READ_FRAMEBUFFER);
Zhenyao Mo 2015/06/09 20:29:50 Same here.
Zhenyao Mo 2015/06/10 05:01:46 See my second comments in ScopedDrawingBufferBinde
yunchao 2015/06/10 08:21:25 I got it. The think the latest code set the correc
1615 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height); 1624 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height);
1616 } 1625 }
1617 1626
1618 PassRefPtrWillBeRawPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer() 1627 PassRefPtrWillBeRawPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
1619 { 1628 {
1620 if (isContextLost()) 1629 if (isContextLost())
1621 return nullptr; 1630 return nullptr;
1622 RefPtrWillBeRawPtr<WebGLBuffer> o = WebGLBuffer::create(this); 1631 RefPtrWillBeRawPtr<WebGLBuffer> o = WebGLBuffer::create(this);
1623 addSharedObject(o.get()); 1632 addSharedObject(o.get());
1624 return o.release(); 1633 return o.release();
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1724 return; 1733 return;
1725 removeBoundBuffer(buffer); 1734 removeBoundBuffer(buffer);
1726 } 1735 }
1727 1736
1728 void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer) 1737 void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
1729 { 1738 {
1730 if (!deleteObject(framebuffer)) 1739 if (!deleteObject(framebuffer))
1731 return; 1740 return;
1732 if (framebuffer == m_framebufferBinding) { 1741 if (framebuffer == m_framebufferBinding) {
1733 m_framebufferBinding = nullptr; 1742 m_framebufferBinding = nullptr;
1734 drawingBuffer()->setFramebufferBinding(0); 1743 drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0);
1735 // Have to call bindFramebuffer here to bind back to internal fbo. 1744 // Have to call drawingBuffer()->bind() here to bind back to internal fb o.
Zhenyao Mo 2015/06/09 20:29:50 By the way, I just noticed, you should get rid of
yunchao 2015/06/10 08:21:25 Done.
1736 drawingBuffer()->bind(); 1745 drawingBuffer()->bind();
1737 } 1746 }
1738 } 1747 }
1739 1748
1740 void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program) 1749 void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
1741 { 1750 {
1742 deleteObject(program); 1751 deleteObject(program);
1743 // We don't reset m_currentProgram to 0 here because the deletion of the 1752 // We don't reset m_currentProgram to 0 here because the deletion of the
1744 // current program is delayed. 1753 // current program is delayed.
1745 } 1754 }
1746 1755
1747 void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff er) 1756 void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff er)
1748 { 1757 {
1749 if (!deleteObject(renderbuffer)) 1758 if (!deleteObject(renderbuffer))
1750 return; 1759 return;
1751 if (renderbuffer == m_renderbufferBinding) 1760 if (renderbuffer == m_renderbufferBinding)
1752 m_renderbufferBinding = nullptr; 1761 m_renderbufferBinding = nullptr;
1753 if (m_framebufferBinding) 1762 if (m_framebufferBinding)
1754 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer) ; 1763 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFE R, renderbuffer);
1764 if (getFramebufferBinding(GL_READ_FRAMEBUFFER))
1765 getFramebufferBinding(GL_READ_FRAMEBUFFER)->removeAttachmentFromBoundFra mebuffer(GL_READ_FRAMEBUFFER, renderbuffer);
1755 } 1766 }
1756 1767
1757 void WebGLRenderingContextBase::deleteShader(WebGLShader* shader) 1768 void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
1758 { 1769 {
1759 deleteObject(shader); 1770 deleteObject(shader);
1760 } 1771 }
1761 1772
1762 void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture) 1773 void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
1763 { 1774 {
1764 if (!deleteObject(texture)) 1775 if (!deleteObject(texture))
(...skipping 16 matching lines...) Expand all
1781 m_textureUnits[i].m_texture3DBinding = nullptr; 1792 m_textureUnits[i].m_texture3DBinding = nullptr;
1782 maxBoundTextureIndex = i; 1793 maxBoundTextureIndex = i;
1783 } 1794 }
1784 if (texture == m_textureUnits[i].m_texture2DArrayBinding) { 1795 if (texture == m_textureUnits[i].m_texture2DArrayBinding) {
1785 m_textureUnits[i].m_texture2DArrayBinding = nullptr; 1796 m_textureUnits[i].m_texture2DArrayBinding = nullptr;
1786 maxBoundTextureIndex = i; 1797 maxBoundTextureIndex = i;
1787 } 1798 }
1788 } 1799 }
1789 } 1800 }
1790 if (m_framebufferBinding) 1801 if (m_framebufferBinding)
1791 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture); 1802 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFE R, texture);
1803 if (getFramebufferBinding(GL_READ_FRAMEBUFFER))
1804 getFramebufferBinding(GL_READ_FRAMEBUFFER)->removeAttachmentFromBoundFra mebuffer(GL_READ_FRAMEBUFFER, texture);
1792 1805
1793 // If the deleted was bound to the the current maximum index, trace backward s to find the new max texture index 1806 // 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)) { 1807 if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBound TextureIndex + 1)) {
1795 findNewMaxNonDefaultTextureUnit(); 1808 findNewMaxNonDefaultTextureUnit();
1796 } 1809 }
1797 } 1810 }
1798 1811
1799 void WebGLRenderingContextBase::depthFunc(GLenum func) 1812 void WebGLRenderingContextBase::depthFunc(GLenum func)
1800 { 1813 {
1801 if (isContextLost()) 1814 if (isContextLost())
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid t arget"); 2014 synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid t arget");
2002 return; 2015 return;
2003 } 2016 }
2004 if (buffer && !buffer->validate(contextGroup(), this)) { 2017 if (buffer && !buffer->validate(contextGroup(), this)) {
2005 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no b uffer or buffer not from this context"); 2018 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no b uffer or buffer not from this context");
2006 return; 2019 return;
2007 } 2020 }
2008 // Don't allow the default framebuffer to be mutated; all current 2021 // Don't allow the default framebuffer to be mutated; all current
2009 // implementations use an FBO internally in place of the default 2022 // implementations use an FBO internally in place of the default
2010 // FBO. 2023 // FBO.
2011 if (!m_framebufferBinding || !m_framebufferBinding->object()) { 2024 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
2025 if (!framebufferBinding || !framebufferBinding->object()) {
2012 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no f ramebuffer bound"); 2026 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no f ramebuffer bound");
2013 return; 2027 return;
2014 } 2028 }
2015 Platform3DObject bufferObject = objectOrZero(buffer); 2029 Platform3DObject bufferObject = objectOrZero(buffer);
2016 switch (attachment) { 2030 switch (attachment) {
2017 case GL_DEPTH_STENCIL_ATTACHMENT: 2031 case GL_DEPTH_STENCIL_ATTACHMENT:
2018 if (isDepthStencilSupported() || !buffer) { 2032 if (isDepthStencilSupported() || !buffer) {
2019 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject); 2033 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject);
2020 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject); 2034 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
2021 } else { 2035 } else {
2022 WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuff er(renderbuffertarget, buffer); 2036 WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuff er(renderbuffertarget, buffer);
2023 if (!emulatedStencilBuffer) { 2037 if (!emulatedStencilBuffer) {
2024 synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", " out of memory"); 2038 synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", " out of memory");
2025 return; 2039 return;
2026 } 2040 }
2027 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject); 2041 webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, r enderbuffertarget, bufferObject);
2028 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer)); 2042 webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
2029 } 2043 }
2030 break; 2044 break;
2031 default: 2045 default:
2032 webContext()->framebufferRenderbuffer(target, attachment, renderbufferta rget, bufferObject); 2046 webContext()->framebufferRenderbuffer(target, attachment, renderbufferta rget, bufferObject);
2033 } 2047 }
2034 m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer); 2048 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buf fer);
2035 applyStencilTest(); 2049 applyStencilTest();
2036 } 2050 }
2037 2051
2038 void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac hment, GLenum textarget, WebGLTexture* texture, GLint level) 2052 void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac hment, GLenum textarget, WebGLTexture* texture, GLint level)
2039 { 2053 {
2040 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur e2D", target, attachment)) 2054 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur e2D", target, attachment))
2041 return; 2055 return;
2042 if (level) { 2056 if (level) {
2043 synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0 "); 2057 synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0 ");
2044 return; 2058 return;
2045 } 2059 }
2046 if (texture && !texture->validate(contextGroup(), this)) { 2060 if (texture && !texture->validate(contextGroup(), this)) {
2047 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text ure or texture not from this context"); 2061 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text ure or texture not from this context");
2048 return; 2062 return;
2049 } 2063 }
2050 // Don't allow the default framebuffer to be mutated; all current 2064 // Don't allow the default framebuffer to be mutated; all current
2051 // implementations use an FBO internally in place of the default 2065 // implementations use an FBO internally in place of the default
2052 // FBO. 2066 // FBO.
2053 if (!m_framebufferBinding || !m_framebufferBinding->object()) { 2067 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
2068 if (!framebufferBinding || !framebufferBinding->object()) {
2054 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram ebuffer bound"); 2069 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram ebuffer bound");
2055 return; 2070 return;
2056 } 2071 }
2057 Platform3DObject textureObject = objectOrZero(texture); 2072 Platform3DObject textureObject = objectOrZero(texture);
2058 switch (attachment) { 2073 switch (attachment) {
2059 case GL_DEPTH_STENCIL_ATTACHMENT: 2074 case GL_DEPTH_STENCIL_ATTACHMENT:
2060 webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarge t, textureObject, level); 2075 webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarge t, textureObject, level);
2061 webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textar get, textureObject, level); 2076 webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textar get, textureObject, level);
2062 break; 2077 break;
2063 case GL_DEPTH_ATTACHMENT:
Zhenyao Mo 2015/06/09 20:29:50 Why removing these two?
2064 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level);
2065 break;
2066 case GL_STENCIL_ATTACHMENT:
2067 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level);
2068 break;
2069 default: 2078 default:
2070 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level); 2079 webContext()->framebufferTexture2D(target, attachment, textarget, textur eObject, level);
2071 } 2080 }
2072 m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget , texture, level); 2081 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, tex target, texture, level);
2073 applyStencilTest(); 2082 applyStencilTest();
2074 } 2083 }
2075 2084
2076 void WebGLRenderingContextBase::frontFace(GLenum mode) 2085 void WebGLRenderingContextBase::frontFace(GLenum mode)
2077 { 2086 {
2078 if (isContextLost()) 2087 if (isContextLost())
2079 return; 2088 return;
2080 switch (mode) { 2089 switch (mode) {
2081 case GL_CW: 2090 case GL_CW:
2082 case GL_CCW: 2091 case GL_CCW:
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3316 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type n ot RGBA/UNSIGNED_BYTE or implementation-defined values"); 3325 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type n ot RGBA/UNSIGNED_BYTE or implementation-defined values");
3317 return; 3326 return;
3318 } 3327 }
3319 } 3328 }
3320 // Validate array type against pixel type. 3329 // Validate array type against pixel type.
3321 if (pixels->type() != expectedViewType) { 3330 if (pixels->type() != expectedViewType) {
3322 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format"); 3331 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format");
3323 return; 3332 return;
3324 } 3333 }
3325 const char* reason = "framebuffer incomplete"; 3334 const char* reason = "framebuffer incomplete";
3326 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 3335 GLenum target = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER;
3336 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(target);
3337 if (readFramebufferBinding && !readFramebufferBinding->onAccess(webContext() , target, &reason)) {
3327 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason ); 3338 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason );
3328 return; 3339 return;
3329 } 3340 }
3330 // Calculate array size, taking into consideration of PACK_ALIGNMENT. 3341 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
3331 unsigned totalBytesRequired = 0; 3342 unsigned totalBytesRequired = 0;
3332 unsigned padding = 0; 3343 unsigned padding = 0;
3333 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding); 3344 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding);
3334 if (error != GL_NO_ERROR) { 3345 if (error != GL_NO_ERROR) {
3335 synthesizeGLError(error, "readPixels", "invalid dimensions"); 3346 synthesizeGLError(error, "readPixels", "invalid dimensions");
3336 return; 3347 return;
3337 } 3348 }
3338 if (pixels->byteLength() < totalBytesRequired) { 3349 if (pixels->byteLength() < totalBytesRequired) {
3339 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions"); 3350 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions");
3340 return; 3351 return;
3341 } 3352 }
3342 3353
3343 clearIfComposited(); 3354 clearIfComposited();
3344 void* data = pixels->baseAddress(); 3355 void* data = pixels->baseAddress();
3345 3356
3346 { 3357 {
3347 ScopedDrawingBufferBinder binder(drawingBuffer(), m_framebufferBinding.g et()); 3358 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding , target);
Zhenyao Mo 2015/06/09 20:29:51 Again, I don't understand why we need the binder h
Zhenyao Mo 2015/06/09 20:33:40 Never mind. Of course we need the binder for mult
yunchao 2015/06/10 08:21:25 I think there is no problem.
3348 webContext()->readPixels(x, y, width, height, format, type, data); 3359 webContext()->readPixels(x, y, width, height, format, type, data);
3349 } 3360 }
3350 3361
3351 #if OS(MACOSX) 3362 #if OS(MACOSX)
3352 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e., 3363 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
3353 // when alpha is off, readPixels should set alpha to 255 instead of 0. 3364 // when alpha is off, readPixels should set alpha to 255 instead of 0.
3354 if (!m_framebufferBinding && !drawingBuffer()->getActualAttributes().alpha) { 3365 if (!readFramebufferBinding && !drawingBuffer()->getActualAttributes().alpha ) {
3355 unsigned char* pixels = reinterpret_cast<unsigned char*>(data); 3366 unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
3356 for (GLsizei iy = 0; iy < height; ++iy) { 3367 for (GLsizei iy = 0; iy < height; ++iy) {
3357 for (GLsizei ix = 0; ix < width; ++ix) { 3368 for (GLsizei ix = 0; ix < width; ++ix) {
3358 pixels[3] = 255; 3369 pixels[3] = 255;
3359 pixels += 4; 3370 pixels += 4;
3360 } 3371 }
3361 pixels += padding; 3372 pixels += padding;
3362 } 3373 }
3363 } 3374 }
3364 #endif 3375 #endif
(...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after
4622 4633
4623 if (mode == RealLostContext) { 4634 if (mode == RealLostContext) {
4624 // Inform the embedder that a lost context was received. In response, th e embedder might 4635 // Inform the embedder that a lost context was received. In response, th e embedder might
4625 // decide to take action such as asking the user for permission to use W ebGL again. 4636 // decide to take action such as asking the user for permission to use W ebGL again.
4626 if (LocalFrame* frame = canvas()->document().frame()) 4637 if (LocalFrame* frame = canvas()->document().frame())
4627 frame->loader().client()->didLoseWebGLContext(webContext()->getGraph icsResetStatusARB()); 4638 frame->loader().client()->didLoseWebGLContext(webContext()->getGraph icsResetStatusARB());
4628 } 4639 }
4629 4640
4630 // Make absolutely sure we do not refer to an already-deleted texture or fra mebuffer. 4641 // Make absolutely sure we do not refer to an already-deleted texture or fra mebuffer.
4631 drawingBuffer()->setTexture2DBinding(0); 4642 drawingBuffer()->setTexture2DBinding(0);
4632 drawingBuffer()->setFramebufferBinding(0); 4643 drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0);
4633 4644
4634 detachAndRemoveAllObjects(); 4645 detachAndRemoveAllObjects();
4635 4646
4636 // Lose all the extensions. 4647 // Lose all the extensions.
4637 for (size_t i = 0; i < m_extensions.size(); ++i) { 4648 for (size_t i = 0; i < m_extensions.size(); ++i) {
4638 ExtensionTracker* tracker = m_extensions[i].get(); 4649 ExtensionTracker* tracker = m_extensions[i].get();
4639 tracker->loseExtension(); 4650 tracker->loseExtension();
4640 } 4651 }
4641 4652
4642 for (size_t i = 0; i < WebGLExtensionNameCount; ++i) 4653 for (size_t i = 0; i < WebGLExtensionNameCount; ++i)
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after
5725 if (!count) { 5736 if (!count) {
5726 markContextChanged(CanvasChanged); 5737 markContextChanged(CanvasChanged);
5727 return false; 5738 return false;
5728 } 5739 }
5729 5740
5730 if (!validateRenderingState(functionName)) { 5741 if (!validateRenderingState(functionName)) {
5731 return false; 5742 return false;
5732 } 5743 }
5733 5744
5734 const char* reason = "framebuffer incomplete"; 5745 const char* reason = "framebuffer incomplete";
5735 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 5746 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), GL _FRAMEBUFFER, &reason)) {
5736 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason ); 5747 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason );
5737 return false; 5748 return false;
5738 } 5749 }
5739 5750
5740 return true; 5751 return true;
5741 } 5752 }
5742 5753
5743 bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, G Lenum mode, GLsizei count, GLenum type, long long offset) 5754 bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, G Lenum mode, GLsizei count, GLenum type, long long offset)
5744 { 5755 {
5745 if (isContextLost() || !validateDrawMode(functionName, mode)) 5756 if (isContextLost() || !validateDrawMode(functionName, mode))
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5777 if (!m_boundVertexArrayObject->boundElementArrayBuffer()) { 5788 if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
5778 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_ BUFFER bound"); 5789 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_ BUFFER bound");
5779 return false; 5790 return false;
5780 } 5791 }
5781 5792
5782 if (!validateRenderingState(functionName)) { 5793 if (!validateRenderingState(functionName)) {
5783 return false; 5794 return false;
5784 } 5795 }
5785 5796
5786 const char* reason = "framebuffer incomplete"; 5797 const char* reason = "framebuffer incomplete";
5787 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &r eason)) { 5798 if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), GL _FRAMEBUFFER, &reason)) {
5788 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason ); 5799 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason );
5789 return false; 5800 return false;
5790 } 5801 }
5791 5802
5792 return true; 5803 return true;
5793 } 5804 }
5794 5805
5795 // Helper function to validate draw*Instanced calls 5806 // Helper function to validate draw*Instanced calls
5796 bool WebGLRenderingContextBase::validateDrawInstanced(const char* functionName, GLsizei primcount) 5807 bool WebGLRenderingContextBase::validateDrawInstanced(const char* functionName, GLsizei primcount)
5797 { 5808 {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
6106 6117
6107 void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer* buffer) 6118 void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer* buffer)
6108 { 6119 {
6109 if (buffer) 6120 if (buffer)
6110 buffer->setHasEverBeenBound(); 6121 buffer->setHasEverBeenBound();
6111 6122
6112 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) { 6123 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) {
6113 m_framebufferBinding = buffer; 6124 m_framebufferBinding = buffer;
6114 applyStencilTest(); 6125 applyStencilTest();
6115 } 6126 }
6116 drawingBuffer()->setFramebufferBinding(objectOrZero(m_framebufferBinding.get ())); 6127 drawingBuffer()->setFramebufferBinding(target, objectOrZero(getFramebufferBi nding(target)));
6117 6128
6118 if (!buffer) { 6129 if (!buffer) {
6119 // Instead of binding fb 0, bind the drawing buffer. 6130 // Instead of binding fb 0, bind the drawing buffer.
6120 drawingBuffer()->bind(target); 6131 drawingBuffer()->bind(target);
6121 } else { 6132 } else {
6122 webContext()->bindFramebuffer(target, buffer->object()); 6133 webContext()->bindFramebuffer(target, buffer->object());
6123 } 6134 }
6124 } 6135 }
6125 6136
6126 void WebGLRenderingContextBase::restoreCurrentFramebuffer() 6137 void WebGLRenderingContextBase::restoreCurrentFramebuffer()
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
6211 6222
6212 return totalBytesPerPixel; 6223 return totalBytesPerPixel;
6213 } 6224 }
6214 6225
6215 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const 6226 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const
6216 { 6227 {
6217 return m_drawingBuffer.get(); 6228 return m_drawingBuffer.get();
6218 } 6229 }
6219 6230
6220 } // namespace blink 6231 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698