1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:07:35 +00:00

LibAccelGfx+WebContent: Use the same Painter across page repaints

In the upcoming changes, Painter will be used to store the state of
OpenGL context. For example, if Painter is aware of the shader that
have already been loaded, it will be possible to reuse them across
repaints. Also, it would be possible to manage state of loaded textures
and add/remove them depending on which ones are present in the next
sequence of painting commands.
This commit is contained in:
Aliaksandr Kalenik 2023-11-02 00:01:16 +01:00 committed by Andreas Kling
parent e73a1803ac
commit 1e85bf221d
7 changed files with 54 additions and 27 deletions

View file

@ -69,6 +69,12 @@ OwnPtr<Context> Context::create()
};
EGLContext egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attributes);
EGLBoolean result = eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context);
if (result == EGL_FALSE) {
dbgln("eglMakeCurrent failed");
VERIFY_NOT_REACHED();
}
return make<Context>(egl_display, egl_context, egl_config);
}

View file

@ -33,17 +33,23 @@ static ColorComponents gfx_color_to_opengl_color(Gfx::Color color)
Gfx::FloatRect Painter::to_clip_space(Gfx::FloatRect const& screen_rect) const
{
float x = 2.0f * screen_rect.x() / m_canvas.width() - 1.0f;
float y = -1.0f + 2.0f * screen_rect.y() / m_canvas.height();
float x = 2.0f * screen_rect.x() / m_canvas->width() - 1.0f;
float y = -1.0f + 2.0f * screen_rect.y() / m_canvas->height();
float width = 2.0f * screen_rect.width() / m_canvas.width();
float height = 2.0f * screen_rect.height() / m_canvas.height();
float width = 2.0f * screen_rect.width() / m_canvas->width();
float height = 2.0f * screen_rect.height() / m_canvas->height();
return { x, y, width, height };
}
Painter::Painter(Canvas& canvas)
: m_canvas(canvas)
OwnPtr<Painter> Painter::create()
{
auto& context = Context::the();
return make<Painter>(context);
}
Painter::Painter(Context& context)
: m_context(context)
{
m_state_stack.empend(State());
}
@ -171,7 +177,7 @@ void Painter::restore()
void Painter::flush()
{
m_canvas.flush();
m_canvas->flush();
}
}

View file

@ -8,6 +8,7 @@
#include <AK/Noncopyable.h>
#include <AK/Vector.h>
#include <LibAccelGfx/Canvas.h>
#include <LibAccelGfx/Forward.h>
#include <LibGfx/AffineTransform.h>
#include <LibGfx/Forward.h>
@ -19,7 +20,9 @@ class Painter {
AK_MAKE_NONMOVABLE(Painter);
public:
Painter(Canvas&);
static OwnPtr<Painter> create();
Painter(Context&);
~Painter();
void clear(Gfx::Color);
@ -33,10 +36,12 @@ public:
void fill_rect(Gfx::FloatRect, Gfx::Color);
void fill_rect(Gfx::IntRect, Gfx::Color);
private:
void set_canvas(Canvas& canvas) { m_canvas = canvas; }
void flush();
Canvas& m_canvas;
private:
Context& m_context;
Optional<Canvas> m_canvas;
struct State {
Gfx::AffineTransform transform;

View file

@ -8,16 +8,14 @@
namespace Web::Painting {
PaintingCommandExecutorGPU::PaintingCommandExecutorGPU(Gfx::Bitmap& bitmap)
: m_target_bitmap(bitmap)
, m_canvas(AccelGfx::Canvas::create(AccelGfx::Context::the(), bitmap))
, m_painter(m_canvas)
PaintingCommandExecutorGPU::PaintingCommandExecutorGPU(AccelGfx::Painter& painter)
: m_painter(painter)
{
}
PaintingCommandExecutorGPU::~PaintingCommandExecutorGPU()
{
m_canvas.flush();
m_painter.flush();
}
CommandResult PaintingCommandExecutorGPU::draw_text_run(Color const&, Gfx::IntPoint const&, String const&, Gfx::Font const&)

View file

@ -50,15 +50,13 @@ public:
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;
PaintingCommandExecutorGPU(Gfx::Bitmap& bitmap);
PaintingCommandExecutorGPU(AccelGfx::Painter& painter);
~PaintingCommandExecutorGPU() override;
private:
AccelGfx::Painter& painter() { return m_painter; }
Gfx::Bitmap& m_target_bitmap;
AccelGfx::Canvas m_canvas;
AccelGfx::Painter m_painter;
AccelGfx::Painter& m_painter;
};
}

View file

@ -27,6 +27,13 @@
namespace WebContent {
static bool s_use_gpu_painter = false;
void PageHost::set_use_gpu_painter()
{
s_use_gpu_painter = true;
}
PageHost::PageHost(ConnectionFromClient& client)
: m_client(client)
, m_page(make<Web::Page>(*this))
@ -36,17 +43,16 @@ PageHost::PageHost(ConnectionFromClient& client)
m_client.async_did_invalidate_content_rect({ m_invalidation_rect.x().value(), m_invalidation_rect.y().value(), m_invalidation_rect.width().value(), m_invalidation_rect.height().value() });
m_invalidation_rect = {};
});
if (s_use_gpu_painter) {
#ifdef HAS_ACCELERATED_GRAPHICS
m_accelerated_painter = AccelGfx::Painter::create();
#endif
}
}
PageHost::~PageHost() = default;
static bool s_use_gpu_painter = false;
void PageHost::set_use_gpu_painter()
{
s_use_gpu_painter = true;
}
void PageHost::set_has_focus(bool has_focus)
{
m_has_focus = has_focus;
@ -158,8 +164,11 @@ void PageHost::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& targ
if (s_use_gpu_painter) {
#ifdef HAS_ACCELERATED_GRAPHICS
Web::Painting::PaintingCommandExecutorGPU painting_command_executor(target);
auto canvas = AccelGfx::Canvas::create(AccelGfx::Context::the(), target);
m_accelerated_painter->set_canvas(canvas);
Web::Painting::PaintingCommandExecutorGPU painting_command_executor(*m_accelerated_painter);
recording_painter.execute(painting_command_executor);
m_accelerated_painter->flush();
#endif
} else {
Web::Painting::PaintingCommandExecutorCPU painting_command_executor(target);

View file

@ -7,6 +7,7 @@
#pragma once
#include <LibAccelGfx/Forward.h>
#include <LibGfx/Rect.h>
#include <LibWeb/Page/Page.h>
#include <LibWeb/PixelUnits.h>
@ -139,6 +140,10 @@ private:
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
RefPtr<WebDriverConnection> m_webdriver;
#ifdef HAS_ACCELERATED_GRAPHICS
OwnPtr<AccelGfx::Painter> m_accelerated_painter;
#endif
};
}