Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
embedder_surface_gl_impeller.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 "flutter/shell/platform/embedder/embedder_surface_gl_impeller.h"
6
7#include <utility>
8
9#include "impeller/entity/gles/entity_shaders_gles.h"
10#include "impeller/entity/gles/framebuffer_blend_shaders_gles.h"
11#include "impeller/entity/gles/modern_shaders_gles.h"
14
15#if IMPELLER_ENABLE_3D
16#include "impeller/scene/shaders/gles/scene_shaders_gles.h" // nogncheck
17#endif // IMPELLER_ENABLE_3D
18
19namespace flutter {
20
22 public:
23 ReactorWorker() = default;
24
25 // |ReactorGLES::Worker|
27 const impeller::ReactorGLES& reactor) const override {
28 impeller::ReaderLock lock(mutex_);
29 auto found = reactions_allowed_.find(std::this_thread::get_id());
30 if (found == reactions_allowed_.end()) {
31 return false;
32 }
33 return found->second;
34 }
35
37 impeller::WriterLock lock(mutex_);
38 reactions_allowed_[std::this_thread::get_id()] = allowed;
39 }
40
41 private:
42 mutable impeller::RWMutex mutex_;
43 std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
44
46};
47
49 EmbedderSurfaceGL::GLDispatchTable gl_dispatch_table,
50 bool fbo_reset_after_present,
51 std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder)
52 : gl_dispatch_table_(std::move(gl_dispatch_table)),
53 fbo_reset_after_present_(fbo_reset_after_present),
54 external_view_embedder_(std::move(external_view_embedder)),
55 worker_(std::make_shared<ReactorWorker>()) {
56 // Make sure all required members of the dispatch table are checked.
57 if (!gl_dispatch_table_.gl_make_current_callback ||
58 !gl_dispatch_table_.gl_clear_current_callback ||
59 !gl_dispatch_table_.gl_present_callback ||
60 !gl_dispatch_table_.gl_fbo_callback ||
61 !gl_dispatch_table_.gl_populate_existing_damage ||
62 !gl_dispatch_table_.gl_proc_resolver) {
63 return;
64 }
65 // Certain GL backends need to made current before any GL
66 // state can be accessed.
67 gl_dispatch_table_.gl_make_current_callback();
68
69 std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
70 std::make_shared<fml::NonOwnedMapping>(
71 impeller_entity_shaders_gles_data,
72 impeller_entity_shaders_gles_length),
73 std::make_shared<fml::NonOwnedMapping>(
74 impeller_modern_shaders_gles_data,
75 impeller_modern_shaders_gles_length),
76 std::make_shared<fml::NonOwnedMapping>(
77 impeller_framebuffer_blend_shaders_gles_data,
78 impeller_framebuffer_blend_shaders_gles_length),
79#if IMPELLER_ENABLE_3D
80 std::make_shared<fml::NonOwnedMapping>(
81 impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
82#endif // IMPELLER_ENABLE_3D
83 };
84 auto gl = std::make_unique<impeller::ProcTableGLES>(
85 gl_dispatch_table_.gl_proc_resolver);
86 if (!gl->IsValid()) {
87 return;
88 }
89
90 impeller_context_ = impeller::ContextGLES::Create(
91 std::move(gl), shader_mappings, /*enable_gpu_tracing=*/false);
92
93 if (!impeller_context_) {
94 FML_LOG(ERROR) << "Could not create Impeller context.";
95 return;
96 }
97
98 auto worker_id = impeller_context_->AddReactorWorker(worker_);
99 if (!worker_id.has_value()) {
100 FML_LOG(ERROR) << "Could not add reactor worker.";
101 return;
102 }
103
104 gl_dispatch_table_.gl_clear_current_callback();
105 FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (OpenGL).";
106 valid_ = true;
107}
108
110
111// |EmbedderSurface|
113 return valid_;
114}
115
116// |GPUSurfaceGLDelegate|
117std::unique_ptr<GLContextResult>
119 worker_->SetReactionsAllowedOnCurrentThread(true);
120 return std::make_unique<GLContextDefaultResult>(
121 gl_dispatch_table_.gl_make_current_callback());
122}
123
124// |GPUSurfaceGLDelegate|
126 worker_->SetReactionsAllowedOnCurrentThread(false);
127 return gl_dispatch_table_.gl_clear_current_callback();
128}
129
130// |GPUSurfaceGLDelegate|
132 const GLPresentInfo& present_info) {
133 // Pass the present information to the embedder present callback.
134 return gl_dispatch_table_.gl_present_callback(present_info);
135}
136
137// |GPUSurfaceGLDelegate|
139 GLFrameInfo frame_info) const {
140 // Get the FBO ID using the gl_fbo_callback and then get exiting damage by
141 // passing that ID to the gl_populate_existing_damage.
142 return gl_dispatch_table_.gl_populate_existing_damage(
143 gl_dispatch_table_.gl_fbo_callback(frame_info));
144}
145
146// |GPUSurfaceGLDelegate|
148 return fbo_reset_after_present_;
149}
150
151// |GPUSurfaceGLDelegate|
153 auto callback = gl_dispatch_table_.gl_surface_transformation_callback;
154 if (!callback) {
155 SkMatrix matrix;
156 matrix.setIdentity();
157 return matrix;
158 }
159 return callback();
160}
161
162// |GPUSurfaceGLDelegate|
167
168// |GPUSurfaceGLDelegate|
171 // Enable partial repaint by default on the embedders.
173 info.supports_readback = true;
174 info.supports_partial_repaint =
175 gl_dispatch_table_.gl_populate_existing_damage != nullptr;
176 return info;
177}
178
179// |EmbedderSurface|
181 // Ensure that the GL context is current before creating the GPU surface.
182 // GPUSurfaceGLImpeller initialization will set up shader pipelines, and the
183 // current thread needs to be able to execute reactor operations.
185
186 return std::make_unique<GPUSurfaceGLImpeller>(
187 this, // GPU surface GL delegate
188 impeller_context_, // Impeller context
189 !external_view_embedder_ // render to surface
190 );
191}
192
193// |EmbedderSurface|
194std::shared_ptr<impeller::Context>
196 return impeller_context_;
197}
198
199// |EmbedderSurface|
201 const {
202 if (gl_dispatch_table_.gl_make_resource_current_callback()) {
203 worker_->SetReactionsAllowedOnCurrentThread(true);
204 } else {
205 FML_DLOG(ERROR) << "Could not make the resource context current.";
206 worker_->SetReactionsAllowedOnCurrentThread(false);
207 }
208 return nullptr;
209}
210
211} // namespace flutter
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
std::shared_ptr< impeller::Context > CreateImpellerContext() const override
SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override
std::unique_ptr< GLContextResult > GLContextMakeCurrent() override
bool GLContextPresent(const GLPresentInfo &present_info) override
EmbedderSurfaceGLImpeller(EmbedderSurfaceGL::GLDispatchTable gl_dispatch_table, bool fbo_reset_after_present, std::shared_ptr< EmbedderExternalViewEmbedder > external_view_embedder)
std::unique_ptr< Surface > CreateGPUSurface() override
GLProcResolver GetGLProcResolver() const override
GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override
sk_sp< GrDirectContext > CreateResourceContext() const override
std::function< void *(const char *)> GLProcResolver
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 ...
void SetReactionsAllowedOnCurrentThread(bool allowed)
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.
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DLOG(severity)
Definition logging.h:102
#define FML_LOG(severity)
Definition logging.h:82
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
Definition ref_ptr.h:256
std::function< bool(GLPresentInfo)> gl_present_callback
std::function< bool(void)> gl_clear_current_callback
std::function< void *(const char *)> gl_proc_resolver
std::function< bool(void)> gl_make_resource_current_callback
std::function< bool(void)> gl_make_current_callback
std::function< intptr_t(GLFrameInfo)> gl_fbo_callback
std::function< SkMatrix(void)> gl_surface_transformation_callback
std::function< GLFBOInfo(intptr_t)> gl_populate_existing_damage
#define ERROR(message)
#define IPLR_GUARDED_BY(x)