Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
render_context_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
9#include "flutter/impeller/entity/gles3/entity_shaders_gles.h"
16
18 return true;
19}
20
21namespace {
22std::vector<std::shared_ptr<fml::Mapping>>
23ShaderLibraryMappingsForApplication() {
24 return {
25 std::make_shared<fml::NonOwnedMapping>(
26 impeller_entity_shaders_gles3_data,
27 impeller_entity_shaders_gles3_length),
28 };
29}
30
31class ReactorWorker : public impeller::ReactorGLES::Worker {
32 public:
33 ReactorWorker() = default;
34 ReactorWorker(const ReactorWorker&) = delete;
35
36 ReactorWorker& operator=(const ReactorWorker&) = delete;
37
39 const impeller::ReactorGLES& reactor) const override {
40 return true;
41 }
42};
43
44class ImpellerRenderContext;
45thread_local std::vector<ImpellerRenderContext*> active_contexts;
46
47class ImpellerRenderContext : public Skwasm::RenderContext {
48 public:
49 ImpellerRenderContext(std::shared_ptr<impeller::ContextGLES> context,
50 std::shared_ptr<ReactorWorker> worker)
51 : context_(std::move(context)),
52 worker_(std::move(worker)),
53 typographer_context_(impeller::TypographerContextSkia::Make()),
54 content_context_(
55 std::make_unique<impeller::ContentContext>(context_,
56 typographer_context_,
57 nullptr)) {
58 content_context_->SetTextureCachingEnabled(true);
59 active_contexts.push_back(this);
60 }
61
62 virtual ~ImpellerRenderContext() {
63 auto it = std::find(active_contexts.begin(), active_contexts.end(), this);
64 if (it != active_contexts.end()) {
65 active_contexts.erase(it);
66 }
67 }
68
69 virtual void RenderPicture(
70 const sk_sp<flutter::DisplayList> display_list) override {
72 *content_context_, surface_->GetRenderTarget(), display_list,
73 impeller::Rect::MakeLTRB(0, 0, width_, height_), true, true);
74 }
75
78 void* out_pixels) override {
79 auto impeller_image = image ? image->asImpellerImage() : nullptr;
80 auto texture =
81 impeller_image ? impeller_image->GetImpellerTexture(context_) : nullptr;
82 if (!texture) {
83 return false;
84 }
85
86 auto gles_texture = static_cast<impeller::TextureGLES*>(texture.get());
87 GLuint fbo = 0;
88 glGenFramebuffers(1, &fbo);
89 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
90
91 bool attached = gles_texture->SetAsFramebufferAttachment(
93 if (!attached) {
94 glDeleteFramebuffers(1, &fbo);
95 glBindFramebuffer(GL_FRAMEBUFFER, 0);
96 return false;
97 }
98
99 glReadPixels(0, 0, image->width(), image->height(), GL_RGBA,
100 GL_UNSIGNED_BYTE, out_pixels);
101
102 glDeleteFramebuffers(1, &fbo);
103 glBindFramebuffer(GL_FRAMEBUFFER, 0);
104
105 return true;
106 }
107
108 virtual void Resize(int width, int height) override {
109 if (width_ != width || height_ != height) {
110 width_ = width;
111 height_ = height;
112 RecreateSurface();
113 }
114 }
115
116 void RemoveImage(const flutter::DlImage* image) {
117 if (content_context_) {
118 content_context_->RemoveCachedTexture(image);
119 }
120 }
121
122 virtual void SetResourceCacheLimit(int bytes) override {
123 // No-op
124 }
125
126 private:
127 void RecreateSurface() {
129 /*context=*/context_,
130 /*swap_callback=*/[]() { return true; },
131 /*fbo=*/0u,
133 /*fbo_size=*/{width_, height_});
134 }
135
136 std::shared_ptr<impeller::ContextGLES> context_;
137 std::shared_ptr<ReactorWorker> worker_;
138 std::shared_ptr<impeller::TypographerContext> typographer_context_;
139 std::unique_ptr<impeller::ContentContext> content_context_;
140 std::unique_ptr<impeller::Surface> surface_;
141 int width_ = 0;
142 int height_ = 0;
143};
144} // namespace
145
146std::unique_ptr<Skwasm::RenderContext> Skwasm::RenderContext::Make(
147 int sample_count,
148 int stencil) {
149 auto clear_depth_emulated = [](float depth) {};
150 auto depth_range_emulated = [](float near_val, float far_val) {};
151
152 std::map<std::string, void*> gl_procs;
153
154 gl_procs["glGetError"] = (void*)&glGetError;
155 gl_procs["glClearDepthf"] = (void*)&clear_depth_emulated;
156 gl_procs["glDepthRangef"] = (void*)&depth_range_emulated;
157
158#define IMPELLER_PROC(name) gl_procs["gl" #name] = (void*)&gl##name;
162 IMPELLER_PROC(GenQueriesEXT);
163 IMPELLER_PROC(DeleteQueriesEXT);
164 IMPELLER_PROC(GetQueryObjectui64vEXT);
165 IMPELLER_PROC(BeginQueryEXT);
166 IMPELLER_PROC(EndQueryEXT);
167 IMPELLER_PROC(GetQueryObjectuivEXT);
168#undef IMPELLER_PROC
169
170 auto gl = std::make_unique<impeller::ProcTableGLES>(
171 [gl_procs = std::move(gl_procs)](const char* function_name) -> void* {
172 auto found = gl_procs.find(function_name);
173 if (found == gl_procs.end()) {
174 return nullptr;
175 }
176 return found->second;
177 });
178
179 auto context = impeller::ContextGLES::Create(
180 impeller::Flags{}, std::move(gl), ShaderLibraryMappingsForApplication(),
181 false);
182
183 auto worker = std::make_shared<ReactorWorker>();
184 context->AddReactorWorker(worker);
185 return std::make_unique<ImpellerRenderContext>(std::move(context),
186 std::move(worker));
187}
188
190 const flutter::DlImage* image =
191 reinterpret_cast<const flutter::DlImage*>(dl_image_ptr);
192 for (auto* context : active_contexts) {
193 context->RemoveImage(image);
194 }
195}
virtual void RenderPicture(const sk_sp< flutter::DisplayList > display_list)=0
static std::unique_ptr< RenderContext > Make(int sample_count, int stencil)
virtual void Resize(int width, int height)=0
virtual void SetResourceCacheLimit(int bytes)=0
virtual bool RasterizeImage(flutter::DlImage *image, ImageByteFormat format, void *out_pixels)=0
Represents an image whose allocation is (usually) resident on device memory.
Definition dl_image.h:34
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...
virtual bool CanReactorReactOnCurrentThreadNow(const ReactorGLES &reactor) const =0
Determines the ability of the worker to service a reaction on the current thread. The OpenGL context ...
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
static std::unique_ptr< Surface > WrapFBO(const std::shared_ptr< Context > &context, SwapCallback swap_callback, GLuint fbo, PixelFormat color_format, ISize fbo_size)
FlutterVulkanImage * image
EGLSurface surface_
void skwasm_disposeDlImageOnWorker(void *dl_image_ptr)
FlTexture * texture
ImageByteFormat
Definition helpers.h:75
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
#define IMPELLER_PROC(proc_ivar)
#define FOR_EACH_IMPELLER_GLES3_PROC(PROC)
#define FOR_EACH_IMPELLER_ES_ONLY_PROC(PROC)
#define FOR_EACH_IMPELLER_PROC(PROC)
SKWASM_EXPORT bool skwasm_isWimp()
int32_t height
int32_t width
#define SKWASM_EXPORT
Definition export.h:10
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129