2D canvas contexts started publishing partial frames after canvas rasterization moved into the Compositor. WebContent still splits large recorded command lists after 64 commands, but every split batch was sent through the same compositor path as the end-of-frame flush. The compositor replayed each batch into the DrawCanvas source surface, so a pending present could sample a canvas after clear and before the rest of the next frame had been drawn. Canvas-heavy pages such as slither.com then flickered between partial and complete frames. Carry an explicit commit bit with 2D canvas command updates. Non-commit batches now update a hidden working canvas in the Compositor, while the display-list-visible surface keeps the last committed canvas contents. The end-of-frame canvas preparation sends the commit boundary, including the empty-commit case needed when the auto-flush consumed all recorded commands before prepare_for_compositing() runs.
88 lines
2 KiB
C++
88 lines
2 KiB
C++
/*
|
|
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/AtomicRefCounted.h>
|
|
#include <AK/Function.h>
|
|
#include <AK/NonnullOwnPtr.h>
|
|
#include <AK/RefPtr.h>
|
|
#include <LibGfx/Color.h>
|
|
#include <LibGfx/Size.h>
|
|
#include <LibGfx/SkiaBackendContext.h>
|
|
|
|
#ifdef USE_VULKAN_DMABUF_IMAGES
|
|
namespace Gfx {
|
|
|
|
struct VulkanImage;
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef AK_OS_MACOS
|
|
# include <LibGfx/MetalContext.h>
|
|
#endif
|
|
|
|
class SkCanvas;
|
|
class SkSurface;
|
|
|
|
namespace Gfx {
|
|
|
|
class SharedImage;
|
|
|
|
class PaintingSurface : public AtomicRefCounted<PaintingSurface> {
|
|
public:
|
|
enum class Origin {
|
|
TopLeft,
|
|
BottomLeft,
|
|
};
|
|
|
|
Function<void(PaintingSurface&)> on_flush;
|
|
|
|
static NonnullRefPtr<PaintingSurface> create_with_size(IntSize size, BitmapFormat color_type, AlphaType alpha_type, RefPtr<SkiaBackendContext> = {});
|
|
static NonnullRefPtr<PaintingSurface> wrap_bitmap(Bitmap&);
|
|
|
|
#ifdef AK_OS_MACOS
|
|
static NonnullRefPtr<PaintingSurface> create_from_shared_image_buffer(SharedImageBuffer&, NonnullRefPtr<SkiaBackendContext>, Origin = Origin::TopLeft);
|
|
#endif
|
|
|
|
#ifdef USE_VULKAN_DMABUF_IMAGES
|
|
static NonnullRefPtr<PaintingSurface> create_from_vkimage(NonnullRefPtr<SkiaBackendContext> context, NonnullRefPtr<VulkanImage> vulkan_image, Origin origin);
|
|
#endif
|
|
|
|
NonnullRefPtr<Bitmap> snapshot_bitmap() const;
|
|
SharedImage snapshot_into_shared_image() const;
|
|
|
|
void read_into_bitmap(Bitmap&, IntPoint source_position = {}) const;
|
|
void write_from_bitmap(Bitmap const&);
|
|
void copy_from_surface(PaintingSurface&);
|
|
|
|
void notify_content_will_change();
|
|
|
|
IntSize size() const;
|
|
IntRect rect() const;
|
|
|
|
SkCanvas& canvas() const;
|
|
SkSurface& sk_surface() const;
|
|
|
|
template<typename T>
|
|
T sk_image_snapshot() const;
|
|
|
|
RefPtr<SkiaBackendContext> skia_backend_context() const;
|
|
|
|
void flush();
|
|
|
|
~PaintingSurface();
|
|
|
|
private:
|
|
struct Impl;
|
|
|
|
PaintingSurface(NonnullOwnPtr<Impl>&&);
|
|
|
|
NonnullOwnPtr<Impl> m_impl;
|
|
};
|
|
|
|
}
|