Flutter Engine
raster_thread_merger.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 
5 #define FML_USED_ON_EMBEDDER
6 
7 #include "flutter/fml/raster_thread_merger.h"
8 
9 #include "flutter/fml/message_loop_impl.h"
10 
11 namespace fml {
12 
13 const int RasterThreadMerger::kLeaseNotSet = -1;
14 
16  fml::TaskQueueId gpu_queue_id)
17  : platform_queue_id_(platform_queue_id),
18  gpu_queue_id_(gpu_queue_id),
19  task_queues_(fml::MessageLoopTaskQueues::GetInstance()),
20  lease_term_(kLeaseNotSet),
21  enabled_(true) {
22  FML_CHECK(!task_queues_->Owns(platform_queue_id_, gpu_queue_id_));
23 }
24 
26  merge_unmerge_callback_ = callback;
27 }
28 
29 void RasterThreadMerger::MergeWithLease(size_t lease_term) {
30  std::scoped_lock lock(lease_term_mutex_);
31  if (TaskQueuesAreSame()) {
32  return;
33  }
34  if (!IsEnabledUnSafe()) {
35  return;
36  }
37  FML_DCHECK(lease_term > 0) << "lease_term should be positive.";
38 
39  if (IsMergedUnSafe()) {
40  merged_condition_.notify_one();
41  return;
42  }
43 
44  bool success = task_queues_->Merge(platform_queue_id_, gpu_queue_id_);
45  if (success && merge_unmerge_callback_ != nullptr) {
46  merge_unmerge_callback_();
47  }
48  FML_CHECK(success) << "Unable to merge the raster and platform threads.";
49  lease_term_ = lease_term;
50 
51  merged_condition_.notify_one();
52 }
53 
55  std::scoped_lock lock(lease_term_mutex_);
56  if (TaskQueuesAreSame()) {
57  return;
58  }
59  if (!IsEnabledUnSafe()) {
60  return;
61  }
62  lease_term_ = 0;
63  bool success = task_queues_->Unmerge(platform_queue_id_);
64  if (success && merge_unmerge_callback_ != nullptr) {
65  merge_unmerge_callback_();
66  }
67  FML_CHECK(success) << "Unable to un-merge the raster and platform threads.";
68 }
69 
71  return MessageLoop::GetCurrentTaskQueueId() == platform_queue_id_;
72 }
73 
75  if (IsMergedUnSafe()) {
76  return IsOnPlatformThread();
77  } else {
78  return !IsOnPlatformThread();
79  }
80 }
81 
82 void RasterThreadMerger::ExtendLeaseTo(size_t lease_term) {
83  if (TaskQueuesAreSame()) {
84  return;
85  }
86  std::scoped_lock lock(lease_term_mutex_);
87  FML_DCHECK(IsMergedUnSafe()) << "lease_term should be positive.";
88  if (lease_term_ != kLeaseNotSet &&
89  static_cast<int>(lease_term) > lease_term_) {
90  lease_term_ = lease_term;
91  }
92 }
93 
95  std::scoped_lock lock(lease_term_mutex_);
96  return IsMergedUnSafe();
97 }
98 
100  std::scoped_lock lock(lease_term_mutex_);
101  enabled_ = true;
102 }
103 
105  std::scoped_lock lock(lease_term_mutex_);
106  enabled_ = false;
107 }
108 
110  std::scoped_lock lock(lease_term_mutex_);
111  return IsEnabledUnSafe();
112 }
113 
114 bool RasterThreadMerger::IsEnabledUnSafe() const {
115  return enabled_;
116 }
117 
118 bool RasterThreadMerger::IsMergedUnSafe() const {
119  return lease_term_ > 0 || TaskQueuesAreSame();
120 }
121 
122 bool RasterThreadMerger::TaskQueuesAreSame() const {
123  return platform_queue_id_ == gpu_queue_id_;
124 }
125 
127  if (TaskQueuesAreSame()) {
128  return;
129  }
131  std::unique_lock<std::mutex> lock(lease_term_mutex_);
132  merged_condition_.wait(lock, [&] { return IsMergedUnSafe(); });
133 }
134 
136  if (TaskQueuesAreSame()) {
138  }
139  std::unique_lock<std::mutex> lock(lease_term_mutex_);
140  if (!IsMergedUnSafe()) {
142  }
143  if (!IsEnabledUnSafe()) {
145  }
146  FML_DCHECK(lease_term_ > 0)
147  << "lease_term should always be positive when merged.";
148  lease_term_--;
149  if (lease_term_ == 0) {
150  // |UnMergeNow| is going to acquire the lock again.
151  lock.unlock();
152  UnMergeNow();
154  }
155 
157 }
158 
159 } // namespace fml
bool Owns(TaskQueueId owner, TaskQueueId subsumed) const
RasterThreadMerger(fml::TaskQueueId platform_queue_id, fml::TaskQueueId gpu_queue_id)
#define FML_DCHECK(condition)
Definition: logging.h:86
bool Merge(TaskQueueId owner, TaskQueueId subsumed)
Definition: ascii_trie.cc:9
void MergeWithLease(size_t lease_term)
static TaskQueueId GetCurrentTaskQueueId()
Definition: message_loop.cc:76
std::function< void()> closure
Definition: closure.h:14
RasterThreadStatus DecrementLease()
void SetMergeUnmergeCallback(const fml::closure &callback)
#define FML_CHECK(condition)
Definition: logging.h:68
void ExtendLeaseTo(size_t lease_term)