Flutter Impeller
playground_impl_gles.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 #define GLFW_INCLUDE_NONE
8 #include "third_party/glfw/include/GLFW/glfw3.h"
9 
10 #include "flutter/fml/build_config.h"
11 #include "impeller/entity/gles/entity_shaders_gles.h"
12 #include "impeller/fixtures/gles/fixtures_shaders_gles.h"
13 #include "impeller/playground/imgui/gles/imgui_shaders_gles.h"
16 #include "impeller/scene/shaders/gles/scene_shaders_gles.h"
17 
18 namespace impeller {
19 
21  public:
22  ReactorWorker() = default;
23 
24  // |ReactorGLES::Worker|
26  const ReactorGLES& reactor) const override {
27  ReaderLock lock(mutex_);
28  auto found = reactions_allowed_.find(std::this_thread::get_id());
29  if (found == reactions_allowed_.end()) {
30  return false;
31  }
32  return found->second;
33  }
34 
36  WriterLock lock(mutex_);
37  reactions_allowed_[std::this_thread::get_id()] = allowed;
38  }
39 
40  private:
41  mutable RWMutex mutex_;
42  std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
43 
44  FML_DISALLOW_COPY_AND_ASSIGN(ReactorWorker);
45 };
46 
47 void PlaygroundImplGLES::DestroyWindowHandle(WindowHandle handle) {
48  if (!handle) {
49  return;
50  }
51  ::glfwDestroyWindow(reinterpret_cast<GLFWwindow*>(handle));
52 }
53 
55  : PlaygroundImpl(switches),
56  handle_(nullptr, &DestroyWindowHandle),
57  worker_(std::shared_ptr<ReactorWorker>(new ReactorWorker())) {
58  ::glfwDefaultWindowHints();
59 
60 #if FML_OS_MACOSX
61  // ES Profiles are not supported on Mac.
62  ::glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
63 #else // FML_OS_MACOSX
64  ::glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
65  ::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
66  ::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
67 #endif // FML_OS_MACOSX
68  ::glfwWindowHint(GLFW_RED_BITS, 8);
69  ::glfwWindowHint(GLFW_GREEN_BITS, 8);
70  ::glfwWindowHint(GLFW_BLUE_BITS, 8);
71  ::glfwWindowHint(GLFW_ALPHA_BITS, 8);
72  ::glfwWindowHint(GLFW_DEPTH_BITS, 32); // 32 bit depth buffer
73  ::glfwWindowHint(GLFW_STENCIL_BITS, 8); // 8 bit stencil buffer
74  ::glfwWindowHint(GLFW_SAMPLES, 4); // 4xMSAA
75 
76  ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
77 
78  auto window = ::glfwCreateWindow(1, 1, "Test", nullptr, nullptr);
79 
80  ::glfwMakeContextCurrent(window);
81  worker_->SetReactionsAllowedOnCurrentThread(true);
82 
83  handle_.reset(window);
84 }
85 
87 
88 static std::vector<std::shared_ptr<fml::Mapping>>
90  return {
91  std::make_shared<fml::NonOwnedMapping>(
92  impeller_entity_shaders_gles_data,
93  impeller_entity_shaders_gles_length),
94  std::make_shared<fml::NonOwnedMapping>(
95  impeller_fixtures_shaders_gles_data,
96  impeller_fixtures_shaders_gles_length),
97  std::make_shared<fml::NonOwnedMapping>(
98  impeller_imgui_shaders_gles_data, impeller_imgui_shaders_gles_length),
99  std::make_shared<fml::NonOwnedMapping>(
100  impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
101  };
102 }
103 
104 // |PlaygroundImpl|
105 std::shared_ptr<Context> PlaygroundImplGLES::GetContext() const {
106  auto resolver = [](const char* name) -> void* {
107  return reinterpret_cast<void*>(::glfwGetProcAddress(name));
108  };
109  auto gl = std::make_unique<ProcTableGLES>(resolver);
110  if (!gl->IsValid()) {
111  FML_LOG(ERROR) << "Proc table when creating a playground was invalid.";
112  return nullptr;
113  }
114 
115  auto context =
117  if (!context) {
118  FML_LOG(ERROR) << "Could not create context.";
119  return nullptr;
120  }
121 
122  auto worker_id = context->AddReactorWorker(worker_);
123  if (!worker_id.has_value()) {
124  FML_LOG(ERROR) << "Could not add reactor worker.";
125  return nullptr;
126  }
127  return context;
128 }
129 
130 // |PlaygroundImpl|
131 PlaygroundImpl::WindowHandle PlaygroundImplGLES::GetWindowHandle() const {
132  return handle_.get();
133 }
134 
135 // |PlaygroundImpl|
136 std::unique_ptr<Surface> PlaygroundImplGLES::AcquireSurfaceFrame(
137  std::shared_ptr<Context> context) {
138  auto window = reinterpret_cast<GLFWwindow*>(GetWindowHandle());
139  int width = 0;
140  int height = 0;
141  ::glfwGetFramebufferSize(window, &width, &height);
142  if (width <= 0 || height <= 0) {
143  return nullptr;
144  }
145  SurfaceGLES::SwapCallback swap_callback = [window]() -> bool {
146  ::glfwSwapBuffers(window);
147  return true;
148  };
149  return SurfaceGLES::WrapFBO(context, //
150  swap_callback, //
151  0u, //
153  ISize::MakeWH(width, height) //
154  );
155 }
156 
157 } // namespace impeller
playground_impl_gles.h
impeller::PlaygroundImplGLES::ReactorWorker::ReactorWorker
ReactorWorker()=default
impeller::PlaygroundImplGLES::~PlaygroundImplGLES
~PlaygroundImplGLES()
impeller::WriterLock
Definition: thread.h:83
context_gles.h
impeller::PlaygroundImplGLES::ReactorWorker
Definition: playground_impl_gles.cc:20
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::ReactorGLES::Worker
Definition: reactor_gles.h:23
impeller::PlaygroundImpl
Definition: playground_impl.h:17
surface_gles.h
impeller::ReaderLock
Definition: thread.h:68
impeller::ShaderLibraryMappingsForPlayground
static std::vector< std::shared_ptr< fml::Mapping > > ShaderLibraryMappingsForPlayground()
Definition: playground_impl_gles.cc:89
impeller::PlaygroundImplGLES::ReactorWorker::CanReactorReactOnCurrentThreadNow
bool CanReactorReactOnCurrentThreadNow(const ReactorGLES &reactor) const override
Definition: playground_impl_gles.cc:25
impeller::PlaygroundImplGLES::ReactorWorker::SetReactionsAllowedOnCurrentThread
void SetReactionsAllowedOnCurrentThread(bool allowed)
Definition: playground_impl_gles.cc:35
impeller::PlaygroundSwitches
Definition: switches.h:15
std
Definition: comparable.h:98
impeller::SurfaceGLES::SwapCallback
std::function< bool(void)> SwapCallback
Definition: surface_gles.h:19
impeller::PlaygroundImplGLES::PlaygroundImplGLES
PlaygroundImplGLES(PlaygroundSwitches switches)
Definition: playground_impl_gles.cc:54
impeller::ReactorGLES
Definition: reactor_gles.h:19
impeller::ContextGLES::Create
static std::shared_ptr< ContextGLES > Create(std::unique_ptr< ProcTableGLES > gl, const std::vector< std::shared_ptr< fml::Mapping >> &shader_libraries)
Definition: context_gles.cc:12
impeller::SurfaceGLES::WrapFBO
static std::unique_ptr< Surface > WrapFBO(const std::shared_ptr< Context > &context, SwapCallback swap_callback, GLuint fbo, PixelFormat color_format, ISize fbo_size)
Definition: surface_gles.cc:14
impeller::TSize< int64_t >::MakeWH
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:33
impeller
Definition: aiks_context.cc:10
impeller::PlaygroundImpl::WindowHandle
void * WindowHandle
Definition: playground_impl.h:24