blob: c6dab1cf58ece563d0f5eb501144ea17b07ae700 (
plain)
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
|
// Copyright (c) 2017 The Chromium 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 GPU_COMMAND_BUFFER_SERVICE_SCHEDULER_H_
#define GPU_COMMAND_BUFFER_SERVICE_SCHEDULER_H_
#include <queue>
#include <vector>
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "gpu/command_buffer/common/scheduling_priority.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/command_buffer/service/sequence_id.h"
#include "gpu/gpu_export.h"
namespace base {
class SingleThreadTaskRunner;
namespace trace_event {
class ConvertableToTraceFormat;
}
}
namespace gpu {
class SyncPointManager;
class GPU_EXPORT Scheduler {
public:
Scheduler(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
SyncPointManager* sync_point_manager);
virtual ~Scheduler();
// Create a sequence with given priority. Returns an identifier for the
// sequence that can be used with SyncPonintManager for creating sync point
// release clients. Sequences start off as enabled (see |EnableSequence|).
SequenceId CreateSequence(SchedulingPriority priority);
// Destroy the sequence and run any scheduled tasks immediately.
void DestroySequence(SequenceId sequence_id);
// Enables the sequence so that its tasks may be scheduled.
void EnableSequence(SequenceId sequence_id);
// Disables the sequence.
void DisableSequence(SequenceId sequence_id);
// Schedules task (closure) to run on the sequence. The task is blocked until
// the sync token fences are released or determined to be invalid. Tasks are
// run in the order in which they are submitted.
void ScheduleTask(SequenceId sequence_id,
base::OnceClosure closure,
const std::vector<SyncToken>& sync_token_fences);
// Continue running task on the sequence with the closure. This must be called
// while running a previously scheduled task.
void ContinueTask(SequenceId sequence_id, base::OnceClosure closure);
// If the sequence should yield so that a higher priority sequence may run.
bool ShouldYield(SequenceId sequence_id);
private:
class Sequence;
struct SchedulingState {
static bool Comparator(const SchedulingState& lhs,
const SchedulingState& rhs) {
return rhs.RunsBefore(lhs);
}
SchedulingState();
SchedulingState(const SchedulingState& other);
~SchedulingState();
bool RunsBefore(const SchedulingState& other) const {
return std::tie(priority, order_num) <
std::tie(other.priority, other.order_num);
}
std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue()
const;
SequenceId sequence_id;
SchedulingPriority priority = SchedulingPriority::kLowest;
uint32_t order_num = 0;
};
void SyncTokenFenceReleased(const SyncToken& sync_token,
uint32_t order_num,
SequenceId release_sequence_id,
SequenceId waiting_sequence_id);
void TryScheduleSequence(Sequence* sequence);
void RebuildSchedulingQueue();
Sequence* GetSequence(SequenceId sequence_id);
void RunNextTask();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
SyncPointManager* const sync_point_manager_;
mutable base::Lock lock_;
// The following are protected by |lock_|.
bool running_ = false;
base::flat_map<SequenceId, std::unique_ptr<Sequence>> sequences_;
// Used as a priority queue for scheduling sequences. Min heap of
// SchedulingState with highest priority (lowest order) in front.
std::vector<SchedulingState> scheduling_queue_;
// If the running sequence should yield so that a higher priority sequence can
// run.
bool should_yield_ = false;
// If the scheduling queue needs to be rebuild because a sequence changed
// priority.
bool rebuild_scheduling_queue_ = false;
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<Scheduler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Scheduler);
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_SCHEDULER_H_
|