Changeset 261639 in webkit


Ignore:
Timestamp:
May 13, 2020 12:57:05 PM (4 years ago)
Author:
commit-queue@webkit.org
Message:

Bad flicker on three.js example
https://bugs.webkit.org/show_bug.cgi?id=183151

Patch by Kenneth Russell <kbr@chromium.org> on 2020-05-13
Reviewed by Dean Jackson.

With preserveDrawingBuffer:true and antialias:false, allocate an
intermediate texture and FBO, and blit from it to the destination
texture in prepareTexture(). Use wipeAlphaChannelFromPixels on iOS
as well as macOS.

In addition to fixing the test case from the bug, this also fixes
the webgl/2.0.0/conformance2/textures/webgl_canvas/ layout tests,
which will be re-enabled in a subsequent patch. It also passes the
more stringent webgl_canvas conformance tests in
https://github.com/KhronosGroup/WebGL/pull/3071 .

  • platform/graphics/angle/GraphicsContextGLANGLE.cpp:

(WebCore::GraphicsContextGLOpenGL::readPixelsAndConvertToBGRAIfNecessary):
(WebCore::GraphicsContextGLOpenGL::reshapeFBOs):
(WebCore::GraphicsContextGLOpenGL::resolveMultisamplingIfNecessary):
(WebCore::GraphicsContextGLOpenGL::readPixels):
(WebCore::GraphicsContextGLOpenGL::validateDepthStencil):
(WebCore::GraphicsContextGLOpenGL::prepareTexture):
(WebCore::GraphicsContextGLOpenGL::reshape):

  • platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:

(WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
(WebCore::GraphicsContextGLOpenGL::~GraphicsContextGLOpenGL):

  • platform/graphics/opengl/GraphicsContextGLOpenGL.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r261638 r261639  
     12020-05-13  Kenneth Russell  <kbr@chromium.org>
     2
     3        Bad flicker on three.js example
     4        https://bugs.webkit.org/show_bug.cgi?id=183151
     5
     6        Reviewed by Dean Jackson.
     7
     8        With preserveDrawingBuffer:true and antialias:false, allocate an
     9        intermediate texture and FBO, and blit from it to the destination
     10        texture in prepareTexture(). Use wipeAlphaChannelFromPixels on iOS
     11        as well as macOS.
     12
     13        In addition to fixing the test case from the bug, this also fixes
     14        the webgl/2.0.0/conformance2/textures/webgl_canvas/ layout tests,
     15        which will be re-enabled in a subsequent patch. It also passes the
     16        more stringent webgl_canvas conformance tests in
     17        https://github.com/KhronosGroup/WebGL/pull/3071 .
     18
     19        * platform/graphics/angle/GraphicsContextGLANGLE.cpp:
     20        (WebCore::GraphicsContextGLOpenGL::readPixelsAndConvertToBGRAIfNecessary):
     21        (WebCore::GraphicsContextGLOpenGL::reshapeFBOs):
     22        (WebCore::GraphicsContextGLOpenGL::resolveMultisamplingIfNecessary):
     23        (WebCore::GraphicsContextGLOpenGL::readPixels):
     24        (WebCore::GraphicsContextGLOpenGL::validateDepthStencil):
     25        (WebCore::GraphicsContextGLOpenGL::prepareTexture):
     26        (WebCore::GraphicsContextGLOpenGL::reshape):
     27        * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:
     28        (WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
     29        (WebCore::GraphicsContextGLOpenGL::~GraphicsContextGLOpenGL):
     30        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
     31
    1322020-05-13  Wenson Hsieh  <wenson_hsieh@apple.com>
    233
  • trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp

    r260908 r261639  
    7474static const char* packedDepthStencilExtensionName = "GL_OES_packed_depth_stencil";
    7575
     76namespace {
     77
     78class ScopedResetBufferBinding {
     79    WTF_MAKE_NONCOPYABLE(ScopedResetBufferBinding);
     80public:
     81    ScopedResetBufferBinding(bool shouldDoWork, GLenum bindingPointQuery, GLenum bindingPoint)
     82        : m_bindingPointQuery(bindingPointQuery)
     83        , m_bindingPoint(bindingPoint)
     84    {
     85        if (shouldDoWork)
     86            gl::GetIntegerv(m_bindingPointQuery, &m_bindingValue);
     87        if (m_bindingValue)
     88            gl::BindBuffer(m_bindingPoint, 0);
     89    }
     90
     91    ~ScopedResetBufferBinding()
     92    {
     93        if (m_bindingValue)
     94            gl::BindBuffer(m_bindingPoint, m_bindingValue);
     95    }
     96
     97private:
     98    GLint m_bindingPointQuery { 0 };
     99    GLint m_bindingPoint { 0 };
     100    GLint m_bindingValue { 0 };
     101};
     102
     103} // namespace anonymous
     104
    76105void GraphicsContextGLOpenGL::releaseShaderCompiler()
    77106{
     
    80109}
    81110
    82 #if PLATFORM(MAC)
     111#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
    83112static void wipeAlphaChannelFromPixels(int width, int height, unsigned char* pixels)
    84113{
     
    117146#endif
    118147
    119 #if PLATFORM(MAC)
     148#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
    120149    if (!contextAttributes().alpha)
    121150        wipeAlphaChannelFromPixels(width, height, pixels);
     
    192221    allocateIOSurfaceBackingStore(IntSize(width, height));
    193222    updateFramebufferTextureBackingStoreFromLayer();
    194     gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GraphicsContextGL::IOSurfaceTextureTarget, m_texture, 0);
     223    if (m_preserveDrawingBufferTexture) {
     224        // The context requires the use of an intermediate texture in order to implement
     225        // preserveDrawingBuffer:true without antialiasing.
     226        GLint texture2DBinding = 0;
     227        gl::GetIntegerv(GL_TEXTURE_BINDING_2D, &texture2DBinding);
     228        gl::BindTexture(GL_TEXTURE_2D, m_preserveDrawingBufferTexture);
     229        // Note that any pixel unpack buffer was unbound earlier, in reshape().
     230        gl::TexImage2D(GL_TEXTURE_2D, 0, colorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
     231        // m_fbo is bound at this point.
     232        gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_preserveDrawingBufferTexture, 0);
     233        gl::BindTexture(GL_TEXTURE_2D, texture2DBinding);
     234        // Attach m_texture to m_preserveDrawingBufferFBO for later blitting.
     235        gl::BindFramebuffer(GL_FRAMEBUFFER, m_preserveDrawingBufferFBO);
     236        gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GraphicsContextGL::IOSurfaceTextureTarget, m_texture, 0);
     237        gl::BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
     238    } else
     239        gl::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GraphicsContextGL::IOSurfaceTextureTarget, m_texture, 0);
    195240#elif PLATFORM(GTK)
    196241    gl::BindTexture(GL_TEXTURE_RECTANGLE_ANGLE, m_texture);
     
    255300    TemporaryANGLESetting scopedDither(GL_DITHER, GL_FALSE);
    256301
    257     GLint boundFrameBuffer;
    258     gl::GetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
     302    GLint boundFrameBuffer = 0;
     303    GLint boundReadFrameBuffer = 0;
     304    if (m_isForWebGL2) {
     305        gl::GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundFrameBuffer);
     306        gl::GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFrameBuffer);
     307    } else
     308        gl::GetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
    259309    gl::BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO);
    260310    gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo);
     
    268318
    269319    gl::BlitFramebufferANGLE(resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
    270     gl::BindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
     320    if (m_isForWebGL2) {
     321        gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER, boundFrameBuffer);
     322        gl::BindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFrameBuffer);
     323    } else
     324        gl::BindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
    271325}
    272326
     
    363417        gl::BindFramebuffer(framebufferTarget, m_multisampleFBO);
    364418
    365 #if PLATFORM(MAC)
     419#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
    366420    if (!attrs.alpha && (format == GraphicsContextGL::RGBA || format == GraphicsContextGL::BGRA) && (m_state.boundReadFBO == m_fbo || (attrs.antialias && m_state.boundReadFBO == m_multisampleFBO)))
    367421        wipeAlphaChannelFromPixels(width, height, static_cast<unsigned char*>(data));
     
    396450            extensions.ensureEnabled("GL_OES_rgb8_rgba8");
    397451        }
     452    } else if (attrs.preserveDrawingBuffer) {
     453        // Needed for preserveDrawingBuffer:true support without antialiasing.
     454        extensions.ensureEnabled("GL_ANGLE_framebuffer_blit");
    398455    }
    399456}
     
    484541        gl::BindFramebuffer(GraphicsContextGL::FRAMEBUFFER, m_fbo);
    485542#else
     543    if (m_preserveDrawingBufferTexture) {
     544        // Blit m_preserveDrawingBufferTexture into m_texture.
     545        gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_preserveDrawingBufferFBO);
     546        gl::BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
     547        gl::BlitFramebufferANGLE(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
     548
     549        // Note: it's been observed that BlitFramebuffer may destroy the alpha channel of the
     550        // destination texture if it's an RGB texture bound to an IOSurface. This wasn't observable
     551        // through the WebGL conformance tests, but it may be necessary to save and restore the
     552        // color mask and clear color, and use the color mask to clear the alpha channel of the
     553        // destination texture to 1.0.
     554
     555        // Restore user's framebuffer bindings.
     556        if (m_isForWebGL2) {
     557            gl::BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_state.boundDrawFBO);
     558            gl::BindFramebuffer(GL_READ_FRAMEBUFFER, m_state.boundReadFBO);
     559        } else
     560            gl::BindFramebuffer(GL_FRAMEBUFFER, m_state.boundDrawFBO);
     561    }
    486562    gl::Flush();
    487563#endif
     
    548624    TemporaryANGLESetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
    549625    TemporaryANGLESetting scopedDither(GL_DITHER, GL_FALSE);
     626    ScopedResetBufferBinding scopedPixelUnpackBufferReset(m_isForWebGL2, GL_PIXEL_UNPACK_BUFFER_BINDING, GL_PIXEL_UNPACK_BUFFER);
    550627
    551628    bool mustRestoreFBO = reshapeFBOs(IntSize(width, height));
  • trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm

    r261133 r261639  
    496496        if (attrs.stencil || attrs.depth)
    497497            gl::GenRenderbuffers(1, &m_multisampleDepthStencilBuffer);
    498     }
    499 
     498    } else if (attrs.preserveDrawingBuffer) {
     499        // If necessary, create another texture to handle preserveDrawingBuffer:true without
     500        // antialiasing.
     501        gl::GenTextures(1, &m_preserveDrawingBufferTexture);
     502        gl::BindTexture(GL_TEXTURE_2D, m_preserveDrawingBufferTexture);
     503        gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     504        gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     505        gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     506        gl::TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     507        gl::BindTexture(GL_TEXTURE_2D, 0);
     508        // Create an FBO with which to perform BlitFramebuffer from one texture to the other.
     509        gl::GenFramebuffers(1, &m_preserveDrawingBufferFBO);
     510    }
    500511#endif // USE(ANGLE)
    501512
     
    581592        }
    582593        gl::DeleteFramebuffers(1, &m_fbo);
     594        if (m_preserveDrawingBufferTexture)
     595            gl::DeleteTextures(1, &m_preserveDrawingBufferTexture);
     596        if (m_preserveDrawingBufferFBO)
     597            gl::DeleteFramebuffers(1, &m_preserveDrawingBufferFBO);
    583598#endif
    584599
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h

    r260588 r261639  
    868868    GCGLuint m_multisampleColorBuffer { 0 };
    869869
     870#if USE(ANGLE)
     871    // For preserveDrawingBuffer:true without multisampling.
     872    GCGLuint m_preserveDrawingBufferTexture { 0 };
     873    // Attaches m_texture when m_preserveDrawingBufferTexture is non-zero.
     874    GCGLuint m_preserveDrawingBufferFBO { 0 };
     875#endif
     876
    870877    // Errors raised by synthesizeGLError().
    871878    ListHashSet<GCGLenum> m_syntheticErrors;
Note: See TracChangeset for help on using the changeset viewer.