Skip to content

Commit

Permalink
Transparent, composited canvas is rendered black when layer is change…
Browse files Browse the repository at this point in the history
…d to render layer backing sharing

https://bugs.webkit.org/show_bug.cgi?id=258927
rdar://110088034

Reviewed by Simon Fraser.

Explicitly composited canvas element might switch to being
composited to other RenderLayerBacking. This left the
RenderLayer::m_shouldPaintUsingCompositeCopy unreset.

Instead, store the flag to RenderLayerBacking.

* Source/WebCore/html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::paint):
* Source/WebCore/html/HTMLCanvasElement.h:
* Source/WebCore/rendering/RenderHTMLCanvas.cpp:
(WebCore::RenderHTMLCanvas::paintReplaced):
* Source/WebCore/rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
* Source/WebCore/rendering/RenderLayer.h:
(WebCore::RenderLayer::shouldPaintUsingCompositeCopy const): Deleted.
(WebCore::RenderLayer::setShouldPaintUsingCompositeCopy): Deleted.
* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::RenderLayerBacking::paintIntoLayer):
* Source/WebCore/rendering/RenderLayerBacking.h:

Canonical link: https://commits.webkit.org/265837@main
  • Loading branch information
kkinnunen-apple committed Jul 7, 2023
1 parent 29e41d3 commit dbef4cf
Show file tree
Hide file tree
Showing 8 changed files with 18 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Source/WebCore/html/HTMLCanvasElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ bool HTMLCanvasElement::paintsIntoCanvasBuffer() const



void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r, CompositeOperator op)
void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r)
{
if (m_context)
m_context->clearAccumulatedDirtyRect();
Expand All @@ -656,7 +656,7 @@ void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r, Com
if (shouldPaint) {
if (hasCreatedImageBuffer()) {
if (ImageBuffer* imageBuffer = buffer())
context.drawImageBuffer(*imageBuffer, snappedIntRect(r), op);
context.drawImageBuffer(*imageBuffer, snappedIntRect(r), context.compositeOperation());
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/HTMLCanvasElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class HTMLCanvasElement final : public HTMLElement, public CanvasBase, public Ac
// Used for rendering
void didDraw(const std::optional<FloatRect>&, ShouldApplyPostProcessingToDirtyRect) final;

void paint(GraphicsContext&, const LayoutRect&, CompositeOperator);
void paint(GraphicsContext&, const LayoutRect&);

#if ENABLE(MEDIA_STREAM) || ENABLE(WEB_CODECS)
RefPtr<VideoFrame> toVideoFrame();
Expand Down
7 changes: 1 addition & 6 deletions Source/WebCore/rendering/RenderHTMLCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& pa
InterpolationQualityMaintainer interpolationMaintainer(context, ImageQualityController::interpolationQualityFromStyle(style()));

canvasElement().setIsSnapshotting(paintInfo.paintBehavior.contains(PaintBehavior::Snapshotting));
CompositeOperator op = CompositeOperator::SourceOver;
#if ENABLE(CSS_COMPOSITING)
if (paintInfo.enclosingSelfPaintingLayer() && paintInfo.enclosingSelfPaintingLayer()->shouldPaintUsingCompositeCopy())
op = CompositeOperator::Copy;
#endif
canvasElement().paint(context, replacedContentRect, op);
canvasElement().paint(context, replacedContentRect);
canvasElement().setIsSnapshotting(false);
}

Expand Down
1 change: 0 additions & 1 deletion Source/WebCore/rendering/RenderLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject& renderer)
, m_hasTransformedAncestor(false)
, m_has3DTransformedAncestor(false)
, m_insideSVGForeignObject(false)
, m_shouldPaintUsingCompositeCopy(false)
, m_indirectCompositingReason(static_cast<unsigned>(IndirectCompositingReason::None))
, m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
#if ASSERT_ENABLED
Expand Down
4 changes: 0 additions & 4 deletions Source/WebCore/rendering/RenderLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ class RenderLayer : public CanMakeWeakPtr<RenderLayer> {
bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return false; }
#endif

bool shouldPaintUsingCompositeCopy() const { return m_shouldPaintUsingCompositeCopy; }
bool isComposited() const { return m_backing != nullptr; }
bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
bool hasCompositedMask() const;
Expand Down Expand Up @@ -1144,8 +1143,6 @@ class RenderLayer : public CanMakeWeakPtr<RenderLayer> {

bool computeHasVisibleContent() const;

void setShouldPaintUsingCompositeCopy(bool copy) { m_shouldPaintUsingCompositeCopy = copy; }

bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
bool has3DTransformedAncestor() const { return m_has3DTransformedAncestor; }

Expand Down Expand Up @@ -1251,7 +1248,6 @@ class RenderLayer : public CanMakeWeakPtr<RenderLayer> {
bool m_has3DTransformedAncestor : 1;

bool m_insideSVGForeignObject : 1;
bool m_shouldPaintUsingCompositeCopy : 1;
bool m_isHiddenByOverflowTruncation : 1 { false };

unsigned m_indirectCompositingReason : 4; // IndirectCompositingReason
Expand Down
19 changes: 12 additions & 7 deletions Source/WebCore/rendering/RenderLayerBacking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,14 +1135,12 @@ bool RenderLayerBacking::updateConfiguration(const RenderLayer* compositingAnces
layerConfigChanged = true;
}

#if ENABLE(CSS_COMPOSITING)
bool shouldPaintUsingCompositeCopy = unscaledBitmap && is<RenderHTMLCanvas>(renderer());
if (shouldPaintUsingCompositeCopy != m_owningLayer.shouldPaintUsingCompositeCopy()) {
m_owningLayer.setShouldPaintUsingCompositeCopy(shouldPaintUsingCompositeCopy);
if (shouldPaintUsingCompositeCopy != m_shouldPaintUsingCompositeCopy) {
m_shouldPaintUsingCompositeCopy = shouldPaintUsingCompositeCopy;
m_graphicsLayer->setShouldPaintUsingCompositeCopy(shouldPaintUsingCompositeCopy);
layerConfigChanged = true;
}
#endif

if (is<RenderEmbeddedObject>(renderer()) && downcast<RenderEmbeddedObject>(renderer()).allowsAcceleratedCompositing()) {
auto* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer()).widget());
Expand Down Expand Up @@ -3443,7 +3441,6 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
#endif
return;
}

auto paintFlags = paintFlagsForLayer(*graphicsLayer);

if (is<EventRegionContext>(regionContext))
Expand All @@ -3464,8 +3461,16 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
paintingInfo.regionContext = regionContext;

if (&layer == &m_owningLayer) {
layer.paintLayerContents(context, paintingInfo, paintFlags);

{
bool shouldResetCompositeMode = false;
if (m_shouldPaintUsingCompositeCopy && context.compositeMode() == CompositeMode { CompositeOperator::SourceOver, BlendMode::Normal }) {
context.setCompositeMode({ CompositeOperator::Copy, BlendMode::Normal });
shouldResetCompositeMode = true;
}
layer.paintLayerContents(context, paintingInfo, paintFlags);
if (shouldResetCompositeMode)
context.setCompositeMode({ CompositeOperator::SourceOver, BlendMode::Normal });
}
auto* scrollableArea = layer.scrollableArea();
if (scrollableArea && scrollableArea->containsDirtyOverlayScrollbars() && !regionContext)
layer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerFlag::PaintingOverlayScrollbars);
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/rendering/RenderLayerBacking.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class RenderLayerBacking final : public GraphicsLayerClient {
WEBCORE_EXPORT void setIsTrackingDisplayListReplay(bool);
WEBCORE_EXPORT String replayDisplayListAsText(OptionSet<DisplayList::AsTextFlag>) const;

bool shouldPaintUsingCompositeCopy() const { return m_shouldPaintUsingCompositeCopy; }
private:
friend class PaintedContentsInfo;

Expand Down Expand Up @@ -456,6 +457,7 @@ class RenderLayerBacking final : public GraphicsLayerClient {
#if ENABLE(ASYNC_SCROLLING)
bool m_needsEventRegionUpdate { true };
#endif
bool m_shouldPaintUsingCompositeCopy { false };
};

enum CanvasCompositingStrategy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ class RemoteImageBufferProxy : public WebCore::ImageBuffer {
void convertToLuminanceMask() final;
void transformToColorSpace(const WebCore::DestinationColorSpace&) final;

bool prefersPreparationForDisplay() final { return true; }

void flushDrawingContext() final;
bool flushDrawingContextAsync() final;

Expand Down

0 comments on commit dbef4cf

Please sign in to comment.