Modified: trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp (261638 => 261639)
--- trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp 2020-05-13 19:43:10 UTC (rev 261638)
+++ trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp 2020-05-13 19:57:05 UTC (rev 261639)
@@ -73,6 +73,35 @@
static const char* packedDepthStencilExtensionName = "GL_OES_packed_depth_stencil";
+namespace {
+
+class ScopedResetBufferBinding {
+ WTF_MAKE_NONCOPYABLE(ScopedResetBufferBinding);
+public:
+ ScopedResetBufferBinding(bool shouldDoWork, GLenum bindingPointQuery, GLenum bindingPoint)
+ : m_bindingPointQuery(bindingPointQuery)
+ , m_bindingPoint(bindingPoint)
+ {
+ if (shouldDoWork)
+ gl::GetIntegerv(m_bindingPointQuery, &m_bindingValue);
+ if (m_bindingValue)
+ gl::BindBuffer(m_bindingPoint, 0);
+ }
+
+ ~ScopedResetBufferBinding()
+ {
+ if (m_bindingValue)
+ gl::BindBuffer(m_bindingPoint, m_bindingValue);
+ }
+
+private:
+ GLint m_bindingPointQuery { 0 };
+ GLint m_bindingPoint { 0 };
+ GLint m_bindingValue { 0 };
+};
+
+} // namespace anonymous
+
void GraphicsContextGLOpenGL::releaseShaderCompiler()
{
makeContextCurrent();
@@ -79,7 +108,7 @@
notImplemented();
}
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
static void wipeAlphaChannelFromPixels(int width, int height, unsigned char* pixels)
{
// We can assume this doesn't overflow because the calling functions
@@ -116,7 +145,7 @@
std::swap(pixels[i], pixels[i + 2]);
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
if (!contextAttributes().alpha)
wipeAlphaChannelFromPixels(width, height, pixels);
#endif
@@ -191,7 +220,23 @@
#if PLATFORM(COCOA)
allocateIOSurfaceBackingStore(IntSize(width, height));
updateFramebufferTextureBackingStoreFromLayer();
- gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GraphicsContextGL::IOSurfaceTextureTarget, m_texture, 0);
+ if (m_preserveDrawingBufferTexture) {
+ // The context requires the use of an intermediate texture in order to implement
+ // preserveDrawingBuffer:true without antialiasing.
+ GLint texture2DBinding = 0;
+ gl::GetIntegerv(GL_TEXTURE_BINDING_2D, &texture2DBinding);
+ gl::BindTexture(GL_TEXTURE_2D, m_preserveDrawingBufferTexture);
+ // Note that any pixel unpack buffer was unbound earlier, in reshape().
+ gl::TexImage2D(GL_TEXTURE_2D, 0, colorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
+ // m_fbo is bound at this point.
+ gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_preserveDrawingBufferTexture, 0);
+ gl::BindTexture(GL_TEXTURE_2D, texture2DBinding);
+ // Attach m_texture to m_preserveDrawingBufferFBO for later blitting.
+ gl::BindFramebuffer(GL_FRAMEBUFFER, m_preserveDrawingBufferFBO);
+ gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GraphicsContextGL::IOSurfaceTextureTarget, m_texture, 0);
+ gl::BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ } else
+ gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GraphicsContextGL::IOSurfaceTextureTarget, m_texture, 0);
#elif PLATFORM(GTK)
gl::BindTexture(GL_TEXTURE_RECTANGLE_ANGLE, m_texture);
gl::TexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
@@ -254,8 +299,13 @@
TemporaryANGLESetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
TemporaryANGLESetting scopedDither(GL_DITHER, GL_FALSE);
- GLint boundFrameBuffer;
- gl::GetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
+ GLint boundFrameBuffer = 0;
+ GLint boundReadFrameBuffer = 0;
+ if (m_isForWebGL2) {
+ gl::GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundFrameBuffer);
+ gl::GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFrameBuffer);
+ } else
+ gl::GetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
gl::BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO);
gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo);
@@ -267,7 +317,11 @@
resolveRect = IntRect(0, 0, m_currentWidth, m_currentHeight);
gl::BlitFramebufferANGLE(resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
- gl::BindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
+ if (m_isForWebGL2) {
+ gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER, boundFrameBuffer);
+ gl::BindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFrameBuffer);
+ } else
+ gl::BindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
}
void GraphicsContextGLOpenGL::renderbufferStorage(GCGLenum target, GCGLenum internalformat, GCGLsizei width, GCGLsizei height)
@@ -362,7 +416,7 @@
if (attrs.antialias && m_state.boundReadFBO == m_multisampleFBO)
gl::BindFramebuffer(framebufferTarget, m_multisampleFBO);
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
if (!attrs.alpha && (format == GraphicsContextGL::RGBA || format == GraphicsContextGL::BGRA) && (m_state.boundReadFBO == m_fbo || (attrs.antialias && m_state.boundReadFBO == m_multisampleFBO)))
wipeAlphaChannelFromPixels(width, height, static_cast<unsigned char*>(data));
#endif
@@ -395,6 +449,9 @@
extensions.ensureEnabled("GL_ANGLE_framebuffer_blit");
extensions.ensureEnabled("GL_OES_rgb8_rgba8");
}
+ } else if (attrs.preserveDrawingBuffer) {
+ // Needed for preserveDrawingBuffer:true support without antialiasing.
+ extensions.ensureEnabled("GL_ANGLE_framebuffer_blit");
}
}
@@ -483,6 +540,25 @@
else
gl::BindFramebuffer(GraphicsContextGL::FRAMEBUFFER, m_fbo);
#else
+ if (m_preserveDrawingBufferTexture) {
+ // Blit m_preserveDrawingBufferTexture into m_texture.
+ gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_preserveDrawingBufferFBO);
+ gl::BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
+ gl::BlitFramebufferANGLE(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ // Note: it's been observed that BlitFramebuffer may destroy the alpha channel of the
+ // destination texture if it's an RGB texture bound to an IOSurface. This wasn't observable
+ // through the WebGL conformance tests, but it may be necessary to save and restore the
+ // color mask and clear color, and use the color mask to clear the alpha channel of the
+ // destination texture to 1.0.
+
+ // Restore user's framebuffer bindings.
+ if (m_isForWebGL2) {
+ gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_state.boundDrawFBO);
+ gl::BindFramebuffer(GL_READ_FRAMEBUFFER, m_state.boundReadFBO);
+ } else
+ gl::BindFramebuffer(GL_FRAMEBUFFER, m_state.boundDrawFBO);
+ }
gl::Flush();
#endif
}
@@ -547,6 +623,7 @@
TemporaryANGLESetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
TemporaryANGLESetting scopedDither(GL_DITHER, GL_FALSE);
+ ScopedResetBufferBinding scopedPixelUnpackBufferReset(m_isForWebGL2, GL_PIXEL_UNPACK_BUFFER_BINDING, GL_PIXEL_UNPACK_BUFFER);
bool mustRestoreFBO = reshapeFBOs(IntSize(width, height));
auto attrs = contextAttributes();
Modified: trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm (261638 => 261639)
--- trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm 2020-05-13 19:43:10 UTC (rev 261638)
+++ trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm 2020-05-13 19:57:05 UTC (rev 261639)
@@ -495,8 +495,19 @@
gl::GenRenderbuffers(1, &m_multisampleColorBuffer);
if (attrs.stencil || attrs.depth)
gl::GenRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+ } else if (attrs.preserveDrawingBuffer) {
+ // If necessary, create another texture to handle preserveDrawingBuffer:true without
+ // antialiasing.
+ gl::GenTextures(1, &m_preserveDrawingBufferTexture);
+ gl::BindTexture(GL_TEXTURE_2D, m_preserveDrawingBufferTexture);
+ gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl::BindTexture(GL_TEXTURE_2D, 0);
+ // Create an FBO with which to perform BlitFramebuffer from one texture to the other.
+ gl::GenFramebuffers(1, &m_preserveDrawingBufferFBO);
}
-
#endif // USE(ANGLE)
#if !USE(ANGLE)
@@ -580,6 +591,10 @@
gl::DeleteRenderbuffers(1, &m_depthStencilBuffer);
}
gl::DeleteFramebuffers(1, &m_fbo);
+ if (m_preserveDrawingBufferTexture)
+ gl::DeleteTextures(1, &m_preserveDrawingBufferTexture);
+ if (m_preserveDrawingBufferFBO)
+ gl::DeleteFramebuffers(1, &m_preserveDrawingBufferFBO);
#endif
#if USE(OPENGL_ES)