Flutter Engine
embedded_views.h
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 
5 #ifndef FLUTTER_FLOW_EMBEDDED_VIEWS_H_
6 #define FLUTTER_FLOW_EMBEDDED_VIEWS_H_
7 
8 #include <vector>
9 
10 #include "flutter/flow/surface_frame.h"
11 #include "flutter/fml/memory/ref_counted.h"
12 #include "flutter/fml/raster_thread_merger.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkPath.h"
15 #include "third_party/skia/include/core/SkPoint.h"
16 #include "third_party/skia/include/core/SkRRect.h"
17 #include "third_party/skia/include/core/SkRect.h"
18 #include "third_party/skia/include/core/SkSize.h"
19 #include "third_party/skia/include/core/SkSurface.h"
20 
21 namespace flutter {
22 
23 // TODO(chinmaygarde): Make these enum names match the style guide.
25 
26 // Stores mutation information like clipping or transform.
27 //
28 // The `type` indicates the type of the mutation: clip_rect, transform and etc.
29 // Each `type` is paired with an object that supports the mutation. For example,
30 // if the `type` is clip_rect, `rect()` is used the represent the rect to be
31 // clipped. One mutation object must only contain one type of mutation.
32 class Mutator {
33  public:
34  Mutator(const Mutator& other) {
35  type_ = other.type_;
36  switch (other.type_) {
37  case clip_rect:
38  rect_ = other.rect_;
39  break;
40  case clip_rrect:
41  rrect_ = other.rrect_;
42  break;
43  case clip_path:
44  path_ = new SkPath(*other.path_);
45  break;
46  case transform:
47  matrix_ = other.matrix_;
48  break;
49  case opacity:
50  alpha_ = other.alpha_;
51  break;
52  default:
53  break;
54  }
55  }
56 
57  explicit Mutator(const SkRect& rect) : type_(clip_rect), rect_(rect) {}
58  explicit Mutator(const SkRRect& rrect) : type_(clip_rrect), rrect_(rrect) {}
59  explicit Mutator(const SkPath& path)
60  : type_(clip_path), path_(new SkPath(path)) {}
61  explicit Mutator(const SkMatrix& matrix)
62  : type_(transform), matrix_(matrix) {}
63  explicit Mutator(const int& alpha) : type_(opacity), alpha_(alpha) {}
64 
65  const MutatorType& GetType() const { return type_; }
66  const SkRect& GetRect() const { return rect_; }
67  const SkRRect& GetRRect() const { return rrect_; }
68  const SkPath& GetPath() const { return *path_; }
69  const SkMatrix& GetMatrix() const { return matrix_; }
70  const int& GetAlpha() const { return alpha_; }
71  float GetAlphaFloat() const { return (alpha_ / 255.0); }
72 
73  bool operator==(const Mutator& other) const {
74  if (type_ != other.type_) {
75  return false;
76  }
77  switch (type_) {
78  case clip_rect:
79  return rect_ == other.rect_;
80  case clip_rrect:
81  return rrect_ == other.rrect_;
82  case clip_path:
83  return *path_ == *other.path_;
84  case transform:
85  return matrix_ == other.matrix_;
86  case opacity:
87  return alpha_ == other.alpha_;
88  }
89 
90  return false;
91  }
92 
93  bool operator!=(const Mutator& other) const { return !operator==(other); }
94 
95  bool IsClipType() {
96  return type_ == clip_rect || type_ == clip_rrect || type_ == clip_path;
97  }
98 
100  if (type_ == clip_path) {
101  delete path_;
102  }
103  };
104 
105  private:
106  MutatorType type_;
107 
108  union {
109  SkRect rect_;
110  SkRRect rrect_;
111  SkMatrix matrix_;
112  SkPath* path_;
113  int alpha_;
114  };
115 
116 }; // Mutator
117 
118 // A stack of mutators that can be applied to an embedded platform view.
119 //
120 // The stack may include mutators like transforms and clips, each mutator
121 // applies to all the mutators that are below it in the stack and to the
122 // embedded view.
123 //
124 // For example consider the following stack: [T1, T2, T3], where T1 is the top
125 // of the stack and T3 is the bottom of the stack. Applying this mutators stack
126 // to a platform view P1 will result in T1(T2(T2(P1))).
128  public:
129  MutatorsStack() = default;
130 
131  void PushClipRect(const SkRect& rect);
132  void PushClipRRect(const SkRRect& rrect);
133  void PushClipPath(const SkPath& path);
134  void PushTransform(const SkMatrix& matrix);
135  void PushOpacity(const int& alpha);
136 
137  // Removes the `Mutator` on the top of the stack
138  // and destroys it.
139  void Pop();
140 
141  // Returns a reverse iterator pointing to the top of the stack, which is the
142  // mutator that is furtherest from the leaf node.
143  const std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator Top()
144  const;
145  // Returns a reverse iterator pointing to the bottom of the stack, which is
146  // the mutator that is closeset from the leaf node.
147  const std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator Bottom()
148  const;
149 
150  // Returns an iterator pointing to the begining of the mutator vector, which
151  // is the mutator that is furtherest from the leaf node.
152  const std::vector<std::shared_ptr<Mutator>>::const_iterator Begin() const;
153 
154  // Returns an iterator pointing to the end of the mutator vector, which is the
155  // mutator that is closest from the leaf node.
156  const std::vector<std::shared_ptr<Mutator>>::const_iterator End() const;
157 
158  bool is_empty() const { return vector_.empty(); }
159 
160  bool operator==(const MutatorsStack& other) const {
161  if (vector_.size() != other.vector_.size()) {
162  return false;
163  }
164  for (size_t i = 0; i < vector_.size(); i++) {
165  if (*vector_[i] != *other.vector_[i]) {
166  return false;
167  }
168  }
169  return true;
170  }
171 
172  bool operator==(const std::vector<Mutator>& other) const {
173  if (vector_.size() != other.size()) {
174  return false;
175  }
176  for (size_t i = 0; i < vector_.size(); i++) {
177  if (*vector_[i] != other[i]) {
178  return false;
179  }
180  }
181  return true;
182  }
183 
184  bool operator!=(const MutatorsStack& other) const {
185  return !operator==(other);
186  }
187 
188  bool operator!=(const std::vector<Mutator>& other) const {
189  return !operator==(other);
190  }
191 
192  private:
193  std::vector<std::shared_ptr<Mutator>> vector_;
194 }; // MutatorsStack
195 
197  public:
198  EmbeddedViewParams() = default;
199 
200  EmbeddedViewParams(SkMatrix matrix,
201  SkSize size_points,
202  MutatorsStack mutators_stack)
203  : matrix_(matrix),
204  size_points_(size_points),
205  mutators_stack_(mutators_stack) {
206  SkPath path;
207  SkRect starting_rect = SkRect::MakeSize(size_points);
208  path.addRect(starting_rect);
209  path.transform(matrix);
210  final_bounding_rect_ = path.getBounds();
211  }
212 
214  size_points_ = other.size_points_;
215  mutators_stack_ = other.mutators_stack_;
216  matrix_ = other.matrix_;
217  final_bounding_rect_ = other.final_bounding_rect_;
218  };
219 
220  // The original size of the platform view before any mutation matrix is
221  // applied.
222  const SkSize& sizePoints() const { return size_points_; };
223  // The mutators stack contains the detailed step by step mutations for this
224  // platform view.
225  const MutatorsStack& mutatorsStack() const { return mutators_stack_; };
226  // The bounding rect of the platform view after applying all the mutations.
227  //
228  // Clippings are ignored.
229  const SkRect& finalBoundingRect() const { return final_bounding_rect_; }
230 
231  bool operator==(const EmbeddedViewParams& other) const {
232  return size_points_ == other.size_points_ &&
233  mutators_stack_ == other.mutators_stack_ &&
234  final_bounding_rect_ == other.final_bounding_rect_ &&
235  matrix_ == other.matrix_;
236  }
237 
238  private:
239  SkMatrix matrix_;
240  SkSize size_points_;
241  MutatorsStack mutators_stack_;
242  SkRect final_bounding_rect_;
243 };
244 
245 enum class PostPrerollResult {
246  // Frame has successfully rasterized.
247  kSuccess,
248  // Frame is submitted twice. This is currently only used when
249  // thread configuration change occurs.
251  // Frame is dropped and a new frame with the same layer tree is
252  // attempted. This is currently only used when thread configuration
253  // change occurs.
255 };
256 
257 // Facilitates embedding of platform views within the flow layer tree.
258 //
259 // Used on iOS, Android (hybrid composite mode), and on embedded platforms
260 // that provide a system compositor as part of the project arguments.
262  // TODO(cyanglaz): Make embedder own the `EmbeddedViewParams`.
263 
264  public:
265  ExternalViewEmbedder() = default;
266 
267  virtual ~ExternalViewEmbedder() = default;
268 
269  // Usually, the root canvas is not owned by the view embedder. However, if
270  // the view embedder wants to provide a canvas to the rasterizer, it may
271  // return one here. This canvas takes priority over the canvas materialized
272  // from the on-screen render target.
273  virtual SkCanvas* GetRootCanvas() = 0;
274 
275  // Call this in-lieu of |SubmitFrame| to clear pre-roll state and
276  // sets the stage for the next pre-roll.
277  virtual void CancelFrame() = 0;
278 
279  // Indicates the begining of a frame.
280  //
281  // The `raster_thread_merger` will be null if |SupportsDynamicThreadMerging|
282  // returns false.
283  virtual void BeginFrame(
284  SkISize frame_size,
285  GrDirectContext* context,
286  double device_pixel_ratio,
287  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) = 0;
288 
289  virtual void PrerollCompositeEmbeddedView(
290  int view_id,
291  std::unique_ptr<EmbeddedViewParams> params) = 0;
292 
293  // This needs to get called after |Preroll| finishes on the layer tree.
294  // Returns kResubmitFrame if the frame needs to be processed again, this is
295  // after it does any requisite tasks needed to bring itself to a valid state.
296  // Returns kSuccess if the view embedder is already in a valid state.
298  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
300  }
301 
302  virtual std::vector<SkCanvas*> GetCurrentCanvases() = 0;
303 
304  // Must be called on the UI thread.
305  virtual SkCanvas* CompositeEmbeddedView(int view_id) = 0;
306 
307  // Implementers must submit the frame by calling frame.Submit().
308  //
309  // This method can mutate the root Skia canvas before submitting the frame.
310  //
311  // It can also allocate frames for overlay surfaces to compose hybrid views.
312  virtual void SubmitFrame(GrDirectContext* context,
313  std::unique_ptr<SurfaceFrame> frame);
314 
315  // This method provides the embedder a way to do additional tasks after
316  // |SubmitFrame|. For example, merge task runners if `should_resubmit_frame`
317  // is true.
318  //
319  // For example on the iOS embedder, threads are merged in this call.
320  // A new frame on the platform thread starts immediately. If the GPU thread
321  // still has some task running, there could be two frames being rendered
322  // concurrently, which causes undefined behaviors.
323  //
324  // The `raster_thread_merger` will be null if |SupportsDynamicThreadMerging|
325  // returns false.
326  virtual void EndFrame(
327  bool should_resubmit_frame,
328  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {}
329 
330  // Whether the embedder should support dynamic thread merging.
331  //
332  // Returning `true` results a |RasterThreadMerger| instance to be created.
333  // * See also |BegineFrame| and |EndFrame| for getting the
334  // |RasterThreadMerger| instance.
335  virtual bool SupportsDynamicThreadMerging();
336 
338 
339 }; // ExternalViewEmbedder
340 
341 } // namespace flutter
342 
343 #endif // FLUTTER_FLOW_EMBEDDED_VIEWS_H_
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32
Mutator(const Mutator &other)
const MutatorType & GetType() const
bool operator==(const Mutator &other) const
Mutator(const SkMatrix &matrix)
float GetAlphaFloat() const
Mutator(const int &alpha)
const SkRRect & GetRRect() const
virtual void EndFrame(bool should_resubmit_frame, fml::RefPtr< fml::RasterThreadMerger > raster_thread_merger)
Mutator(const SkRect &rect)
EmbeddedViewParams(const EmbeddedViewParams &other)
bool operator!=(const MutatorsStack &other) const
virtual PostPrerollResult PostPrerollAction(fml::RefPtr< fml::RasterThreadMerger > raster_thread_merger)
const SkSize & sizePoints() const
bool operator!=(const Mutator &other) const
Mutator(const SkPath &path)
bool operator==(const std::vector< Mutator > &other) const
const SkRect & GetRect() const
EmbeddedViewParams(SkMatrix matrix, SkSize size_points, MutatorsStack mutators_stack)
const SkRect & finalBoundingRect() const
Mutator(const SkRRect &rrect)
bool operator!=(const std::vector< Mutator > &other) const
bool operator==(const MutatorsStack &other) const
const MutatorsStack & mutatorsStack() const
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
bool operator==(const EmbeddedViewParams &other) const
const SkPath & GetPath() const
const SkMatrix & GetMatrix() const
const int & GetAlpha() const