- Revision
- 267616
- Author
- [email protected]
- Date
- 2020-09-25 19:44:02 -0700 (Fri, 25 Sep 2020)
Log 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:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (267615 => 267616)
--- trunk/LayoutTests/ChangeLog 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/LayoutTests/ChangeLog 2020-09-26 02:44:02 UTC (rev 267616)
@@ -1,3 +1,15 @@
+2020-09-25 Wenson Hsieh <[email protected]>
+
+ [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.
+
+ 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:
+
2020-09-25 Chris Dumez <[email protected]>
visibilitychange:hidden doesn't fire during page navigations
Modified: trunk/LayoutTests/displaylists/canvas-display-list-expected.txt (267615 => 267616)
--- trunk/LayoutTests/displaylists/canvas-display-list-expected.txt 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/LayoutTests/displaylists/canvas-display-list-expected.txt 2020-09-26 02:44:02 UTC (rev 267616)
@@ -6,11 +6,11 @@
(fill-color #C80000)
(shadows-ignore-transforms 1))
(fill-rect
- (extent at (10,10) size 55x50)
+ (extent at (10,140) size 55x50)
(rect at (10,10) size 55x50))
(set-state
(change-flags 128)
(fill-color #0000C880))
(fill-rect
- (extent at (30,30) size 55x50)
+ (extent at (30,120) size 55x50)
(rect at (30,30) size 55x50))
Modified: trunk/Source/WebCore/ChangeLog (267615 => 267616)
--- trunk/Source/WebCore/ChangeLog 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/ChangeLog 2020-09-26 02:44:02 UTC (rev 267616)
@@ -1,3 +1,56 @@
+2020-09-25 Wenson Hsieh <[email protected]>
+
+ [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.
+
+ 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:
+
2020-09-25 Said Abou-Hallawa <[email protected]>
Move SerializationState from ImageBuffer to ImageBitmap
Modified: trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h 2020-09-26 02:44:02 UTC (rev 267616)
@@ -99,6 +99,7 @@
virtual PlatformLayer* platformLayer() const { return nullptr; }
virtual bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; }
+ static constexpr bool isOriginAtUpperLeftCorner = false;
virtual bool isAccelerated() const { return false; }
protected:
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h 2020-09-26 02:44:02 UTC (rev 267616)
@@ -49,6 +49,8 @@
RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect&) const override;
void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
+ static constexpr bool isOriginAtUpperLeftCorner = true;
+
private:
ImageBufferCGBitmapBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace, void* data, RetainPtr<CGDataProviderRef>&&, std::unique_ptr<GraphicsContext>&&);
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h 2020-09-26 02:44:02 UTC (rev 267616)
@@ -64,6 +64,8 @@
IOSurface* surface();
bool isAccelerated() const override;
+ static constexpr bool isOriginAtUpperLeftCorner = true;
+
protected:
static RetainPtr<CGColorSpaceRef> contextColorSpace(const GraphicsContext&);
unsigned bytesPerRow() const override;
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp 2020-09-26 02:44:02 UTC (rev 267616)
@@ -33,9 +33,9 @@
namespace WebCore {
namespace DisplayList {
-DrawingContext::DrawingContext(const FloatSize& logicalSize, Recorder::Observer* observer)
+DrawingContext::DrawingContext(const FloatSize& logicalSize, const AffineTransform& initialCTM, Recorder::Observer* observer)
: m_context([&](GraphicsContext& displayListContext) {
- return makeUnique<Recorder>(displayListContext, m_displayList, GraphicsContextState(), FloatRect({ }, logicalSize), AffineTransform(), observer);
+ return makeUnique<Recorder>(displayListContext, m_displayList, GraphicsContextState(), FloatRect({ }, logicalSize), initialCTM, observer);
})
{
}
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h 2020-09-26 02:44:02 UTC (rev 267616)
@@ -35,7 +35,7 @@
class DrawingContext {
WTF_MAKE_FAST_ALLOCATED;
public:
- WEBCORE_EXPORT DrawingContext(const FloatSize& logicalSize, Recorder::Observer* = nullptr);
+ WEBCORE_EXPORT DrawingContext(const FloatSize& logicalSize, const AffineTransform& initialCTM = { }, Recorder::Observer* = nullptr);
GraphicsContext& context() const { return const_cast<DrawingContext&>(*this).m_context; }
WEBCORE_EXPORT Recorder& recorder();
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h 2020-09-26 02:44:02 UTC (rev 267616)
@@ -48,12 +48,12 @@
ImageBuffer(std::unique_ptr<BackendType>&& dataBackend, const FloatSize& size)
: BaseConcreteImageBuffer(WTFMove(dataBackend))
- , m_drawingContext(size, this)
+ , m_drawingContext(size, initialDrawingContextCTM(size), this)
{
}
ImageBuffer(const FloatSize& size)
- : m_drawingContext(size, this)
+ : m_drawingContext(size, initialDrawingContextCTM(size), this)
{
}
@@ -74,7 +74,17 @@
m_drawingContext.replayDisplayList(BaseConcreteImageBuffer::context());
}
+protected:
DrawingContext m_drawingContext;
+
+private:
+ static AffineTransform initialDrawingContextCTM(const FloatSize& logicalSize)
+ {
+ AffineTransform initialCTM;
+ if (BackendType::isOriginAtUpperLeftCorner)
+ initialCTM = initialCTM.scale(1, -1).translate(0, -logicalSize.height());
+ return initialCTM;
+ }
};
} // DisplayList
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp 2020-09-26 02:44:02 UTC (rev 267616)
@@ -36,13 +36,13 @@
namespace WebCore {
namespace DisplayList {
-Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const GraphicsContextState& state, const FloatRect& initialClip, const AffineTransform& baseCTM, Observer* observer)
- : GraphicsContextImpl(context, initialClip, baseCTM)
+Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const GraphicsContextState& state, const FloatRect& initialClip, const AffineTransform& initialCTM, Observer* observer)
+ : GraphicsContextImpl(context, initialClip, AffineTransform())
, m_displayList(displayList)
, m_observer(observer)
{
LOG_WITH_STREAM(DisplayLists, stream << "\nRecording with clip " << initialClip);
- m_stateStack.append(ContextState(state, baseCTM, initialClip));
+ m_stateStack.append({ state, initialCTM, initialClip });
}
Recorder::~Recorder()
Modified: trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h (267615 => 267616)
--- trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h 2020-09-26 01:42:08 UTC (rev 267615)
+++ trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h 2020-09-26 02:44:02 UTC (rev 267616)
@@ -111,7 +111,7 @@
WEBCORE_EXPORT AffineTransform& multiply(const AffineTransform& other);
WEBCORE_EXPORT AffineTransform& scale(double);
- AffineTransform& scale(double sx, double sy);
+ WEBCORE_EXPORT AffineTransform& scale(double sx, double sy);
WEBCORE_EXPORT AffineTransform& scaleNonUniform(double sx, double sy); // Same as scale(sx, sy).
WEBCORE_EXPORT AffineTransform& scale(const FloatSize&);
WEBCORE_EXPORT AffineTransform& rotate(double);