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