mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibGfx+LibWeb: Move Skia backend context to process level singleton
Previously, this was attached to the traversable navigable. Using a singleton instead allows us to use the context for detached documents.
This commit is contained in:
committed by
Jelle Raaijmakers
parent
d4cf537d58
commit
26389363ad
Notes:
github-actions[bot]
2026-03-19 12:36:24 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/26389363ad2 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8460 Reviewed-by: https://github.com/gmta ✅
@@ -94,12 +94,13 @@ NonnullRefPtr<PaintingSurface> PaintingSurface::create_from_vkimage(NonnullRefPt
|
||||
}
|
||||
#endif
|
||||
|
||||
NonnullRefPtr<PaintingSurface> PaintingSurface::create_with_size(RefPtr<SkiaBackendContext> context, IntSize size, BitmapFormat color_type, AlphaType alpha_type)
|
||||
NonnullRefPtr<PaintingSurface> PaintingSurface::create_with_size(IntSize size, BitmapFormat color_type, AlphaType alpha_type)
|
||||
{
|
||||
auto sk_color_type = to_skia_color_type(color_type);
|
||||
auto sk_alpha_type = to_skia_alpha_type(color_type, alpha_type);
|
||||
auto image_info = SkImageInfo::Make(size.width(), size.height(), sk_color_type, sk_alpha_type, SkColorSpace::MakeSRGB());
|
||||
|
||||
auto context = SkiaBackendContext::the();
|
||||
if (context) {
|
||||
context->lock();
|
||||
auto surface = SkSurfaces::RenderTarget(context->sk_context(), skgpu::Budgeted::kNo, image_info);
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
|
||||
Function<void(PaintingSurface&)> on_flush;
|
||||
|
||||
static NonnullRefPtr<PaintingSurface> create_with_size(RefPtr<SkiaBackendContext> context, IntSize size, BitmapFormat color_type, AlphaType alpha_type);
|
||||
static NonnullRefPtr<PaintingSurface> create_with_size(IntSize size, BitmapFormat color_type, AlphaType alpha_type);
|
||||
static NonnullRefPtr<PaintingSurface> wrap_bitmap(Bitmap&);
|
||||
|
||||
#ifdef AK_OS_MACOS
|
||||
|
||||
@@ -27,6 +27,31 @@
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
static RefPtr<SkiaBackendContext> s_the;
|
||||
|
||||
void SkiaBackendContext::initialize_gpu_backend()
|
||||
{
|
||||
VERIFY(!s_the);
|
||||
|
||||
#ifdef AK_OS_MACOS
|
||||
auto metal_context = get_metal_context();
|
||||
s_the = create_metal_context(*metal_context);
|
||||
#elif USE_VULKAN
|
||||
auto maybe_vulkan_context = Gfx::create_vulkan_context();
|
||||
if (maybe_vulkan_context.is_error()) {
|
||||
dbgln("Vulkan context creation failed: {}", maybe_vulkan_context.error());
|
||||
return;
|
||||
}
|
||||
auto vulkan_context = maybe_vulkan_context.release_value();
|
||||
s_the = create_vulkan_context(vulkan_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
RefPtr<SkiaBackendContext> SkiaBackendContext::the()
|
||||
{
|
||||
return s_the;
|
||||
}
|
||||
|
||||
#ifdef USE_VULKAN
|
||||
class SkiaVulkanBackendContext final : public SkiaBackendContext {
|
||||
AK_MAKE_NONCOPYABLE(SkiaVulkanBackendContext);
|
||||
|
||||
@@ -39,6 +39,9 @@ public:
|
||||
static RefPtr<SkiaBackendContext> create_metal_context(NonnullRefPtr<MetalContext>);
|
||||
#endif
|
||||
|
||||
static void initialize_gpu_backend();
|
||||
static RefPtr<SkiaBackendContext> the();
|
||||
|
||||
SkiaBackendContext() { }
|
||||
virtual ~SkiaBackendContext() { }
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <LibWeb/HTML/ImageRequest.h>
|
||||
#include <LibWeb/HTML/Path2D.h>
|
||||
#include <LibWeb/HTML/TextMetrics.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Infra/CharacterTypes.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
@@ -248,8 +247,7 @@ void CanvasRenderingContext2D::allocate_painting_surface_if_needed()
|
||||
|
||||
auto color_type = m_context_attributes.alpha ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888;
|
||||
|
||||
auto skia_backend_context = canvas_element().navigable()->traversable_navigable()->skia_backend_context();
|
||||
m_surface = Gfx::PaintingSurface::create_with_size(skia_backend_context, canvas_element().bitmap_size_for_canvas(), color_type, Gfx::AlphaType::Premultiplied);
|
||||
m_surface = Gfx::PaintingSurface::create_with_size(canvas_element().bitmap_size_for_canvas(), color_type, Gfx::AlphaType::Premultiplied);
|
||||
m_painter = nullptr;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#the-canvas-settings:concept-canvas-alpha
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
#include <LibWeb/HTML/Numbers.h>
|
||||
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Layout/CanvasBox.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
@@ -307,14 +306,13 @@ Gfx::IntSize HTMLCanvasElement::bitmap_size_for_canvas(size_t minimum_width, siz
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-todataurl
|
||||
String HTMLCanvasElement::to_data_url(StringView type, JS::Value js_quality)
|
||||
{
|
||||
// It is possible the canvas doesn't have a associated bitmap so create one
|
||||
// It is possible the canvas doesn't have an associated bitmap so create one
|
||||
allocate_painting_surface_if_needed();
|
||||
auto surface = this->surface();
|
||||
auto size = bitmap_size_for_canvas();
|
||||
if (!surface && !size.is_empty()) {
|
||||
// If the context is not initialized yet, we need to allocate transparent surface for serialization
|
||||
auto skia_backend_context = navigable()->traversable_navigable()->skia_backend_context();
|
||||
surface = Gfx::PaintingSurface::create_with_size(skia_backend_context, size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
surface = Gfx::PaintingSurface::create_with_size(size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
}
|
||||
|
||||
// FIXME: 1. If this canvas element's bitmap's origin-clean flag is set to false, then throw a "SecurityError" DOMException.
|
||||
@@ -391,8 +389,7 @@ RefPtr<Gfx::Bitmap> HTMLCanvasElement::get_bitmap_from_surface()
|
||||
auto surface = this->surface();
|
||||
if (auto const size = bitmap_size_for_canvas(); !surface && !size.is_empty()) {
|
||||
// If the context is not initialized yet, we need to allocate transparent surface for serialization
|
||||
auto const skia_backend_context = navigable()->traversable_navigable()->skia_backend_context();
|
||||
surface = Gfx::PaintingSurface::create_with_size(skia_backend_context, size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
surface = Gfx::PaintingSurface::create_with_size(size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Bitmap> bitmap;
|
||||
|
||||
@@ -145,28 +145,6 @@ bool Navigable::is_ancestor_of(GC::Ref<Navigable> other) const
|
||||
return false;
|
||||
}
|
||||
|
||||
static RefPtr<Gfx::SkiaBackendContext> g_cached_skia_backend_context;
|
||||
|
||||
static RefPtr<Gfx::SkiaBackendContext> get_skia_backend_context()
|
||||
{
|
||||
if (!g_cached_skia_backend_context) {
|
||||
#ifdef AK_OS_MACOS
|
||||
auto metal_context = Gfx::get_metal_context();
|
||||
g_cached_skia_backend_context = Gfx::SkiaBackendContext::create_metal_context(*metal_context);
|
||||
#elif USE_VULKAN
|
||||
auto maybe_vulkan_context = Gfx::create_vulkan_context();
|
||||
if (maybe_vulkan_context.is_error()) {
|
||||
dbgln("Vulkan context creation failed: {}", maybe_vulkan_context.error());
|
||||
return {};
|
||||
}
|
||||
|
||||
auto vulkan_context = maybe_vulkan_context.release_value();
|
||||
g_cached_skia_backend_context = Gfx::SkiaBackendContext::create_vulkan_context(vulkan_context);
|
||||
#endif
|
||||
}
|
||||
return g_cached_skia_backend_context;
|
||||
}
|
||||
|
||||
Navigable::Navigable(GC::Ref<Page> page, bool is_svg_page)
|
||||
: m_page(page)
|
||||
, m_event_handler({}, *this)
|
||||
@@ -179,19 +157,9 @@ Navigable::Navigable(GC::Ref<Page> page, bool is_svg_page)
|
||||
{
|
||||
all_navigables().set(*this);
|
||||
|
||||
auto display_list_player_type = page->client().display_list_player_type();
|
||||
if (display_list_player_type == DisplayListPlayerType::SkiaGPUIfAvailable) {
|
||||
m_skia_backend_context = get_skia_backend_context();
|
||||
}
|
||||
|
||||
if (!m_is_svg_page) {
|
||||
OwnPtr<Painting::DisplayListPlayerSkia> skia_player;
|
||||
if (display_list_player_type == DisplayListPlayerType::SkiaGPUIfAvailable) {
|
||||
skia_player = make<Painting::DisplayListPlayerSkia>(m_skia_backend_context);
|
||||
} else {
|
||||
skia_player = make<Painting::DisplayListPlayerSkia>();
|
||||
}
|
||||
m_rendering_thread.set_skia_player(move(skia_player));
|
||||
auto display_list_player_type = page->client().display_list_player_type();
|
||||
m_rendering_thread.set_skia_player(make<Painting::DisplayListPlayerSkia>());
|
||||
m_rendering_thread.start(display_list_player_type);
|
||||
}
|
||||
}
|
||||
@@ -2911,11 +2879,6 @@ void Navigable::render_screenshot(Gfx::PaintingSurface& painting_surface, PaintC
|
||||
m_rendering_thread.request_screenshot(painting_surface, move(callback));
|
||||
}
|
||||
|
||||
RefPtr<Gfx::SkiaBackendContext> Navigable::skia_backend_context() const
|
||||
{
|
||||
return m_skia_backend_context;
|
||||
}
|
||||
|
||||
GC::Ref<WebIDL::Promise> Navigable::scroll_viewport_by_delta(CSSPixelPoint delta)
|
||||
{
|
||||
auto vv = active_document()->visual_viewport();
|
||||
|
||||
@@ -212,8 +212,6 @@ public:
|
||||
|
||||
[[nodiscard]] bool has_inclusive_ancestor_with_visibility_hidden() const;
|
||||
|
||||
RefPtr<Gfx::SkiaBackendContext> skia_backend_context() const;
|
||||
|
||||
RenderingThread& rendering_thread() { return m_rendering_thread; }
|
||||
|
||||
void set_pending_set_browser_zoom_request(bool value) { m_pending_set_browser_zoom_request = value; }
|
||||
@@ -291,7 +289,6 @@ private:
|
||||
bool m_pending_set_browser_zoom_request { false };
|
||||
bool m_should_show_line_box_borders { false };
|
||||
GC::Ref<Painting::BackingStoreManager> m_backing_store_manager;
|
||||
RefPtr<Gfx::SkiaBackendContext> m_skia_backend_context;
|
||||
RenderingThread m_rendering_thread;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/PaintingSurface.h>
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Painting/BackingStoreManager.h>
|
||||
#include <WebContent/PageClient.h>
|
||||
@@ -50,7 +51,7 @@ void BackingStoreManager::restart_resize_timer()
|
||||
|
||||
void BackingStoreManager::reallocate_backing_stores(Gfx::IntSize size)
|
||||
{
|
||||
auto skia_backend_context = m_navigable->skia_backend_context();
|
||||
auto skia_backend_context = Gfx::SkiaBackendContext::the();
|
||||
|
||||
RefPtr<Gfx::PaintingSurface> front_store;
|
||||
RefPtr<Gfx::PaintingSurface> back_store;
|
||||
@@ -119,11 +120,11 @@ void BackingStoreManager::reallocate_backing_stores(Gfx::IntSize size)
|
||||
|
||||
#ifdef USE_VULKAN
|
||||
if (skia_backend_context) {
|
||||
front_store = Gfx::PaintingSurface::create_with_size(skia_backend_context, size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
front_store = Gfx::PaintingSurface::create_with_size(size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
front_store->on_flush = [front_bitmap](auto& surface) {
|
||||
surface.read_into_bitmap(*front_bitmap);
|
||||
};
|
||||
back_store = Gfx::PaintingSurface::create_with_size(skia_backend_context, size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
back_store = Gfx::PaintingSurface::create_with_size(size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
back_store->on_flush = [back_bitmap](auto& surface) {
|
||||
surface.read_into_bitmap(*back_bitmap);
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <LibGfx/Font/Font.h>
|
||||
#include <LibGfx/PainterSkia.h>
|
||||
#include <LibGfx/PathSkia.h>
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibGfx/SkiaUtils.h>
|
||||
#include <LibWeb/CSS/ComputedValues.h>
|
||||
#include <LibWeb/Painting/DisplayListPlayerSkia.h>
|
||||
@@ -35,11 +36,6 @@
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
DisplayListPlayerSkia::DisplayListPlayerSkia(RefPtr<Gfx::SkiaBackendContext> context)
|
||||
: m_context(context)
|
||||
{
|
||||
}
|
||||
|
||||
DisplayListPlayerSkia::DisplayListPlayerSkia()
|
||||
{
|
||||
}
|
||||
@@ -97,8 +93,8 @@ static SkM44 to_skia_matrix4x4(Gfx::FloatMatrix4x4 const& matrix)
|
||||
|
||||
void DisplayListPlayerSkia::flush()
|
||||
{
|
||||
if (m_context)
|
||||
m_context->flush_and_submit(&surface().sk_surface());
|
||||
if (auto context = Gfx::SkiaBackendContext::the())
|
||||
context->flush_and_submit(&surface().sk_surface());
|
||||
surface().flush();
|
||||
}
|
||||
|
||||
@@ -143,7 +139,7 @@ void DisplayListPlayerSkia::draw_external_content(DrawExternalContent const& com
|
||||
auto bitmap = command.source->current_bitmap();
|
||||
if (!bitmap)
|
||||
return;
|
||||
if (m_context && !bitmap->ensure_sk_image(*m_context))
|
||||
if (Gfx::SkiaBackendContext::the() && !bitmap->ensure_sk_image(*Gfx::SkiaBackendContext::the()))
|
||||
return;
|
||||
auto dst_rect = to_skia_rect(command.dst_rect);
|
||||
SkRect src_rect = SkRect::MakeIWH(bitmap->width(), bitmap->height());
|
||||
@@ -155,7 +151,7 @@ void DisplayListPlayerSkia::draw_external_content(DrawExternalContent const& com
|
||||
|
||||
void DisplayListPlayerSkia::draw_scaled_immutable_bitmap(DrawScaledImmutableBitmap const& command)
|
||||
{
|
||||
if (m_context && !command.bitmap->ensure_sk_image(*m_context))
|
||||
if (Gfx::SkiaBackendContext::the() && !command.bitmap->ensure_sk_image(*Gfx::SkiaBackendContext::the()))
|
||||
return;
|
||||
|
||||
auto dst_rect = to_skia_rect(command.dst_rect);
|
||||
@@ -171,7 +167,7 @@ void DisplayListPlayerSkia::draw_scaled_immutable_bitmap(DrawScaledImmutableBitm
|
||||
|
||||
void DisplayListPlayerSkia::draw_repeated_immutable_bitmap(DrawRepeatedImmutableBitmap const& command)
|
||||
{
|
||||
if (m_context && !command.bitmap->ensure_sk_image(*m_context))
|
||||
if (Gfx::SkiaBackendContext::the() && !command.bitmap->ensure_sk_image(*Gfx::SkiaBackendContext::the()))
|
||||
return;
|
||||
|
||||
SkMatrix matrix;
|
||||
@@ -488,7 +484,7 @@ SkPaint DisplayListPlayerSkia::paint_style_to_skia_paint(Painting::SVGPaintServe
|
||||
if (tile_size.is_empty())
|
||||
return {};
|
||||
|
||||
auto tile_surface = Gfx::PaintingSurface::create_with_size(m_context, tile_size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
auto tile_surface = Gfx::PaintingSurface::create_with_size(tile_size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
|
||||
execute_display_list_into_surface(*pattern->tile_display_list(), *tile_surface);
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibWeb/Painting/DisplayList.h>
|
||||
#include <LibWeb/Painting/DisplayListCommand.h>
|
||||
#include <LibWeb/Painting/DisplayListRecorder.h>
|
||||
@@ -18,7 +17,6 @@ namespace Web::Painting {
|
||||
|
||||
class DisplayListPlayerSkia final : public DisplayListPlayer {
|
||||
public:
|
||||
DisplayListPlayerSkia(RefPtr<Gfx::SkiaBackendContext>);
|
||||
DisplayListPlayerSkia();
|
||||
~DisplayListPlayerSkia();
|
||||
|
||||
@@ -59,8 +57,6 @@ private:
|
||||
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;
|
||||
|
||||
SkPaint paint_style_to_skia_paint(SVGPaintServerPaintStyle const&, Gfx::FloatRect const& bounding_rect);
|
||||
|
||||
RefPtr<Gfx::SkiaBackendContext> m_context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ RefPtr<Gfx::PaintingSurface> SVGDecodedImageData::render_to_surface(Gfx::IntSize
|
||||
if (m_cached_rendered_surfaces.size() > 10)
|
||||
m_cached_rendered_surfaces.remove(m_cached_rendered_surfaces.begin());
|
||||
|
||||
auto surface = Gfx::PaintingSurface::create_with_size(m_document->navigable()->skia_backend_context(), size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
auto surface = Gfx::PaintingSurface::create_with_size(size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
|
||||
auto display_list = record_display_list(size);
|
||||
if (!display_list)
|
||||
return nullptr;
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/WebGL2RenderingContextPrototype.h>
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/WebGL/EventNames.h>
|
||||
@@ -34,7 +34,7 @@ JS::ThrowCompletionOr<GC::Ptr<WebGL2RenderingContext>> WebGL2RenderingContext::c
|
||||
// We should be coming here from getContext being called on a wrapped <canvas> element.
|
||||
auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.vm(), options));
|
||||
|
||||
auto skia_backend_context = canvas_element.navigable()->traversable_navigable()->skia_backend_context();
|
||||
auto skia_backend_context = Gfx::SkiaBackendContext::the();
|
||||
if (!skia_backend_context) {
|
||||
fire_webgl_context_creation_error(canvas_element);
|
||||
return GC::Ptr<WebGL2RenderingContext> { nullptr };
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/WebGLRenderingContextPrototype.h>
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/WebGL/EventNames.h>
|
||||
@@ -50,7 +50,7 @@ JS::ThrowCompletionOr<GC::Ptr<WebGLRenderingContext>> WebGLRenderingContext::cre
|
||||
// We should be coming here from getContext being called on a wrapped <canvas> element.
|
||||
auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.vm(), options));
|
||||
|
||||
auto skia_backend_context = canvas_element.navigable()->traversable_navigable()->skia_backend_context();
|
||||
auto skia_backend_context = Gfx::SkiaBackendContext::the();
|
||||
if (!skia_backend_context) {
|
||||
fire_webgl_context_creation_error(canvas_element);
|
||||
return GC::Ptr<WebGLRenderingContext> { nullptr };
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <LibCrypto/OpenSSLForward.h>
|
||||
#include <LibGfx/Font/FontDatabase.h>
|
||||
#include <LibGfx/Font/PathFontProvider.h>
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibIPC/ConnectionFromClient.h>
|
||||
#include <LibIPC/TransportHandle.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
@@ -198,7 +199,12 @@ ErrorOr<int> ladybird_main(Main::Arguments arguments)
|
||||
Web::set_browser_process_executable_path(executable_path);
|
||||
|
||||
// Always use the CPU backend for tests, as the GPU backend is not deterministic
|
||||
WebContent::PageClient::set_use_skia_painter(force_cpu_painting ? WebContent::PageClient::UseSkiaPainter::CPUBackend : WebContent::PageClient::UseSkiaPainter::GPUBackendIfAvailable);
|
||||
if (force_cpu_painting) {
|
||||
WebContent::PageClient::set_use_skia_painter(WebContent::PageClient::UseSkiaPainter::CPUBackend);
|
||||
} else {
|
||||
Gfx::SkiaBackendContext::initialize_gpu_backend();
|
||||
WebContent::PageClient::set_use_skia_painter(WebContent::PageClient::UseSkiaPainter::GPUBackendIfAvailable);
|
||||
}
|
||||
|
||||
WebContent::PageClient::set_is_headless(is_headless);
|
||||
|
||||
|
||||
8
Tests/LibWeb/Crash/HTML/canvas-2d-in-detached-doc.html
Normal file
8
Tests/LibWeb/Crash/HTML/canvas-2d-in-detached-doc.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
var doc = document.implementation.createHTMLDocument("");
|
||||
var canvas = doc.createElement("canvas");
|
||||
doc.body.appendChild(canvas);
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillRect(0, 0, 50, 50);
|
||||
</script>
|
||||
11
Tests/LibWeb/Crash/HTML/canvas-detached-doc-toDataURL.html
Normal file
11
Tests/LibWeb/Crash/HTML/canvas-detached-doc-toDataURL.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script>
|
||||
var doc = document.implementation.createHTMLDocument('');
|
||||
var canvas = doc.createElement('canvas');
|
||||
canvas.width = 100;
|
||||
canvas.height = 100;
|
||||
doc.body.appendChild(canvas);
|
||||
canvas.toDataURL();
|
||||
</script>
|
||||
</body>
|
||||
11
Tests/LibWeb/Crash/HTML/canvas-webgl-in-detached-doc.html
Normal file
11
Tests/LibWeb/Crash/HTML/canvas-webgl-in-detached-doc.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script>
|
||||
var doc = document.implementation.createHTMLDocument('');
|
||||
var canvas = doc.createElement('canvas');
|
||||
canvas.width = 100;
|
||||
canvas.height = 100;
|
||||
doc.body.appendChild(canvas);
|
||||
canvas.getContext('webgl');
|
||||
</script>
|
||||
</body>
|
||||
Reference in New Issue
Block a user