Flutter Impeller
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 
10 #include "impeller/base/config.h"
13 
14 namespace impeller {
15 namespace {
16 
17 /// Invokes a deferred command buffer completion callback exactly once.
18 ///
19 /// The callback is completed with `kCompleted` when the deferred reactor
20 /// operation runs. If the operation is discarded before it runs, such as during
21 /// reactor teardown, the callback is completed with `kError`.
22 class DeferredCompletionCallback {
23  public:
24  explicit DeferredCompletionCallback(
26  : callback_(std::move(callback)) {}
27 
28  /// Completes with `kError` unless the callback was already invoked.
29  ~DeferredCompletionCallback() { Invoke(CommandBuffer::Status::kError); }
30 
31  DeferredCompletionCallback(const DeferredCompletionCallback&) = delete;
32  DeferredCompletionCallback& operator=(const DeferredCompletionCallback&) =
33  delete;
34  DeferredCompletionCallback(DeferredCompletionCallback&&) = delete;
35  DeferredCompletionCallback& operator=(DeferredCompletionCallback&&) = delete;
36 
37  /// Completes with `kCompleted` when the deferred reactor operation runs.
38  void Complete() { Invoke(CommandBuffer::Status::kCompleted); }
39 
40  private:
41  void Invoke(CommandBuffer::Status status) {
42  if (!callback_) {
43  return;
44  }
45  auto callback = std::exchange(callback_, nullptr);
46  callback(status);
47  }
48 
50 };
51 
52 } // namespace
53 
54 CommandBufferGLES::CommandBufferGLES(std::weak_ptr<const Context> context,
55  std::shared_ptr<ReactorGLES> reactor)
56  : CommandBuffer(std::move(context)),
57  reactor_(std::move(reactor)),
58  is_valid_(reactor_ && reactor_->IsValid()) {}
59 
60 CommandBufferGLES::~CommandBufferGLES() = default;
61 
62 // |CommandBuffer|
63 void CommandBufferGLES::SetLabel(std::string_view label) const {
64  // Cannot support.
65 }
66 
67 // |CommandBuffer|
68 bool CommandBufferGLES::IsValid() const {
69  return is_valid_;
70 }
71 
72 // |CommandBuffer|
73 bool CommandBufferGLES::OnSubmitCommands(bool block_on_schedule,
74  CompletionCallback callback) {
75  if (reactor_->CanReactOnCurrentThread()) {
76  const auto result = reactor_->React();
77  if (callback) {
78  callback(result ? CommandBuffer::Status::kCompleted
79  : CommandBuffer::Status::kError);
80  }
81  return result;
82  }
83 
84  // Submission is accepted even when no GL context is current yet. The
85  // reactor keeps previously encoded operations queued on this thread.
86  if (!callback) {
87  return true;
88  }
89 
90  auto deferred_callback =
91  std::make_shared<DeferredCompletionCallback>(std::move(callback));
92  if (!reactor_->AddOperation(
93  [deferred_callback](const ReactorGLES& reactor) {
94  deferred_callback->Complete();
95  },
96  /*defer=*/true)) {
97  return false;
98  }
99  return true;
100 }
101 
102 // |CommandBuffer|
103 void CommandBufferGLES::OnWaitUntilCompleted() {
104  reactor_->GetProcTable().Finish();
105 }
106 
107 // |CommandBuffer|
108 void CommandBufferGLES::OnWaitUntilScheduled() {
109  reactor_->GetProcTable().Flush();
110 }
111 
112 // |CommandBuffer|
113 std::shared_ptr<RenderPass> CommandBufferGLES::OnCreateRenderPass(
114  RenderTarget target) {
115  if (!IsValid()) {
116  return nullptr;
117  }
118  auto context = context_.lock();
119  if (!context) {
120  return nullptr;
121  }
122  auto pass = std::shared_ptr<RenderPassGLES>(
123  new RenderPassGLES(context, target, reactor_));
124  if (!pass->IsValid()) {
125  return nullptr;
126  }
127  return pass;
128 }
129 
130 // |CommandBuffer|
131 std::shared_ptr<BlitPass> CommandBufferGLES::OnCreateBlitPass() {
132  if (!IsValid()) {
133  return nullptr;
134  }
135  auto pass = std::shared_ptr<BlitPassGLES>(new BlitPassGLES(reactor_));
136  if (!pass->IsValid()) {
137  return nullptr;
138  }
139  return pass;
140 }
141 
142 // |CommandBuffer|
143 std::shared_ptr<ComputePass> CommandBufferGLES::OnCreateComputePass() {
144  // Compute passes aren't supported until GLES 3.2, at which point Vulkan is
145  // available anyway.
146  return nullptr;
147 }
148 
149 } // namespace impeller
std::function< void(Status)> CompletionCallback
Definition: comparable.h:93
std::shared_ptr< ReactorGLES > reactor
std::shared_ptr< ContextGLES > context