Flutter Engine
 
Loading...
Searching...
No Matches
command_buffer.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 "dart_api.h"
8#include "fml/make_copyable.h"
13
14namespace flutter {
15namespace gpu {
16
18
20 std::shared_ptr<impeller::Context> context,
21 std::shared_ptr<impeller::CommandBuffer> command_buffer)
22 : context_(std::move(context)),
23 command_buffer_(std::move(command_buffer)) {}
24
26
27std::shared_ptr<impeller::CommandBuffer> CommandBuffer::GetCommandBuffer() {
28 return command_buffer_;
29}
30
32 std::shared_ptr<impeller::RenderPass> render_pass) {
33 encodables_.push_back(std::move(render_pass));
34}
35
37 return CommandBuffer::Submit({});
38}
39
41 const impeller::CommandBuffer::CompletionCallback& completion_callback) {
42 // For the GLES backend, command queue submission just flushes the reactor,
43 // which needs to happen on the raster thread.
44 if (context_->GetBackendType() == impeller::Context::BackendType::kOpenGLES) {
45 auto dart_state = flutter::UIDartState::Current();
46 auto& task_runners = dart_state->GetTaskRunners();
47
48 task_runners.GetRasterTaskRunner()->PostTask(
49 fml::MakeCopyable([context = context_, command_buffer = command_buffer_,
50 completion_callback = completion_callback,
51 encodables = encodables_]() mutable {
52 for (auto& encodable : encodables) {
53 encodable->EncodeCommands();
54 }
55
56 context->GetCommandQueue()->Submit({command_buffer},
57 completion_callback);
58 context->DisposeThreadLocalCachedResources();
59 }));
60 return true;
61 }
62
63 for (auto& encodable : encodables_) {
64 encodable->EncodeCommands();
65 }
66
67 auto status = context_->GetCommandQueue()->Submit({command_buffer_},
68 completion_callback);
69 context_->DisposeThreadLocalCachedResources();
70 return status.ok();
71}
72
73} // namespace gpu
74} // namespace flutter
75
76//----------------------------------------------------------------------------
77/// Exports
78///
79
81 Dart_Handle wrapper,
82 flutter::gpu::Context* contextWrapper) {
83 auto res = fml::MakeRefCounted<flutter::gpu::CommandBuffer>(
84 contextWrapper->GetContextShared(),
85 contextWrapper->GetContext().CreateCommandBuffer());
86 res->AssociateWithDartWrapper(wrapper);
87
88 return true;
89}
90
93 Dart_Handle completion_callback) {
94 if (Dart_IsNull(completion_callback)) {
95 bool success = wrapper->Submit();
96 if (!success) {
97 return tonic::ToDart("Failed to submit CommandBuffer");
98 }
99 return Dart_Null();
100 }
101
102 if (!Dart_IsClosure(completion_callback)) {
103 return tonic::ToDart("Completion callback must be a function");
104 }
105
106 auto dart_state = flutter::UIDartState::Current();
107 auto& task_runners = dart_state->GetTaskRunners();
108
109 auto persistent_completion_callback =
110 std::make_unique<tonic::DartPersistentValue>(dart_state,
111 completion_callback);
112
113 auto ui_task_completion_callback = fml::MakeCopyable(
114 [callback = std::move(persistent_completion_callback),
115 task_runners](impeller::CommandBuffer::Status status) mutable {
116 bool success = status != impeller::CommandBuffer::Status::kError;
117
118 auto ui_completion_task = fml::MakeCopyable(
119 [callback = std::move(callback), success]() mutable {
120 auto dart_state = callback->dart_state().lock();
121 if (!dart_state) {
122 // The root isolate could have died in the meantime.
123 return;
124 }
125 tonic::DartState::Scope scope(dart_state);
126
127 tonic::DartInvoke(callback->Get(), {tonic::ToDart(success)});
128
129 // callback is associated with the Dart isolate and must be
130 // deleted on the UI thread.
131 callback.reset();
132 });
133 task_runners.GetUITaskRunner()->PostTask(ui_completion_task);
134 });
135 bool success = wrapper->Submit(ui_task_completion_callback);
136 if (!success) {
137 return tonic::ToDart("Failed to submit CommandBuffer");
138 }
139 return Dart_Null();
140}
static UIDartState * Current()
CommandBuffer(std::shared_ptr< impeller::Context > context, std::shared_ptr< impeller::CommandBuffer > command_buffer)
std::shared_ptr< impeller::CommandBuffer > GetCommandBuffer()
void AddRenderPass(std::shared_ptr< impeller::RenderPass > render_pass)
std::shared_ptr< impeller::Context > & GetContextShared()
Definition context.cc:81
impeller::Context & GetContext()
Definition context.cc:77
std::function< void(Status)> CompletionCallback
virtual std::shared_ptr< CommandBuffer > CreateCommandBuffer() const =0
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
FlutterDesktopBinaryReply callback
Dart_Handle InternalFlutterGpu_CommandBuffer_Submit(flutter::gpu::CommandBuffer *wrapper, Dart_Handle completion_callback)
bool InternalFlutterGpu_CommandBuffer_Initialize(Dart_Handle wrapper, flutter::gpu::Context *contextWrapper)
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition ref_ptr.h:261
Dart_Handle ToDart(const T &object)
Dart_Handle DartInvoke(Dart_Handle closure, std::initializer_list< Dart_Handle > args)