BackingStoreManager.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibCore/Timer.h>
  7. #include <LibWeb/HTML/TraversableNavigable.h>
  8. #include <WebContent/BackingStoreManager.h>
  9. #include <WebContent/PageClient.h>
  10. namespace WebContent {
  11. BackingStoreManager::BackingStoreManager(PageClient& page_client)
  12. : m_page_client(page_client)
  13. {
  14. m_backing_store_shrink_timer = Core::Timer::create_single_shot(3000, [this] {
  15. resize_backing_stores_if_needed(WindowResizingInProgress::No);
  16. });
  17. }
  18. void BackingStoreManager::restart_resize_timer()
  19. {
  20. m_backing_store_shrink_timer->restart();
  21. }
  22. void BackingStoreManager::resize_backing_stores_if_needed(WindowResizingInProgress window_resize_in_progress)
  23. {
  24. auto css_pixels_viewport_rect = m_page_client.page().top_level_traversable()->viewport_rect();
  25. auto viewport_size = m_page_client.page().css_to_device_rect(css_pixels_viewport_rect).size();
  26. if (viewport_size.is_empty())
  27. return;
  28. Web::DevicePixelSize minimum_needed_size;
  29. if (window_resize_in_progress == WindowResizingInProgress::Yes) {
  30. // Pad the minimum needed size so that we don't have to keep reallocating backing stores while the window is being resized.
  31. minimum_needed_size = { viewport_size.width() + 256, viewport_size.height() + 256 };
  32. } else {
  33. // If we're not in the middle of a resize, we can shrink the backing store size to match the viewport size.
  34. minimum_needed_size = viewport_size;
  35. m_front_bitmap.clear();
  36. m_back_bitmap.clear();
  37. }
  38. auto old_front_bitmap_id = m_front_bitmap_id;
  39. auto old_back_bitmap_id = m_back_bitmap_id;
  40. auto reallocate_backing_store_if_needed = [&](RefPtr<Gfx::Bitmap>& bitmap, int& id) {
  41. if (!bitmap || !bitmap->size().contains(minimum_needed_size.to_type<int>())) {
  42. if (auto new_bitmap_or_error = Gfx::Bitmap::create_shareable(Gfx::BitmapFormat::BGRA8888, minimum_needed_size.to_type<int>()); !new_bitmap_or_error.is_error()) {
  43. bitmap = new_bitmap_or_error.release_value();
  44. id = m_next_bitmap_id++;
  45. }
  46. }
  47. };
  48. reallocate_backing_store_if_needed(m_front_bitmap, m_front_bitmap_id);
  49. reallocate_backing_store_if_needed(m_back_bitmap, m_back_bitmap_id);
  50. auto& front_bitmap = m_front_bitmap;
  51. auto& back_bitmap = m_back_bitmap;
  52. if (m_front_bitmap_id != old_front_bitmap_id || m_back_bitmap_id != old_back_bitmap_id) {
  53. m_page_client.page_did_allocate_backing_stores(m_front_bitmap_id, front_bitmap->to_shareable_bitmap(), m_back_bitmap_id, back_bitmap->to_shareable_bitmap());
  54. }
  55. }
  56. void BackingStoreManager::swap_back_and_front()
  57. {
  58. swap(m_front_bitmap, m_back_bitmap);
  59. swap(m_front_bitmap_id, m_back_bitmap_id);
  60. }
  61. }