Skip to content

Commit

Permalink
Move Context2D display list implementation to CustomPaintCanvas
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261401
rdar://115277503

Reviewed by Antti Koivisto.

The display list functinality was only used for CSS Painting API in
CustomPaintCanvas. Move holding the display list into that class.
This clarifies both classes.

* Source/WebCore/WebCore.order:
* Source/WebCore/html/CustomPaintCanvas.cpp:
(WebCore::CustomPaintCanvas::getContext):
(WebCore::CustomPaintCanvas::replayDisplayList):
(WebCore::CustomPaintCanvas::copiedImage const):
(WebCore::CustomPaintCanvas::drawingContext const):
(WebCore::CustomPaintCanvas::existingDrawingContext const):
(WebCore::CustomPaintCanvas::replayDisplayListImpl):
(WebCore::CustomPaintCanvas::replayDisplayList const): Deleted.
* Source/WebCore/html/CustomPaintCanvas.h:
* Source/WebCore/html/CustomPaintImage.cpp:
(WebCore::CustomPaintImage::doCustomPaint):
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::reset):
(WebCore::CanvasRenderingContext2DBase::drawingContext const):
(WebCore::CanvasRenderingContext2DBase::paintRenderingResultsToCanvas): Deleted.
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h:
(WebCore::CanvasRenderingContext2DBase::setUsesDisplayListDrawing): Deleted.

Canonical link: https://commits.webkit.org/268191@main
  • Loading branch information
kkinnunen-apple committed Sep 20, 2023
1 parent d165194 commit 9062558
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 65 deletions.
1 change: 0 additions & 1 deletion Source/WebCore/WebCore.order
Original file line number Diff line number Diff line change
Expand Up @@ -16596,7 +16596,6 @@ __ZN7WebCore15GraphicsLayerCA19updateContentsImageEv
__ZN7WebCore15PlatformCALayer21setMinificationFilterENS0_10FilterTypeE
__ZN7WebCore16RenderHTMLCanvas13paintReplacedERNS_9PaintInfoERKNS_11LayoutPointE
__ZN7WebCore17HTMLCanvasElement5paintEPNS_15GraphicsContextERKNS_10LayoutRectEb
__ZN7WebCore22CanvasRenderingContext29paintRenderingResultsToCanvasEv
__ZN7WebCore24setJSDOMWindowOnpopstateEPN3JSC9ExecStateEPNS0_8JSObjectENS0_7JSValueE
__ZN7WebCore9DOMWindow13setOnpopstateEN3WTF10PassRefPtrINS_13EventListenerEEE
__ZN7WebCore24ApplyPropertyBorderImageILNS_15BorderImageTypeE1ELNS_13CSSPropertyIDE1283EXadL_ZNKS_11RenderStyle12maskBoxImageEvEEXadL_ZNS3_15setMaskBoxImageERKNS_14NinePieceImageEEEE10applyValueES2_PNS_13StyleResolverEPNS_8CSSValueE
Expand Down
52 changes: 27 additions & 25 deletions Source/WebCore/html/CustomPaintCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#if ENABLE(CSS_PAINTING_API)

#include "CanvasRenderingContext.h"
#include "DisplayListDrawingContext.h"
#include "DisplayListRecorder.h"
#include "DisplayListReplayer.h"
#include "ImageBitmap.h"
#include "PaintRenderingContext2D.h"
#include "ScriptExecutionContext.h"
Expand Down Expand Up @@ -60,48 +63,33 @@ RefPtr<PaintRenderingContext2D> CustomPaintCanvas::getContext()
return &downcast<PaintRenderingContext2D>(*m_context);

m_context = PaintRenderingContext2D::create(*this);
downcast<PaintRenderingContext2D>(*m_context).setUsesDisplayListDrawing(true);

return &downcast<PaintRenderingContext2D>(*m_context);
}

void CustomPaintCanvas::replayDisplayList(GraphicsContext* ctx) const
void CustomPaintCanvas::replayDisplayList(GraphicsContext& target)
{
ASSERT(!m_destinationGraphicsContext);
if (!width() || !height())
return;

// FIXME: Using an intermediate buffer is not needed if there are no composite operations.
auto clipBounds = ctx->clipBounds();

auto image = ctx->createAlignedImageBuffer(clipBounds.size());
auto clipBounds = target.clipBounds();
auto image = target.createAlignedImageBuffer(clipBounds.size());
if (!image)
return;

m_destinationGraphicsContext = &image->context();
m_destinationGraphicsContext->translate(-clipBounds.location());
if (m_context)
m_context->paintRenderingResultsToCanvas();
m_destinationGraphicsContext = nullptr;

ctx->drawImageBuffer(*image, clipBounds);
auto& imageTarget = image->context();
imageTarget.translate(-clipBounds.location());
replayDisplayListImpl(imageTarget);
target.drawImageBuffer(*image, clipBounds);
}

Image* CustomPaintCanvas::copiedImage() const
{
ASSERT(!m_destinationGraphicsContext);
if (!width() || !height())
return nullptr;

m_copiedBuffer = ImageBuffer::create(size(), RenderingPurpose::Unspecified, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
if (!m_copiedBuffer)
return nullptr;

m_destinationGraphicsContext = &m_copiedBuffer->context();
if (m_context)
m_context->paintRenderingResultsToCanvas();
m_destinationGraphicsContext = nullptr;

replayDisplayListImpl(m_copiedBuffer->context());
m_copiedImage = m_copiedBuffer->copyImage(DontCopyBackingStore, PreserveResolution::Yes);
return m_copiedImage.get();
}
Expand All @@ -113,12 +101,26 @@ void CustomPaintCanvas::clearCopiedImage() const

GraphicsContext* CustomPaintCanvas::drawingContext() const
{
return m_destinationGraphicsContext;
if (!m_recordingContext)
m_recordingContext = makeUnique<DisplayList::DrawingContext>(size());
return &m_recordingContext->context();
}

GraphicsContext* CustomPaintCanvas::existingDrawingContext() const
{
return drawingContext();
return m_recordingContext ? &m_recordingContext->context() : nullptr;
}

void CustomPaintCanvas::replayDisplayListImpl(GraphicsContext& target) const
{
if (!m_recordingContext)
return;
auto& displayList = m_recordingContext->displayList();
if (!displayList.isEmpty()) {
DisplayList::Replayer replayer(target, displayList);
replayer.replay(FloatRect { { }, size() });
displayList.clear();
}
}

}
Expand Down
11 changes: 8 additions & 3 deletions Source/WebCore/html/CustomPaintCanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class CanvasRenderingContext;
class ImageBitmap;
class PaintRenderingContext2D;

namespace DisplayList {
class DrawingContext;
}

class CustomPaintCanvas final : public RefCounted<CustomPaintCanvas>, public CanvasBase, private ContextDestructionObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
Expand All @@ -61,11 +65,11 @@ class CustomPaintCanvas final : public RefCounted<CustomPaintCanvas>, public Can

void didDraw(const std::optional<FloatRect>&, ShouldApplyPostProcessingToDirtyRect) final { }

AffineTransform baseTransform() const final { ASSERT(m_destinationGraphicsContext && m_copiedBuffer); return m_copiedBuffer->baseTransform(); }
AffineTransform baseTransform() const final { ASSERT(m_copiedBuffer); return m_copiedBuffer->baseTransform(); }
Image* copiedImage() const final;
void clearCopiedImage() const final;

void replayDisplayList(GraphicsContext*) const;
void replayDisplayList(GraphicsContext&);

void queueTaskKeepingObjectAlive(TaskSource, Function<void()>&&) final { };
void dispatchEvent(Event&) final { }
Expand All @@ -79,9 +83,10 @@ class CustomPaintCanvas final : public RefCounted<CustomPaintCanvas>, public Can
void refCanvasBase() final { ref(); }
void derefCanvasBase() final { deref(); }
ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
void replayDisplayListImpl(GraphicsContext& target) const;

std::unique_ptr<CanvasRenderingContext> m_context;
mutable GraphicsContext* m_destinationGraphicsContext = nullptr;
mutable std::unique_ptr<DisplayList::DrawingContext> m_recordingContext;
mutable RefPtr<ImageBuffer> m_copiedBuffer;
mutable RefPtr<Image> m_copiedImage;
};
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/CustomPaintImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ ImageDrawResult CustomPaintImage::doCustomPaint(GraphicsContext& destContext, co
if (result.type() != CallbackResultType::Success)
return ImageDrawResult::DidNothing;

canvas->replayDisplayList(&destContext);
canvas->replayDisplayList(destContext);

return ImageDrawResult::DidDraw;
}
Expand Down
27 changes: 0 additions & 27 deletions Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
#include "ColorSerialization.h"
#include "DOMMatrix.h"
#include "DOMMatrix2DInit.h"
#include "DisplayListDrawingContext.h"
#include "DisplayListRecorder.h"
#include "DisplayListReplayer.h"
#include "FloatQuad.h"
#include "GeometryUtilities.h"
#include "Gradient.h"
Expand Down Expand Up @@ -274,8 +271,6 @@ void CanvasRenderingContext2DBase::reset()
m_unrealizedSaveCount = 0;
m_cachedImageData = std::nullopt;

m_recordingContext = nullptr;

clearAccumulatedDirtyRect();
resetTransform();

Expand Down Expand Up @@ -2269,33 +2264,11 @@ const Vector<CanvasRenderingContext2DBase::State, 1>& CanvasRenderingContext2DBa
return m_stateStack;
}

void CanvasRenderingContext2DBase::paintRenderingResultsToCanvas()
{
if (!m_recordingContext)
return;

ASSERT(m_usesDisplayListDrawing);

auto& displayList = m_recordingContext->displayList();
if (!displayList.isEmpty()) {
DisplayList::Replayer replayer(*canvasBase().drawingContext(), displayList);
replayer.replay(backingStoreBounds());
displayList.clear();
}
}

GraphicsContext* CanvasRenderingContext2DBase::drawingContext() const
{
if (UNLIKELY(m_usesDisplayListDrawing)) {
if (!m_recordingContext)
m_recordingContext = makeUnique<DisplayList::DrawingContext>(canvasBase().size());
return &m_recordingContext->context();
}

return canvasBase().drawingContext();
}


void CanvasRenderingContext2DBase::prepareForDisplay()
{
if (auto buffer = canvasBase().buffer())
Expand Down
8 changes: 0 additions & 8 deletions Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ class WebCodecsVideoFrame;

struct DOMMatrix2DInit;

namespace DisplayList {
class DrawingContext;
}

using CanvasImageSource = std::variant<RefPtr<HTMLImageElement>
, RefPtr<SVGImageElement>
Expand Down Expand Up @@ -226,8 +223,6 @@ class CanvasRenderingContext2DBase : public CanvasRenderingContext, public Canva
void setPath(Path2D&);
Ref<Path2D> getPath() const;

void setUsesDisplayListDrawing(bool flag) { m_usesDisplayListDrawing = flag; };

String font() const { return state().fontString(); }

CanvasTextAlign textAlign() const { return state().canvasTextAlign(); }
Expand Down Expand Up @@ -356,7 +351,6 @@ class CanvasRenderingContext2DBase : public CanvasRenderingContext, public Canva
template<typename RectProvider> void didDraw(bool entireCanvas, RectProvider);

bool is2dBase() const final { return true; }
void paintRenderingResultsToCanvas() override;
bool needsPreparationForDisplay() const final;
void prepareForDisplay() final;

Expand Down Expand Up @@ -441,8 +435,6 @@ class CanvasRenderingContext2DBase : public CanvasRenderingContext, public Canva
FloatRect m_dirtyRect;
unsigned m_unrealizedSaveCount { 0 };
bool m_usesCSSCompatibilityParseMode;
bool m_usesDisplayListDrawing { false };
mutable std::unique_ptr<DisplayList::DrawingContext> m_recordingContext;
HashSet<uint32_t> m_suppliedColors;
mutable std::optional<CachedImageData> m_cachedImageData;
CanvasRenderingContext2DSettings m_settings;
Expand Down

0 comments on commit 9062558

Please sign in to comment.