Skip to content

Commit 3469602

Browse files
committed
Wire up the OpenGL renderer.
1 parent c6f5e87 commit 3469602

File tree

5 files changed

+156
-93
lines changed

5 files changed

+156
-93
lines changed

src/flutter_application.cc

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,35 @@ static std::string GetICUDataPath() {
5858
return icu_path;
5959
}
6060

61-
FlutterApplication::FlutterApplication() {
61+
FlutterApplication::FlutterApplication(
62+
const std::vector<std::string>& command_line_args,
63+
RenderDelegate& render_delegate)
64+
: render_delegate_(render_delegate) {
6265
FlutterRendererConfig config = {};
63-
config.type = kSoftware;
64-
config.software.struct_size = sizeof(FlutterSoftwareRendererConfig);
65-
config.software.surface_present_callback =
66-
&FlutterApplication::PresentSurface;
66+
config.type = kOpenGL;
67+
config.open_gl.struct_size = sizeof(config.open_gl);
68+
config.open_gl.make_current = [](void* userdata) -> bool {
69+
return reinterpret_cast<FlutterApplication*>(userdata)
70+
->render_delegate_.OnApplicationContextMakeCurrent();
71+
};
72+
config.open_gl.clear_current = [](void* userdata) -> bool {
73+
return reinterpret_cast<FlutterApplication*>(userdata)
74+
->render_delegate_.OnApplicationContextClearCurrent();
75+
};
76+
config.open_gl.present = [](void* userdata) -> bool {
77+
return reinterpret_cast<FlutterApplication*>(userdata)
78+
->render_delegate_.OnApplicationPresent();
79+
};
80+
config.open_gl.fbo_callback = [](void* userdata) -> uint32_t {
81+
return reinterpret_cast<FlutterApplication*>(userdata)
82+
->render_delegate_.OnApplicationGetOnscreenFBO();
83+
};
6784

6885
// TODO: Pipe this in through command line args.
6986
#define MY_PROJECT \
7087
"/usr/local/google/home/chinmaygarde/VersionControlled/flutter/examples/" \
7188
"flutter_gallery/build/flutter_assets"
7289

73-
std::vector<const char*> engine_command_line_args = {
74-
"--disable-observatory", //
75-
"--dart-non-checked-mode", //
76-
};
77-
7890
auto icu_data_path = GetICUDataPath();
7991

8092
if (icu_data_path == "") {
@@ -84,19 +96,25 @@ FlutterApplication::FlutterApplication() {
8496
return;
8597
}
8698

99+
std::vector<const char*> command_line_args_c;
100+
101+
for (const auto& arg : command_line_args) {
102+
command_line_args_c.push_back(arg.c_str());
103+
}
104+
87105
FlutterProjectArgs args = {
88106
.struct_size = sizeof(FlutterProjectArgs),
89-
.assets_path = MY_PROJECT "/build/flutter_assets",
107+
.assets_path = MY_PROJECT,
90108
.main_path = "",
91109
.packages_path = "",
92110
.icu_data_path = icu_data_path.c_str(),
93-
.command_line_argc = static_cast<int>(engine_command_line_args.size()),
94-
.command_line_argv = engine_command_line_args.data(),
111+
.command_line_argc = static_cast<int>(command_line_args_c.size()),
112+
.command_line_argv = command_line_args_c.data(),
95113
};
96114

97115
FlutterEngine engine = nullptr;
98-
auto result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, // renderer
99-
&args, this, &engine_);
116+
auto result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args,
117+
this /* userdata */, &engine_);
100118

101119
if (result != kSuccess) {
102120
FLWAY_ERROR << "Could not run the Flutter engine" << std::endl;
@@ -135,31 +153,6 @@ void FlutterApplication::ProcessEvents() {
135153
__FlutterEngineFlushPendingTasksNow();
136154
}
137155

138-
bool FlutterApplication::PresentSurface(void* user_data,
139-
const void* allocation,
140-
size_t row_bytes,
141-
size_t height) {
142-
return reinterpret_cast<FlutterApplication*>(user_data)->PresentSurface(
143-
allocation, row_bytes, height);
144-
}
145-
146-
void FlutterApplication::SetOnPresentCallback(PresentCallback callback) {
147-
std::lock_guard<std::mutex> lock(mutex_);
148-
present_callback_ = callback;
149-
}
150-
151-
bool FlutterApplication::PresentSurface(const void* allocation,
152-
size_t row_bytes,
153-
size_t height) {
154-
std::lock_guard<std::mutex> lock(mutex_);
155-
if (!present_callback_) {
156-
FLWAY_ERROR << "Present callback was not set." << std::endl;
157-
return false;
158-
}
159-
present_callback_(allocation, row_bytes, height);
160-
return true;
161-
}
162-
163156
bool FlutterApplication::SendPointerEvent(int button, int x, int y) {
164157
if (!valid_) {
165158
FLWAY_ERROR << "Pointer events on an invalid application." << std::endl;

src/flutter_application.h

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,27 @@
77
#include <flutter_embedder.h>
88

99
#include <functional>
10-
#include <map>
11-
#include <mutex>
10+
#include <vector>
1211

1312
#include "macros.h"
1413

1514
namespace flutter {
1615

1716
class FlutterApplication {
1817
public:
19-
FlutterApplication();
18+
class RenderDelegate {
19+
public:
20+
virtual bool OnApplicationContextMakeCurrent() = 0;
21+
22+
virtual bool OnApplicationContextClearCurrent() = 0;
23+
24+
virtual bool OnApplicationPresent() = 0;
25+
26+
virtual uint32_t OnApplicationGetOnscreenFBO() = 0;
27+
};
28+
29+
FlutterApplication(const std::vector<std::string>& args,
30+
RenderDelegate& render_delegate);
2031

2132
~FlutterApplication();
2233

@@ -28,24 +39,12 @@ class FlutterApplication {
2839

2940
bool SendPointerEvent(int button, int x, int y);
3041

31-
using PresentCallback = std::function<
32-
void(const void* allocation, size_t row_bytes, size_t height)>;
33-
void SetOnPresentCallback(PresentCallback callback);
34-
3542
private:
3643
bool valid_;
44+
RenderDelegate& render_delegate_;
3745
FlutterEngine engine_ = nullptr;
38-
std::mutex mutex_;
39-
PresentCallback present_callback_;
4046
int last_button_ = 0;
4147

42-
static bool PresentSurface(void* user_data,
43-
const void* allocation,
44-
size_t row_bytes,
45-
size_t height);
46-
47-
bool PresentSurface(const void* allocation, size_t row_bytes, size_t height);
48-
4948
bool SendFlutterPointerEvent(FlutterPointerPhase phase, double x, double y);
5049

5150
FLWAY_DISALLOW_COPY_AND_ASSIGN(FlutterApplication);

src/main.cc

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,47 @@
44

55
#include <stdlib.h>
66

7+
#include <string>
8+
#include <vector>
9+
710
#include "flutter_application.h"
811
#include "wayland_display.h"
912

10-
int main(int argc, char* argv[]) {
11-
auto application = std::make_unique<flutter::FlutterApplication>();
13+
namespace flutter {
1214

13-
if (!application->IsValid()) {
14-
FLWAY_ERROR << "Could not run the Flutter application." << std::endl;
15-
return EXIT_FAILURE;
16-
}
15+
bool Main(std::vector<std::string> args) {
16+
const size_t kWidth = 800;
17+
const size_t kHeight = 600;
1718

18-
flutter::WaylandDisplay display(std::move(application), //
19-
"Flutter Gallery", //
20-
800, 600);
19+
WaylandDisplay display(kWidth, kHeight);
2120

2221
if (!display.IsValid()) {
23-
FLWAY_ERROR << "Could not create the wayland display." << std::endl;
24-
return EXIT_FAILURE;
22+
FLWAY_ERROR << "Wayland display was not valid." << std::endl;
23+
return false;
24+
}
25+
26+
FlutterApplication application(args, display);
27+
if (!application.IsValid()) {
28+
FLWAY_ERROR << "Flutter application was not valid." << std::endl;
29+
return false;
30+
}
31+
32+
if (!application.SetWindowSize(kWidth, kHeight)) {
33+
FLWAY_ERROR << "Could not update Flutter application size." << std::endl;
34+
return false;
2535
}
2636

2737
display.Run();
2838

29-
return EXIT_SUCCESS;
39+
return true;
40+
}
41+
42+
} // namespace flutter
43+
44+
int main(int argc, char* argv[]) {
45+
std::vector<std::string> args;
46+
for (int i = 0; i < argc; ++i) {
47+
args.push_back(argv[i]);
48+
}
49+
return flutter::Main(std::move(args)) ? EXIT_SUCCESS : EXIT_FAILURE;
3050
}

src/wayland_display.cc

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,8 @@ const wl_registry_listener WaylandDisplay::kRegistryListener = {
3030
},
3131
};
3232

33-
WaylandDisplay::WaylandDisplay(std::unique_ptr<FlutterApplication> application,
34-
std::string name,
35-
size_t width,
36-
size_t height)
37-
: application_(std::move(application)),
38-
screen_name_(std::move(name)),
39-
screen_width_(width),
40-
screen_height_(height) {
41-
if (!application_ || !application_->IsValid()) {
42-
FLWAY_ERROR << "Invalid application to run." << std::endl;
43-
return;
44-
}
45-
33+
WaylandDisplay::WaylandDisplay(size_t width, size_t height)
34+
: screen_width_(width), screen_height_(height) {
4635
if (screen_width_ == 0 || screen_height_ == 0) {
4736
FLWAY_ERROR << "Invalid screen dimensions." << std::endl;
4837
return;
@@ -70,11 +59,6 @@ WaylandDisplay::WaylandDisplay(std::unique_ptr<FlutterApplication> application,
7059
return;
7160
}
7261

73-
if (!application_->SetWindowSize(width, height)) {
74-
FLWAY_ERROR << "Could not set the application window size." << std::endl;
75-
return;
76-
}
77-
7862
valid_ = true;
7963
}
8064

@@ -300,4 +284,64 @@ void WaylandDisplay::UnannounceRegistryInterface(
300284
struct wl_registry* wl_registry,
301285
uint32_t name) {}
302286

287+
// |flutter::FlutterApplication::RenderDelegate|
288+
bool WaylandDisplay::OnApplicationContextMakeCurrent() {
289+
if (!valid_) {
290+
FLWAY_ERROR << "Invalid display." << std::endl;
291+
return false;
292+
}
293+
294+
if (eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_) !=
295+
EGL_TRUE) {
296+
LogLastEGLError();
297+
FLWAY_ERROR << "Could not make the onscreen context current" << std::endl;
298+
return false;
299+
}
300+
301+
return true;
302+
}
303+
304+
// |flutter::FlutterApplication::RenderDelegate|
305+
bool WaylandDisplay::OnApplicationContextClearCurrent() {
306+
if (!valid_) {
307+
FLWAY_ERROR << "Invalid display." << std::endl;
308+
return false;
309+
}
310+
311+
if (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
312+
EGL_NO_CONTEXT) != EGL_TRUE) {
313+
LogLastEGLError();
314+
FLWAY_ERROR << "Could not clear the context." << std::endl;
315+
return false;
316+
}
317+
318+
return true;
319+
}
320+
321+
// |flutter::FlutterApplication::RenderDelegate|
322+
bool WaylandDisplay::OnApplicationPresent() {
323+
if (!valid_) {
324+
FLWAY_ERROR << "Invalid display." << std::endl;
325+
return false;
326+
}
327+
328+
if (eglSwapBuffers(egl_display_, surface_) != EGL_TRUE) {
329+
LogLastEGLError();
330+
FLWAY_ERROR << "Could not swap the EGL buffer." << std::endl;
331+
return false;
332+
}
333+
334+
return true;
335+
}
336+
337+
// |flutter::FlutterApplication::RenderDelegate|
338+
uint32_t WaylandDisplay::OnApplicationGetOnscreenFBO() {
339+
if (!valid_) {
340+
FLWAY_ERROR << "Invalid display." << std::endl;
341+
return 999;
342+
}
343+
344+
return 0; // FBO0
345+
}
346+
303347
} // namespace flutter

src/wayland_display.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616

1717
namespace flutter {
1818

19-
class WaylandDisplay {
19+
class WaylandDisplay : public FlutterApplication::RenderDelegate {
2020
public:
21-
WaylandDisplay(std::unique_ptr<FlutterApplication> application,
22-
std::string name,
23-
size_t width,
24-
size_t height);
21+
WaylandDisplay(size_t width, size_t height);
2522

2623
~WaylandDisplay();
2724

@@ -32,8 +29,6 @@ class WaylandDisplay {
3229
private:
3330
static const wl_registry_listener kRegistryListener;
3431
bool valid_ = false;
35-
std::unique_ptr<FlutterApplication> application_;
36-
std::string screen_name_;
3732
const int screen_width_;
3833
const int screen_height_;
3934
wl_display* display_ = nullptr;
@@ -57,6 +52,18 @@ class WaylandDisplay {
5752

5853
bool StopRunning();
5954

55+
// |flutter::FlutterApplication::RenderDelegate|
56+
bool OnApplicationContextMakeCurrent() override;
57+
58+
// |flutter::FlutterApplication::RenderDelegate|
59+
bool OnApplicationContextClearCurrent() override;
60+
61+
// |flutter::FlutterApplication::RenderDelegate|
62+
bool OnApplicationPresent() override;
63+
64+
// |flutter::FlutterApplication::RenderDelegate|
65+
uint32_t OnApplicationGetOnscreenFBO() override;
66+
6067
FLWAY_DISALLOW_COPY_AND_ASSIGN(WaylandDisplay);
6168
};
6269

0 commit comments

Comments
 (0)