Flutter Engine
raster_thread_merger.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 FML_SHELL_COMMON_TASK_RUNNER_MERGER_H_
6 #define FML_SHELL_COMMON_TASK_RUNNER_MERGER_H_
7 
8 #include <condition_variable>
9 #include <mutex>
10 
11 #include "flutter/fml/macros.h"
12 #include "flutter/fml/memory/ref_counted.h"
13 #include "flutter/fml/message_loop_task_queues.h"
14 #include "flutter/fml/shared_thread_merger.h"
15 
16 namespace fml {
17 
18 class MessageLoopImpl;
19 
20 enum class RasterThreadStatus {
24 };
25 
26 /// This class is a client and proxy between the rasterizer and
27 /// |SharedThreadMerger|. The multiple |RasterThreadMerger| instances with same
28 /// owner_queue_id and same subsumed_queue_id share the same
29 /// |SharedThreadMerger| instance. Whether they share the same inner instance is
30 /// determined by |RasterThreadMerger::CreateOrShareThreadMerger| method.
32  : public fml::RefCountedThreadSafe<RasterThreadMerger> {
33  public:
34  // Merges the raster thread into platform thread for the duration of
35  // the lease term. Lease is managed by the caller by either calling
36  // |ExtendLeaseTo| or |DecrementLease|.
37  // When the caller merges with a lease term of say 2. The threads
38  // are going to remain merged until 2 invocations of |DecreaseLease|,
39  // unless an |ExtendLeaseTo| gets called.
40  //
41  // If the task queues are the same, we consider them statically merged.
42  // When task queues are statically merged this method becomes no-op.
43  void MergeWithLease(size_t lease_term);
44 
45  // Gets the shared merger from current merger object
46  const fml::RefPtr<SharedThreadMerger>& GetSharedRasterThreadMerger() const;
47 
48  /// Creates a new merger from parent, share the inside shared_merger member
49  /// when the platform_queue_id and raster_queue_id are same, otherwise create
50  /// a new shared_merger instance
51  static fml::RefPtr<fml::RasterThreadMerger> CreateOrShareThreadMerger(
52  const fml::RefPtr<fml::RasterThreadMerger>& parent_merger,
53  TaskQueueId platform_id,
54  TaskQueueId raster_id);
55 
56  // Un-merges the threads now if current caller is the last merge caller,
57  // and it resets the lease term to 0, otherwise it will remove the caller
58  // record and return. The multiple caller records were recorded after
59  // |MergeWithLease| or |ExtendLeaseTo| method.
60  //
61  // Must be executed on the raster task runner.
62  //
63  // If the task queues are the same, we consider them statically merged.
64  // When task queues are statically merged, we never unmerge them and
65  // this method becomes no-op.
66  void UnMergeNowIfLastOne();
67 
68  // If the task queues are the same, we consider them statically merged.
69  // When task queues are statically merged this method becomes no-op.
70  void ExtendLeaseTo(size_t lease_term);
71 
72  // Returns |RasterThreadStatus::kUnmergedNow| if this call resulted in
73  // splitting the raster and platform threads. Reduces the lease term by 1.
74  //
75  // If the task queues are the same, we consider them statically merged.
76  // When task queues are statically merged this method becomes no-op.
77  RasterThreadStatus DecrementLease();
78 
79  // The method is locked by current instance, and asks the shared instance of
80  // SharedThreadMerger and the merging state is determined by the
81  // lease_term_ counter.
82  bool IsMerged();
83 
84  // Waits until the threads are merged.
85  //
86  // Must run on the platform task runner.
87  void WaitUntilMerged();
88 
89  // Returns true if the current thread owns rasterizing.
90  // When the threads are merged, platform thread owns rasterizing.
91  // When un-merged, raster thread owns rasterizing.
92  bool IsOnRasterizingThread();
93 
94  // Returns true if the current thread is the platform thread.
95  bool IsOnPlatformThread() const;
96 
97  // Enables the thread merger.
98  void Enable();
99 
100  // Disables the thread merger. Once disabled, any call to
101  // |MergeWithLease| or |UnMergeNowIfLastOne| results in a noop.
102  void Disable();
103 
104  // Whether the thread merger is enabled. By default, the thread merger is
105  // enabled. If false, calls to |MergeWithLease| or |UnMergeNowIfLastOne|
106  // or |ExtendLeaseTo| or |DecrementLease| results in a noop.
107  bool IsEnabled();
108 
109  // Registers a callback that can be used to clean up global state right after
110  // the thread configuration has changed.
111  //
112  // For example, it can be used to clear the GL context so it can be used in
113  // the next task from a different thread.
114  void SetMergeUnmergeCallback(const fml::closure& callback);
115 
116  private:
117  fml::TaskQueueId platform_queue_id_;
118  fml::TaskQueueId gpu_queue_id_;
119 
120  RasterThreadMerger(fml::TaskQueueId platform_queue_id,
121  fml::TaskQueueId gpu_queue_id);
123  fml::TaskQueueId platform_queue_id,
124  fml::TaskQueueId gpu_queue_id);
125 
126  const fml::RefPtr<fml::SharedThreadMerger> shared_merger_;
127  std::condition_variable merged_condition_;
128  std::mutex mutex_;
129  fml::closure merge_unmerge_callback_;
130 
131  bool IsMergedUnSafe() const;
132 
133  bool IsEnabledUnSafe() const;
134 
135  // The platform_queue_id and gpu_queue_id are exactly the same.
136  // We consider the threads are always merged and cannot be unmerged.
137  bool TaskQueuesAreSame() const;
138 
142 };
143 
144 } // namespace fml
145 
146 #endif // FML_SHELL_COMMON_TASK_RUNNER_MERGER_H_
#define FML_FRIEND_REF_COUNTED_THREAD_SAFE(T)
Definition: ref_counted.h:125
FlKeyEvent FlKeyResponderAsyncCallback callback
Definition: ascii_trie.cc:9
std::function< void()> closure
Definition: closure.h:14
#define FML_FRIEND_MAKE_REF_COUNTED(T)
Definition: ref_counted.h:131
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27