Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Skia] Fix corner cases involving drawing shadows #28168

Merged
merged 1 commit into from
Jun 14, 2024

Conversation

Scony
Copy link
Contributor

@Scony Scony commented May 6, 2024

120f5b1

[Skia] Fix corner cases involving drawing shadows
https://bugs.webkit.org/show_bug.cgi?id=273239

Reviewed by Adrian Perez de Castro.

So far - in the ports that use skia - shadows were being drawn in the same draw call as the original drawing operation.
This was possible as shadows were basically created using a filter that can be added to every drawing operation in skia.
The problem with such apporach is, however, that it does not work properly with some composite operations.
Some composite operations such as e.g. 'destination-atop' are expected to alter drawing in a way that shadow
is being drawn in front of it's origin.
To achieve that with skia:
 - drawing of shadow must be done as a separate draw call.
 - drawing of both shadow and shadow origin must be done on separate transparency layers so that shadow, shadow origin,
   and the original content present before draw operation will overlap correctly.

* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow-and-fitting-perfectly-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow-and-fitting-perfectly.html: Added.
* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow.html: Added.
* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::beginCompositeLayer):
(WebCore::CanvasRenderingContext2DBase::endCompositeLayer):
(WebCore::CanvasRenderingContext2DBase::fillRect):
* Source/WebCore/platform/graphics/BifurcatedGraphicsContext.cpp:
(WebCore::BifurcatedGraphicsContext::beginTransparencyLayer):
* Source/WebCore/platform/graphics/BifurcatedGraphicsContext.h:
* Source/WebCore/platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::beginTransparencyLayer):
* Source/WebCore/platform/graphics/GraphicsContext.h:
* Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContextCG::beginTransparencyLayer):
* Source/WebCore/platform/graphics/cg/GraphicsContextCG.h:
* Source/WebCore/platform/graphics/displaylists/DisplayListItem.h:
* Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::apply const):
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::dump const):
* Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::BeginTransparencyLayerWithCompositeMode):
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::compositeMode const):
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::beginTransparencyLayer):
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h:
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp:
(WebCore::DisplayList::RecorderImpl::recordBeginTransparencyLayer):
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h:
* Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
(Nicosia::CairoOperationRecorder::beginTransparencyLayer):
* Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h:
* Source/WebCore/platform/graphics/skia/FontCascadeSkia.cpp:
(WebCore::FontCascade::drawGlyphs):
* Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp:
(WebCore::GraphicsContextSkia::drawRect):
(WebCore::GraphicsContextSkia::drawNativeImageInternal):
(WebCore::GraphicsContextSkia::drawSkiaPath):
(WebCore::GraphicsContextSkia::fillPath):
(WebCore::GraphicsContextSkia::strokePath):
(WebCore::GraphicsContextSkia::createDropShadowFilterIfNeeded const):
(WebCore::GraphicsContextSkia::drawOutsetShadow):
(WebCore::GraphicsContextSkia::drawSkiaRect):
(WebCore::GraphicsContextSkia::fillRect):
(WebCore::GraphicsContextSkia::beginTransparencyLayer):
(WebCore::GraphicsContextSkia::endTransparencyLayer):
(WebCore::GraphicsContextSkia::strokeRect):
(WebCore::GraphicsContextSkia::fillRoundedRectImpl):
(WebCore::GraphicsContextSkia::drawSkiaText):
* Source/WebCore/platform/graphics/skia/GraphicsContextSkia.h:
* Source/WebCore/rendering/GlyphDisplayListCache.cpp:
(WebCore::GlyphDisplayListCache::canShareDisplayList):
* Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
(WebKit::RemoteDisplayListRecorder::beginTransparencyLayerWithCompositeMode):
* Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h:
* Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.messages.in:
* Source/WebKit/Scripts/webkit/messages.py:
(headers_for_type):
* Source/WebKit/Shared/DisplayListArgumentCoders.serialization.in:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
(WebKit::RemoteDisplayListRecorderProxy::recordBeginTransparencyLayer):
* Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:

Co-authored-by: Carlos Garcia Campos <[email protected]>
Canonical link: https://commits.webkit.org/280008@main

165007e

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2 βœ… πŸ§ͺ wincairo-tests
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ webkitpy βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ›  wpe-cairo
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ›  gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress βœ… πŸ§ͺ api-gtk
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch
βœ… πŸ›  watch-sim

@Scony Scony self-assigned this May 6, 2024
@Scony Scony added the WPE WebKit WebKit WPE component label May 6, 2024
@Scony
Copy link
Contributor Author

Scony commented May 6, 2024

To be continued once #27513 lands

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 6, 2024
@Scony Scony removed the merging-blocked Applied to prevent a change from being merged label May 8, 2024
@Scony Scony force-pushed the 273239-skia-fix-shadows branch from 6b77a21 to bc704b8 Compare May 8, 2024 13:27
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 8, 2024
@Scony Scony removed the merging-blocked Applied to prevent a change from being merged label May 9, 2024
@Scony Scony force-pushed the 273239-skia-fix-shadows branch from bc704b8 to 74e35e6 Compare May 9, 2024 09:32
@Scony Scony force-pushed the 273239-skia-fix-shadows branch from 74e35e6 to ebfd534 Compare May 9, 2024 10:49
@Scony Scony marked this pull request as ready for review May 9, 2024 10:50
@Scony
Copy link
Contributor Author

Scony commented May 9, 2024

The change in current form makes skia implementation to behave as close to CG/cairo as possible, although full alignment is not possible as CG and cairo work differently in some cases due to likely problems with spec, see whatwg/html#10338

@csaavedra
Copy link
Member

Can you rebase this? For some reason the base commit is not building in some bots.

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 29, 2024
@Scony Scony removed the merging-blocked Applied to prevent a change from being merged label May 29, 2024
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for cae4d4e. Live statuses available at the PR page, #28168

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jun 7, 2024
@Scony Scony removed the merging-blocked Applied to prevent a change from being merged label Jun 7, 2024
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 18d9fdd. Live statuses available at the PR page, #28168

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jun 7, 2024
@Scony Scony removed the merging-blocked Applied to prevent a change from being merged label Jun 7, 2024
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 1fb2acf. Live statuses available at the PR page, #28168

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jun 7, 2024
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for 1fb2acf. Live statuses available at the PR page, #28168

@Scony Scony removed the merging-blocked Applied to prevent a change from being merged label Jun 11, 2024
Copy link
Contributor

@aperezdc aperezdc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks reasonable to me, I left only a very small nit.

FWIW, good idea reusing the cross-port entry points for setting the temporary composition layer; and thanks for taking the time to write the commit log notesβ€”they do help to understand what's the intention πŸ™πŸΌ

@carlosgcampos carlosgcampos added the merge-queue Applied to send a pull request to merge-queue label Jun 14, 2024
https://bugs.webkit.org/show_bug.cgi?id=273239

Reviewed by Adrian Perez de Castro.

So far - in the ports that use skia - shadows were being drawn in the same draw call as the original drawing operation.
This was possible as shadows were basically created using a filter that can be added to every drawing operation in skia.
The problem with such apporach is, however, that it does not work properly with some composite operations.
Some composite operations such as e.g. 'destination-atop' are expected to alter drawing in a way that shadow
is being drawn in front of it's origin.
To achieve that with skia:
 - drawing of shadow must be done as a separate draw call.
 - drawing of both shadow and shadow origin must be done on separate transparency layers so that shadow, shadow origin,
   and the original content present before draw operation will overlap correctly.

* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow-and-fitting-perfectly-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow-and-fitting-perfectly.html: Added.
* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-composite-fill-with-shadow.html: Added.
* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::beginCompositeLayer):
(WebCore::CanvasRenderingContext2DBase::endCompositeLayer):
(WebCore::CanvasRenderingContext2DBase::fillRect):
* Source/WebCore/platform/graphics/BifurcatedGraphicsContext.cpp:
(WebCore::BifurcatedGraphicsContext::beginTransparencyLayer):
* Source/WebCore/platform/graphics/BifurcatedGraphicsContext.h:
* Source/WebCore/platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::beginTransparencyLayer):
* Source/WebCore/platform/graphics/GraphicsContext.h:
* Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContextCG::beginTransparencyLayer):
* Source/WebCore/platform/graphics/cg/GraphicsContextCG.h:
* Source/WebCore/platform/graphics/displaylists/DisplayListItem.h:
* Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::apply const):
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::dump const):
* Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::BeginTransparencyLayerWithCompositeMode):
(WebCore::DisplayList::BeginTransparencyLayerWithCompositeMode::compositeMode const):
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::beginTransparencyLayer):
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h:
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp:
(WebCore::DisplayList::RecorderImpl::recordBeginTransparencyLayer):
* Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h:
* Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
(Nicosia::CairoOperationRecorder::beginTransparencyLayer):
* Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h:
* Source/WebCore/platform/graphics/skia/FontCascadeSkia.cpp:
(WebCore::FontCascade::drawGlyphs):
* Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp:
(WebCore::GraphicsContextSkia::drawRect):
(WebCore::GraphicsContextSkia::drawNativeImageInternal):
(WebCore::GraphicsContextSkia::drawSkiaPath):
(WebCore::GraphicsContextSkia::fillPath):
(WebCore::GraphicsContextSkia::strokePath):
(WebCore::GraphicsContextSkia::createDropShadowFilterIfNeeded const):
(WebCore::GraphicsContextSkia::drawOutsetShadow):
(WebCore::GraphicsContextSkia::drawSkiaRect):
(WebCore::GraphicsContextSkia::fillRect):
(WebCore::GraphicsContextSkia::beginTransparencyLayer):
(WebCore::GraphicsContextSkia::endTransparencyLayer):
(WebCore::GraphicsContextSkia::strokeRect):
(WebCore::GraphicsContextSkia::fillRoundedRectImpl):
(WebCore::GraphicsContextSkia::drawSkiaText):
* Source/WebCore/platform/graphics/skia/GraphicsContextSkia.h:
* Source/WebCore/rendering/GlyphDisplayListCache.cpp:
(WebCore::GlyphDisplayListCache::canShareDisplayList):
* Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
(WebKit::RemoteDisplayListRecorder::beginTransparencyLayerWithCompositeMode):
* Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h:
* Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.messages.in:
* Source/WebKit/Scripts/webkit/messages.py:
(headers_for_type):
* Source/WebKit/Shared/DisplayListArgumentCoders.serialization.in:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
(WebKit::RemoteDisplayListRecorderProxy::recordBeginTransparencyLayer):
* Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:

Co-authored-by: Carlos Garcia Campos <[email protected]>
Canonical link: https://commits.webkit.org/280008@main
@webkit-commit-queue
Copy link
Collaborator

Committed 280008@main (120f5b1): https://commits.webkit.org/280008@main

Reviewed commits have been landed. Closing PR #28168 and removing active labels.

@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Jun 14, 2024
@webkit-commit-queue webkit-commit-queue merged commit 120f5b1 into WebKit:main Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WPE WebKit WebKit WPE component
Projects
None yet
7 participants