Flutter Engine
 
Loading...
Searching...
No Matches
embedder_external_view.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
10#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
11#include "third_party/skia/include/gpu/ganesh/GrRecordingContext.h"
12
13#ifdef IMPELLER_SUPPORTS_RENDERING
14#include "impeller/display_list/dl_dispatcher.h" // nogncheck
15#endif // IMPELLER_SUPPORTS_RENDERING
16
17namespace flutter {
18
20 const DlMatrix& transformation) {
21 const auto source_rect = DlRect::MakeSize(size);
22 const auto transformed_rect =
23 source_rect.TransformAndClipBounds(transformation);
24 return DlIRect::RoundOut(transformed_rect).GetSize();
25}
26
28 const DlISize& frame_size,
29 const DlMatrix& surface_transformation)
30 : EmbedderExternalView(frame_size, surface_transformation, {}, nullptr) {}
31
33 const DlISize& frame_size,
34 const DlMatrix& surface_transformation,
36 std::unique_ptr<EmbeddedViewParams> params)
37 : render_surface_size_(
38 TransformedSurfaceSize(frame_size, surface_transformation)),
39 surface_transformation_(surface_transformation),
40 view_identifier_(view_identifier),
41 embedded_view_params_(std::move(params)),
42 slice_(std::make_unique<DisplayListEmbedderViewSlice>(
43 DlRect::MakeSize(frame_size))) {}
44
46
51
53 return slice_->canvas();
54}
55
57 return render_surface_size_;
58}
59
61 return !HasPlatformView();
62}
63
65 return view_identifier_.platform_view_id.has_value();
66}
67
69 return slice_->getRegion();
70}
71
73 if (has_engine_rendered_contents_.has_value()) {
74 return has_engine_rendered_contents_.value();
75 }
76 TryEndRecording();
77 DlOpSpy dl_op_spy;
78 slice_->dispatch(dl_op_spy);
79 has_engine_rendered_contents_ = dl_op_spy.did_draw() && !slice_->is_empty();
80 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
81 return has_engine_rendered_contents_.value();
82}
83
88
90 return embedded_view_params_.get();
91}
92
93// TODO(https://github.com/flutter/flutter/issues/151670): Implement this for
94// Impeller as well.
95#if !SLIMPELLER
96static void InvalidateApiState(SkSurface& skia_surface) {
97 auto recording_context = skia_surface.recordingContext();
98
99 // Should never happen.
100 FML_DCHECK(recording_context) << "Recording context was null.";
101
102 auto direct_context = recording_context->asDirectContext();
103 if (direct_context == nullptr) {
104 // Can happen when using software rendering.
105 // Print an error but otherwise continue in that case.
106 FML_LOG(ERROR) << "Embedder asked to invalidate cached graphics API state "
107 "but Flutter is not using a graphics API.";
108 } else {
109 direct_context->resetContext(kAll_GrBackendState);
110 }
111}
112#endif
113
115 bool clear_surface) {
116 TRACE_EVENT0("flutter", "EmbedderExternalView::Render");
117 TryEndRecording();
119 << "Unnecessarily asked to render into a render target when there was "
120 "nothing to render.";
121
122#ifdef IMPELLER_SUPPORTS_RENDERING
123 auto* impeller_target = render_target.GetImpellerRenderTarget();
124 if (impeller_target) {
125 auto aiks_context = render_target.GetAiksContext();
126
127 auto dl_builder = DisplayListBuilder();
128 dl_builder.SetTransform(surface_transformation_);
129 slice_->render_into(&dl_builder);
130 auto display_list = dl_builder.Build();
131
132 auto cull_rect =
133 impeller::Rect::MakeSize(impeller_target->GetRenderTargetSize());
134
135 return impeller::RenderToTarget(aiks_context->GetContentContext(), //
136 *impeller_target, //
137 display_list, //
138 cull_rect, //
139 /*reset_host_buffer=*/true, //
140 /*is_onscreen=*/false //
141 );
142 }
143#endif // IMPELLER_SUPPORTS_RENDERING
144
145#if SLIMPELLER
146 FML_LOG(FATAL) << "Impeller opt-out unavailable.";
147 return false;
148#else // SLIMPELLER
149 auto skia_surface = render_target.GetSkiaSurface();
150 if (!skia_surface) {
151 return false;
152 }
153
154 auto [ok, invalidate_api_state] = render_target.MaybeMakeCurrent();
155
156 if (invalidate_api_state) {
157 InvalidateApiState(*skia_surface);
158 }
159 if (!ok) {
160 FML_LOG(ERROR) << "Could not make the surface current.";
161 return false;
162 }
163
164 // Clear the current render target (most likely EGLSurface) at the
165 // end of this scope.
166 fml::ScopedCleanupClosure clear_current_surface([&]() {
167 auto [ok, invalidate_api_state] = render_target.MaybeClearCurrent();
168 if (invalidate_api_state) {
169 InvalidateApiState(*skia_surface);
170 }
171 if (!ok) {
172 FML_LOG(ERROR) << "Could not clear the current surface.";
173 }
174 });
175
176 FML_DCHECK(render_target.GetRenderTargetSize() == render_surface_size_);
177
178 auto canvas = skia_surface->getCanvas();
179 if (!canvas) {
180 return false;
181 }
182 DlSkCanvasAdapter dl_canvas(canvas);
183 int restore_count = dl_canvas.GetSaveCount();
184 dl_canvas.SetTransform(surface_transformation_);
185 if (clear_surface) {
186 dl_canvas.Clear(DlColor::kTransparent());
187 }
188 slice_->render_into(&dl_canvas);
189 dl_canvas.RestoreToCount(restore_count);
190 dl_canvas.Flush();
191#endif // !SLIMPELLER
192
193 return true;
194}
195
196void EmbedderExternalView::TryEndRecording() const {
197 if (slice_->recording_ended()) {
198 return;
199 }
200 slice_->end_recording();
201}
202
203} // namespace flutter
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
void Clear(DlColor color)
Definition dl_canvas.h:104
bool did_draw()
Returns true if any non transparent content has been drawn.
Definition dl_op_spy.cc:9
Backend implementation of |DlCanvas| for |SkCanvas|.
int GetSaveCount() const override
void SetTransform(const DlMatrix &matrix) override
void RestoreToCount(int restore_count) override
const EmbeddedViewParams * GetEmbeddedViewParams() const
RenderTargetDescriptor CreateRenderTargetDescriptor() const
bool Render(const EmbedderRenderTarget &render_target, bool clear_surface=true)
EmbedderExternalView(const DlISize &frame_size, const DlMatrix &surface_transformation)
const DlRegion & GetDlRegion() const
ViewIdentifier GetViewIdentifier() const
Describes a surface whose backing store is managed by the embedder. The type of surface depends on th...
virtual impeller::RenderTarget * GetImpellerRenderTarget() const =0
An impeller render target the rasterizer can use to draw into the backing store.
virtual sk_sp< SkSurface > GetSkiaSurface() const =0
A render surface the rasterizer can use to draw into the backing store of this render target.
virtual SetCurrentResult MaybeClearCurrent() const
Clear the current render target.
virtual std::shared_ptr< impeller::AiksContext > GetAiksContext() const =0
Returns the AiksContext that should be used for rendering, if this render target is backed by Impelle...
virtual SetCurrentResult MaybeMakeCurrent() const
Make the render target current.
virtual DlISize GetRenderTargetSize() const =0
Returns the size of the render target.
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition closure.h:32
EmbedderExternalView::ViewIdentifier view_identifier
const EmbeddedViewParams * params
#define FML_LOG(severity)
Definition logging.h:101
#define FML_DCHECK(condition)
Definition logging.h:122
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all 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
static void InvalidateApiState(SkSurface &skia_surface)
static DlISize TransformedSurfaceSize(const DlISize &size, const DlMatrix &transformation)
bool RenderToTarget(ContentContext &context, RenderTarget render_target, const sk_sp< flutter::DisplayList > &display_list, Rect cull_rect, bool reset_host_buffer, bool is_onscreen)
Render the provided display list to the render target.
Definition ref_ptr.h:261
static constexpr DlColor kTransparent()
Definition dl_color.h:68
A 4x4 matrix using column-major storage.
Definition matrix.h:37
RoundOut(const TRect< U > &r)
Definition rect.h:679
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:150
#define TRACE_EVENT0(category_group, name)