| 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
5 #include "impeller/playground/backend/gles/playground_impl_gles.h"
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"
14 #include "impeller/renderer/backend/gles/context_gles.h"
15 #include "impeller/renderer/backend/gles/surface_gles.h"
16 #include "impeller/scene/shaders/gles/scene_shaders_gles.h"
17
18 namespace impeller {
19
20 class PlaygroundImplGLES::ReactorWorker final : public ReactorGLES::Worker {
21 public:
22 ReactorWorker() = default;
23
24 // |ReactorGLES::Worker|
25 bool CanReactorReactOnCurrentThreadNow(
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
35 void SetReactionsAllowedOnCurrentThread(bool allowed) {
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 ReactorWorker(const ReactorWorker&) = delete;
45
46 ReactorWorker& operator=(const ReactorWorker&) = delete;
47 };
48
49 void PlaygroundImplGLES::DestroyWindowHandle(WindowHandle handle) {
50 if (!handle) {
51 return;
52 }
53 ::glfwDestroyWindow(reinterpret_cast<GLFWwindow*>(handle));
54 }
55
56 PlaygroundImplGLES::PlaygroundImplGLES(PlaygroundSwitches switches)
57 : PlaygroundImpl(switches),
58 handle_(nullptr, &DestroyWindowHandle),
59 worker_(std::shared_ptr<ReactorWorker>(new ReactorWorker())) {
60 ::glfwDefaultWindowHints();
61
62 #if FML_OS_MACOSX
63 // ES Profiles are not supported on Mac.
64 ::glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
65 #else // FML_OS_MACOSX
66 ::glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
67 ::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
68 ::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
69 #endif // FML_OS_MACOSX
70 ::glfwWindowHint(GLFW_RED_BITS, 8);
71 ::glfwWindowHint(GLFW_GREEN_BITS, 8);
72 ::glfwWindowHint(GLFW_BLUE_BITS, 8);
73 ::glfwWindowHint(GLFW_ALPHA_BITS, 8);
74 ::glfwWindowHint(GLFW_DEPTH_BITS, 32); // 32 bit depth buffer
75 ::glfwWindowHint(GLFW_STENCIL_BITS, 8); // 8 bit stencil buffer
76 ::glfwWindowHint(GLFW_SAMPLES, 4); // 4xMSAA
77
78 ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
79
80 auto window = ::glfwCreateWindow(1, 1, "Test", nullptr, nullptr);
81
82 ::glfwMakeContextCurrent(window);
83 worker_->SetReactionsAllowedOnCurrentThread(true);
84
85 handle_.reset(window);
86 }
87
88 PlaygroundImplGLES::~PlaygroundImplGLES() = default;
89
90 static std::vector<std::shared_ptr<fml::Mapping>>
91 ShaderLibraryMappingsForPlayground() {
92 return {
93 std::make_shared<fml::NonOwnedMapping>(
94 impeller_entity_shaders_gles_data,
95 impeller_entity_shaders_gles_length),
96 std::make_shared<fml::NonOwnedMapping>(
97 impeller_fixtures_shaders_gles_data,
98 impeller_fixtures_shaders_gles_length),
99 std::make_shared<fml::NonOwnedMapping>(
100 impeller_imgui_shaders_gles_data, impeller_imgui_shaders_gles_length),
101 std::make_shared<fml::NonOwnedMapping>(
102 impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
103 };
104 }
105
106 // |PlaygroundImpl|
107 std::shared_ptr<Context> PlaygroundImplGLES::GetContext() const {
108 auto resolver = [](const char* name) -> void* {
109 return reinterpret_cast<void*>(::glfwGetProcAddress(name));
110 };
111 auto gl = std::make_unique<ProcTableGLES>(resolver);
112 if (!gl->IsValid()) {
113 FML_LOG(ERROR) << "Proc table when creating a playground was invalid.";
114 return nullptr;
115 }
116
117 auto context = ContextGLES::Create(
118 std::move(gl), ShaderLibraryMappingsForPlayground(), true);
119 if (!context) {
120 FML_LOG(ERROR) << "Could not create context.";
121 return nullptr;
122 }
123
124 auto worker_id = context->AddReactorWorker(worker_);
125 if (!worker_id.has_value()) {
126 FML_LOG(ERROR) << "Could not add reactor worker.";
127 return nullptr;
128 }
129 return context;
130 }
131
132 // |PlaygroundImpl|
133 PlaygroundImpl::WindowHandle PlaygroundImplGLES::GetWindowHandle() const {
134 return handle_.get();
135 }
136
137 // |PlaygroundImpl|
138 std::unique_ptr<Surface> PlaygroundImplGLES::AcquireSurfaceFrame(
139 std::shared_ptr<Context> context) {
140 auto window = reinterpret_cast<GLFWwindow*>(GetWindowHandle());
141 int width = 0;
142 int height = 0;
143 ::glfwGetFramebufferSize(window, &width, &height);
144 if (width <= 0 || height <= 0) {
145 return nullptr;
146 }
147 SurfaceGLES::SwapCallback swap_callback = [window]() -> bool {
148 ::glfwSwapBuffers(window);
149 return true;
150 };
151 return SurfaceGLES::WrapFBO(context, //
152 swap_callback, //
153 0u, //
154 PixelFormat::kR8G8B8A8UNormInt, //
155 ISize::MakeWH(width, height) //
156 );
157 }
158
159 fml::Status PlaygroundImplGLES::SetCapabilities(
160 const std::shared_ptr<Capabilities>& capabilities) {
161 return fml::Status(
162 fml::StatusCode::kUnimplemented,
163 "PlaygroundImplGLES doesn't support setting the capabilities.");
164 }
165
166 } // namespace impeller
impeller::PlaygroundImplGLES::SetCapabilities
fml::Status SetCapabilities(const std::shared_ptr< Capabilities > &capabilities) override
Definition: playground_impl_gles.cc:159
playground_impl_gles.h
impeller::PlaygroundImplGLES::ReactorWorker::ReactorWorker
ReactorWorker()=default
impeller::PlaygroundImplGLES::~PlaygroundImplGLES
~PlaygroundImplGLES()
impeller::WriterLock
Definition: thread.h:116
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
context_gles.h
impeller::PlaygroundImplGLES::ReactorWorker
Definition: playground_impl_gles.cc:20
impeller::ReactorGLES::Worker
A delegate implemented by a thread on which an OpenGL context is current. There may be multiple worke...
Definition: reactor_gles.h:68
impeller::PlaygroundImpl
Definition: playground_impl.h:18
surface_gles.h
impeller::ContextGLES::Create
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)
Definition: context_gles.cc:15
impeller::ReaderLock
Definition: thread.h:95
impeller::ShaderLibraryMappingsForPlayground
static std::vector< std::shared_ptr< fml::Mapping > > ShaderLibraryMappingsForPlayground()
Definition: playground_impl_gles.cc:91
impeller::PlaygroundImplGLES::ReactorWorker::CanReactorReactOnCurrentThreadNow
bool CanReactorReactOnCurrentThreadNow(const ReactorGLES &reactor) const override
Determines the ability of the worker to service a reaction on the current thread. The OpenGL context ...
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:16
std
Definition: comparable.h:95
impeller::SurfaceGLES::SwapCallback
std::function< bool(void)> SwapCallback
Definition: surface_gles.h:20
impeller::PlaygroundImplGLES::PlaygroundImplGLES
PlaygroundImplGLES(PlaygroundSwitches switches)
Definition: playground_impl_gles.cc:56
impeller::ReactorGLES
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
Definition: reactor_gles.h:56
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:34
impeller
Definition: aiks_context.cc:10
impeller::PlaygroundImpl::WindowHandle
void * WindowHandle
Definition: playground_impl.h:25