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