7 #define IMPELLER_PLAYGROUND_SUPPORTS_ANGLE FML_OS_MACOSX 
    9 #if IMPELLER_PLAYGROUND_SUPPORTS_ANGLE 
   13 #define GLFW_INCLUDE_NONE 
   14 #include "third_party/glfw/include/GLFW/glfw3.h" 
   16 #include "flutter/fml/build_config.h" 
   17 #include "impeller/entity/gles/entity_shaders_gles.h" 
   18 #include "impeller/entity/gles/framebuffer_blend_shaders_gles.h" 
   19 #include "impeller/entity/gles/modern_shaders_gles.h" 
   20 #include "impeller/fixtures/gles/fixtures_shaders_gles.h" 
   21 #include "impeller/fixtures/gles/modern_fixtures_shaders_gles.h" 
   22 #include "impeller/playground/imgui/gles/imgui_shaders_gles.h" 
   36     auto found = reactions_allowed_.find(std::this_thread::get_id());
 
   37     if (found == reactions_allowed_.end()) {
 
   45     reactions_allowed_[std::this_thread::get_id()] = allowed;
 
   49   mutable RWMutex mutex_;
 
   50   std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
 
   57 void PlaygroundImplGLES::DestroyWindowHandle(WindowHandle handle) {
 
   61   ::glfwDestroyWindow(
reinterpret_cast<GLFWwindow*
>(handle));
 
   66       handle_(nullptr, &DestroyWindowHandle),
 
   68       use_angle_(switches.use_angle) {
 
   70 #if IMPELLER_PLAYGROUND_SUPPORTS_ANGLE 
   71     angle_glesv2_ = dlopen(
"libGLESv2.dylib", RTLD_LAZY);
 
   73     FML_CHECK(angle_glesv2_ != 
nullptr);
 
   76   ::glfwDefaultWindowHints();
 
   79   FML_CHECK(use_angle_) << 
"Must use Angle on macOS for OpenGL ES.";
 
   80   ::glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
 
   82   ::glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
 
   83   ::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
 
   84   ::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
 
   85   ::glfwWindowHint(GLFW_RED_BITS, 8);
 
   86   ::glfwWindowHint(GLFW_GREEN_BITS, 8);
 
   87   ::glfwWindowHint(GLFW_BLUE_BITS, 8);
 
   88   ::glfwWindowHint(GLFW_ALPHA_BITS, 8);
 
   89   ::glfwWindowHint(GLFW_DEPTH_BITS, 32);   
 
   90   ::glfwWindowHint(GLFW_STENCIL_BITS, 8);  
 
   91   ::glfwWindowHint(GLFW_SAMPLES, 4);       
 
   93   ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
 
   95   auto window = ::glfwCreateWindow(1, 1, 
"Test", 
nullptr, 
nullptr);
 
   97   ::glfwMakeContextCurrent(window);
 
   98   worker_->SetReactionsAllowedOnCurrentThread(
true);
 
  100   handle_.reset(window);
 
  105 static std::vector<std::shared_ptr<fml::Mapping>>
 
  108       std::make_shared<fml::NonOwnedMapping>(
 
  109           impeller_entity_shaders_gles_data,
 
  110           impeller_entity_shaders_gles_length),
 
  111       std::make_shared<fml::NonOwnedMapping>(
 
  112           impeller_modern_shaders_gles_data,
 
  113           impeller_modern_shaders_gles_length),
 
  114       std::make_shared<fml::NonOwnedMapping>(
 
  115           impeller_framebuffer_blend_shaders_gles_data,
 
  116           impeller_framebuffer_blend_shaders_gles_length),
 
  117       std::make_shared<fml::NonOwnedMapping>(
 
  118           impeller_fixtures_shaders_gles_data,
 
  119           impeller_fixtures_shaders_gles_length),
 
  120       std::make_shared<fml::NonOwnedMapping>(
 
  121           impeller_modern_fixtures_shaders_gles_data,
 
  122           impeller_modern_fixtures_shaders_gles_length),
 
  123       std::make_shared<fml::NonOwnedMapping>(
 
  124           impeller_imgui_shaders_gles_data, impeller_imgui_shaders_gles_length),
 
  129 std::shared_ptr<Context> PlaygroundImplGLES::GetContext()
 const {
 
  130   auto gl = std::make_unique<ProcTableGLES>(CreateGLProcAddressResolver());
 
  131   if (!gl->IsValid()) {
 
  132     FML_LOG(ERROR) << 
"Proc table when creating a playground was invalid.";
 
  140     FML_LOG(ERROR) << 
"Could not create context.";
 
  144   auto worker_id = context->AddReactorWorker(worker_);
 
  145   if (!worker_id.has_value()) {
 
  146     FML_LOG(ERROR) << 
"Could not add reactor worker.";
 
  154 PlaygroundImplGLES::CreateGLProcAddressResolver()
 const {
 
  155   return use_angle_ ? [](
const char* name) -> 
void* {
 
  156     void* symbol = 
nullptr;
 
  157 #if IMPELLER_PLAYGROUND_SUPPORTS_ANGLE 
  158     void* angle_glesv2 = dlopen(
"libGLESv2.dylib", RTLD_LAZY);
 
  159     symbol = dlsym(angle_glesv2, name);
 
  164   : [](
const char* name) -> 
void* {
 
  165       return reinterpret_cast<void*
>(::glfwGetProcAddress(name));
 
  171   return handle_.get();
 
  175 std::unique_ptr<Surface> PlaygroundImplGLES::AcquireSurfaceFrame(
 
  176     std::shared_ptr<Context> context) {
 
  177   auto window = 
reinterpret_cast<GLFWwindow*
>(GetWindowHandle());
 
  180   ::glfwGetFramebufferSize(window, &width, &height);
 
  181   if (width <= 0 || height <= 0) {
 
  185     ::glfwSwapBuffers(window);
 
  197     const std::shared_ptr<Capabilities>& capabilities) {
 
  199       fml::StatusCode::kUnimplemented,
 
  200       "PlaygroundImplGLES doesn't support setting the capabilities.");
 
static std::shared_ptr< ContextGLES > Create(const Flags &flags, std::unique_ptr< ProcTableGLES > gl, const std::vector< std::shared_ptr< fml::Mapping >> &shader_libraries, bool enable_gpu_tracing)
std::function< void *(const char *proc_name)> GLProcAddressResolver
bool CanReactorReactOnCurrentThreadNow(const ReactorGLES &reactor) const override
Determines the ability of the worker to service a reaction on the current thread. The OpenGL context ...
void SetReactionsAllowedOnCurrentThread(bool allowed)
PlaygroundImplGLES(PlaygroundSwitches switches)
fml::Status SetCapabilities(const std::shared_ptr< Capabilities > &capabilities) override
const PlaygroundSwitches switches_
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.
static std::unique_ptr< Surface > WrapFBO(const std::shared_ptr< Context > &context, SwapCallback swap_callback, GLuint fbo, PixelFormat color_format, ISize fbo_size)
std::function< bool(void)> SwapCallback
static std::vector< std::shared_ptr< fml::Mapping > > ShaderLibraryMappingsForPlayground()
static constexpr TSize MakeWH(Type width, Type height)