LayoutPools.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "LayoutPools.h"
  2. #include "../../../Include/RmlUi/Core/Element.h"
  3. #include "../ControlledLifetimeResource.h"
  4. #include "../Pool.h"
  5. #include "BlockContainer.h"
  6. #include "FloatedBoxSpace.h"
  7. #include "FormattingContext.h"
  8. #include "InlineBox.h"
  9. #include "InlineContainer.h"
  10. #include "LineBox.h"
  11. #include "ReplacedFormattingContext.h"
  12. #include <algorithm>
  13. #include <cstddef>
  14. namespace Rml {
  15. template <size_t Size>
  16. struct LayoutChunk {
  17. alignas(std::max_align_t) byte buffer[Size];
  18. };
  19. static constexpr size_t ChunkSizeBig = std::max({sizeof(BlockContainer)});
  20. static constexpr size_t ChunkSizeMedium =
  21. std::max({sizeof(InlineContainer), sizeof(InlineBox), sizeof(RootBox), sizeof(FlexContainer), sizeof(TableWrapper)});
  22. static constexpr size_t ChunkSizeSmall =
  23. std::max({sizeof(ReplacedBox), sizeof(InlineLevelBox_Text), sizeof(InlineLevelBox_Atomic), sizeof(LineBox), sizeof(FloatedBoxSpace)});
  24. struct LayoutPoolsData {
  25. Pool<LayoutChunk<ChunkSizeBig>> layout_chunk_pool_big{50, true};
  26. Pool<LayoutChunk<ChunkSizeMedium>> layout_chunk_pool_medium{50, true};
  27. Pool<LayoutChunk<ChunkSizeSmall>> layout_chunk_pool_small{50, true};
  28. };
  29. static ControlledLifetimeResource<LayoutPoolsData> layout_pools_data;
  30. void LayoutPools::Initialize()
  31. {
  32. layout_pools_data.Initialize();
  33. }
  34. void LayoutPools::Shutdown()
  35. {
  36. layout_pools_data.Shutdown();
  37. }
  38. void* LayoutPools::AllocateLayoutChunk(size_t size)
  39. {
  40. static_assert(ChunkSizeBig > ChunkSizeMedium && ChunkSizeMedium > ChunkSizeSmall, "The following assumes a strict ordering of the chunk sizes.");
  41. // Note: If any change is made here, make sure a corresponding change is applied to the deallocation procedure below.
  42. if (size <= ChunkSizeSmall)
  43. return layout_pools_data->layout_chunk_pool_small.AllocateAndConstruct();
  44. else if (size <= ChunkSizeMedium)
  45. return layout_pools_data->layout_chunk_pool_medium.AllocateAndConstruct();
  46. else if (size <= ChunkSizeBig)
  47. return layout_pools_data->layout_chunk_pool_big.AllocateAndConstruct();
  48. RMLUI_ERROR;
  49. return nullptr;
  50. }
  51. void LayoutPools::DeallocateLayoutChunk(void* chunk, size_t size)
  52. {
  53. // Note: If any change is made here, make sure a corresponding change is applied to the allocation procedure above.
  54. if (size <= ChunkSizeSmall)
  55. layout_pools_data->layout_chunk_pool_small.DestroyAndDeallocate((LayoutChunk<ChunkSizeSmall>*)chunk);
  56. else if (size <= ChunkSizeMedium)
  57. layout_pools_data->layout_chunk_pool_medium.DestroyAndDeallocate((LayoutChunk<ChunkSizeMedium>*)chunk);
  58. else if (size <= ChunkSizeBig)
  59. layout_pools_data->layout_chunk_pool_big.DestroyAndDeallocate((LayoutChunk<ChunkSizeBig>*)chunk);
  60. else
  61. {
  62. RMLUI_ERROR;
  63. }
  64. }
  65. } // namespace Rml