• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/fml/gpu_thread_merger.h"
11 #include "flutter/fml/memory/ref_counted.h"
12 #include "third_party/skia/include/core/SkCanvas.h"
13 #include "third_party/skia/include/core/SkPath.h"
14 #include "third_party/skia/include/core/SkPoint.h"
15 #include "third_party/skia/include/core/SkRRect.h"
16 #include "third_party/skia/include/core/SkRect.h"
17 #include "third_party/skia/include/core/SkSize.h"
18 #include "third_party/skia/include/core/SkSurface.h"
19 
20 namespace flutter {
21 
22 enum MutatorType { clip_rect, clip_rrect, clip_path, transform, opacity };
23 
24 // Stores mutation information like clipping or transform.
25 //
26 // The `type` indicates the type of the mutation: clip_rect, transform and etc.
27 // Each `type` is paired with an object that supports the mutation. For example,
28 // if the `type` is clip_rect, `rect()` is used the represent the rect to be
29 // clipped. One mutation object must only contain one type of mutation.
30 class Mutator {
31  public:
Mutator(const Mutator & other)32   Mutator(const Mutator& other) {
33     type_ = other.type_;
34     switch (other.type_) {
35       case clip_rect:
36         rect_ = other.rect_;
37         break;
38       case clip_rrect:
39         rrect_ = other.rrect_;
40         break;
41       case clip_path:
42         path_ = new SkPath(*other.path_);
43         break;
44       case transform:
45         matrix_ = other.matrix_;
46         break;
47       case opacity:
48         alpha_ = other.alpha_;
49         break;
50       default:
51         break;
52     }
53   }
54 
Mutator(const SkRect & rect)55   explicit Mutator(const SkRect& rect) : type_(clip_rect), rect_(rect) {}
Mutator(const SkRRect & rrect)56   explicit Mutator(const SkRRect& rrect) : type_(clip_rrect), rrect_(rrect) {}
Mutator(const SkPath & path)57   explicit Mutator(const SkPath& path)
58       : type_(clip_path), path_(new SkPath(path)) {}
Mutator(const SkMatrix & matrix)59   explicit Mutator(const SkMatrix& matrix)
60       : type_(transform), matrix_(matrix) {}
Mutator(const int & alpha)61   explicit Mutator(const int& alpha) : type_(opacity), alpha_(alpha) {}
62 
GetType()63   const MutatorType& GetType() const { return type_; }
GetRect()64   const SkRect& GetRect() const { return rect_; }
GetRRect()65   const SkRRect& GetRRect() const { return rrect_; }
GetPath()66   const SkPath& GetPath() const { return *path_; }
GetMatrix()67   const SkMatrix& GetMatrix() const { return matrix_; }
GetAlpha()68   const int& GetAlpha() const { return alpha_; }
GetAlphaFloat()69   float GetAlphaFloat() const { return (alpha_ / 255.0); }
70 
71   bool operator==(const Mutator& other) const {
72     if (type_ != other.type_) {
73       return false;
74     }
75     switch (type_) {
76       case clip_rect:
77         return rect_ == other.rect_;
78       case clip_rrect:
79         return rrect_ == other.rrect_;
80       case clip_path:
81         return *path_ == *other.path_;
82       case transform:
83         return matrix_ == other.matrix_;
84       case opacity:
85         return alpha_ == other.alpha_;
86     }
87 
88     return false;
89   }
90 
91   bool operator!=(const Mutator& other) const { return !operator==(other); }
92 
IsClipType()93   bool IsClipType() {
94     return type_ == clip_rect || type_ == clip_rrect || type_ == clip_path;
95   }
96 
~Mutator()97   ~Mutator() {
98     if (type_ == clip_path) {
99       delete path_;
100     }
101   };
102 
103  private:
104   MutatorType type_;
105 
106   union {
107     SkRect rect_;
108     SkRRect rrect_;
109     SkMatrix matrix_;
110     SkPath* path_;
111     int alpha_;
112   };
113 
114 };  // Mutator
115 
116 // A stack of mutators that can be applied to an embedded platform view.
117 //
118 // The stack may include mutators like transforms and clips, each mutator
119 // applies to all the mutators that are below it in the stack and to the
120 // embedded view.
121 //
122 // For example consider the following stack: [T1, T2, T3], where T1 is the top
123 // of the stack and T3 is the bottom of the stack. Applying this mutators stack
124 // to a platform view P1 will result in T1(T2(T2(P1))).
125 class MutatorsStack {
126  public:
127   MutatorsStack() = default;
128 
129   void PushClipRect(const SkRect& rect);
130   void PushClipRRect(const SkRRect& rrect);
131   void PushClipPath(const SkPath& path);
132   void PushTransform(const SkMatrix& matrix);
133   void PushOpacity(const int& alpha);
134 
135   // Removes the `Mutator` on the top of the stack
136   // and destroys it.
137   void Pop();
138 
139   // Returns an iterator pointing to the top of the stack.
140   const std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator Top()
141       const;
142   // Returns an iterator pointing to the bottom of the stack.
143   const std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator Bottom()
144       const;
145 
146   bool operator==(const MutatorsStack& other) const {
147     if (vector_.size() != other.vector_.size()) {
148       return false;
149     }
150     for (size_t i = 0; i < vector_.size(); i++) {
151       if (*vector_[i] != *other.vector_[i]) {
152         return false;
153       }
154     }
155     return true;
156   }
157 
158   bool operator!=(const MutatorsStack& other) const {
159     return !operator==(other);
160   }
161 
162  private:
163   std::vector<std::shared_ptr<Mutator>> vector_;
164 };  // MutatorsStack
165 
166 class EmbeddedViewParams {
167  public:
168   EmbeddedViewParams() = default;
169 
EmbeddedViewParams(const EmbeddedViewParams & other)170   EmbeddedViewParams(const EmbeddedViewParams& other) {
171     offsetPixels = other.offsetPixels;
172     sizePoints = other.sizePoints;
173     mutatorsStack = other.mutatorsStack;
174   };
175 
176   SkPoint offsetPixels;
177   SkSize sizePoints;
178   MutatorsStack mutatorsStack;
179 
180   bool operator==(const EmbeddedViewParams& other) const {
181     return offsetPixels == other.offsetPixels &&
182            sizePoints == other.sizePoints &&
183            mutatorsStack == other.mutatorsStack;
184   }
185 };
186 
187 enum class PostPrerollResult { kResubmitFrame, kSuccess };
188 
189 // This is only used on iOS when running in a non headless mode,
190 // in this case ExternalViewEmbedder is a reference to the
191 // FlutterPlatformViewsController which is owned by FlutterViewController.
192 class ExternalViewEmbedder {
193   // TODO(cyanglaz): Make embedder own the `EmbeddedViewParams`.
194 
195  public:
196   ExternalViewEmbedder() = default;
197 
198   virtual ~ExternalViewEmbedder() = default;
199 
200   // Usually, the root surface is not owned by the view embedder. However, if
201   // the view embedder wants to provide a surface to the rasterizer, it may
202   // return one here. This surface takes priority over the surface materialized
203   // from the on-screen render target.
204   virtual sk_sp<SkSurface> GetRootSurface() = 0;
205 
206   // Call this in-lieu of |SubmitFrame| to clear pre-roll state and
207   // sets the stage for the next pre-roll.
208   virtual void CancelFrame() = 0;
209 
210   virtual void BeginFrame(SkISize frame_size, GrContext* context) = 0;
211 
212   virtual void PrerollCompositeEmbeddedView(
213       int view_id,
214       std::unique_ptr<EmbeddedViewParams> params) = 0;
215 
216   // This needs to get called after |Preroll| finishes on the layer tree.
217   // Returns kResubmitFrame if the frame needs to be processed again, this is
218   // after it does any requisite tasks needed to bring itself to a valid state.
219   // Returns kSuccess if the view embedder is already in a valid state.
PostPrerollAction(fml::RefPtr<fml::GpuThreadMerger> gpu_thread_merger)220   virtual PostPrerollResult PostPrerollAction(
221       fml::RefPtr<fml::GpuThreadMerger> gpu_thread_merger) {
222     return PostPrerollResult::kSuccess;
223   }
224 
225   virtual std::vector<SkCanvas*> GetCurrentCanvases() = 0;
226 
227   // Must be called on the UI thread.
228   virtual SkCanvas* CompositeEmbeddedView(int view_id) = 0;
229 
230   virtual bool SubmitFrame(GrContext* context);
231 
232   FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder);
233 
234 };  // ExternalViewEmbedder
235 
236 }  // namespace flutter
237 
238 #endif  // FLUTTER_FLOW_EMBEDDED_VIEWS_H_
239