mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
LibWeb: Protect SkiaBackendContext with a mutex
The Skia Ganesh backend we currently use doesn't support painting from multiple threads, which could happen before this change when the main thread used Skia to paint on the HTML canvas while the rendering thread was working on display list rasterization. Fixes https://github.com/LadybirdBrowser/ladybird/issues/4172
This commit is contained in:
parent
24527b6ae3
commit
fd147e6be0
Notes:
github-actions[bot]
2025-04-01 21:40:01 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: fd147e6be0
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4175
7 changed files with 98 additions and 29 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2024, Andreas Kling <andreas@ladybird.org>
|
* Copyright (c) 2024, Andreas Kling <andreas@ladybird.org>
|
||||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
* Copyright (c) 2024, Lucien Fiorini <lucienfiorini@gmail.com>
|
* Copyright (c) 2024, Lucien Fiorini <lucienfiorini@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
@ -33,9 +33,13 @@ struct PainterSkia::Impl {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SkCanvas* canvas() const
|
template<typename Callback>
|
||||||
|
void with_canvas(Callback&& callback)
|
||||||
{
|
{
|
||||||
return &painting_surface->canvas();
|
painting_surface->lock_context();
|
||||||
|
auto& canvas = painting_surface->canvas();
|
||||||
|
callback(canvas);
|
||||||
|
painting_surface->unlock_context();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,14 +126,18 @@ void PainterSkia::clear_rect(Gfx::FloatRect const& rect, Gfx::Color color)
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
paint.setBlendMode(SkBlendMode::kClear);
|
paint.setBlendMode(SkBlendMode::kClear);
|
||||||
impl().canvas()->drawRect(to_skia_rect(rect), paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawRect(to_skia_rect(rect), paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::fill_rect(Gfx::FloatRect const& rect, Color color)
|
void PainterSkia::fill_rect(Gfx::FloatRect const& rect, Color color)
|
||||||
{
|
{
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
impl().canvas()->drawRect(to_skia_rect(rect), paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawRect(to_skia_rect(rect), paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::draw_bitmap(Gfx::FloatRect const& dst_rect, Gfx::ImmutableBitmap const& src_bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode, ReadonlySpan<Gfx::Filter> filters, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
void PainterSkia::draw_bitmap(Gfx::FloatRect const& dst_rect, Gfx::ImmutableBitmap const& src_bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode, ReadonlySpan<Gfx::Filter> filters, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
||||||
|
@ -139,13 +147,15 @@ void PainterSkia::draw_bitmap(Gfx::FloatRect const& dst_rect, Gfx::ImmutableBitm
|
||||||
paint.setAlpha(static_cast<u8>(global_alpha * 255));
|
paint.setAlpha(static_cast<u8>(global_alpha * 255));
|
||||||
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
||||||
|
|
||||||
impl().canvas()->drawImageRect(
|
impl().with_canvas([&](auto& canvas) {
|
||||||
src_bitmap.sk_image(),
|
canvas.drawImageRect(
|
||||||
to_skia_rect(src_rect),
|
src_bitmap.sk_image(),
|
||||||
to_skia_rect(dst_rect),
|
to_skia_rect(src_rect),
|
||||||
to_skia_sampling_options(scaling_mode),
|
to_skia_rect(dst_rect),
|
||||||
&paint,
|
to_skia_sampling_options(scaling_mode),
|
||||||
SkCanvas::kStrict_SrcRectConstraint);
|
&paint,
|
||||||
|
SkCanvas::kStrict_SrcRectConstraint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::set_transform(Gfx::AffineTransform const& transform)
|
void PainterSkia::set_transform(Gfx::AffineTransform const& transform)
|
||||||
|
@ -155,7 +165,9 @@ void PainterSkia::set_transform(Gfx::AffineTransform const& transform)
|
||||||
transform.b(), transform.d(), transform.f(),
|
transform.b(), transform.d(), transform.f(),
|
||||||
0, 0, 1);
|
0, 0, 1);
|
||||||
|
|
||||||
impl().canvas()->setMatrix(matrix);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.setMatrix(matrix);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thickness)
|
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thickness)
|
||||||
|
@ -170,7 +182,9 @@ void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thi
|
||||||
paint.setStrokeWidth(thickness);
|
paint.setStrokeWidth(thickness);
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
auto sk_path = to_skia_path(path);
|
auto sk_path = to_skia_path(path);
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thickness, float blur_radius, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thickness, float blur_radius, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
||||||
|
@ -187,7 +201,9 @@ void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thi
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
||||||
auto sk_path = to_skia_path(path);
|
auto sk_path = to_skia_path(path);
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_style, ReadonlySpan<Gfx::Filter> filters, float thickness, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_style, ReadonlySpan<Gfx::Filter> filters, float thickness, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
||||||
|
@ -204,7 +220,9 @@ void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& pain
|
||||||
paint.setStyle(SkPaint::Style::kStroke_Style);
|
paint.setStyle(SkPaint::Style::kStroke_Style);
|
||||||
paint.setStrokeWidth(thickness);
|
paint.setStrokeWidth(thickness);
|
||||||
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_style, ReadonlySpan<Gfx::Filter> filters, float thickness, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator, Gfx::Path::CapStyle const& cap_style, Gfx::Path::JoinStyle const& join_style)
|
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_style, ReadonlySpan<Gfx::Filter> filters, float thickness, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator, Gfx::Path::CapStyle const& cap_style, Gfx::Path::JoinStyle const& join_style)
|
||||||
|
@ -223,7 +241,9 @@ void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& pain
|
||||||
paint.setStrokeCap(to_skia_cap(cap_style));
|
paint.setStrokeCap(to_skia_cap(cap_style));
|
||||||
paint.setStrokeJoin(to_skia_join(join_style));
|
paint.setStrokeJoin(to_skia_join(join_style));
|
||||||
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::fill_path(Gfx::Path const& path, Gfx::Color color, Gfx::WindingRule winding_rule)
|
void PainterSkia::fill_path(Gfx::Path const& path, Gfx::Color color, Gfx::WindingRule winding_rule)
|
||||||
|
@ -233,7 +253,9 @@ void PainterSkia::fill_path(Gfx::Path const& path, Gfx::Color color, Gfx::Windin
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
auto sk_path = to_skia_path(path);
|
auto sk_path = to_skia_path(path);
|
||||||
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::fill_path(Gfx::Path const& path, Gfx::Color color, Gfx::WindingRule winding_rule, float blur_radius, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
void PainterSkia::fill_path(Gfx::Path const& path, Gfx::Color color, Gfx::WindingRule winding_rule, float blur_radius, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
||||||
|
@ -245,7 +267,9 @@ void PainterSkia::fill_path(Gfx::Path const& path, Gfx::Color color, Gfx::Windin
|
||||||
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
||||||
auto sk_path = to_skia_path(path);
|
auto sk_path = to_skia_path(path);
|
||||||
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::fill_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_style, ReadonlySpan<Gfx::Filter> filters, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator, Gfx::WindingRule winding_rule)
|
void PainterSkia::fill_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_style, ReadonlySpan<Gfx::Filter> filters, float global_alpha, Gfx::CompositingAndBlendingOperator compositing_and_blending_operator, Gfx::WindingRule winding_rule)
|
||||||
|
@ -257,24 +281,32 @@ void PainterSkia::fill_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_
|
||||||
float alpha = paint.getAlphaf();
|
float alpha = paint.getAlphaf();
|
||||||
paint.setAlphaf(alpha * global_alpha);
|
paint.setAlphaf(alpha * global_alpha);
|
||||||
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
paint.setBlender(to_skia_blender(compositing_and_blending_operator));
|
||||||
impl().canvas()->drawPath(sk_path, paint);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.drawPath(sk_path, paint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::save()
|
void PainterSkia::save()
|
||||||
{
|
{
|
||||||
impl().canvas()->save();
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.save();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::restore()
|
void PainterSkia::restore()
|
||||||
{
|
{
|
||||||
impl().canvas()->restore();
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.restore();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterSkia::clip(Gfx::Path const& path, Gfx::WindingRule winding_rule)
|
void PainterSkia::clip(Gfx::Path const& path, Gfx::WindingRule winding_rule)
|
||||||
{
|
{
|
||||||
auto sk_path = to_skia_path(path);
|
auto sk_path = to_skia_path(path);
|
||||||
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
||||||
impl().canvas()->clipPath(sk_path, SkClipOp::kIntersect, true);
|
impl().with_canvas([&](auto& canvas) {
|
||||||
|
canvas.clipPath(sk_path, SkClipOp::kIntersect, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
struct PaintingSurface::Impl {
|
struct PaintingSurface::Impl {
|
||||||
|
RefPtr<SkiaBackendContext> context;
|
||||||
IntSize size;
|
IntSize size;
|
||||||
sk_sp<SkSurface> surface;
|
sk_sp<SkSurface> surface;
|
||||||
RefPtr<Bitmap> bitmap;
|
RefPtr<Bitmap> bitmap;
|
||||||
|
@ -36,12 +37,12 @@ NonnullRefPtr<PaintingSurface> PaintingSurface::create_with_size(RefPtr<SkiaBack
|
||||||
auto bitmap = Bitmap::create(color_type, alpha_type, size).value();
|
auto bitmap = Bitmap::create(color_type, alpha_type, size).value();
|
||||||
auto surface = SkSurfaces::WrapPixels(image_info, bitmap->begin(), bitmap->pitch());
|
auto surface = SkSurfaces::WrapPixels(image_info, bitmap->begin(), bitmap->pitch());
|
||||||
VERIFY(surface);
|
VERIFY(surface);
|
||||||
return adopt_ref(*new PaintingSurface(make<Impl>(size, surface, bitmap)));
|
return adopt_ref(*new PaintingSurface(make<Impl>(context, size, surface, bitmap)));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto surface = SkSurfaces::RenderTarget(context->sk_context(), skgpu::Budgeted::kNo, image_info);
|
auto surface = SkSurfaces::RenderTarget(context->sk_context(), skgpu::Budgeted::kNo, image_info);
|
||||||
VERIFY(surface);
|
VERIFY(surface);
|
||||||
return adopt_ref(*new PaintingSurface(make<Impl>(size, surface, nullptr)));
|
return adopt_ref(*new PaintingSurface(make<Impl>(context, size, surface, nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_bitmap(Bitmap& bitmap)
|
NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_bitmap(Bitmap& bitmap)
|
||||||
|
@ -51,7 +52,7 @@ NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_bitmap(Bitmap& bitmap)
|
||||||
auto size = bitmap.size();
|
auto size = bitmap.size();
|
||||||
auto image_info = SkImageInfo::Make(bitmap.width(), bitmap.height(), color_type, alpha_type, SkColorSpace::MakeSRGB());
|
auto image_info = SkImageInfo::Make(bitmap.width(), bitmap.height(), color_type, alpha_type, SkColorSpace::MakeSRGB());
|
||||||
auto surface = SkSurfaces::WrapPixels(image_info, bitmap.begin(), bitmap.pitch());
|
auto surface = SkSurfaces::WrapPixels(image_info, bitmap.begin(), bitmap.pitch());
|
||||||
return adopt_ref(*new PaintingSurface(make<Impl>(size, surface, bitmap)));
|
return adopt_ref(*new PaintingSurface(make<Impl>(RefPtr<SkiaBackendContext> {}, size, surface, bitmap)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AK_OS_MACOS
|
#ifdef AK_OS_MACOS
|
||||||
|
@ -75,7 +76,7 @@ NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_iosurface(Core::IOSurfaceHa
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
auto surface = SkSurfaces::WrapBackendRenderTarget(context->sk_context(), backend_render_target, sk_origin, kBGRA_8888_SkColorType, nullptr, nullptr);
|
auto surface = SkSurfaces::WrapBackendRenderTarget(context->sk_context(), backend_render_target, sk_origin, kBGRA_8888_SkColorType, nullptr, nullptr);
|
||||||
return adopt_ref(*new PaintingSurface(make<Impl>(size, surface, nullptr)));
|
return adopt_ref(*new PaintingSurface(make<Impl>(context, size, surface, nullptr)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -141,4 +142,18 @@ void PaintingSurface::flush()
|
||||||
on_flush(*this);
|
on_flush(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaintingSurface::lock_context() const
|
||||||
|
{
|
||||||
|
auto& context = m_impl->context;
|
||||||
|
if (context)
|
||||||
|
context->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaintingSurface::unlock_context() const
|
||||||
|
{
|
||||||
|
auto& context = m_impl->context;
|
||||||
|
if (context)
|
||||||
|
context->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,9 @@ public:
|
||||||
|
|
||||||
~PaintingSurface();
|
~PaintingSurface();
|
||||||
|
|
||||||
|
void lock_context() const;
|
||||||
|
void unlock_context() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/Noncopyable.h>
|
#include <AK/Noncopyable.h>
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
|
#include <LibThreading/Mutex.h>
|
||||||
|
|
||||||
#ifdef USE_VULKAN
|
#ifdef USE_VULKAN
|
||||||
# include <LibGfx/VulkanContext.h>
|
# include <LibGfx/VulkanContext.h>
|
||||||
|
@ -44,6 +45,12 @@ public:
|
||||||
virtual GrDirectContext* sk_context() const = 0;
|
virtual GrDirectContext* sk_context() const = 0;
|
||||||
|
|
||||||
virtual MetalContext& metal_context() = 0;
|
virtual MetalContext& metal_context() = 0;
|
||||||
|
|
||||||
|
void lock() { m_mutex.lock(); }
|
||||||
|
void unlock() { m_mutex.unlock(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Threading::Mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,17 @@ static bool command_is_clip_or_mask(Command const& command)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListPlayer::execute(DisplayList& display_list, RefPtr<Gfx::PaintingSurface> surface)
|
void DisplayListPlayer::execute(DisplayList& display_list, RefPtr<Gfx::PaintingSurface> surface)
|
||||||
|
{
|
||||||
|
if (surface) {
|
||||||
|
surface->lock_context();
|
||||||
|
}
|
||||||
|
execute_impl(display_list, surface);
|
||||||
|
if (surface) {
|
||||||
|
surface->unlock_context();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayListPlayer::execute_impl(DisplayList& display_list, RefPtr<Gfx::PaintingSurface> surface)
|
||||||
{
|
{
|
||||||
if (surface)
|
if (surface)
|
||||||
m_surfaces.append(*surface);
|
m_surfaces.append(*surface);
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gfx::PaintingSurface& surface() const { return m_surfaces.last(); }
|
Gfx::PaintingSurface& surface() const { return m_surfaces.last(); }
|
||||||
|
void execute_impl(DisplayList&, RefPtr<Gfx::PaintingSurface>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void flush() = 0;
|
virtual void flush() = 0;
|
||||||
|
|
|
@ -972,7 +972,7 @@ void DisplayListPlayerSkia::add_mask(AddMask const& command)
|
||||||
|
|
||||||
auto mask_surface = Gfx::PaintingSurface::create_with_size(m_context, rect.size(), Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
auto mask_surface = Gfx::PaintingSurface::create_with_size(m_context, rect.size(), Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||||
|
|
||||||
execute(*command.display_list, mask_surface);
|
execute_impl(*command.display_list, mask_surface);
|
||||||
|
|
||||||
SkMatrix mask_matrix;
|
SkMatrix mask_matrix;
|
||||||
mask_matrix.setTranslate(rect.x(), rect.y());
|
mask_matrix.setTranslate(rect.x(), rect.y());
|
||||||
|
@ -985,7 +985,7 @@ void DisplayListPlayerSkia::paint_nested_display_list(PaintNestedDisplayList con
|
||||||
{
|
{
|
||||||
auto& canvas = surface().canvas();
|
auto& canvas = surface().canvas();
|
||||||
canvas.translate(command.rect.x(), command.rect.y());
|
canvas.translate(command.rect.x(), command.rect.y());
|
||||||
execute(*command.display_list, {});
|
execute_impl(*command.display_list, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListPlayerSkia::paint_scrollbar(PaintScrollBar const& command)
|
void DisplayListPlayerSkia::paint_scrollbar(PaintScrollBar const& command)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue