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

Remove BitmapImage::updateFromSettings() #22844

Conversation

shallawa
Copy link
Contributor

@shallawa shallawa commented Jan 17, 2024

0c6288b

Remove BitmapImage::updateFromSettings()
https://bugs.webkit.org/show_bug.cgi?id=267607
rdar://121077174

Reviewed by Cameron McCormack.

Calculate all the image painting options before calling BitmapImage::draw().
Remove all the calls to BitmapImage::updateFromSettings() and pass the calculated
AllowImageSubsampling and ShowDebugBackground through ImagePaintingOptions.

The first frame of an animated image had to be decoded synchronously. In fact
this restriction is not needed. The rules to decode the static image and the
first frame of an animated image should be the same.

Late decoded frames of an animated images was showing a yellow rectangle if
showDebugBackground is enabled. This is not really needed since the animation
does not advance until the next frame is fully decoded.

* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawImage):
* Source/WebCore/platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::draw):
(WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages const):
(WebCore::BitmapImage::subsamplingLevelForScaleFactor):
(WebCore::BitmapImage::internalStartAnimation):
(WebCore::BitmapImage::advanceAnimation):
(WebCore::BitmapImage::decode):
(WebCore::BitmapImage::updateFromSettings): Deleted.
* Source/WebCore/platform/graphics/BitmapImage.h:
* Source/WebCore/platform/graphics/ImagePaintingOptions.h:
(WebCore::ImagePaintingOptions::allowImageSubsampling const):
(WebCore::ImagePaintingOptions::showDebugBackground const):
(WebCore::ImagePaintingOptions::setOption):
* Source/WebCore/platform/graphics/ImageTypes.h:
* Source/WebCore/rendering/BackgroundPainter.cpp:
(WebCore::BackgroundPainter::paintFillLayer):
* Source/WebCore/rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::decodingModeForImageDraw const):
* Source/WebCore/rendering/RenderImage.cpp:
(WebCore::RenderImage::paintIntoRect):
* Source/WebCore/rendering/svg/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::paintIntoRect):
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::imageFrameIndex):

Canonical link: https://commits.webkit.org/273528@main

8f3509f

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

@shallawa shallawa self-assigned this Jan 17, 2024
@shallawa shallawa added the Images For bugs in image handling. label Jan 17, 2024
@shallawa shallawa force-pushed the eng/Remove-BitmapImageupdateFromSettings branch from f54003d to dc1efb9 Compare January 17, 2024 02:02
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for dc1efb9. Live statuses available at the PR page, #22844

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 17, 2024
@shallawa shallawa removed the merging-blocked Applied to prevent a change from being merged label Jan 17, 2024
@shallawa shallawa force-pushed the eng/Remove-BitmapImageupdateFromSettings branch from dc1efb9 to bb150b2 Compare January 17, 2024 07:02
@webkit-early-warning-system
Copy link
Collaborator

Starting EWS tests for bb150b2. Live statuses available at the PR page, #22844

@shallawa shallawa requested review from smfr and heycam and removed request for rniwa and cdumez January 17, 2024 16:22
@@ -393,7 +385,7 @@ bool BitmapImage::canUseAsyncDecodingForLargeImages() const

bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages() const
{
return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForTesting() || m_source->canUseAsyncDecoding());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain why we no longer need m_allowAnimatedImageAsyncDecoding and no longer consult shouldUseAsyncDecodingForTesting()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because they are consulted in RenderBoxModelObject::decodingModeForImageDraw(). This makes the DecodingMode for the animated images and the large images are done the same way,

LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel = %d scaleFactorForDrawing = (%.4f, %.4f)]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(m_currentSubsamplingLevel), scaleFactorForDrawing.width(), scaleFactorForDrawing.height());

RefPtr<NativeImage> image;
if (options.decodingMode() == DecodingMode::Asynchronous) {
ASSERT(!m_currentFrame || !canAnimate());
if (!canAnimate() && options.decodingMode() == DecodingMode::Asynchronous) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain this change, is it a change of behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We used to pass DecodingMode::Synchronous for animated images always in RenderBoxModelObject::decodingModeForImageDraw()

    auto* bitmapImage = dynamicDowncast<BitmapImage>(image);
    if (!bitmapImage || bitmapImage->canAnimate()) {
        // The DecodingMode for the current frame has to be Synchronous. The DecodingMode
        // for the next frame will be calculated in BitmapImage::internalStartAnimation().
        return DecodingMode::Synchronous;
    }

This is to avoid going through the then part of this if-statement. The else part of this if- statement was handling the async for animated images through BitmapImage::internalStartAnimation()

    if (shouldUseAsyncDecodingForAnimatedImages()) {
        ...
        m_source->requestFrameAsyncDecodingAtIndex
   }

This change fix this unclear behavior by making RenderBoxModelObject::decodingModeForImageDraw() passes the correct DecodingMode from the beginning. So this is not a behavior change.

Comment on lines -525 to -527
// Force repaint if showDebugBackground() is on.
if (m_showDebugBackground)
imageObserver()->changedInRect(*this);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain why we no longer need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The animated image wants to advance to the next frame. But we do not advance to the next frame util it is fully decoded. In this case, the decoding takes too much time. The timer fire but the frame is not ready yet. So we have to wait till the decoding is complete and once we receive imageFrameAvailableAtIndex() from the work queue, we draw this frame.

The deleted code was showing a yellow rectangle in this case even though the current frame is rendered. So do we really need to show the yellow rectangle in this case? I do not think so. But I can put back.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, I agree we don't want the yellow rectangle in this case.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is a behavior change, I think it is worth mentioning in the commit message.

return DecodingMode::Synchronous;
}

// Some document types force synchronous decoding.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment should move up with the document().isImageDocument() check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do not quite understand your review here. I think we can even remove this comment since it does not add much.

if (bitmapImage->currentFrameIndex())
return DecodingMode::Asynchronous;

return defaultDecodingMode();
Copy link
Contributor

Choose a reason for hiding this comment

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

To clarify, this is a behavior change for the first frame, is that right? Whereas before, we would always sync decode the first frame of an animated image, but now we will check e.g. if it's visible in the viewport to determine whether to sync decode?

If that's right, please mention this (and any other intended behavior changes) in the commit message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it is a behavior change. And I think it is the only behavior change in this PR. But I think it's the correct behavior. I think the old behavior was done because it was easier to do it this way. There should not be a reason for disallowing us from async decoding the first frame of an animated image.

I will add a comment about this in the commit message.

@shallawa shallawa force-pushed the eng/Remove-BitmapImageupdateFromSettings branch from bb150b2 to 8f3509f Compare January 25, 2024 18:01
@shallawa shallawa added the merge-queue Applied to send a pull request to merge-queue label Jan 25, 2024
@webkit-commit-queue webkit-commit-queue force-pushed the eng/Remove-BitmapImageupdateFromSettings branch from 8f3509f to 4a88ce6 Compare January 25, 2024 20:12
https://bugs.webkit.org/show_bug.cgi?id=267607
rdar://121077174

Reviewed by Cameron McCormack.

Calculate all the image painting options before calling BitmapImage::draw().
Remove all the calls to BitmapImage::updateFromSettings() and pass the calculated
AllowImageSubsampling and ShowDebugBackground through ImagePaintingOptions.

The first frame of an animated image had to be decoded synchronously. In fact
this restriction is not needed. The rules to decode the static image and the
first frame of an animated image should be the same.

Late decoded frames of an animated images was showing a yellow rectangle if
showDebugBackground is enabled. This is not really needed since the animation
does not advance until the next frame is fully decoded.

* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawImage):
* Source/WebCore/platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::draw):
(WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages const):
(WebCore::BitmapImage::subsamplingLevelForScaleFactor):
(WebCore::BitmapImage::internalStartAnimation):
(WebCore::BitmapImage::advanceAnimation):
(WebCore::BitmapImage::decode):
(WebCore::BitmapImage::updateFromSettings): Deleted.
* Source/WebCore/platform/graphics/BitmapImage.h:
* Source/WebCore/platform/graphics/ImagePaintingOptions.h:
(WebCore::ImagePaintingOptions::allowImageSubsampling const):
(WebCore::ImagePaintingOptions::showDebugBackground const):
(WebCore::ImagePaintingOptions::setOption):
* Source/WebCore/platform/graphics/ImageTypes.h:
* Source/WebCore/rendering/BackgroundPainter.cpp:
(WebCore::BackgroundPainter::paintFillLayer):
* Source/WebCore/rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::decodingModeForImageDraw const):
* Source/WebCore/rendering/RenderImage.cpp:
(WebCore::RenderImage::paintIntoRect):
* Source/WebCore/rendering/svg/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::paintIntoRect):
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::imageFrameIndex):

Canonical link: https://commits.webkit.org/273528@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/Remove-BitmapImageupdateFromSettings branch from 4a88ce6 to 0c6288b Compare January 25, 2024 20:15
@webkit-commit-queue webkit-commit-queue merged commit 0c6288b into WebKit:main Jan 25, 2024
@webkit-commit-queue
Copy link
Collaborator

Committed 273528@main (0c6288b): https://commits.webkit.org/273528@main

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

@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Jan 25, 2024
@shallawa shallawa deleted the eng/Remove-BitmapImageupdateFromSettings branch February 1, 2024 05:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Images For bugs in image handling.
Projects
None yet
5 participants