Flutter Impeller
draw_order_resolver.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include "flutter/fml/logging.h"
9 
10 namespace impeller {
11 
12 DrawOrderResolver::DrawOrderResolver() : draw_order_layers_({{}}){};
13 
14 void DrawOrderResolver::AddElement(size_t element_index, bool is_opaque) {
15  DrawOrderLayer& layer = draw_order_layers_.back();
16  if (is_opaque) {
17  layer.opaque_elements.push_back(element_index);
18  } else {
19  layer.dependent_elements.push_back(element_index);
20  }
21 }
22 void DrawOrderResolver::PushClip(size_t element_index) {
23  draw_order_layers_.back().dependent_elements.push_back(element_index);
24  draw_order_layers_.push_back({});
25 };
26 
28  if (draw_order_layers_.size() == 1u) {
29  // This is likely recoverable, so don't assert.
30  VALIDATION_LOG << "Attemped to pop the first draw order clip layer. This "
31  "may be a bug in `EntityPass`.";
32  return;
33  }
34 
35  DrawOrderLayer& layer = draw_order_layers_.back();
36  DrawOrderLayer& parent_layer =
37  draw_order_layers_[draw_order_layers_.size() - 2];
38 
39  layer.WriteCombinedDraws(parent_layer.dependent_elements, 0, 0);
40 
41  draw_order_layers_.pop_back();
42 }
43 
45  FML_DCHECK(draw_order_layers_.size() >= 1u);
46 
47  size_t layer_count = draw_order_layers_.size();
48 
49  // Pop all clip layers.
50  while (draw_order_layers_.size() > 1u) {
51  PopClip();
52  }
53 
54  // Move the root layer items into the sorted list.
55  DrawOrderLayer& layer = draw_order_layers_.back();
56  if (!first_root_flush_.has_value()) {
57  // Record the first flush.
58  first_root_flush_ = std::move(layer);
59  layer = {};
60  } else {
61  // Write subsequent flushes into the sorted root list.
62  layer.WriteCombinedDraws(sorted_elements_, 0, 0);
63  layer.opaque_elements.clear();
64  layer.dependent_elements.clear();
65  }
66 
67  // Refill with empty layers.
68  draw_order_layers_.resize(layer_count);
69 }
70 
72  size_t opaque_skip_count,
73  size_t translucent_skip_count) const {
74  FML_DCHECK(draw_order_layers_.size() == 1u)
75  << "Attempted to get sorted draws before all clips were popped.";
76 
77  ElementRefs sorted_elements;
78  sorted_elements.reserve(
79  (first_root_flush_.has_value()
80  ? first_root_flush_->opaque_elements.size() +
81  first_root_flush_->dependent_elements.size()
82  : 0u) +
83  sorted_elements_.size() +
84  draw_order_layers_.back().opaque_elements.size() +
85  draw_order_layers_.back().dependent_elements.size());
86 
87  // Write all flushed items.
88  if (first_root_flush_.has_value()) {
89  first_root_flush_->WriteCombinedDraws(sorted_elements, opaque_skip_count,
90  translucent_skip_count);
91  }
92  sorted_elements.insert(sorted_elements.end(), sorted_elements_.begin(),
93  sorted_elements_.end());
94 
95  // Write any remaining non-flushed items.
96  draw_order_layers_.back().WriteCombinedDraws(
97  sorted_elements, first_root_flush_.has_value() ? 0 : opaque_skip_count,
98  first_root_flush_.has_value() ? 0 : translucent_skip_count);
99 
100  return sorted_elements;
101 }
102 
103 void DrawOrderResolver::DrawOrderLayer::WriteCombinedDraws(
104  ElementRefs& destination,
105  size_t opaque_skip_count,
106  size_t translucent_skip_count) const {
107  FML_DCHECK(opaque_skip_count <= opaque_elements.size());
108  FML_DCHECK(translucent_skip_count <= dependent_elements.size());
109 
110  destination.reserve(destination.size() + //
111  opaque_elements.size() - opaque_skip_count + //
112  dependent_elements.size() - translucent_skip_count);
113 
114  // Draw backdrop-independent elements in reverse order first.
115  destination.insert(destination.end(), opaque_elements.rbegin(),
116  opaque_elements.rend() - opaque_skip_count);
117  // Then, draw backdrop-dependent elements in their original order.
118  destination.insert(destination.end(),
119  dependent_elements.begin() + translucent_skip_count,
120  dependent_elements.end());
121 }
122 
123 } // namespace impeller
void PushClip(size_t element_index)
ElementRefs GetSortedDraws(size_t opaque_skip_count, size_t translucent_skip_count) const
Returns the sorted draws for the current draw order layer. This should only be called after all recor...
std::vector< size_t > ElementRefs
void AddElement(size_t element_index, bool is_opaque)
#define VALIDATION_LOG
Definition: validation.h:91