Source/WebCore/ChangeLog

 12020-07-22 Kenneth Russell <kbr@chromium.org>
 2
 3 [WebGL2] Implement multiple render target entry points
 4 https://bugs.webkit.org/show_bug.cgi?id=211156
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Implement the drawBuffers and clearBuffer entry points.
 9
 10 Integrate the clearBuffer APIs with preserveDrawingBuffer:false's
 11 auto-clearing. Move some auto-clearing state from
 12 WebGLRenderingContextBase to GraphicsContextGL and
 13 GraphicsContextGLOpenGL.
 14
 15 Rename setPreserveDrawingBuffer to enablePreserveDrawingBuffer to
 16 make it clear that arbitrary changes of preserveDrawingBuffer are
 17 not supported. setPreserveDrawingBuffer was previously added for
 18 capture of preserveDrawingBuffer:false WebGL canvases.
 19
 20 Covered by existing WebGL conformance tests and canvas capture
 21 layout tests.
 22
 23 * Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
 24 (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasChanged):
 25 * html/canvas/WebGL2RenderingContext.cpp:
 26 (WebCore::WebGL2RenderingContext::drawBuffers):
 27 (WebCore::WebGL2RenderingContext::clearBufferiv):
 28 (WebCore::WebGL2RenderingContext::clearBufferuiv):
 29 (WebCore::WebGL2RenderingContext::clearBufferfv):
 30 (WebCore::WebGL2RenderingContext::clearBufferfi):
 31 (WebCore::WebGL2RenderingContext::validateClearBuffer):
 32 (WebCore::WebGL2RenderingContext::updateBuffersToAutoClear):
 33 * html/canvas/WebGL2RenderingContext.h:
 34 * html/canvas/WebGLFramebuffer.cpp:
 35 (WebCore::WebGLFramebuffer::drawBuffersIfNecessary):
 36 * html/canvas/WebGLRenderingContextBase.cpp:
 37 (WebCore::WebGLRenderingContextBase::clearIfComposited):
 38 (WebCore::WebGLRenderingContextBase::enablePreserveDrawingBuffer):
 39 * html/canvas/WebGLRenderingContextBase.h:
 40 (WebCore::WebGLRenderingContextBase::setPreserveDrawingBuffer): Deleted.
 41 * platform/graphics/GraphicsContextGL.cpp:
 42 (WebCore::GraphicsContextGL::enablePreserveDrawingBuffer):
 43 * platform/graphics/GraphicsContextGL.h:
 44 * platform/graphics/angle/GraphicsContextGLANGLE.cpp:
 45 (WebCore::GraphicsContextGLOpenGL::markLayerComposited):
 46 (WebCore::GraphicsContextGLOpenGL::drawBuffers):
 47 (WebCore::GraphicsContextGLOpenGL::clearBufferiv):
 48 (WebCore::GraphicsContextGLOpenGL::clearBufferuiv):
 49 (WebCore::GraphicsContextGLOpenGL::clearBufferfv):
 50 (WebCore::GraphicsContextGLOpenGL::clearBufferfi):
 51 * platform/graphics/opengl/GraphicsContextGLOpenGL.cpp:
 52 (WebCore::GraphicsContextGLOpenGL::resetBuffersToAutoClear):
 53 (WebCore::GraphicsContextGLOpenGL::setBuffersToAutoClear):
 54 (WebCore::GraphicsContextGLOpenGL::getBuffersToAutoClear const):
 55 (WebCore::GraphicsContextGLOpenGL::enablePreserveDrawingBuffer):
 56 * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
 57 * platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp:
 58 (WebCore::GraphicsContextGLOpenGL::markLayerComposited):
 59 (WebCore::GraphicsContextGLOpenGL::drawBuffers):
 60
1612020-07-22 Myles C. Maxfield <mmaxfield@apple.com>
262
363 REGRESSION(r205826): narrowNoBreakSpace (U+202F) has zero width, regardless of font

Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp

@@void CanvasCaptureMediaStreamTrack::Source::canvasChanged(CanvasBase& canvas, co
161161 auto& context = downcast<WebGLRenderingContextBase>(*canvas.renderingContext());
162162 if (!context.isPreservingDrawingBuffer()) {
163163 canvas.scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Turning drawing buffer preservation for the WebGL canvas being captured"_s);
164  context.setPreserveDrawingBuffer(true);
 164 context.enablePreserveDrawingBuffer();
165165 }
166166 }
167167#endif

Source/WebCore/html/canvas/WebGL2RenderingContext.cpp

@@void WebGL2RenderingContext::drawBuffers(const Vector<GCGLenum>& buffers)
17591759 }
17601760 // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
17611761 GCGLenum value = (bufs[0] == GraphicsContextGL::BACK) ? GraphicsContextGL::COLOR_ATTACHMENT0 : GraphicsContextGL::NONE;
1762  graphicsContextGL()->getExtensions().drawBuffersEXT(1, &value);
 1762 m_context->drawBuffers(1, &value);
17631763 setBackDrawBuffer(bufs[0]);
17641764 } else {
17651765 if (n > getMaxDrawBuffers()) {

@@void WebGL2RenderingContext::drawBuffers(const Vector<GCGLenum>& buffers)
17761776 }
17771777}
17781778
1779 void WebGL2RenderingContext::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, Int32List&&, GCGLuint)
 1779void WebGL2RenderingContext::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, Int32List&& values, GCGLuint srcOffset)
17801780{
1781  switch (buffer) {
1782  case GraphicsContextGL::COLOR:
1783  if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
1784  synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferiv", "buffer index out of range");
1785  return;
1786  }
1787  // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
1788  break;
1789  case GraphicsContextGL::STENCIL:
1790  if (drawbuffer) {
1791  synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferiv", "buffer index must be 0");
1792  return;
1793  }
1794  // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
1795  break;
1796  case GraphicsContextGL::DEPTH:
1797  case GraphicsContextGL::DEPTH_STENCIL:
1798  default:
1799  synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferiv", "buffer argument must be COLOR or STENCIL");
1800  break;
1801  }
 1781 if (isContextLostOrPending() || !validateClearBuffer("clearBufferiv", buffer, values.length(), srcOffset))
 1782 return;
 1783
 1784 m_context->clearBufferiv(buffer, drawbuffer, values.data(), srcOffset);
 1785 updateBuffersToAutoClear(ClearBufferCaller::ClearBufferiv, buffer, drawbuffer);
18021786}
18031787
1804 void WebGL2RenderingContext::clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, Uint32List&&, GCGLuint)
 1788void WebGL2RenderingContext::clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, Uint32List&& values, GCGLuint srcOffset)
18051789{
1806  switch (buffer) {
1807  case GraphicsContextGL::COLOR:
1808  if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
1809  synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferuiv", "buffer index out of range");
1810  return;
1811  }
1812  // TODO: Call clearBufferuiv, requires gl3.h and ES3/gl.h
1813  break;
1814  case GraphicsContextGL::DEPTH:
1815  case GraphicsContextGL::STENCIL:
1816  case GraphicsContextGL::DEPTH_STENCIL:
1817  default:
1818  synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferuiv", "buffer argument must be COLOR");
1819  break;
1820  }
 1790 if (isContextLostOrPending() || !validateClearBuffer("clearBufferuiv", buffer, values.length(), srcOffset))
 1791 return;
 1792
 1793 m_context->clearBufferuiv(buffer, drawbuffer, values.data(), srcOffset);
 1794 updateBuffersToAutoClear(ClearBufferCaller::ClearBufferuiv, buffer, drawbuffer);
18211795}
18221796
1823 void WebGL2RenderingContext::clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, Float32List&&, GCGLuint)
 1797void WebGL2RenderingContext::clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, Float32List&& values, GCGLuint srcOffset)
18241798{
1825  switch (buffer) {
1826  case GraphicsContextGL::COLOR:
1827  if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
1828  synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferfv", "buffer index out of range");
1829  return;
1830  }
1831  // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
1832  break;
1833  case GraphicsContextGL::DEPTH:
1834  if (drawbuffer) {
1835  synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
1836  return;
1837  }
1838  // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
1839  break;
1840  case GraphicsContextGL::STENCIL:
1841  case GraphicsContextGL::DEPTH_STENCIL:
1842  default:
1843  synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferfv", "buffer argument must be COLOR OR DEPTH");
1844  break;
1845  }
 1799 if (isContextLostOrPending() || !validateClearBuffer("clearBufferfv", buffer, values.length(), srcOffset))
 1800 return;
 1801
 1802 m_context->clearBufferfv(buffer, drawbuffer, values.data(), srcOffset);
 1803 // clearBufferiv and clearBufferuiv will currently generate an error
 1804 // if they're called against the default back buffer. If support for
 1805 // extended canvas color spaces is added, this call might need to be
 1806 // added to the other versions.
 1807 markContextChanged();
 1808 updateBuffersToAutoClear(ClearBufferCaller::ClearBufferfv, buffer, drawbuffer);
18461809}
18471810
1848 void WebGL2RenderingContext::clearBufferfi(GCGLenum buffer, GCGLint drawbuffer, GCGLfloat, GCGLint)
 1811void WebGL2RenderingContext::clearBufferfi(GCGLenum buffer, GCGLint drawbuffer, GCGLfloat depth, GCGLint stencil)
18491812{
1850  switch (buffer) {
1851  case GraphicsContextGL::DEPTH_STENCIL:
1852  if (drawbuffer) {
1853  synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
1854  return;
1855  }
1856  // TODO: Call clearBufferfi, requires gl3.h and ES3/gl.h
1857  break;
1858  case GraphicsContextGL::COLOR:
1859  case GraphicsContextGL::DEPTH:
1860  case GraphicsContextGL::STENCIL:
1861  default:
1862  synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferfv", "buffer argument must be DEPTH_STENCIL");
1863  break;
1864  }
 1813 if (isContextLostOrPending())
 1814 return;
 1815
 1816 m_context->clearBufferfi(buffer, drawbuffer, depth, stencil);
 1817 // This might have been used to clear the depth and stencil buffers
 1818 // of the default back buffer.
 1819 markContextChanged();
 1820 updateBuffersToAutoClear(ClearBufferCaller::ClearBufferfi, buffer, drawbuffer);
18651821}
18661822
18671823RefPtr<WebGLQuery> WebGL2RenderingContext::createQuery()

@@bool WebGL2RenderingContext::validateCapability(const char* functionName, GCGLen
33073263 }
33083264}
33093265
 3266bool WebGL2RenderingContext::validateClearBuffer(const char* functionName, GCGLenum buffer, size_t size, GCGLuint srcOffset)
 3267{
 3268 Checked<GLsizei, RecordOverflow> checkedSize(size);
 3269 checkedSize -= srcOffset;
 3270 if (checkedSize.hasOverflowed()) {
 3271 synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "invalid array size / srcOffset");
 3272 return false;
 3273 }
 3274 switch (buffer) {
 3275 case GraphicsContextGL::COLOR:
 3276 if (checkedSize.unsafeGet() < 4) {
 3277 synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "invalid array size / srcOffset");
 3278 return false;
 3279 }
 3280 break;
 3281 case GraphicsContextGL::DEPTH:
 3282 case GraphicsContextGL::STENCIL:
 3283 if (checkedSize.unsafeGet() < 1) {
 3284 synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "invalid array size / srcOffset");
 3285 return false;
 3286 }
 3287 break;
 3288 default:
 3289 synthesizeGLError(GraphicsContextGL::INVALID_ENUM, functionName, "invalid buffer");
 3290 return false;
 3291 }
 3292 return true;
 3293}
 3294
33103295void WebGL2RenderingContext::uniform1fv(WebGLUniformLocation* location, Float32List data, GLuint srcOffset, GLuint srcLength)
33113296{
33123297 if (isContextLostOrPending() || !validateUniformParameters("uniform1fv", location, data, 1, srcOffset, srcLength))

@@void WebGL2RenderingContext::uncacheDeletedBuffer(WebGLBuffer* buffer)
34643449
34653450#undef REMOVE_BUFFER_FROM_BINDING
34663451
 3452void WebGL2RenderingContext::updateBuffersToAutoClear(ClearBufferCaller caller, GCGLenum buffer, GCGLint drawbuffer)
 3453{
 3454 // This method makes sure that we don't auto-clear any buffers which the
 3455 // user has manually cleared using the new ES 3.0 clearBuffer* APIs.
 3456
 3457 // If the user has a framebuffer bound, don't update the auto-clear
 3458 // state of the built-in back buffer.
 3459 if (m_framebufferBinding)
 3460 return;
 3461
 3462 // If the scissor test is on, assume that we can't short-circuit
 3463 // these clears.
 3464 if (m_scissorEnabled)
 3465 return;
 3466
 3467 // The default back buffer only has one color attachment.
 3468 if (drawbuffer)
 3469 return;
 3470
 3471 // If the call to the driver generated an error, don't claim that
 3472 // we've auto-cleared these buffers. The early returns below are for
 3473 // cases where errors will be produced.
 3474
 3475 // The default back buffer is currently always RGB(A)8, which
 3476 // restricts the variants which can legally be used to clear the
 3477 // color buffer. TODO(crbug.com/829632): this needs to be
 3478 // generalized.
 3479 switch (caller) {
 3480 case ClearBufferCaller::ClearBufferiv:
 3481 if (buffer != GraphicsContextGL::STENCIL)
 3482 return;
 3483 break;
 3484 case ClearBufferCaller::ClearBufferfv:
 3485 if (buffer != GraphicsContextGL::COLOR && buffer != GraphicsContextGL::DEPTH)
 3486 return;
 3487 break;
 3488 case ClearBufferCaller::ClearBufferuiv:
 3489 return;
 3490 case ClearBufferCaller::ClearBufferfi:
 3491 if (buffer != GraphicsContextGL::DEPTH_STENCIL)
 3492 return;
 3493 break;
 3494 }
 3495
 3496 GCGLbitfield buffersToClear = 0;
 3497
 3498 // Turn it into a bitfield and mask it off.
 3499 switch (buffer) {
 3500 case GraphicsContextGL::COLOR:
 3501 buffersToClear = GraphicsContextGL::COLOR_BUFFER_BIT;
 3502 break;
 3503 case GraphicsContextGL::DEPTH:
 3504 buffersToClear = GraphicsContextGL::DEPTH_BUFFER_BIT;
 3505 break;
 3506 case GraphicsContextGL::STENCIL:
 3507 buffersToClear = GraphicsContextGL::STENCIL_BUFFER_BIT;
 3508 break;
 3509 case GraphicsContextGL::DEPTH_STENCIL:
 3510 buffersToClear = GraphicsContextGL::DEPTH_BUFFER_BIT | GraphicsContextGL::STENCIL_BUFFER_BIT;
 3511 break;
 3512 default:
 3513 // Illegal value.
 3514 return;
 3515 }
 3516
 3517 m_context->setBuffersToAutoClear(m_context->getBuffersToAutoClear() & (~buffersToClear));
 3518}
 3519
34673520} // namespace WebCore
34683521
34693522#endif // ENABLE(WEBGL)

Source/WebCore/html/canvas/WebGL2RenderingContext.h

@@private:
291291 bool validateIndexArrayConservative(GCGLenum type, unsigned& numElementsRequired) final;
292292 bool validateBlendEquation(const char* functionName, GCGLenum mode) final;
293293 bool validateCapability(const char* functionName, GCGLenum cap) final;
 294 bool validateClearBuffer(const char* functionName, GCGLenum buffer, size_t, GCGLuint srcOffset);
294295 bool validateFramebufferTarget(GCGLenum target) final;
295296 WebGLFramebuffer* getFramebufferBinding(GCGLenum target) final;
296297 WebGLFramebuffer* getReadFramebufferBinding() final;

@@private:
317318
318319 void uncacheDeletedBuffer(WebGLBuffer*) final;
319320
 321 enum class ClearBufferCaller : uint8_t {
 322 ClearBufferiv,
 323 ClearBufferuiv,
 324 ClearBufferfv,
 325 ClearBufferfi
 326 };
 327 void updateBuffersToAutoClear(ClearBufferCaller, GCGLenum buffer, GCGLint drawbuffer);
 328
320329 RefPtr<WebGLFramebuffer> m_readFramebufferBinding;
321330 RefPtr<WebGLTransformFeedback> m_boundTransformFeedback;
322331 RefPtr<WebGLTransformFeedback> m_defaultTransformFeedback;

Source/WebCore/html/canvas/WebGLFramebuffer.cpp

@@void WebGLFramebuffer::drawBuffers(const Vector<GCGLenum>& bufs)
621621
622622void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
623623{
624 #if ENABLE(WEBGL2)
625  // FIXME: The logic here seems wrong. If we don't have WebGL 2 enabled at all, then
626  // we skip the m_webglDrawBuffers check. But if we do have WebGL 2 enabled, then we
627  // perform this check, for WebGL 1 contexts only.
628  if (!context()->m_webglDrawBuffers && !context()->isWebGL2())
629  return;
630 #endif
631  bool reset = force;
632  // This filtering works around graphics driver bugs on Mac OS X.
633  for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
634  if (m_drawBuffers[i] != GraphicsContextGL::NONE && getAttachment(m_drawBuffers[i])) {
635  if (m_filteredDrawBuffers[i] != m_drawBuffers[i]) {
636  m_filteredDrawBuffers[i] = m_drawBuffers[i];
637  reset = true;
 624 if (context()->isWebGL2() || context()->m_webglDrawBuffers) {
 625 bool reset = force;
 626 // This filtering works around graphics driver bugs on macOS.
 627 for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
 628 if (m_drawBuffers[i] != GraphicsContextGL::NONE && getAttachment(m_drawBuffers[i])) {
 629 if (m_filteredDrawBuffers[i] != m_drawBuffers[i]) {
 630 m_filteredDrawBuffers[i] = m_drawBuffers[i];
 631 reset = true;
 632 }
 633 } else {
 634 if (m_filteredDrawBuffers[i] != GraphicsContextGL::NONE) {
 635 m_filteredDrawBuffers[i] = GraphicsContextGL::NONE;
 636 reset = true;
 637 }
638638 }
639  } else {
640  if (m_filteredDrawBuffers[i] != GraphicsContextGL::NONE) {
641  m_filteredDrawBuffers[i] = GraphicsContextGL::NONE;
642  reset = true;
 639 }
 640 if (reset) {
 641 if (context()->isWebGL2()) {
 642 context()->graphicsContextGL()->drawBuffers(
 643 m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
 644 } else {
 645 context()->graphicsContextGL()->getExtensions().drawBuffersEXT(
 646 m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
643647 }
644648 }
645649 }
646  if (reset) {
647  context()->graphicsContextGL()->getExtensions().drawBuffersEXT(
648  m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
649  }
650650}
651651
652652GCGLenum WebGLFramebuffer::getDrawBuffer(GCGLenum drawBuffer)

Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

@@bool WebGLRenderingContextBase::clearIfComposited(GCGLbitfield mask)
11001100 if (isContextLostOrPending())
11011101 return false;
11021102
1103  if (!m_context->layerComposited() || m_layerCleared
1104  || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding)
1105  || m_preventBufferClearForInspector)
 1103 if (!m_context->layerComposited() || m_layerCleared || m_preventBufferClearForInspector)
11061104 return false;
11071105
1108  auto contextAttributes = getContextAttributes();
1109  ASSERT(contextAttributes);
 1106 GCGLbitfield buffersNeedingClearing = m_context->getBuffersToAutoClear();
 1107
 1108 if (!buffersNeedingClearing || (mask && m_framebufferBinding))
 1109 return false;
 1110
 1111 // Use the underlying GraphicsContext3D's attributes to take into
 1112 // account (for example) packed depth/stencil buffers.
 1113 auto contextAttributes = m_context->contextAttributes();
11101114
11111115 // Determine if it's possible to combine the clear the user asked for and this clear.
11121116 bool combinedClear = mask && !m_scissorEnabled;

@@bool WebGLRenderingContextBase::clearIfComposited(GCGLbitfield mask)
11211125 m_context->clearColor(0, 0, 0, 0);
11221126 m_context->colorMask(true, true, true, true);
11231127 GCGLbitfield clearMask = GraphicsContextGL::COLOR_BUFFER_BIT;
1124  if (contextAttributes->depth) {
 1128 if (contextAttributes.depth) {
11251129 if (!combinedClear || !m_depthMask || !(mask & GraphicsContextGL::DEPTH_BUFFER_BIT))
11261130 m_context->clearDepth(1.0f);
11271131 clearMask |= GraphicsContextGL::DEPTH_BUFFER_BIT;
11281132 m_context->depthMask(true);
11291133 }
1130  if (contextAttributes->stencil) {
 1134 if (contextAttributes.stencil) {
11311135 if (combinedClear && (mask & GraphicsContextGL::STENCIL_BUFFER_BIT))
11321136 m_context->clearStencil(m_clearStencil & m_stencilMask);
11331137 else

@@bool WebGLRenderingContextBase::clearIfComposited(GCGLbitfield mask)
11351139 clearMask |= GraphicsContextGL::STENCIL_BUFFER_BIT;
11361140 m_context->stencilMaskSeparate(GraphicsContextGL::FRONT, 0xFFFFFFFF);
11371141 }
1138 
 1142
11391143 GCGLenum bindingPoint = isWebGL2() ? GraphicsContextGL::DRAW_FRAMEBUFFER : GraphicsContextGL::FRAMEBUFFER;
11401144 if (m_framebufferBinding)
11411145 m_context->bindFramebuffer(bindingPoint, 0);
1142  m_context->clear(clearMask);
 1146 // If the WebGL 2.0 clearBuffer APIs already have been used to
 1147 // selectively clear some of the buffers, don't destroy those
 1148 // results.
 1149 m_context->clear(clearMask & buffersNeedingClearing);
 1150 m_context->setBuffersToAutoClear(0);
11431151
11441152 restoreStateAfterClear();
11451153 if (m_framebufferBinding)

@@bool WebGLRenderingContextBase::extensionIsEnabled(const String& name)
36883696 return false;
36893697}
36903698
 3699void WebGLRenderingContextBase::enablePreserveDrawingBuffer()
 3700{
 3701 ASSERT(!m_attributes.preserveDrawingBuffer);
 3702 m_attributes.preserveDrawingBuffer = true;
 3703 // Must send this notification down to the GraphicsContextGL as well.
 3704 m_context->enablePreserveDrawingBuffer();
 3705}
 3706
36913707GCGLboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
36923708{
36933709 if (!buffer || isContextLostOrPending())

Source/WebCore/html/canvas/WebGLRenderingContextBase.h

@@public:
215215 bool extensionIsEnabled(const String&);
216216
217217 bool isPreservingDrawingBuffer() const { return m_attributes.preserveDrawingBuffer; }
218  void setPreserveDrawingBuffer(bool value) { m_attributes.preserveDrawingBuffer = value; }
 218 // Concession to canvas capture API, which must dynamically enable
 219 // preserveDrawingBuffer. This can only be called once, when
 220 // isPreservingDrawingBuffer() returns false.
 221 void enablePreserveDrawingBuffer();
219222
220223 bool preventBufferClearForInspector() const { return m_preventBufferClearForInspector; }
221224 void setPreventBufferClearForInspector(bool value) { m_preventBufferClearForInspector = value; }

Source/WebCore/platform/graphics/GraphicsContextGL.cpp

@@GraphicsContextGL::GraphicsContextGL(GraphicsContextGLAttributes attrs, Destinat
4040{
4141}
4242
 43void GraphicsContextGL::enablePreserveDrawingBuffer()
 44{
 45 // Canvas capture should not call this unless necessary.
 46 ASSERT(!m_attrs.preserveDrawingBuffer);
 47 m_attrs.preserveDrawingBuffer = true;
 48}
 49
4350unsigned GraphicsContextGL::getClearBitsByAttachmentType(GCGLenum attachment)
4451{
4552 switch (attachment) {

Source/WebCore/platform/graphics/GraphicsContextGL.h

@@public:
11161116
11171117 GraphicsContextGLAttributes contextAttributes() const { return m_attrs; }
11181118 void setContextAttributes(const GraphicsContextGLAttributes& attrs) { m_attrs = attrs; }
 1119 // Concession to Canvas captureStream, which needs to dynamically set
 1120 // preserveDrawingBuffer to true in order to avoid implicit clears.
 1121 // Implementations generally do not support toggling this bit arbitrarily.
 1122 virtual void enablePreserveDrawingBuffer();
11191123
11201124 // VertexArrayOject calls
11211125 virtual PlatformGLObject createVertexArray() = 0;

@@public:
11861190
11871191 virtual void drawRangeElements(GCGLenum mode, GCGLuint start, GCGLuint end, GCGLsizei count, GCGLenum type, GCGLintptr offset) = 0;
11881192
1189  virtual void drawBuffers(const Vector<GCGLenum>& buffers) = 0;
 1193 virtual void drawBuffers(GCGLsizei n, const GCGLenum* bufs) = 0;
11901194 virtual void clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset) = 0;
11911195 virtual void clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLuint* values, GCGLuint srcOffset) = 0;
11921196 virtual void clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, const GCGLfloat* values, GCGLuint srcOffset) = 0;

Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp

@@void GraphicsContextGLOpenGL::markContextChanged()
18991899void GraphicsContextGLOpenGL::markLayerComposited()
19001900{
19011901 m_layerComposited = true;
 1902 resetBuffersToAutoClear();
19021903
19031904 for (auto* client : copyToVector(m_clients))
19041905 client->didComposite();

@@void GraphicsContextGLOpenGL::drawRangeElements(GCGLenum mode, GCGLuint start, G
23072308 gl::DrawRangeElements(mode, start, end, count, type, reinterpret_cast<void*>(offset));
23082309}
23092310
2310 void GraphicsContextGLOpenGL::drawBuffers(const Vector<GCGLenum>& buffers)
 2311void GraphicsContextGLOpenGL::drawBuffers(GCGLsizei n, const GCGLenum* bufs)
23112312{
2312  UNUSED_PARAM(buffers);
 2313 gl::DrawBuffers(n, bufs);
23132314}
23142315
23152316void GraphicsContextGLOpenGL::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset)
23162317{
2317  UNUSED_PARAM(buffer);
2318  UNUSED_PARAM(drawbuffer);
2319  UNUSED_PARAM(values);
2320  UNUSED_PARAM(srcOffset);
 2318 gl::ClearBufferiv(buffer, drawbuffer, values + srcOffset);
23212319}
23222320
23232321void GraphicsContextGLOpenGL::clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLuint* values, GCGLuint srcOffset)
23242322{
2325  UNUSED_PARAM(buffer);
2326  UNUSED_PARAM(drawbuffer);
2327  UNUSED_PARAM(values);
2328  UNUSED_PARAM(srcOffset);
 2323 gl::ClearBufferuiv(buffer, drawbuffer, values + srcOffset);
23292324}
23302325
23312326void GraphicsContextGLOpenGL::clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, const GCGLfloat* values, GCGLuint srcOffset)
23322327{
2333  UNUSED_PARAM(buffer);
2334  UNUSED_PARAM(drawbuffer);
2335  UNUSED_PARAM(values);
2336  UNUSED_PARAM(srcOffset);
 2328 gl::ClearBufferfv(buffer, drawbuffer, values + srcOffset);
23372329}
23382330
23392331void GraphicsContextGLOpenGL::clearBufferfi(GCGLenum buffer, GCGLint drawbuffer, GCGLfloat depth, GCGLint stencil)
23402332{
2341  UNUSED_PARAM(buffer);
2342  UNUSED_PARAM(drawbuffer);
2343  UNUSED_PARAM(depth);
2344  UNUSED_PARAM(stencil);
 2333 gl::ClearBufferfi(buffer, drawbuffer, depth, stencil);
23452334}
23462335
23472336void GraphicsContextGLOpenGL::deleteQuery(PlatformGLObject query)

Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp

@@GraphicsContextGL::DataFormat getDataFormat(GCGLenum destinationFormat, GCGLenum
271271
272272} // anonymous namespace
273273
 274void GraphicsContextGLOpenGL::resetBuffersToAutoClear()
 275{
 276 GCGLuint buffers = GraphicsContextGL::COLOR_BUFFER_BIT;
 277 // The GraphicsContextGL's attributes (as opposed to
 278 // WebGLRenderingContext's) indicate whether there is an
 279 // implicitly-allocated stencil buffer, for example.
 280 auto attrs = contextAttributes();
 281 if (attrs.depth)
 282 buffers |= GraphicsContextGL::DEPTH_BUFFER_BIT;
 283 if (attrs.stencil)
 284 buffers |= GraphicsContextGL::STENCIL_BUFFER_BIT;
 285 setBuffersToAutoClear(buffers);
 286}
 287
 288void GraphicsContextGLOpenGL::setBuffersToAutoClear(GCGLbitfield buffers)
 289{
 290 auto attrs = contextAttributes();
 291 if (!attrs.preserveDrawingBuffer)
 292 m_buffersToAutoClear = buffers;
 293 else
 294 ASSERT(!m_buffersToAutoClear);
 295}
 296
 297GCGLbitfield GraphicsContextGLOpenGL::getBuffersToAutoClear() const
 298{
 299 return m_buffersToAutoClear;
 300}
 301
 302void GraphicsContextGLOpenGL::enablePreserveDrawingBuffer()
 303{
 304 GraphicsContextGL::enablePreserveDrawingBuffer();
 305 // After dynamically transitioning to preserveDrawingBuffer:true
 306 // for canvas capture, clear out any buffer auto-clearing state.
 307 m_buffersToAutoClear = 0;
 308}
 309
274310bool GraphicsContextGLOpenGL::texImage2DResourceSafe(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLint unpackAlignment)
275311{
276312 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);

Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h

@@public:
433433
434434 void drawRangeElements(GCGLenum mode, GCGLuint start, GCGLuint end, GCGLsizei count, GCGLenum type, GCGLintptr offset) final;
435435
436  void drawBuffers(const Vector<GCGLenum>& buffers) final;
 436 void drawBuffers(GCGLsizei n, const GCGLenum* bufs) final;
437437 void clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset) final;
438438 void clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLuint* values, GCGLuint srcOffset) final;
439439 void clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, const GCGLfloat* values, GCGLuint srcOffset) final;

@@public:
523523 void forceContextLost();
524524 void recycleContext();
525525
 526 // Maintenance of auto-clearing of color/depth/stencil buffers. The
 527 // reset method is present to keep calling code simpler, so it
 528 // doesn't have to know which buffers were allocated.
 529 void resetBuffersToAutoClear();
 530 void setBuffersToAutoClear(GCGLbitfield);
 531 GCGLbitfield getBuffersToAutoClear() const;
 532 void enablePreserveDrawingBuffer() override;
 533
526534 void dispatchContextChangedNotification();
527535 void simulateContextChanged();
528536

@@private:
864872 GCGLuint m_preserveDrawingBufferFBO { 0 };
865873#endif
866874
 875 // A bitmask of GL buffer bits (GL_COLOR_BUFFER_BIT,
 876 // GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT) which need to be
 877 // auto-cleared.
 878 GCGLbitfield m_buffersToAutoClear { 0 };
 879
867880 // Errors raised by synthesizeGLError().
868881 ListHashSet<GCGLenum> m_syntheticErrors;
869882

Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp

@@void GraphicsContextGLOpenGL::markContextChanged()
20192019void GraphicsContextGLOpenGL::markLayerComposited()
20202020{
20212021 m_layerComposited = true;
 2022 resetBuffersToAutoClear();
20222023
20232024 for (auto* client : copyToVector(m_clients))
20242025 client->didComposite();

@@void GraphicsContextGLOpenGL::drawRangeElements(GCGLenum mode, GCGLuint start, G
24242425 UNUSED_PARAM(offset);
24252426}
24262427
2427 void GraphicsContextGLOpenGL::drawBuffers(const Vector<GCGLenum>& buffers)
 2428void GraphicsContextGLOpenGL::drawBuffers(GCGLsizei n, const GCGLenum* bufs)
24282429{
2429  UNUSED_PARAM(buffers);
 2430 UNUSED_PARAM(n);
 2431 UNUSED_PARAM(bufs);
24302432}
24312433
24322434void GraphicsContextGLOpenGL::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset)

LayoutTests/ChangeLog

 12020-07-22 Kenneth Russell <kbr@chromium.org>
 2
 3 [WebGL2] Implement multiple render target entry points
 4 https://bugs.webkit.org/show_bug.cgi?id=211156
 5
 6 Reviewed by Dean Jackson.
 7
 8 Rebaseline one layout test which is now fully passing, and another
 9 which now properly detects errors.
 10
 11 * fast/canvas/webgl/webgl2/sequences-expected.txt:
 12 * webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt:
 13
1142020-07-22 Simon Fraser <simon.fraser@apple.com>
215
316 compositing/repaint/iframes/compositing-iframe-scroll-repaint.html fails on Mojave

LayoutTests/fast/canvas/webgl/webgl2/sequences-expected.txt

@@CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4iv: array too small
22CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4iv: array too small
33CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4uiv: array too small
44CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4uiv: array too small
 5CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferiv: invalid array size / srcOffset
 6CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferiv: invalid array size / srcOffset
 7CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferuiv: invalid array size / srcOffset
 8CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferuiv: invalid array size / srcOffset
 9CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferfv: invalid array size / srcOffset
 10CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferfv: invalid array size / srcOffset
511
612PASS uniform1uiv data with typed array of type ui
713PASS uniform1uiv data with sequence of type ui

LayoutTests/webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt

11This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
22
33Test: ../../resources/webgl_test_files/conformance2/reading/read-pixels-from-fbo-test.html
4 [ 1: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
5 [ 2: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
6 [ 3: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
7 [ 4: PASS ] Color read back as expected
8 [ 5: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
9 [ 6: PASS ] Color read back as expected
10 [ 7: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
11 [ 8: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
12 [ 9: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
13 [ 10: FAIL ] Expected color = 250,0,0,0, was = 0,0,0,1
14 [ 11: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
15 [ 12: FAIL ] Expected color = 250,0,0,0, was = 0
16 [ 13: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
17 [ 14: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
18 [ 15: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
19 [ 16: FAIL ] Expected color = -126,0,0,0, was = 0,0,0,1
20 [ 17: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
21 [ 18: FAIL ] Expected color = -126,0,0,0, was = 0
22 [ 19: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
23 [ 20: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
24 [ 21: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
25 [ 22: FAIL ] Expected color = 30001,0,0,0, was = 0,0,0,1
26 [ 23: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
27 [ 24: FAIL ] Expected color = 30001,0,0,0, was = 0
28 [ 25: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
29 [ 26: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
30 [ 27: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
31 [ 28: FAIL ] Expected color = -14189,0,0,0, was = 0,0,0,1
32 [ 29: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
33 [ 30: FAIL ] Expected color = -14189,0,0,0, was = 0
34 [ 31: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
35 [ 32: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
36 [ 33: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
37 [ 34: FAIL ] Expected color = 126726,0,0,0, was = 0,0,0,1
38 [ 35: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
39 [ 36: FAIL ] Expected color = 126726,0,0,0, was = 0
40 [ 37: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
41 [ 38: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
42 [ 39: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
43 [ 40: FAIL ] Expected color = -126726,0,0,0, was = 0,0,0,1
44 [ 41: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
45 [ 42: FAIL ] Expected color = -126726,0,0,0, was = 0
46 [ 43: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
47 [ 44: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
48 [ 45: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
49 [ 46: PASS ] Color read back as expected
50 [ 47: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
51 [ 48: PASS ] Color read back as expected
52 [ 49: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
53 [ 50: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
54 [ 51: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
55 [ 52: PASS ] Color read back as expected
56 [ 53: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
57 [ 54: PASS ] Color read back as expected
58 [ 55: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
59 [ 56: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
60 [ 57: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
61 [ 58: PASS ] Color read back as expected
62 [ 59: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
63 [ 60: PASS ] Color read back as expected
64 [ 61: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
65 [ 62: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
66 [ 63: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
67 [ 64: PASS ] Color read back as expected
68 [ 65: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
69 [ 66: PASS ] Color read back as expected
70 [ 67: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
71 [ 68: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
72 [ 69: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
73 [ 70: PASS ] Color read back as expected
74 [ 71: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
75 [ 72: PASS ] Color read back as expected
76 [ 73: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
77 [ 74: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
78 [ 75: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
79 [ 76: PASS ] Color read back as expected
80 [ 77: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
81 [ 78: PASS ] Color read back as expected
82 [ 79: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
83 [ 80: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
84 [ 81: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
85 [ 82: PASS ] Color read back as expected
86 [ 83: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
87 [ 84: PASS ] Color read back as expected
88 [ 85: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
89 [ 86: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
90 [ 87: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
91 [ 88: PASS ] Color read back as expected
92 [ 89: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
93 [ 90: PASS ] Color read back as expected
94 [ 91: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
95 [ 92: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
96 [ 93: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
97 [ 94: PASS ] Color read back as expected
98 [ 95: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
99 [ 96: PASS ] Color read back as expected
100 [ 97: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
101 [ 98: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
102 [ 99: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
103 [ 100: PASS ] Color read back as expected
104 [ 101: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
105 [ 102: PASS ] Color read back as expected
106 [ 103: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
107 [ 104: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
108 [ 105: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
109 [ 106: PASS ] Color read back as expected
110 [ 107: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
111 [ 108: PASS ] Color read back as expected
112 [ 109: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
113 [ 110: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
114 [ 111: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
115 [ 112: PASS ] Color read back as expected
116 [ 113: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
117 [ 114: PASS ] Color read back as expected
118 [ 115: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
119 [ 116: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
120 [ 117: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
121 [ 118: PASS ] Color read back as expected
122 [ 119: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
123 [ 120: PASS ] Color read back as expected
124 [ 121: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
125 [ 122: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
126 [ 123: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
127 [ 124: PASS ] Color read back as expected
128 [ 125: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
129 [ 126: PASS ] Color read back as expected
130 [ 127: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
131 [ 128: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
132 [ 129: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
133 [ 130: PASS ] Color read back as expected
134 [ 131: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
135 [ 132: PASS ] Color read back as expected
136 [ 133: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
137 [ 134: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
138 [ 135: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
139 [ 136: PASS ] Color read back as expected
140 [ 137: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
141 [ 138: PASS ] Color read back as expected
142 [ 139: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
143 [ 140: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
144 [ 141: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
145 [ 142: PASS ] Color read back as expected
146 [ 143: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
147 [ 144: PASS ] Color read back as expected
148 [ 145: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
149 [ 146: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
150 [ 147: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
151 [ 148: FAIL ] Expected color = 127,0,255,178, was = 0,0,0,0
152 [ 149: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
153 [ 150: FAIL ] Expected color = 127,0,255,178, was = 0,0,0,0
154 [ 151: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
155 [ 152: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
156 [ 153: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
157 [ 154: FAIL ] Expected color = -55,56,80,127, was = 0,0,0,0
158 [ 155: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
159 [ 156: FAIL ] Expected color = -55,56,80,127, was = 0,0,0,0
160 [ 157: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
161 [ 158: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
162 [ 159: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
163 [ 160: FAIL ] Expected color = 178,0,127,3, was = 0,0,0,0
164 [ 161: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
165 [ 162: FAIL ] Expected color = 178,0,127,3, was = 0,0,0,0
166 [ 163: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
167 [ 164: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
168 [ 165: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
169 [ 166: FAIL ] Expected color = 14189,6735,0,19, was = 0,0,0,0
170 [ 167: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
171 [ 168: FAIL ] Expected color = 14189,6735,0,19, was = 0,0,0,0
172 [ 169: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
173 [ 170: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
174 [ 171: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
175 [ 172: FAIL ] Expected color = 14189,-6735,0,19, was = 0,0,0,0
176 [ 173: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
177 [ 174: FAIL ] Expected color = 14189,-6735,0,19, was = 0,0,0,0
178 [ 175: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
179 [ 176: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
180 [ 177: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
181 [ 178: FAIL ] Expected color = 126726,6726,98765,2015, was = 0,0,0,0
182 [ 179: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
183 [ 180: FAIL ] Expected color = 126726,6726,98765,2015, was = 0,0,0,0
184 [ 181: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
185 [ 182: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
186 [ 183: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
187 [ 184: FAIL ] Expected color = 126726,-6726,-98765,2015, was = 0,0,0,0
188 [ 185: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
189 [ 186: FAIL ] Expected color = 126726,-6726,-98765,2015, was = 0,0,0,0
190 [ 187: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
191 [ 188: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
192 [ 189: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
193 [ 190: PASS ] Color read back as expected
194 [ 191: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
195 [ 192: PASS ] Color read back as expected
196 [ 193: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
197 [ 194: PASS ] Color read back as expected
198 [ 195: PASS ] successfullyParsed is true
199 [ FAIL ] 26 failures reported
 4[ PASS ] All tests passed
2005