Changeset 270253 in webkit


Ignore:
Timestamp:
Nov 30, 2020 11:20:52 AM (20 months ago)
Author:
commit-queue@webkit.org
Message:

[WebGL2] Rasterizer discard interferes with implicit clears
https://bugs.webkit.org/show_bug.cgi?id=219061

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

When rasterizer discard is enabled, user-level draw calls and
clears skip the implicit clear since they have no effect.
Readbacks and copies still perform the implicit clear.

A new WebGL conformance test has been added for this in
https://github.com/KhronosGroup/WebGL/pull/3183 which passes with
this fix. WebKit's TestRunner doesn't run the composite phase as
the browser or MiniBrowser do, so wouldn't pass this test as
integrated as a layout test. Per discussion with dino and
kkinnunen on Slack, will address this in follow-on work.

  • html/canvas/WebGL2RenderingContext.cpp:

(WebCore::WebGL2RenderingContext::copyTexSubImage3D):
(WebCore::WebGL2RenderingContext::readPixels):

  • html/canvas/WebGLRenderingContextBase.cpp:

(WebCore::ScopedDisableRasterizerDiscard::ScopedDisableRasterizerDiscard):
(WebCore::ScopedDisableRasterizerDiscard::~ScopedDisableRasterizerDiscard):
(WebCore::WebGLRenderingContextBase::initializeNewContext):
(WebCore::WebGLRenderingContextBase::clearIfComposited):
(WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas):
(WebCore::WebGLRenderingContextBase::paintRenderingResultsToImageData):
(WebCore::WebGLRenderingContextBase::clear):
(WebCore::WebGLRenderingContextBase::copyTexSubImage2D):
(WebCore::WebGLRenderingContextBase::disable):
(WebCore::WebGLRenderingContextBase::drawArrays):
(WebCore::WebGLRenderingContextBase::drawElements):
(WebCore::WebGLRenderingContextBase::enable):
(WebCore::WebGLRenderingContextBase::readPixels):
(WebCore::WebGLRenderingContextBase::copyTexImage2D):
(WebCore::WebGLRenderingContextBase::drawArraysInstanced):
(WebCore::WebGLRenderingContextBase::drawElementsInstanced):

  • html/canvas/WebGLRenderingContextBase.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r270251 r270253  
     12020-11-30  Kenneth Russell  <kbr@chromium.org>
     2
     3        [WebGL2] Rasterizer discard interferes with implicit clears
     4        https://bugs.webkit.org/show_bug.cgi?id=219061
     5
     6        Reviewed by Dean Jackson.
     7
     8        When rasterizer discard is enabled, user-level draw calls and
     9        clears skip the implicit clear since they have no effect.
     10        Readbacks and copies still perform the implicit clear.
     11
     12        A new WebGL conformance test has been added for this in
     13        https://github.com/KhronosGroup/WebGL/pull/3183 which passes with
     14        this fix. WebKit's TestRunner doesn't run the composite phase as
     15        the browser or MiniBrowser do, so wouldn't pass this test as
     16        integrated as a layout test. Per discussion with dino and
     17        kkinnunen on Slack, will address this in follow-on work.
     18
     19        * html/canvas/WebGL2RenderingContext.cpp:
     20        (WebCore::WebGL2RenderingContext::copyTexSubImage3D):
     21        (WebCore::WebGL2RenderingContext::readPixels):
     22        * html/canvas/WebGLRenderingContextBase.cpp:
     23        (WebCore::ScopedDisableRasterizerDiscard::ScopedDisableRasterizerDiscard):
     24        (WebCore::ScopedDisableRasterizerDiscard::~ScopedDisableRasterizerDiscard):
     25        (WebCore::WebGLRenderingContextBase::initializeNewContext):
     26        (WebCore::WebGLRenderingContextBase::clearIfComposited):
     27        (WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas):
     28        (WebCore::WebGLRenderingContextBase::paintRenderingResultsToImageData):
     29        (WebCore::WebGLRenderingContextBase::clear):
     30        (WebCore::WebGLRenderingContextBase::copyTexSubImage2D):
     31        (WebCore::WebGLRenderingContextBase::disable):
     32        (WebCore::WebGLRenderingContextBase::drawArrays):
     33        (WebCore::WebGLRenderingContextBase::drawElements):
     34        (WebCore::WebGLRenderingContextBase::enable):
     35        (WebCore::WebGLRenderingContextBase::readPixels):
     36        (WebCore::WebGLRenderingContextBase::copyTexImage2D):
     37        (WebCore::WebGLRenderingContextBase::drawArraysInstanced):
     38        (WebCore::WebGLRenderingContextBase::drawElementsInstanced):
     39        * html/canvas/WebGLRenderingContextBase.h:
     40
    1412020-11-30  Simon Fraser  <simon.fraser@apple.com>
    242
  • trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp

    r270185 r270253  
    13411341    if (!validateTexture3DBinding("copyTexSubImage3D", target))
    13421342        return;
    1343     clearIfComposited();
     1343    clearIfComposited(ClearCallerOther);
    13441344    m_context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
    13451345}
     
    35673567    ASSERT(canvasBase().originClean());
    35683568
    3569     clearIfComposited();
     3569    clearIfComposited(ClearCallerOther);
    35703570
    35713571    GCGLsizei length, columns, rows;
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

    r270185 r270253  
    462462};
    463463
     464class ScopedDisableRasterizerDiscard {
     465public:
     466    explicit ScopedDisableRasterizerDiscard(WebGLRenderingContextBase* context, bool wasEnabled)
     467        : m_context(context)
     468        , m_wasEnabled(wasEnabled)
     469    {
     470        if (m_wasEnabled)
     471            m_context->disable(GraphicsContextGL::RASTERIZER_DISCARD);
     472    }
     473
     474    ~ScopedDisableRasterizerDiscard()
     475    {
     476        if (m_wasEnabled)
     477            m_context->enable(GraphicsContextGL::RASTERIZER_DISCARD);
     478    }
     479
     480private:
     481    WebGLRenderingContextBase* m_context;
     482    bool m_wasEnabled;
     483};
     484
    464485#define ADD_VALUES_TO_SET(set, arr) \
    465486    set.add(arr, arr + WTF_ARRAY_LENGTH(arr))
     
    866887    m_layerCleared = false;
    867888    m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
    868    
     889
     890    m_rasterizerDiscardEnabled = false;
     891
    869892    m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
    870893    m_scissorEnabled = false;
     
    10981121}
    10991122
    1100 bool WebGLRenderingContextBase::clearIfComposited(GCGLbitfield mask)
     1123bool WebGLRenderingContextBase::clearIfComposited(WebGLRenderingContextBase::ClearCaller caller, GCGLbitfield mask)
    11011124{
    11021125    if (isContextLostOrPending())
     
    11081131    GCGLbitfield buffersNeedingClearing = m_context->getBuffersToAutoClear();
    11091132
    1110     if (!buffersNeedingClearing || (mask && m_framebufferBinding))
     1133    if (!buffersNeedingClearing || (mask && m_framebufferBinding) || (m_rasterizerDiscardEnabled && caller == ClearCallerDrawOrClear))
    11111134        return false;
    11121135
     
    11461169    if (m_framebufferBinding)
    11471170        m_context->bindFramebuffer(bindingPoint, 0);
    1148     // If the WebGL 2.0 clearBuffer APIs already have been used to
    1149     // selectively clear some of the buffers, don't destroy those
    1150     // results.
    1151     m_context->clear(clearMask & buffersNeedingClearing);
     1171    {
     1172        ScopedDisableRasterizerDiscard disable(this, m_rasterizerDiscardEnabled);
     1173        // If the WebGL 2.0 clearBuffer APIs already have been used to
     1174        // selectively clear some of the buffers, don't destroy those
     1175        // results.
     1176        m_context->clear(clearMask & buffersNeedingClearing);
     1177    }
    11521178    m_context->setBuffersToAutoClear(0);
    11531179
     
    12011227    }
    12021228
    1203     clearIfComposited();
     1229    clearIfComposited(ClearCallerOther);
    12041230
    12051231    if (!m_markedCanvasDirty && !m_layerCleared)
     
    12181244    if (isContextLostOrPending())
    12191245        return nullptr;
    1220     clearIfComposited();
     1246    clearIfComposited(ClearCallerOther);
    12211247    return m_context->paintRenderingResultsToImageData();
    12221248}
     
    16811707    }
    16821708#endif
    1683     if (!clearIfComposited(mask))
     1709    if (!clearIfComposited(ClearCallerDrawOrClear, mask))
    16841710        m_context->clear(mask);
    16851711    markContextChangedAndNotifyCanvasObserver();
     
    18581884    if (!validateTexture2DBinding("copyTexSubImage2D", target))
    18591885        return;
    1860     clearIfComposited();
     1886    clearIfComposited(ClearCallerOther);
    18611887    m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
    18621888#else
     
    18891915        return;
    18901916    }
    1891     clearIfComposited();
     1917    clearIfComposited(ClearCallerOther);
    18921918
    18931919    GCGLint clippedX, clippedY;
     
    21702196    if (cap == GraphicsContextGL::SCISSOR_TEST)
    21712197        m_scissorEnabled = false;
     2198    if (cap == GraphicsContextGL::RASTERIZER_DISCARD)
     2199        m_rasterizerDiscardEnabled = false;
    21722200    m_context->disable(cap);
    21732201}
     
    25372565        return;
    25382566
    2539     clearIfComposited();
     2567    clearIfComposited(ClearCallerDrawOrClear);
    25402568
    25412569#if !USE(ANGLE)
     
    26002628        return;
    26012629
    2602     clearIfComposited();
     2630    clearIfComposited(ClearCallerDrawOrClear);
    26032631
    26042632#if !USE(ANGLE)
     
    26512679    if (cap == GraphicsContextGL::SCISSOR_TEST)
    26522680        m_scissorEnabled = true;
     2681    if (cap == GraphicsContextGL::RASTERIZER_DISCARD)
     2682        m_rasterizerDiscardEnabled = true;
    26532683    m_context->enable(cap);
    26542684}
     
    43354365#endif // USE(ANGLE)
    43364366
    4337     clearIfComposited();
     4367    clearIfComposited(ClearCallerOther);
    43384368    void* data = pixels.baseAddress();
    43394369
     
    55945624        return;
    55955625#if USE(ANGLE)
    5596     clearIfComposited();
     5626    clearIfComposited(ClearCallerOther);
    55975627    m_context->copyTexImage2D(target, level, internalFormat, x, y, width, height, border);
    55985628#else
     
    56105640        return;
    56115641    }
    5612     clearIfComposited();
     5642    clearIfComposited(ClearCallerOther);
    56135643
    56145644    GCGLint clippedX, clippedY;
     
    76867716#endif // !USE(ANGLE)
    76877717
    7688     clearIfComposited();
     7718    clearIfComposited(ClearCallerDrawOrClear);
    76897719
    76907720#if !USE(ANGLE)
     
    77327762#endif // !USE(ANGLE)
    77337763
    7734     clearIfComposited();
     7764    clearIfComposited(ClearCallerDrawOrClear);
    77357765
    77367766#if !USE(ANGLE)
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h

    r270185 r270253  
    648648    GCGLuint m_stencilFuncMask, m_stencilFuncMaskBack;
    649649
     650    bool m_rasterizerDiscardEnabled { false };
     651
    650652    bool m_isGLES2Compliant;
    651653    bool m_isGLES2NPOTStrict;
     
    719721    RefPtr<Int32Array> getWebGLIntArrayParameter(GCGLenum);
    720722
     723    enum ClearCaller {
     724        // Caller of ClearIfComposited is a user-level draw or clear call.
     725        ClearCallerDrawOrClear,
     726        // Caller of ClearIfComposited is anything else, including
     727        // readbacks or copies.
     728        ClearCallerOther,
     729    };
    721730    // Clear the backbuffer if it was composited since the last operation.
    722731    // clearMask is set to the bitfield of any clear that would happen anyway at this time
    723732    // and the function returns true if that clear is now unnecessary.
    724     bool clearIfComposited(GCGLbitfield clearMask = 0);
     733    bool clearIfComposited(ClearCaller, GCGLbitfield clearMask = 0);
    725734
    726735    // Helper to restore state that clearing the framebuffer may destroy.
Note: See TracChangeset for help on using the changeset viewer.