⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 267616 in webkit


Ignore:
Timestamp:
Sep 25, 2020, 7:44:02 PM (6 years ago)
Author:
Wenson Hsieh
Message:

[GPU Process] fast/canvas/canvas-composite-canvas.html and fast/canvas/canvas-composite-image.html fail
https://bugs.webkit.org/show_bug.cgi?id=216982

Reviewed by Simon Fraser.

Source/WebCore:

When painting into display-list-backed image buffers with remote IOSurface-backed image buffers in the GPU
process, the display-list-backed image buffer has an initial CTM of the identity matrix, while the IOSurface-
backed image buffer's initial CTM is flipped about the x-axis. This is because image buffer backends based on
CoreGraphics always flip their context about the x-axis upon creation, in ImageBufferCGBackend::setupContext().
This causes the CTM of the DisplayList context in the web process to fall out of sync with the CTM of the
platform context in the GPU process, so any canvas rendering codepaths that attempt to consult the current CTM
in the web process (e.g. CanvasRenderingContext2DBase::fullCanvasCompositedDrawImage) will get an incorrect
value.

To fix this, we give the display-list-backed image buffer in the web process an initial CTM that matches the CTM
of the native image buffer in the GPU process; see below for more details.

Tests: fast/canvas/canvas-composite-canvas.html and fast/canvas/canvas-composite-image.html

  • platform/graphics/ImageBufferBackend.h:
  • platform/graphics/cg/ImageBufferCGBitmapBackend.h:

Add a flag indicating whether the origin (0, 0) is intended to be at the top left corner of the image, in which
case we set up the image buffer's graphics context by flipping it vertically about the x-axis. This is true on
CoreGraphics-backed image buffers.

  • platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
  • platform/graphics/displaylists/DisplayListDrawingContext.cpp:

(WebCore::DisplayList::DrawingContext::DrawingContext):

  • platform/graphics/displaylists/DisplayListDrawingContext.h:

(WebCore::DisplayList::DrawingContext::DrawingContext):

Add an additional argument to the constructor of DrawingContext, so that it now takes an initial affine CTM.
By default, this is the identity matrix.

  • platform/graphics/displaylists/DisplayListImageBuffer.h:

(WebCore::DisplayList::ImageBuffer::ImageBuffer):
(WebCore::DisplayList::ImageBuffer::initialDrawingContextCTM):

Add a helper to compute the initial CTM of the drawing context. This was previously only the identity matrix,
but if we're using an image buffer backend that will flip the context vertically, then we need to start the
CTM of the display-list-backed image buffer in the same state.

  • platform/graphics/displaylists/DisplayListRecorder.cpp:

(WebCore::DisplayList::Recorder::Recorder):

Rename the baseCTM argument to initialCTM. This is because this argument determines the CTM of the initial
graphics context state in the state stack, rather than the value of the base CTM. See above for more details.

  • platform/graphics/transforms/AffineTransform.h:

LayoutTests:

Rebaseline this display list test to account for the fact that display list extent rects are in the global
coordinate space, and are therefore vertically flipped since the initial CTM flips everything about the x-axis.

  • displaylists/canvas-display-list-expected.txt:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r267614 r267616  
     12020-09-25  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [GPU Process] fast/canvas/canvas-composite-canvas.html and fast/canvas/canvas-composite-image.html fail
     4        https://bugs.webkit.org/show_bug.cgi?id=216982
     5
     6        Reviewed by Simon Fraser.
     7
     8        Rebaseline this display list test to account for the fact that display list extent rects are in the global
     9        coordinate space, and are therefore vertically flipped since the initial CTM flips everything about the x-axis.
     10
     11        * displaylists/canvas-display-list-expected.txt:
     12
    1132020-09-25  Chris Dumez  <cdumez@apple.com>
    214
  • trunk/LayoutTests/displaylists/canvas-display-list-expected.txt

    r258317 r267616  
    77  (shadows-ignore-transforms 1))
    88(fill-rect
    9   (extent at (10,10) size 55x50)
     9  (extent at (10,140) size 55x50)
    1010  (rect at (10,10) size 55x50))
    1111(set-state
     
    1313  (fill-color #0000C880))
    1414(fill-rect
    15   (extent at (30,30) size 55x50)
     15  (extent at (30,120) size 55x50)
    1616  (rect at (30,30) size 55x50))
  • trunk/Source/WebCore/ChangeLog

    r267615 r267616  
     12020-09-25  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [GPU Process] fast/canvas/canvas-composite-canvas.html and fast/canvas/canvas-composite-image.html fail
     4        https://bugs.webkit.org/show_bug.cgi?id=216982
     5
     6        Reviewed by Simon Fraser.
     7
     8        When painting into display-list-backed image buffers with remote `IOSurface`-backed image buffers in the GPU
     9        process, the display-list-backed image buffer has an initial CTM of the identity matrix, while the `IOSurface`-
     10        backed image buffer's initial CTM is flipped about the x-axis. This is because image buffer backends based on
     11        CoreGraphics always flip their context about the x-axis upon creation, in `ImageBufferCGBackend::setupContext()`.
     12        This causes the CTM of the DisplayList context in the web process to fall out of sync with the CTM of the
     13        platform context in the GPU process, so any canvas rendering codepaths that attempt to consult the current CTM
     14        in the web process (e.g. `CanvasRenderingContext2DBase::fullCanvasCompositedDrawImage`) will get an incorrect
     15        value.
     16
     17        To fix this, we give the display-list-backed image buffer in the web process an initial CTM that matches the CTM
     18        of the native image buffer in the GPU process; see below for more details.
     19
     20        Tests: fast/canvas/canvas-composite-canvas.html and fast/canvas/canvas-composite-image.html
     21
     22        * platform/graphics/ImageBufferBackend.h:
     23        * platform/graphics/cg/ImageBufferCGBitmapBackend.h:
     24
     25        Add a flag indicating whether the origin (0, 0) is intended to be at the top left corner of the image, in which
     26        case we set up the image buffer's graphics context by flipping it vertically about the x-axis. This is true on
     27        CoreGraphics-backed image buffers.
     28
     29        * platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
     30        * platform/graphics/displaylists/DisplayListDrawingContext.cpp:
     31        (WebCore::DisplayList::DrawingContext::DrawingContext):
     32        * platform/graphics/displaylists/DisplayListDrawingContext.h:
     33        (WebCore::DisplayList::DrawingContext::DrawingContext):
     34
     35        Add an additional argument to the constructor of `DrawingContext`, so that it now takes an initial affine CTM.
     36        By default, this is the identity matrix.
     37
     38        * platform/graphics/displaylists/DisplayListImageBuffer.h:
     39        (WebCore::DisplayList::ImageBuffer::ImageBuffer):
     40        (WebCore::DisplayList::ImageBuffer::initialDrawingContextCTM):
     41
     42        Add a helper to compute the initial CTM of the drawing context. This was previously only the identity matrix,
     43        but if we're using an image buffer backend that will flip the context vertically, then we need to start the
     44        CTM of the display-list-backed image buffer in the same state.
     45
     46        * platform/graphics/displaylists/DisplayListRecorder.cpp:
     47        (WebCore::DisplayList::Recorder::Recorder):
     48
     49        Rename the `baseCTM` argument to `initialCTM`. This is because this argument determines the CTM of the initial
     50        graphics context state in the state stack, rather than the value of the base CTM. See above for more details.
     51
     52        * platform/graphics/transforms/AffineTransform.h:
     53
    1542020-09-25  Said Abou-Hallawa  <sabouhallawa@apple.com>
    255
  • trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h

    r265360 r267616  
    100100    virtual bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; }
    101101   
     102    static constexpr bool isOriginAtUpperLeftCorner = false;
    102103    virtual bool isAccelerated() const { return false; }
    103104
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h

    r265360 r267616  
    5050    void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
    5151
     52    static constexpr bool isOriginAtUpperLeftCorner = true;
     53
    5254private:
    5355    ImageBufferCGBitmapBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace, void* data, RetainPtr<CGDataProviderRef>&&, std::unique_ptr<GraphicsContext>&&);
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h

    r265360 r267616  
    6565    bool isAccelerated() const override;
    6666
     67    static constexpr bool isOriginAtUpperLeftCorner = true;
     68
    6769protected:
    6870    static RetainPtr<CGColorSpaceRef> contextColorSpace(const GraphicsContext&);
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp

    r258104 r267616  
    3434namespace DisplayList {
    3535
    36 DrawingContext::DrawingContext(const FloatSize& logicalSize, Recorder::Observer* observer)
     36DrawingContext::DrawingContext(const FloatSize& logicalSize, const AffineTransform& initialCTM, Recorder::Observer* observer)
    3737    : m_context([&](GraphicsContext& displayListContext) {
    38         return makeUnique<Recorder>(displayListContext, m_displayList, GraphicsContextState(), FloatRect({ }, logicalSize), AffineTransform(), observer);
     38        return makeUnique<Recorder>(displayListContext, m_displayList, GraphicsContextState(), FloatRect({ }, logicalSize), initialCTM, observer);
    3939    })
    4040{
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h

    r258219 r267616  
    3636    WTF_MAKE_FAST_ALLOCATED;
    3737public:
    38     WEBCORE_EXPORT DrawingContext(const FloatSize& logicalSize, Recorder::Observer* = nullptr);
     38    WEBCORE_EXPORT DrawingContext(const FloatSize& logicalSize, const AffineTransform& initialCTM = { }, Recorder::Observer* = nullptr);
    3939
    4040    GraphicsContext& context() const { return const_cast<DrawingContext&>(*this).m_context; }
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h

    r258104 r267616  
    4949    ImageBuffer(std::unique_ptr<BackendType>&& dataBackend, const FloatSize& size)
    5050        : BaseConcreteImageBuffer(WTFMove(dataBackend))
    51         , m_drawingContext(size, this)
     51        , m_drawingContext(size, initialDrawingContextCTM(size), this)
    5252    {
    5353    }
    5454
    5555    ImageBuffer(const FloatSize& size)
    56         : m_drawingContext(size, this)
     56        : m_drawingContext(size, initialDrawingContextCTM(size), this)
    5757    {
    5858    }
     
    7575    }
    7676
     77protected:
    7778    DrawingContext m_drawingContext;
     79
     80private:
     81    static AffineTransform initialDrawingContextCTM(const FloatSize& logicalSize)
     82    {
     83        AffineTransform initialCTM;
     84        if (BackendType::isOriginAtUpperLeftCorner)
     85            initialCTM = initialCTM.scale(1, -1).translate(0, -logicalSize.height());
     86        return initialCTM;
     87    }
    7888};
    7989
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp

    r265360 r267616  
    3737namespace DisplayList {
    3838
    39 Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const GraphicsContextState& state, const FloatRect& initialClip, const AffineTransform& baseCTM, Observer* observer)
    40     : GraphicsContextImpl(context, initialClip, baseCTM)
     39Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const GraphicsContextState& state, const FloatRect& initialClip, const AffineTransform& initialCTM, Observer* observer)
     40    : GraphicsContextImpl(context, initialClip, AffineTransform())
    4141    , m_displayList(displayList)
    4242    , m_observer(observer)
    4343{
    4444    LOG_WITH_STREAM(DisplayLists, stream << "\nRecording with clip " << initialClip);
    45     m_stateStack.append(ContextState(state, baseCTM, initialClip));
     45    m_stateStack.append({ state, initialCTM, initialClip });
    4646}
    4747
  • trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h

    r245293 r267616  
    112112    WEBCORE_EXPORT AffineTransform& multiply(const AffineTransform& other);
    113113    WEBCORE_EXPORT AffineTransform& scale(double);
    114     AffineTransform& scale(double sx, double sy);
     114    WEBCORE_EXPORT AffineTransform& scale(double sx, double sy);
    115115    WEBCORE_EXPORT AffineTransform& scaleNonUniform(double sx, double sy); // Same as scale(sx, sy).
    116116    WEBCORE_EXPORT AffineTransform& scale(const FloatSize&);
Note: See TracChangeset for help on using the changeset viewer.