diff --git a/Libraries/LibWebView/ViewImplementation.cpp b/Libraries/LibWebView/ViewImplementation.cpp index 02b4ba751ac..3b9586405df 100644 --- a/Libraries/LibWebView/ViewImplementation.cpp +++ b/Libraries/LibWebView/ViewImplementation.cpp @@ -589,6 +589,7 @@ void ViewImplementation::initialize_client(CreateNewClient create_new_client) client().async_set_window_handle(m_client_state.page_index, m_client_state.client_handle); client().async_set_device_pixels_per_css_pixel(m_client_state.page_index, m_device_pixel_ratio); + client().async_set_maximum_frames_per_second(m_client_state.page_index, m_maximum_frames_per_second); client().async_set_system_visibility_state(m_client_state.page_index, m_system_visibility_state); if (auto webdriver_content_ipc_path = Application::browser_options().webdriver_content_ipc_path; webdriver_content_ipc_path.has_value()) diff --git a/Libraries/LibWebView/ViewImplementation.h b/Libraries/LibWebView/ViewImplementation.h index a887fc11f18..e76b064ad66 100644 --- a/Libraries/LibWebView/ViewImplementation.h +++ b/Libraries/LibWebView/ViewImplementation.h @@ -72,6 +72,7 @@ public: void reset_zoom(); float zoom_level() const { return m_zoom_level; } float device_pixel_ratio() const { return m_device_pixel_ratio; } + double maximum_frames_per_second() const { return m_maximum_frames_per_second; } void enqueue_input_event(Web::InputEvent); void did_finish_handling_input_event(Badge, Web::EventResult event_result); @@ -288,6 +289,7 @@ protected: float m_zoom_level { 1.0 }; float m_device_pixel_ratio { 1.0 }; + double m_maximum_frames_per_second { 60.0 }; Queue m_pending_input_events; diff --git a/Services/WebContent/ConnectionFromClient.cpp b/Services/WebContent/ConnectionFromClient.cpp index fb41343ee73..70c84ee9f1e 100644 --- a/Services/WebContent/ConnectionFromClient.cpp +++ b/Services/WebContent/ConnectionFromClient.cpp @@ -1158,6 +1158,12 @@ void ConnectionFromClient::set_device_pixels_per_css_pixel(u64 page_id, float de page->set_device_pixels_per_css_pixel(device_pixels_per_css_pixel); } +void ConnectionFromClient::set_maximum_frames_per_second(u64 page_id, double maximum_frames_per_second) +{ + if (auto page = this->page(page_id); page.has_value()) + page->set_maximum_frames_per_second(maximum_frames_per_second); +} + void ConnectionFromClient::set_window_position(u64 page_id, Web::DevicePixelPoint position) { if (auto page = this->page(page_id); page.has_value()) diff --git a/Services/WebContent/ConnectionFromClient.h b/Services/WebContent/ConnectionFromClient.h index 4b636395dd9..2d3c334e7f1 100644 --- a/Services/WebContent/ConnectionFromClient.h +++ b/Services/WebContent/ConnectionFromClient.h @@ -112,6 +112,7 @@ private: virtual void set_has_focus(u64 page_id, bool) override; virtual void set_is_scripting_enabled(u64 page_id, bool) override; virtual void set_device_pixels_per_css_pixel(u64 page_id, float) override; + virtual void set_maximum_frames_per_second(u64 page_id, double) override; virtual void set_window_position(u64 page_id, Web::DevicePixelPoint) override; virtual void set_window_size(u64 page_id, Web::DevicePixelSize) override; virtual void did_update_window_rect(u64 page_id) override; diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index f6975a70cf6..409513908cf 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -68,7 +68,11 @@ PageClient::PageClient(PageHost& owner, u64 id) { setup_palette(); - int refresh_interval = 1000 / 60; // FIXME: Account for the actual refresh rate of the display + // FIXME: This removes the decimal part, so the refresh interval will actually be higher than the maximum FPS. + // For example, 60 FPS = 1000ms / 60 = 16.6666...ms, but it will become 16ms, making the interval equivalent + // to 62.5 FPS. + int refresh_interval = static_cast(1000.0 / m_maximum_frames_per_second); + m_paint_refresh_timer = Core::Timer::create_repeating(refresh_interval, [] { Web::HTML::main_thread_event_loop().queue_task_to_update_the_rendering(); }); @@ -202,6 +206,19 @@ void PageClient::set_viewport_size(Web::DevicePixelSize const& size) page().top_level_traversable()->set_viewport_size(page().device_to_css_size(size)); } +void PageClient::set_maximum_frames_per_second(u64 maximum_frames_per_second) +{ + m_maximum_frames_per_second = maximum_frames_per_second; + + // FIXME: This removes the decimal part, so the refresh interval will actually be higher than the maximum FPS. + // For example, 60 FPS = 1000ms / 60 = 16.6666...ms, but it will become 16ms, making the interval equivalent + // to 62.5 FPS. + int refresh_interval = static_cast(1000.0 / m_maximum_frames_per_second); + + VERIFY(m_paint_refresh_timer); + m_paint_refresh_timer->set_interval(refresh_interval); +} + void PageClient::page_did_request_cursor_change(Gfx::Cursor const& cursor) { client().async_did_request_cursor_change(m_id, cursor); diff --git a/Services/WebContent/PageClient.h b/Services/WebContent/PageClient.h index 6f40269cbcb..242ec0d48fd 100644 --- a/Services/WebContent/PageClient.h +++ b/Services/WebContent/PageClient.h @@ -55,6 +55,7 @@ public: void set_viewport_size(Web::DevicePixelSize const&); void set_screen_rects(Vector const& rects, size_t main_screen_index) { m_screen_rect = rects[main_screen_index]; } void set_device_pixels_per_css_pixel(float device_pixels_per_css_pixel) { m_device_pixels_per_css_pixel = device_pixels_per_css_pixel; } + void set_maximum_frames_per_second(u64 maximum_frames_per_second); void set_preferred_color_scheme(Web::CSS::PreferredColorScheme); void set_preferred_contrast(Web::CSS::PreferredContrast); void set_preferred_motion(Web::CSS::PreferredMotion); @@ -186,6 +187,7 @@ private: RefPtr m_palette_impl; Web::DevicePixelRect m_screen_rect; float m_device_pixels_per_css_pixel { 1.0f }; + double m_maximum_frames_per_second { 60.0 }; u64 m_id { 0 }; bool m_has_focus { false }; diff --git a/Services/WebContent/WebContentServer.ipc b/Services/WebContent/WebContentServer.ipc index ab0e9d6f5f7..e7b6e2e6402 100644 --- a/Services/WebContent/WebContentServer.ipc +++ b/Services/WebContent/WebContentServer.ipc @@ -99,6 +99,7 @@ endpoint WebContentServer set_has_focus(u64 page_id, bool has_focus) =| set_is_scripting_enabled(u64 page_id, bool is_scripting_enabled) =| set_device_pixels_per_css_pixel(u64 page_id, float device_pixels_per_css_pixel) =| + set_maximum_frames_per_second(u64 page_id, double maximum_frames_per_second) =| set_window_position(u64 page_id, Web::DevicePixelPoint position) =| set_window_size(u64 page_id, Web::DevicePixelSize size) =|