9 #include "flutter/fml/trace_event.h"
15 : proc_table_(
std::move(gl)) {
16 if (!proc_table_ || !proc_table_->IsValid()) {
20 can_set_debug_labels_ = proc_table_->GetDescription()->HasDebugExtension();
31 Lock lock(workers_mutex_);
33 workers_[id] = std::move(worker);
38 Lock lock(workers_mutex_);
39 return workers_.erase(worker) == 1;
42 bool ReactorGLES::HasPendingOperations()
const {
43 Lock ops_lock(ops_mutex_);
54 if (
auto found = handles_.find(handle); found != handles_.end()) {
55 if (found->second.pending_collection) {
57 <<
"Attempted to acquire a handle that was pending collection.";
60 if (!found->second.name.has_value()) {
61 VALIDATION_LOG <<
"Attempt to acquire a handle outside of an operation.";
64 return found->second.name;
75 Lock ops_lock(ops_mutex_);
76 ops_.emplace_back(std::move(operation));
79 [[maybe_unused]]
auto result =
React();
85 GLuint handle = GL_NONE;
90 gl.GenTextures(1u, &handle);
93 gl.GenBuffers(1u, &handle);
96 return gl.CreateProgram();
98 gl.GenRenderbuffers(1u, &handle);
101 gl.GenFramebuffers(1u, &handle);
114 gl.DeleteTextures(1u, &handle);
117 gl.DeleteBuffers(1u, &handle);
120 gl.DeleteProgram(handle);
123 gl.DeleteRenderbuffers(1u, &handle);
126 gl.DeleteFramebuffers(1u, &handle);
136 auto new_handle = HandleGLES::Create(type);
137 if (new_handle.IsDead()) {
141 auto gl_handle = CanReactOnCurrentThread()
144 handles_[new_handle] = LiveHandle{gl_handle};
150 if (
auto found = handles_.find(handle); found != handles_.end()) {
151 found->second.pending_collection =
true;
156 if (!CanReactOnCurrentThread()) {
159 TRACE_EVENT0(
"impeller",
"ReactorGLES::React");
160 while (HasPendingOperations()) {
186 bool ReactorGLES::ReactOnce() {
190 TRACE_EVENT0(
"impeller", __FUNCTION__);
191 return ConsolidateHandles() && FlushOps();
194 bool ReactorGLES::ConsolidateHandles() {
195 TRACE_EVENT0(
"impeller", __FUNCTION__);
197 WriterLock handles_lock(handles_mutex_);
198 std::vector<HandleGLES> handles_to_delete;
199 for (
auto& handle : handles_) {
201 if (handle.second.pending_collection) {
204 if (handle.second.name.has_value()) {
207 handles_to_delete.push_back(handle.first);
211 if (!handle.second.name.has_value()) {
217 handle.second.name = gl_handle;
220 if (handle.second.pending_debug_label.has_value()) {
222 handle.second.name.value(),
223 handle.second.pending_debug_label.value())) {
224 handle.second.pending_debug_label = std::nullopt;
228 for (
const auto& handle_to_delete : handles_to_delete) {
229 handles_.erase(handle_to_delete);
234 bool ReactorGLES::FlushOps() {
235 TRACE_EVENT0(
"impeller", __FUNCTION__);
240 Lock ops_lock(ops_mutex_);
241 std::swap(ops_, ops);
243 for (
const auto& op : ops) {
244 TRACE_EVENT0(
"impeller",
"ReactorGLES::Operation");
251 if (!can_set_debug_labels_) {
258 if (
auto found = handles_.find(handle); found != handles_.end()) {
259 found->second.pending_debug_label = std::move(label);
263 bool ReactorGLES::CanReactOnCurrentThread()
const {
264 std::vector<WorkerID> dead_workers;
265 Lock lock(workers_mutex_);
266 for (
const auto& worker : workers_) {
267 auto worker_ptr = worker.second.lock();
269 dead_workers.push_back(worker.first);
272 if (worker_ptr->CanReactorReactOnCurrentThreadNow(*
this)) {
276 for (
const auto& worker_id : dead_workers) {
277 workers_.erase(worker_id);