Flutter Engine
The Flutter Engine
gpu_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/gpu/gpu_surface_gl_impeller.h"
6
7#include "flutter/fml/make_copyable.h"
12
13namespace flutter {
14
16 GPUSurfaceGLDelegate* delegate,
17 std::shared_ptr<impeller::Context> context,
18 bool render_to_surface)
19 : weak_factory_(this) {
20 if (delegate == nullptr) {
21 return;
22 }
23
24 if (!context || !context->IsValid()) {
25 return;
26 }
27
28 auto renderer = std::make_shared<impeller::Renderer>(context);
29 if (!renderer->IsValid()) {
30 return;
31 }
32
33 auto aiks_context = std::make_shared<impeller::AiksContext>(
35
36 if (!aiks_context->IsValid()) {
37 return;
38 }
39
40 delegate_ = delegate;
41 impeller_context_ = std::move(context);
42 render_to_surface_ = render_to_surface;
43 impeller_renderer_ = std::move(renderer);
44 aiks_context_ = std::move(aiks_context);
45 is_valid_ = true;
46}
47
48// |Surface|
50
51// |Surface|
53 return is_valid_;
54}
55
56// |Surface|
57std::unique_ptr<SurfaceFrame> GPUSurfaceGLImpeller::AcquireFrame(
58 const SkISize& size) {
59 if (!IsValid()) {
60 FML_LOG(ERROR) << "OpenGL surface was invalid.";
61 return nullptr;
62 }
63
64 auto swap_callback = [weak = weak_factory_.GetWeakPtr(),
65 delegate = delegate_]() -> bool {
66 if (weak) {
67 GLPresentInfo present_info = {
68 .fbo_id = 0u,
69 .frame_damage = std::nullopt,
70 // TODO (https://github.com/flutter/flutter/issues/105597): wire-up
71 // presentation time to impeller backend.
72 .presentation_time = std::nullopt,
73 .buffer_damage = std::nullopt,
74 };
75 delegate->GLContextPresent(present_info);
76 }
77 return true;
78 };
79
80 auto context_switch = delegate_->GLContextMakeCurrent();
81 if (!context_switch->GetResult()) {
83 << "Could not make the context current to acquire the frame.";
84 return nullptr;
85 }
86
87 if (!render_to_surface_) {
88 return std::make_unique<SurfaceFrame>(
89 nullptr, SurfaceFrame::FramebufferInfo{.supports_readback = true},
90 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
91 return true;
92 },
93 size);
94 }
95
96 GLFrameInfo frame_info = {static_cast<uint32_t>(size.width()),
97 static_cast<uint32_t>(size.height())};
98 const GLFBOInfo fbo_info = delegate_->GLContextFBO(frame_info);
100 impeller_context_, // context
101 swap_callback, // swap_callback
102 fbo_info.fbo_id, // fbo
104 impeller::ISize{size.width(), size.height()} // fbo_size
105 );
106
107 SurfaceFrame::SubmitCallback submit_callback =
108 fml::MakeCopyable([renderer = impeller_renderer_, //
109 aiks_context = aiks_context_, //
110 surface = std::move(surface) //
111 ](SurfaceFrame& surface_frame, DlCanvas* canvas) mutable -> bool {
112 if (!aiks_context) {
113 return false;
114 }
115
116 auto display_list = surface_frame.BuildDisplayList();
117 if (!display_list) {
118 FML_LOG(ERROR) << "Could not build display list for surface frame.";
119 return false;
120 }
121
122 auto cull_rect =
123 surface->GetTargetRenderPassDescriptor().GetRenderTargetSize();
124 impeller::Rect dl_cull_rect = impeller::Rect::MakeSize(cull_rect);
125 impeller::DlDispatcher impeller_dispatcher(dl_cull_rect);
126 display_list->Dispatch(
127 impeller_dispatcher,
128 SkIRect::MakeWH(cull_rect.width, cull_rect.height));
129 auto picture = impeller_dispatcher.EndRecordingAsPicture();
130
131 return renderer->Render(
132 std::move(surface),
134 [aiks_context, picture = std::move(picture)](
135 impeller::RenderTarget& render_target) -> bool {
136 return aiks_context->Render(picture, render_target,
137 /*reset_host_buffer=*/true);
138 }));
139 });
140
141 return std::make_unique<SurfaceFrame>(
142 nullptr, // surface
143 delegate_->GLContextFramebufferInfo(), // framebuffer info
144 submit_callback, // submit callback
145 size, // frame size
146 std::move(context_switch), // context result
147 true // display list fallback
148 );
149}
150
151// |Surface|
152SkMatrix GPUSurfaceGLImpeller::GetRootTransformation() const {
153 // This backend does not currently support root surface transformations. Just
154 // return identity.
155 return {};
156}
157
158// |Surface|
159GrDirectContext* GPUSurfaceGLImpeller::GetContext() {
160 // Impeller != Skia.
161 return nullptr;
162}
163
164// |Surface|
165std::unique_ptr<GLContextResult>
166GPUSurfaceGLImpeller::MakeRenderContextCurrent() {
167 return delegate_->GLContextMakeCurrent();
168}
169
170// |Surface|
171bool GPUSurfaceGLImpeller::ClearRenderContext() {
172 return delegate_->GLContextClearCurrent();
173}
174
175bool GPUSurfaceGLImpeller::AllowsDrawingWhenGpuDisabled() const {
176 return delegate_->AllowsDrawingWhenGpuDisabled();
177}
178
179// |Surface|
180bool GPUSurfaceGLImpeller::EnableRasterCache() const {
181 return false;
182}
183
184// |Surface|
185std::shared_ptr<impeller::AiksContext> GPUSurfaceGLImpeller::GetAiksContext()
186 const {
187 return aiks_context_;
188}
189
190} // namespace flutter
virtual bool AllowsDrawingWhenGpuDisabled() const
virtual std::unique_ptr< GLContextResult > GLContextMakeCurrent()=0
virtual bool GLContextClearCurrent()=0
virtual SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const
virtual GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const =0
GPUSurfaceGLImpeller(GPUSurfaceGLDelegate *delegate, std::shared_ptr< impeller::Context > context, bool render_to_surface)
std::function< bool(SurfaceFrame &surface_frame, DlCanvas *canvas)> SubmitCallback
Definition: surface_frame.h:27
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
static std::shared_ptr< TypographerContext > Make()
VkSurfaceKHR surface
Definition: main.cc:49
#define FML_LOG(severity)
Definition: logging.h:82
sk_sp< const SkPicture > picture
Definition: SkRecords.h:299
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
flutter::DlCanvas DlCanvas
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
Definition: SkSize.h:16
static constexpr TRect MakeSize(const TSize< U > &size)
Definition: rect.h:146
#define ERROR(message)
Definition: elf_loader.cc:260