Support releasing fence sync from task callback.
There will be follow-up CLs to convert callsites of
SyncPointClientState::ReleaseFenceSync(). This CL converts
some callsites in SharedImageStub to show how this works.
This is one step towards making sure TaskGraph has complete
knowledge of sync point wait/release dependencies among
tasks.
This is part of the work to enable validating sync points
based on task graph dependency information. For more details
please see design doc:
https://docs.google.com/document/d/1OF6OQnNljnH4v6bmg24gkuNj3zfsRAU47wONcTkHk1I/edit
Bug: b/324276400
Change-Id: I94afc308bc30659b33cbe84d25c820aaeab85cda
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5762685
Commit-Queue: Yuzhu Shen <yzshen@chromium.org>
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1348884}
diff --git a/gpu/command_buffer/service/scheduler.h b/gpu/command_buffer/service/scheduler.h
index fe442c1..f980fbd 100644
--- a/gpu/command_buffer/service/scheduler.h
+++ b/gpu/command_buffer/service/scheduler.h
@@ -45,16 +45,26 @@
public:
struct GPU_EXPORT Task {
+ // Use the signature with TaskCallback if the task needs to determine when
+ // to release fence sync during task execution. Please also see comments of
+ // TaskCallback.
+ // Use the signatures with base::OnceClosure if the task doesn't release
+ // fence sync, or the release can be done automatically after task
+ // execution.
Task(SequenceId sequence_id,
- base::OnceClosure closure,
+ TaskCallback task_callback,
std::vector<SyncToken> sync_token_fences,
const SyncToken& release,
ReportingCallback report_callback = ReportingCallback());
- // TODO(b/324276400): Remove this constructor after converting callsites to
- // explicitly specify `release`.
Task(SequenceId sequence_id,
- base::OnceClosure closure,
+ base::OnceClosure task_closure,
+ std::vector<SyncToken> sync_token_fences,
+ const SyncToken& release,
+ ReportingCallback report_callback = ReportingCallback());
+
+ Task(SequenceId sequence_id,
+ base::OnceClosure task_closure,
std::vector<SyncToken> sync_token_fences,
ReportingCallback report_callback = ReportingCallback());
@@ -63,11 +73,14 @@
Task& operator=(Task&& other);
SequenceId sequence_id;
- base::OnceClosure closure;
+
+ // Only one of the two is used.
+ TaskCallback task_callback;
+ base::OnceClosure task_closure;
+
std::vector<SyncToken> sync_token_fences;
// The release that is expected to be reached after execution of this task.
- // Used when graph-based sync point validation is enabled.
SyncToken release;
ReportingCallback report_callback;
@@ -108,6 +121,11 @@
// could be destroyed outside of GPU thread.
void DestroySequence(SequenceId sequence_id);
+ // Creates a SyncPointClientState object associated with the sequence.
+ void CreateSyncPointClientState(SequenceId sequence_id,
+ CommandBufferNamespace namespace_id,
+ CommandBufferId command_buffer_id);
+
// Enables the sequence so that its tasks may be scheduled.
void EnableSequence(SequenceId sequence_id);
@@ -123,16 +141,17 @@
void ResetPriorityForClientWait(SequenceId sequence_id,
CommandBufferId command_buffer_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.
+ // Schedules task 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(Scheduler::Task task);
void ScheduleTasks(std::vector<Scheduler::Task> tasks);
- // 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);
+ // Continue running task on the sequence with the callback. This must be
+ // called while running a previously scheduled task.
+ void ContinueTask(SequenceId sequence_id, TaskCallback task_callback);
+ void ContinueTask(SequenceId sequence_id, base::OnceClosure task_closure);
// If the sequence should yield so that a higher priority sequence may run.
bool ShouldYield(SequenceId sequence_id);
@@ -229,19 +248,24 @@
base::TimeDelta FrontTaskSchedulingDelay();
// Returns the next order number and closure. Sets running state to RUNNING.
- uint32_t BeginTask(base::OnceClosure* closure);
+ uint32_t BeginTask(base::OnceClosure* task_closure);
// Called after running the closure returned by BeginTask. Sets running
// state to IDLE.
void FinishTask();
// Enqueues a task in the sequence and returns the generated order number.
- uint32_t ScheduleTask(base::OnceClosure closure,
+ uint32_t ScheduleTask(TaskCallback task_callback,
+ const SyncToken& release,
+ ReportingCallback report_callback);
+ uint32_t ScheduleTask(base::OnceClosure task_closure,
+ const SyncToken& release,
ReportingCallback report_callback);
// Continue running the current task with the given closure. Must be called
// in between |BeginTask| and |FinishTask|.
- void ContinueTask(base::OnceClosure closure);
+ void ContinueTask(TaskCallback task_callback);
+ void ContinueTask(base::OnceClosure task_closure);
// Sets the first dependency added time on the last task if it wasn't
// already set, no-op otherwise.
@@ -261,8 +285,15 @@
void RemoveClientWait(CommandBufferId command_buffer_id);
+ void CreateSyncPointClientState(CommandBufferNamespace namespace_id,
+ CommandBufferId command_buffer_id);
+
SchedulingPriority current_priority() const { return current_priority_; }
+ const SyncToken& current_task_release() const {
+ return current_task_release_;
+ }
+
private:
friend class Scheduler;
@@ -293,14 +324,18 @@
struct Task {
Task(Task&& other);
- Task(base::OnceClosure closure,
+ Task(base::OnceClosure task_closure,
uint32_t order_num,
+ const SyncToken& release,
ReportingCallback report_callback);
~Task();
Task& operator=(Task&& other);
- base::OnceClosure closure;
+ // Always store tasks as closures. TaskCallbacks are bound with argument
+ // and wrap as closures.
+ base::OnceClosure task_closure;
uint32_t order_num;
+ SyncToken release;
ReportingCallback report_callback;
// Note: this time is only correct once the last fence has been removed,
@@ -343,6 +378,8 @@
// Re-compute current priority.
void UpdateSchedulingPriority();
+ base::OnceClosure CreateTaskClosure(TaskCallback task_callback);
+
// If the sequence is enabled. Sequences are disabled/enabled based on when
// the command buffer is descheduled/scheduled.
bool enabled_ = true;
@@ -361,6 +398,12 @@
SchedulingPriority current_priority_;
scoped_refptr<SyncPointOrderData> order_data_;
+ std::vector<scoped_refptr<SyncPointClientState>> sync_point_states_;
+
+ // While processing a task, the task is removed from `tasks_`. This field is
+ // used to preserve `release` of the task. So that it can be used if the
+ // task is later continued.
+ SyncToken current_task_release_;
// Deque of tasks. Tasks are inserted at the back with increasing order
// number generated from SyncPointOrderData. If a running task needs to be
@@ -378,6 +421,10 @@
1] = {};
base::flat_set<CommandBufferId> client_waits_;
+
+ // Not supposed to be accessed from multiple thread simultaneously. It is
+ // updated by BeginTask() and called by user task callback.
+ FenceSyncReleaseDelegate release_delegate_;
};
void AddWaitingPriority(SequenceId sequence_id, SchedulingPriority priority);