Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
command_buffer_gles.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
6
7#include <memory>
8#include <utility>
9
14
15namespace impeller {
16namespace {
17
18/// Invokes a deferred command buffer completion callback exactly once.
19///
20/// The callback is completed with `kCompleted` when the deferred reactor
21/// operation runs. If the operation is discarded before it runs, such as during
22/// reactor teardown, the callback is completed with `kError`.
23class DeferredCompletionCallback {
24 public:
25 explicit DeferredCompletionCallback(
27 : callback_(std::move(callback)) {}
28
29 /// Completes with `kError` unless the callback was already invoked.
30 ~DeferredCompletionCallback() { Invoke(CommandBuffer::Status::kError); }
31
32 DeferredCompletionCallback(const DeferredCompletionCallback&) = delete;
33 DeferredCompletionCallback& operator=(const DeferredCompletionCallback&) =
34 delete;
35 DeferredCompletionCallback(DeferredCompletionCallback&&) = delete;
36 DeferredCompletionCallback& operator=(DeferredCompletionCallback&&) = delete;
37
38 /// Completes with `kCompleted` when the deferred reactor operation runs.
39 void Complete() { Invoke(CommandBuffer::Status::kCompleted); }
40
41 private:
42 void Invoke(CommandBuffer::Status status) {
43 if (!callback_) {
44 return;
45 }
46 auto callback = std::exchange(callback_, nullptr);
47 callback(status);
48 }
49
51};
52
53} // namespace
54
55CommandBufferGLES::CommandBufferGLES(std::weak_ptr<const Context> context,
56 std::shared_ptr<ReactorGLES> reactor)
57 : CommandBuffer(std::move(context)),
58 reactor_(std::move(reactor)),
59 is_valid_(reactor_ && reactor_->IsValid()) {}
60
61CommandBufferGLES::~CommandBufferGLES() = default;
62
63// |CommandBuffer|
64void CommandBufferGLES::SetLabel(std::string_view label) const {
65 // Cannot support.
66}
67
68// |CommandBuffer|
69bool CommandBufferGLES::IsValid() const {
70 return is_valid_;
71}
72
73// |CommandBuffer|
74bool CommandBufferGLES::OnSubmitCommands(bool block_on_schedule,
75 CompletionCallback callback) {
76 // The reactor consumes commands on the GL thread and GL synchronizes
77 // buffer reuse implicitly, so submissions are tracked at reactor
78 // consumption granularity rather than GPU completion.
79 std::shared_ptr<GpuSubmissionTracker> tracker;
80 uint64_t submission_id = 0;
81 if (auto context = context_.lock()) {
82 tracker = ContextGLES::Cast(*context).GetMutableSubmissionTracker();
83 submission_id = tracker->RecordSubmission();
84 }
85
86 if (reactor_->CanReactOnCurrentThread()) {
87 const auto result = reactor_->React();
88 if (tracker) {
89 tracker->RecordCompletion(submission_id);
90 }
91 if (callback) {
92 callback(result ? CommandBuffer::Status::kCompleted
93 : CommandBuffer::Status::kError);
94 }
95 return result;
96 }
97
98 // Submission is accepted even when no GL context is current yet. The
99 // reactor keeps previously encoded operations queued on this thread.
100 std::shared_ptr<DeferredCompletionCallback> deferred_callback;
101 if (callback) {
102 deferred_callback =
103 std::make_shared<DeferredCompletionCallback>(std::move(callback));
104 }
105 if (!reactor_->AddOperation(
106 [deferred_callback, tracker,
107 submission_id](const ReactorGLES& reactor) {
108 if (tracker) {
109 tracker->RecordCompletion(submission_id);
110 }
111 if (deferred_callback) {
112 deferred_callback->Complete();
113 }
114 },
115 /*defer=*/true)) {
116 if (tracker) {
117 tracker->RecordCompletion(submission_id);
118 }
119 return false;
120 }
121 return true;
122}
123
124// |CommandBuffer|
125void CommandBufferGLES::OnWaitUntilCompleted() {
126 reactor_->GetProcTable().Finish();
127}
128
129// |CommandBuffer|
130void CommandBufferGLES::OnWaitUntilScheduled() {
131 reactor_->GetProcTable().Flush();
132}
133
134// |CommandBuffer|
135std::shared_ptr<RenderPass> CommandBufferGLES::OnCreateRenderPass(
136 RenderTarget target) {
137 if (!IsValid()) {
138 return nullptr;
139 }
140 auto context = context_.lock();
141 if (!context) {
142 return nullptr;
143 }
144 auto pass = std::shared_ptr<RenderPassGLES>(
145 new RenderPassGLES(context, target, reactor_));
146 if (!pass->IsValid()) {
147 return nullptr;
148 }
149 return pass;
150}
151
152// |CommandBuffer|
153std::shared_ptr<BlitPass> CommandBufferGLES::OnCreateBlitPass() {
154 if (!IsValid()) {
155 return nullptr;
156 }
157 auto pass = std::shared_ptr<BlitPassGLES>(new BlitPassGLES(reactor_));
158 if (!pass->IsValid()) {
159 return nullptr;
160 }
161 return pass;
162}
163
164// |CommandBuffer|
165std::shared_ptr<ComputePass> CommandBufferGLES::OnCreateComputePass() {
166 // Compute passes aren't supported until GLES 3.2, at which point Vulkan is
167 // available anyway.
168 return nullptr;
169}
170
171} // namespace impeller
std::function< void(Status)> CompletionCallback
if(engine==nullptr)
uint32_t * target
FlutterDesktopBinaryReply callback
Definition ref_ptr.h:261
std::shared_ptr< ReactorGLES > reactor
std::shared_ptr< ContextGLES > context