9 #include "flutter/fml/trace_event.h"
10 #include "fml/logging.h"
16 : proc_table_(
std::move(gl)) {
17 if (!proc_table_ || !proc_table_->IsValid()) {
21 can_set_debug_labels_ = proc_table_->GetDescription()->HasDebugExtension();
32 Lock lock(workers_mutex_);
34 workers_[id] = std::move(worker);
39 Lock lock(workers_mutex_);
40 return workers_.erase(worker) == 1;
43 bool ReactorGLES::HasPendingOperations()
const {
44 Lock ops_lock(ops_mutex_);
55 if (
auto found = handles_.find(handle); found != handles_.end()) {
56 if (found->second.pending_collection) {
58 <<
"Attempted to acquire a handle that was pending collection.";
61 if (!found->second.name.has_value()) {
62 VALIDATION_LOG <<
"Attempt to acquire a handle outside of an operation.";
65 return found->second.name;
76 Lock ops_lock(ops_mutex_);
77 ops_.emplace_back(std::move(operation));
80 [[maybe_unused]]
auto result =
React();
86 GLuint handle = GL_NONE;
91 gl.GenTextures(1u, &handle);
94 gl.GenBuffers(1u, &handle);
97 return gl.CreateProgram();
99 gl.GenRenderbuffers(1u, &handle);
102 gl.GenFramebuffers(1u, &handle);
115 gl.DeleteTextures(1u, &handle);
118 gl.DeleteBuffers(1u, &handle);
121 gl.DeleteProgram(handle);
124 gl.DeleteRenderbuffers(1u, &handle);
127 gl.DeleteFramebuffers(1u, &handle);
137 auto new_handle = HandleGLES::Create(type);
138 if (new_handle.IsDead()) {
142 auto gl_handle = CanReactOnCurrentThread()
145 handles_[new_handle] = LiveHandle{gl_handle};
151 if (
auto found = handles_.find(handle); found != handles_.end()) {
152 found->second.pending_collection =
true;
157 if (!CanReactOnCurrentThread()) {
160 TRACE_EVENT0(
"impeller",
"ReactorGLES::React");
161 while (HasPendingOperations()) {
164 Lock execution_lock(ops_execution_mutex_);
191 bool ReactorGLES::ReactOnce() {
195 TRACE_EVENT0(
"impeller", __FUNCTION__);
196 return ConsolidateHandles() && FlushOps();
199 bool ReactorGLES::ConsolidateHandles() {
200 TRACE_EVENT0(
"impeller", __FUNCTION__);
202 WriterLock handles_lock(handles_mutex_);
203 std::vector<HandleGLES> handles_to_delete;
204 for (
auto& handle : handles_) {
206 if (handle.second.pending_collection) {
209 if (handle.second.name.has_value()) {
212 handles_to_delete.push_back(handle.first);
216 if (!handle.second.name.has_value()) {
222 handle.second.name = gl_handle;
225 if (handle.second.pending_debug_label.has_value()) {
227 handle.second.name.value(),
228 handle.second.pending_debug_label.value())) {
229 handle.second.pending_debug_label = std::nullopt;
233 for (
const auto& handle_to_delete : handles_to_delete) {
234 handles_.erase(handle_to_delete);
239 bool ReactorGLES::FlushOps() {
240 TRACE_EVENT0(
"impeller", __FUNCTION__);
242 #ifdef IMPELLER_DEBUG
252 Lock ops_lock(ops_mutex_);
253 std::swap(ops_, ops);
255 for (
const auto& op : ops) {
256 TRACE_EVENT0(
"impeller",
"ReactorGLES::Operation");
262 void ReactorGLES::SetupDebugGroups() {
264 if (proc_table_->DebugMessageControlKHR.IsAvailable()) {
265 proc_table_->DebugMessageControlKHR(GL_DONT_CARE,
275 if (!can_set_debug_labels_) {
282 if (
auto found = handles_.find(handle); found != handles_.end()) {
283 found->second.pending_debug_label = std::move(label);
287 bool ReactorGLES::CanReactOnCurrentThread()
const {
288 std::vector<WorkerID> dead_workers;
289 Lock lock(workers_mutex_);
290 for (
const auto& worker : workers_) {
291 auto worker_ptr = worker.second.lock();
293 dead_workers.push_back(worker.first);
296 if (worker_ptr->CanReactorReactOnCurrentThreadNow(*
this)) {
300 for (
const auto& worker_id : dead_workers) {
301 workers_.erase(worker_id);