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
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"
15
16namespace flutter {
17
19 public:
20 ReactorWorker() = default;
21
22 // |ReactorGLES::Worker|
24 const impeller::ReactorGLES& reactor) const override {
25 impeller::ReaderLock lock(mutex_);
26 auto found = reactions_allowed_.find(std::this_thread::get_id());
27 if (found == reactions_allowed_.end()) {
28 return false;
29 }
30 return found->second;
31 }
32
34 impeller::WriterLock lock(mutex_);
35 reactions_allowed_[std::this_thread::get_id()] = allowed;
36 }
37
38 private:
39 mutable impeller::RWMutex mutex_;
40 std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
41
43};
44
47 bool fbo_reset_after_present,
48 std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder)
49 : gl_dispatch_table_(std::move(gl_dispatch_table)),
50 fbo_reset_after_present_(fbo_reset_after_present),
51 external_view_embedder_(std::move(external_view_embedder)),
52 worker_(std::make_shared<ReactorWorker>()) {
53 // Make sure all required members of the dispatch table are checked.
54 if (!gl_dispatch_table_.gl_make_current_callback ||
55 !gl_dispatch_table_.gl_clear_current_callback ||
56 !gl_dispatch_table_.gl_present_callback ||
57 !gl_dispatch_table_.gl_fbo_callback ||
58 !gl_dispatch_table_.gl_populate_existing_damage ||
59 !gl_dispatch_table_.gl_proc_resolver) {
60 return;
61 }
62 // Certain GL backends need to made current before any GL
63 // state can be accessed.
64 gl_dispatch_table_.gl_make_current_callback();
65
66 std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
67 std::make_shared<fml::NonOwnedMapping>(
68 impeller_entity_shaders_gles_data,
69 impeller_entity_shaders_gles_length),
70 std::make_shared<fml::NonOwnedMapping>(
71 impeller_modern_shaders_gles_data,
72 impeller_modern_shaders_gles_length),
73 std::make_shared<fml::NonOwnedMapping>(
74 impeller_framebuffer_blend_shaders_gles_data,
75 impeller_framebuffer_blend_shaders_gles_length),
76 };
77 auto gl = std::make_unique<impeller::ProcTableGLES>(
78 gl_dispatch_table_.gl_proc_resolver);
79 if (!gl->IsValid()) {
80 return;
81 }
82
83 impeller_context_ = impeller::ContextGLES::Create(
84 impeller::Flags{}, std::move(gl), shader_mappings,
85 /*enable_gpu_tracing=*/false);
86
87 if (!impeller_context_) {
88 FML_LOG(ERROR) << "Could not create Impeller context.";
89 return;
90 }
91
92 auto worker_id = impeller_context_->AddReactorWorker(worker_);
93 if (!worker_id.has_value()) {
94 FML_LOG(ERROR) << "Could not add reactor worker.";
95 return;
96 }
97
98 gl_dispatch_table_.gl_clear_current_callback();
99 FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (OpenGL).";
100 valid_ = true;
101}
102
104
105// |EmbedderSurface|
106bool EmbedderSurfaceGLImpeller::IsValid() const {
107 return valid_;
108}
109
110// |GPUSurfaceGLDelegate|
111std::unique_ptr<GLContextResult>
112EmbedderSurfaceGLImpeller::GLContextMakeCurrent() {
113 worker_->SetReactionsAllowedOnCurrentThread(true);
114 return std::make_unique<GLContextDefaultResult>(
115 gl_dispatch_table_.gl_make_current_callback());
116}
117
118// |GPUSurfaceGLDelegate|
119bool EmbedderSurfaceGLImpeller::GLContextClearCurrent() {
120 worker_->SetReactionsAllowedOnCurrentThread(false);
121 return gl_dispatch_table_.gl_clear_current_callback();
122}
123
124// |GPUSurfaceGLDelegate|
125bool EmbedderSurfaceGLImpeller::GLContextPresent(
126 const GLPresentInfo& present_info) {
127 // Pass the present information to the embedder present callback.
128 return gl_dispatch_table_.gl_present_callback(present_info);
129}
130
131// |GPUSurfaceGLDelegate|
132GLFBOInfo EmbedderSurfaceGLImpeller::GLContextFBO(
133 GLFrameInfo frame_info) const {
134 // Get the FBO ID using the gl_fbo_callback and then get exiting damage by
135 // passing that ID to the gl_populate_existing_damage.
136 return gl_dispatch_table_.gl_populate_existing_damage(
137 gl_dispatch_table_.gl_fbo_callback(frame_info));
138}
139
140// |GPUSurfaceGLDelegate|
141bool EmbedderSurfaceGLImpeller::GLContextFBOResetAfterPresent() const {
142 return fbo_reset_after_present_;
143}
144
145// |GPUSurfaceGLDelegate|
146DlMatrix EmbedderSurfaceGLImpeller::GLContextSurfaceTransformation() const {
147 auto callback = gl_dispatch_table_.gl_surface_transformation_callback;
148 if (!callback) {
149 return DlMatrix();
150 }
151 return callback();
152}
153
154// |GPUSurfaceGLDelegate|
156EmbedderSurfaceGLImpeller::GetGLProcResolver() const {
157 return gl_dispatch_table_.gl_proc_resolver;
158}
159
160// |GPUSurfaceGLDelegate|
161SurfaceFrame::FramebufferInfo
162EmbedderSurfaceGLImpeller::GLContextFramebufferInfo() const {
163 // Enable partial repaint by default on the embedders.
164 auto info = SurfaceFrame::FramebufferInfo{};
165 info.supports_readback = true;
166 info.supports_partial_repaint =
167 gl_dispatch_table_.gl_populate_existing_damage != nullptr;
168 return info;
169}
170
171// |EmbedderSurface|
172std::unique_ptr<Surface> EmbedderSurfaceGLImpeller::CreateGPUSurface() {
173 // Ensure that the GL context is current before creating the GPU surface.
174 // GPUSurfaceGLImpeller initialization will set up shader pipelines, and the
175 // current thread needs to be able to execute reactor operations.
176 GLContextMakeCurrent();
177
178 return std::make_unique<GPUSurfaceGLImpeller>(
179 this, // GPU surface GL delegate
180 impeller_context_, // Impeller context
181 !external_view_embedder_ // render to surface
182 );
183}
184
185// |EmbedderSurface|
186std::shared_ptr<impeller::Context>
187EmbedderSurfaceGLImpeller::CreateImpellerContext() const {
188 return impeller_context_;
189}
190
191// |EmbedderSurface|
192sk_sp<GrDirectContext> EmbedderSurfaceGLImpeller::CreateResourceContext()
193 const {
194 if (gl_dispatch_table_.gl_make_resource_current_callback()) {
195 worker_->SetReactionsAllowedOnCurrentThread(true);
196 } else {
197 FML_DLOG(ERROR) << "Could not make the resource context current.";
198 worker_->SetReactionsAllowedOnCurrentThread(false);
199 }
200 return nullptr;
201}
202
203} // namespace flutter
EmbedderSurfaceGLImpeller(EmbedderSurfaceGLSkia::GLDispatchTable gl_dispatch_table, bool fbo_reset_after_present, std::shared_ptr< EmbedderExternalViewEmbedder > external_view_embedder)
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
#define IPLR_GUARDED_BY(x)