blob: 3e6d090269046f1b124a39c1e121100b327260c5 [file] [log] [blame]
/*
* Copyright (C) 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "DisplayListRecorder.h"
namespace WebCore {
namespace DisplayList {
class RecorderImpl : public Recorder {
WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(RecorderImpl);
public:
class Delegate;
WEBCORE_EXPORT RecorderImpl(DisplayList&, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform&, Delegate* = nullptr, DrawGlyphsRecorder::DeconstructDrawGlyphs = DrawGlyphsRecorder::DeconstructDrawGlyphs::Yes);
RecorderImpl(RecorderImpl& parent, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform& initialCTM);
WEBCORE_EXPORT virtual ~RecorderImpl();
bool isEmpty() const { return m_displayList.isEmpty(); }
class Delegate {
public:
virtual ~Delegate() { }
virtual bool canAppendItemOfType(ItemType) { return false; }
virtual void recordNativeImageUse(NativeImage&) { }
virtual bool isCachedImageBuffer(const ImageBuffer&) const { return false; }
virtual void recordFontUse(Font&) { }
virtual void recordImageBufferUse(ImageBuffer&) { }
virtual RenderingMode renderingMode() const { return RenderingMode::Unaccelerated; }
};
WEBCORE_EXPORT void getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect) final;
WEBCORE_EXPORT void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) final;
void flushContext(GraphicsContextFlushIdentifier identifier) final { append<FlushContext>(identifier); }
private:
// FIXME: Maybe remove this?
bool canDrawImageBuffer(const ImageBuffer&) const final;
RenderingMode renderingMode() const final;
void recordSave() final;
void recordRestore() final;
void recordTranslate(float x, float y) final;
void recordRotate(float angle) final;
void recordScale(const FloatSize&) final;
void recordSetCTM(const AffineTransform&) final;
void recordConcatenateCTM(const AffineTransform&) final;
void recordSetInlineFillColor(SRGBA<uint8_t>) final;
void recordSetInlineStrokeColor(SRGBA<uint8_t>) final;
void recordSetStrokeThickness(float) final;
void recordSetState(const GraphicsContextState&, GraphicsContextState::StateChangeFlags) final;
void recordSetLineCap(LineCap) final;
void recordSetLineDash(const DashArray&, float dashOffset) final;
void recordSetLineJoin(LineJoin) final;
void recordSetMiterLimit(float) final;
void recordClearShadow() final;
void recordClip(const FloatRect&) final;
void recordClipOut(const FloatRect&) final;
void recordClipToImageBuffer(RenderingResourceIdentifier imageBufferIdentifier, const FloatRect& destinationRect) final;
void recordClipOutToPath(const Path&) final;
void recordClipPath(const Path&, WindRule) final;
void recordBeginClipToDrawingCommands(const FloatRect& destination, DestinationColorSpace) final;
void recordEndClipToDrawingCommands(const FloatRect& destination) final;
void recordDrawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned count, const FloatPoint& localAnchor, FontSmoothingMode) final;
void recordDrawImageBuffer(RenderingResourceIdentifier imageBufferIdentifier, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) final;
void recordDrawNativeImage(RenderingResourceIdentifier imageIdentifier, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) final;
void recordDrawPattern(RenderingResourceIdentifier, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }) final;
void recordBeginTransparencyLayer(float) final;
void recordEndTransparencyLayer() final;
void recordDrawRect(const FloatRect&, float) final;
void recordDrawLine(const FloatPoint& point1, const FloatPoint& point2) final;
void recordDrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines) final;
void recordDrawDotsForDocumentMarker(const FloatRect&, const DocumentMarkerLineStyle&) final;
void recordDrawEllipse(const FloatRect&) final;
void recordDrawPath(const Path&) final;
void recordDrawFocusRingPath(const Path&, float width, float offset, const Color&) final;
void recordDrawFocusRingRects(const Vector<FloatRect>&, float width, float offset, const Color&) final;
void recordFillRect(const FloatRect&) final;
void recordFillRectWithColor(const FloatRect&, const Color&) final;
void recordFillRectWithGradient(const FloatRect&, Gradient&) final;
void recordFillCompositedRect(const FloatRect&, const Color&, CompositeOperator, BlendMode) final;
void recordFillRoundedRect(const FloatRoundedRect&, const Color&, BlendMode) final;
void recordFillRectWithRoundedHole(const FloatRect&, const FloatRoundedRect&, const Color&) final;
#if ENABLE(INLINE_PATH_DATA)
void recordFillLine(const LineData&) final;
void recordFillArc(const ArcData&) final;
void recordFillQuadCurve(const QuadCurveData&) final;
void recordFillBezierCurve(const BezierCurveData&) final;
#endif
void recordFillPath(const Path&) final;
void recordFillEllipse(const FloatRect&) final;
#if ENABLE(VIDEO)
void recordPaintFrameForMedia(MediaPlayer&, const FloatRect& destination) final;
#endif
void recordStrokeRect(const FloatRect&, float) final;
#if ENABLE(INLINE_PATH_DATA)
void recordStrokeLine(const LineData&) final;
void recordStrokeArc(const ArcData&) final;
void recordStrokeQuadCurve(const QuadCurveData&) final;
void recordStrokeBezierCurve(const BezierCurveData&) final;
#endif
void recordStrokePath(const Path&) final;
void recordStrokeEllipse(const FloatRect&) final;
void recordClearRect(const FloatRect&) final;
#if USE(CG)
void recordApplyStrokePattern() final;
void recordApplyFillPattern() final;
#endif
void recordApplyDeviceScaleFactor(float) final;
void recordResourceUse(NativeImage&) final;
void recordResourceUse(Font&) final;
void recordResourceUse(ImageBuffer&) final;
std::unique_ptr<GraphicsContext> createNestedContext(const FloatRect& initialClip, const AffineTransform& initialCTM) final;
template<typename T, class... Args>
void append(Args&&... args)
{
if (UNLIKELY(!canAppendItemOfType(T::itemType)))
return;
m_displayList.append<T>(std::forward<Args>(args)...);
if constexpr (T::isDrawingItem) {
if (LIKELY(!m_displayList.tracksDrawingItemExtents()))
return;
auto item = T(std::forward<Args>(args)...);
if (auto rect = item.localBounds(*this))
m_displayList.addDrawingItemExtent(extentFromLocalBounds(*rect));
else if (auto rect = item.globalBounds())
m_displayList.addDrawingItemExtent(*rect);
else
m_displayList.addDrawingItemExtent(std::nullopt);
}
}
FloatRect extentFromLocalBounds(const FloatRect&) const;
WEBCORE_EXPORT bool canAppendItemOfType(ItemType) const;
DisplayList& m_displayList;
Delegate* m_delegate { nullptr };
bool m_isNested { false };
};
}
}