Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
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
6
7#include <utility>
8
10#include "impeller/entity/gles/entity_shaders_gles.h"
11#include "impeller/entity/gles/framebuffer_blend_shaders_gles.h"
12#include "impeller/entity/gles/modern_shaders_gles.h"
13#include "impeller/entity/gles3/entity_shaders_gles.h"
14#include "impeller/entity/gles3/framebuffer_blend_shaders_gles.h"
15#include "impeller/entity/gles3/modern_shaders_gles.h"
18
19namespace flutter {
20
21namespace {
22std::vector<std::shared_ptr<fml::Mapping>> GetShaderMappings(bool is_gles3) {
23 if (is_gles3) {
24 return {
25 std::make_shared<fml::NonOwnedMapping>(
26 impeller_entity_shaders_gles3_data,
27 impeller_entity_shaders_gles3_length),
28 std::make_shared<fml::NonOwnedMapping>(
29 impeller_modern_shaders_gles3_data,
30 impeller_modern_shaders_gles3_length),
31 std::make_shared<fml::NonOwnedMapping>(
32 impeller_framebuffer_blend_shaders_gles3_data,
33 impeller_framebuffer_blend_shaders_gles3_length),
34 };
35 }
36 return {
37 std::make_shared<fml::NonOwnedMapping>(
38 impeller_entity_shaders_gles_data,
39 impeller_entity_shaders_gles_length),
40 std::make_shared<fml::NonOwnedMapping>(
41 impeller_modern_shaders_gles_data,
42 impeller_modern_shaders_gles_length),
43 std::make_shared<fml::NonOwnedMapping>(
44 impeller_framebuffer_blend_shaders_gles_data,
45 impeller_framebuffer_blend_shaders_gles_length),
46 };
47}
48} // namespace
49
51 public:
52 ReactorWorker() = default;
53
54 // |ReactorGLES::Worker|
56 const impeller::ReactorGLES& reactor) const override {
57 impeller::ReaderLock lock(mutex_);
58 auto found = reactions_allowed_.find(std::this_thread::get_id());
59 if (found == reactions_allowed_.end()) {
60 return false;
61 }
62 return found->second;
63 }
64
66 impeller::WriterLock lock(mutex_);
67 reactions_allowed_[std::this_thread::get_id()] = allowed;
68 }
69
70 private:
71 mutable impeller::RWMutex mutex_;
72 std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
73
75};
76
79 bool fbo_reset_after_present,
80 std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder,
81 impeller::Flags impeller_flags)
82 : gl_dispatch_table_(std::move(gl_dispatch_table)),
83 fbo_reset_after_present_(fbo_reset_after_present),
84 external_view_embedder_(std::move(external_view_embedder)),
85 worker_(std::make_shared<ReactorWorker>()) {
86 // Make sure all required members of the dispatch table are checked.
87 if (!gl_dispatch_table_.gl_make_current_callback ||
88 !gl_dispatch_table_.gl_clear_current_callback ||
89 !gl_dispatch_table_.gl_present_callback ||
90 !gl_dispatch_table_.gl_fbo_callback ||
91 !gl_dispatch_table_.gl_populate_existing_damage ||
92 !gl_dispatch_table_.gl_proc_resolver) {
93 return;
94 }
95 // Certain GL backends need to made current before any GL
96 // state can be accessed.
97 gl_dispatch_table_.gl_make_current_callback();
98
99 auto gl = std::make_unique<impeller::ProcTableGLES>(
100 gl_dispatch_table_.gl_proc_resolver);
101 if (!gl->IsValid()) {
102 return;
103 }
104
105 const auto is_gles3 =
106 gl->GetDescription()->GetGlVersion().IsAtLeast(impeller::Version(3));
107 const auto shader_mappings = GetShaderMappings(is_gles3);
108
109 impeller_context_ = impeller::ContextGLES::Create(
110 impeller_flags, std::move(gl), shader_mappings,
111 /*enable_gpu_tracing=*/false);
112
113 if (!impeller_context_) {
114 FML_LOG(ERROR) << "Could not create Impeller context.";
115 return;
116 }
117
118 auto worker_id = impeller_context_->AddReactorWorker(worker_);
119 if (!worker_id.has_value()) {
120 FML_LOG(ERROR) << "Could not add reactor worker.";
121 return;
122 }
123
124 gl_dispatch_table_.gl_clear_current_callback();
125 if (impeller_flags.use_sdfs) {
126 FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (OpenGLESSDF).";
127 } else {
128 FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (OpenGLES).";
129 }
130 valid_ = true;
131}
132
134
135// |EmbedderSurface|
136bool EmbedderSurfaceGLImpeller::IsValid() const {
137 return valid_;
138}
139
140// |GPUSurfaceGLDelegate|
141std::unique_ptr<GLContextResult>
142EmbedderSurfaceGLImpeller::GLContextMakeCurrent() {
143 worker_->SetReactionsAllowedOnCurrentThread(true);
144 return std::make_unique<GLContextDefaultResult>(
145 gl_dispatch_table_.gl_make_current_callback());
146}
147
148// |GPUSurfaceGLDelegate|
149bool EmbedderSurfaceGLImpeller::GLContextClearCurrent() {
150 worker_->SetReactionsAllowedOnCurrentThread(false);
151 return gl_dispatch_table_.gl_clear_current_callback();
152}
153
154// |GPUSurfaceGLDelegate|
155bool EmbedderSurfaceGLImpeller::GLContextPresent(
156 const GLPresentInfo& present_info) {
157 // Pass the present information to the embedder present callback.
158 return gl_dispatch_table_.gl_present_callback(present_info);
159}
160
161// |GPUSurfaceGLDelegate|
162GLFBOInfo EmbedderSurfaceGLImpeller::GLContextFBO(
163 GLFrameInfo frame_info) const {
164 // Get the FBO ID using the gl_fbo_callback and then get exiting damage by
165 // passing that ID to the gl_populate_existing_damage.
166 return gl_dispatch_table_.gl_populate_existing_damage(
167 gl_dispatch_table_.gl_fbo_callback(frame_info));
168}
169
170// |GPUSurfaceGLDelegate|
171bool EmbedderSurfaceGLImpeller::GLContextFBOResetAfterPresent() const {
172 return fbo_reset_after_present_;
173}
174
175// |GPUSurfaceGLDelegate|
176DlMatrix EmbedderSurfaceGLImpeller::GLContextSurfaceTransformation() const {
177 auto callback = gl_dispatch_table_.gl_surface_transformation_callback;
178 if (!callback) {
179 return DlMatrix();
180 }
181 return callback();
182}
183
184// |GPUSurfaceGLDelegate|
186EmbedderSurfaceGLImpeller::GetGLProcResolver() const {
187 return gl_dispatch_table_.gl_proc_resolver;
188}
189
190// |GPUSurfaceGLDelegate|
191SurfaceFrame::FramebufferInfo
192EmbedderSurfaceGLImpeller::GLContextFramebufferInfo() const {
193 // Enable partial repaint by default on the embedders.
194 auto info = SurfaceFrame::FramebufferInfo{};
195 info.supports_readback = true;
196 info.supports_partial_repaint =
197 gl_dispatch_table_.gl_populate_existing_damage != nullptr;
198 return info;
199}
200
201// |EmbedderSurface|
202std::unique_ptr<Surface> EmbedderSurfaceGLImpeller::CreateGPUSurface() {
203 // Ensure that the GL context is current before creating the GPU surface.
204 // GPUSurfaceGLImpeller initialization will set up shader pipelines, and the
205 // current thread needs to be able to execute reactor operations.
206 GLContextMakeCurrent();
207
208 return std::make_unique<GPUSurfaceGLImpeller>(
209 this, // GPU surface GL delegate
210 impeller_context_, // Impeller context
211 !external_view_embedder_ // render to surface
212 );
213}
214
215// |EmbedderSurface|
216std::shared_ptr<impeller::Context>
217EmbedderSurfaceGLImpeller::CreateImpellerContext() const {
218 return impeller_context_;
219}
220
221// |EmbedderSurface|
222sk_sp<GrDirectContext> EmbedderSurfaceGLImpeller::CreateResourceContext()
223 const {
224 if (gl_dispatch_table_.gl_make_resource_current_callback()) {
225 worker_->SetReactionsAllowedOnCurrentThread(true);
226 } else {
227 FML_DLOG(ERROR) << "Could not make the resource context current.";
228 worker_->SetReactionsAllowedOnCurrentThread(false);
229 }
230 return nullptr;
231}
232
233} // namespace flutter
EmbedderSurfaceGLImpeller(EmbedderSurfaceGLSkia::GLDispatchTable gl_dispatch_table, bool fbo_reset_after_present, std::shared_ptr< EmbedderExternalViewEmbedder > external_view_embedder, impeller::Flags impeller_flags={})
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(const Flags &flags, 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.
FlutterDesktopBinaryReply callback
#define FML_DLOG(severity)
Definition logging.h:121
#define FML_LOG(severity)
Definition logging.h:101
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
impeller::Matrix DlMatrix
Definition ref_ptr.h:261
std::function< GLFBOInfo(intptr_t)> gl_populate_existing_damage
std::function< intptr_t(GLFrameInfo)> gl_fbo_callback
std::function< bool(GLPresentInfo)> gl_present_callback
std::function< void *(const char *)> gl_proc_resolver
std::function< DlMatrix(void)> gl_surface_transformation_callback
bool use_sdfs
Use SDFs for rendering.
Definition flags.h:13
#define IPLR_GUARDED_BY(x)