5#include "flutter/shell/platform/android/android_context_gl_impeller.h"
7#include "flutter/impeller/renderer/backend/gles/context_gles.h"
8#include "flutter/impeller/renderer/backend/gles/proc_table_gles.h"
9#include "flutter/impeller/renderer/backend/gles/reactor_gles.h"
10#include "flutter/impeller/toolkit/egl/context.h"
11#include "flutter/impeller/toolkit/egl/surface.h"
12#include "impeller/entity/gles/entity_shaders_gles.h"
13#include "impeller/entity/gles/framebuffer_blend_shaders_gles.h"
17#include "impeller/scene/shaders/gles/scene_shaders_gles.h"
33 auto found = reactions_allowed_.find(std::this_thread::get_id());
34 if (found == reactions_allowed_.end()) {
42 reactions_allowed_[std::this_thread::get_id()] = allowed;
46 mutable impeller::RWMutex mutex_;
47 std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
53 const std::shared_ptr<impeller::ReactorGLES::Worker>& worker,
54 bool enable_gpu_tracing) {
55 auto proc_table = std::make_unique<impeller::ProcTableGLES>(
58 if (!proc_table->IsValid()) {
63 std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
64 std::make_shared<fml::NonOwnedMapping>(
65 impeller_entity_shaders_gles_data,
66 impeller_entity_shaders_gles_length),
67 std::make_shared<fml::NonOwnedMapping>(
68 impeller_framebuffer_blend_shaders_gles_data,
69 impeller_framebuffer_blend_shaders_gles_length),
71 std::make_shared<fml::NonOwnedMapping>(
72 impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
77 std::move(proc_table), shader_mappings, enable_gpu_tracing);
79 FML_LOG(
ERROR) <<
"Could not create OpenGLES Impeller Context.";
83 if (!context->AddReactorWorker(worker).has_value()) {
87 FML_LOG(IMPORTANT) <<
"Using the Impeller rendering backend (OpenGLES).";
92 std::unique_ptr<impeller::egl::Display> display,
93 bool enable_gpu_tracing)
97 if (!display_ || !display_->IsValid()) {
98 FML_DLOG(
ERROR) <<
"Could not create context with invalid EGL display.";
110 std::unique_ptr<impeller::egl::Config> onscreen_config =
111 display_->ChooseConfig(
desc);
112 if (!onscreen_config) {
115 onscreen_config = display_->ChooseConfig(
desc);
116 if (onscreen_config) {
117 FML_LOG(INFO) <<
"Warning: This device doesn't support MSAA for onscreen "
118 "framebuffers. Falling back to a single sample.";
126 auto offscreen_config = display_->ChooseConfig(
desc);
127 if (!offscreen_config) {
132 auto onscreen_context = display_->CreateContext(*onscreen_config,
nullptr);
133 if (!onscreen_context) {
138 auto offscreen_context =
139 display_->CreateContext(*offscreen_config, onscreen_context.get());
140 if (!offscreen_context) {
147 auto offscreen_surface =
148 display_->CreatePixelBufferSurface(*offscreen_config, 1u, 1u);
149 if (!offscreen_context->MakeCurrent(*offscreen_surface)) {
150 FML_DLOG(
ERROR) <<
"Could not make offscreen context current.";
154 auto impeller_context =
157 if (!impeller_context) {
162 if (!offscreen_context->ClearCurrent()) {
169 reactor_worker_](impeller::egl ::Context::LifecycleEvent
event) {
172 worker->SetReactionsAllowedOnCurrentThread(
true);
175 worker->SetReactionsAllowedOnCurrentThread(
false);
179 if (!onscreen_context->AddLifecycleListener(listener).has_value() ||
180 !offscreen_context->AddLifecycleListener(listener).has_value()) {
184 onscreen_config_ = std::move(onscreen_config);
185 offscreen_config_ = std::move(offscreen_config);
186 onscreen_context_ = std::move(onscreen_context);
187 offscreen_context_ = std::move(offscreen_context);
200 if (!offscreen_context_) {
204 return offscreen_context_->ClearCurrent();
209 if (!offscreen_context_ || !offscreen_surface) {
213 return offscreen_context_->MakeCurrent(*offscreen_surface);
216std::unique_ptr<impeller::egl::Surface>
218 return display_->CreatePixelBufferSurface(*offscreen_config_, 1u, 1u);
223 if (!onscreen_surface || !onscreen_context_) {
227 return onscreen_context_->MakeCurrent(*onscreen_surface);
231 if (!onscreen_context_) {
235 return onscreen_context_->ClearCurrent();
238std::unique_ptr<impeller::egl::Surface>
240 return display_->CreateWindowSurface(*onscreen_config_,
window);
void SetReactionsAllowedOnCurrentThread(bool allowed)
bool CanReactorReactOnCurrentThreadNow(const impeller::ReactorGLES &reactor) const override
Determines the ability of the worker to service a reaction on the current thread. The OpenGL context ...
~ReactorWorker() override=default
std::unique_ptr< impeller::egl::Surface > CreateOnscreenSurface(EGLNativeWindowType window)
bool OnscreenContextMakeCurrent(impeller::egl::Surface *onscreen_surface)
bool OnscreenContextClearCurrent()
bool ResourceContextClearCurrent()
bool IsValid() const override
bool ResourceContextMakeCurrent(impeller::egl::Surface *offscreen_surface)
~AndroidContextGLImpeller()
std::unique_ptr< impeller::egl::Surface > CreateOffscreenSurface()
AndroidContextGLImpeller(std::unique_ptr< impeller::egl::Display > display, bool enable_gpu_tracing)
Holds state that is shared across Android surfaces.
void SetImpellerContext(const std::shared_ptr< impeller::Context > &context)
static std::shared_ptr< ContextGLES > Create(std::unique_ptr< ProcTableGLES > gl, const std::vector< std::shared_ptr< fml::Mapping > > &shader_libraries, bool enable_gpu_tracing)
A delegate implemented by a thread on which an OpenGL context is current. There may be multiple worke...
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
std::function< void(LifecycleEvent)> LifecycleListener
An instance of an EGL surface. There is no ability to create surfaces directly. Instead,...
#define FML_DLOG(severity)
#define FML_LOG(severity)
static std::shared_ptr< impeller::Context > CreateImpellerContext(const std::shared_ptr< impeller::ReactorGLES::Worker > &worker, bool enable_gpu_tracing)
std::function< void *(const char *)> CreateProcAddressResolver()
Creates a proc address resolver that resolves function pointers to EGL and OpenGL (ES) procs.