Sfoglia il codice sorgente

LibWeb: Add support for nested painting command executors

This adds two new CommandResults: ContinueWithNestedExecutor and
ContinueWithParentExecutor.

ContinueWithNestedExecutor switches the command executor to the result
of calling `.nested_executor()` on the current CommandExecutor.

ContinueWithParentExecutor returns to the previous command executor
(i.e. what it was before the last ContinueWithNestedExecutor).
MacDue 1 anno fa
parent
commit
6333159108

+ 12 - 5
Userland/Libraries/LibWeb/Painting/CommandList.cpp

@@ -112,6 +112,8 @@ void CommandList::execute(CommandExecutor& executor)
 
     HashTable<u32> skipped_sample_corner_commands;
     size_t next_command_index = 0;
+    Vector<CommandExecutor&, 16> executor_stack;
+    CommandExecutor* current_executor = &executor;
     while (next_command_index < m_commands.size()) {
         if (m_commands[next_command_index].skip) {
             next_command_index++;
@@ -120,7 +122,7 @@ void CommandList::execute(CommandExecutor& executor)
 
         auto& command = m_commands[next_command_index++].command;
         auto bounding_rect = command_bounding_rectangle(command);
-        if (bounding_rect.has_value() && (bounding_rect->is_empty() || executor.would_be_fully_clipped_by_painter(*bounding_rect))) {
+        if (bounding_rect.has_value() && (bounding_rect->is_empty() || current_executor->would_be_fully_clipped_by_painter(*bounding_rect))) {
             if (command.has<SampleUnderCorners>()) {
                 auto const& sample_under_corners = command.get<SampleUnderCorners>();
                 skipped_sample_corner_commands.set(sample_under_corners.id);
@@ -140,9 +142,9 @@ void CommandList::execute(CommandExecutor& executor)
             }
         }
 
-#define HANDLE_COMMAND(command_type, executor_method)                   \
-    if (command.has<command_type>()) {                                  \
-        result = executor.executor_method(command.get<command_type>()); \
+#define HANDLE_COMMAND(command_type, executor_method)                            \
+    if (command.has<command_type>()) {                                           \
+        result = current_executor->executor_method(command.get<command_type>()); \
     }
 
         // clang-format off
@@ -179,7 +181,12 @@ void CommandList::execute(CommandExecutor& executor)
         else VERIFY_NOT_REACHED();
         // clang-format on
 
-        if (result == CommandResult::SkipStackingContext) {
+        if (result == CommandResult::ContinueWithNestedExecutor) {
+            executor_stack.append(*current_executor);
+            current_executor = &current_executor->nested_executor();
+        } else if (result == CommandResult::ContinueWithParentExecutor) {
+            current_executor = &executor_stack.take_last();
+        } else if (result == CommandResult::SkipStackingContext) {
             auto stacking_context_nesting_level = 1;
             while (next_command_index < m_commands.size()) {
                 if (m_commands[next_command_index].command.has<PushStackingContext>()) {

+ 3 - 0
Userland/Libraries/LibWeb/Painting/CommandList.h

@@ -41,6 +41,8 @@ namespace Web::Painting {
 enum class CommandResult {
     Continue,
     SkipStackingContext,
+    ContinueWithNestedExecutor,
+    ContinueWithParentExecutor
 };
 
 class CommandExecutor {
@@ -82,6 +84,7 @@ public:
     virtual void prepare_to_execute([[maybe_unused]] size_t corner_clip_max_depth) { }
     virtual bool needs_update_immutable_bitmap_texture_cache() const = 0;
     virtual void update_immutable_bitmap_texture_cache(HashMap<u32, Gfx::ImmutableBitmap const*>&) = 0;
+    virtual CommandExecutor& nested_executor() { VERIFY_NOT_REACHED(); }
 };
 
 class CommandList {