diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-07-04 11:44:03 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-07-04 11:44:03 +0200 |
| commit | 844d3d6d5c7a297db33408bf18488ec0e961b601 (patch) | |
| tree | 928de86555c94a56c31c57cab55b2c85a158bdbf /src | |
| parent | 8a2559e1af0da2c33a05d466fdb37da1b5f8851b (diff) | |
Wayland platform.: complete support of gl_start/gl_finish.
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx | 62 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.H | 3 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 11 |
4 files changed, 64 insertions, 14 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H index 80f91970c..2241c5e76 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H @@ -50,8 +50,8 @@ class Fl_Wayland_Gl_Window_Driver : public Fl_Gl_Window_Driver { virtual void delete_gl_context(GLContext); virtual void make_overlay_current(); virtual void redraw_overlay(); - virtual void waitGL(); virtual void gl_start(); + virtual void gl_visual(Fl_Gl_Choice *c); virtual Fl_RGB_Image* capture_gl_rectangle(int x, int y, int w, int h); char *alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs); static EGLDisplay egl_display; diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx index 5bf04fc31..686d0c1db 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx @@ -46,6 +46,15 @@ public: } }; +struct gl_start_support { // to support use of gl_start / gl_finish + struct wl_surface *surface; + struct wl_subsurface *subsurface; + struct wl_egl_window *egl_window; + EGLSurface egl_surface; +}; + +static EGLConfig wld_egl_conf = NULL; + EGLDisplay Fl_Wayland_Gl_Window_Driver::egl_display = EGL_NO_DISPLAY; EGLint Fl_Wayland_Gl_Window_Driver::configs_count = 0; struct wl_event_queue *Fl_Wayland_Gl_Window_Driver::gl_event_queue = NULL; @@ -172,23 +181,36 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons //fprintf(stderr, "eglCreateContext=%p shared_ctx=%p\n", ctx, shared_ctx); if (ctx) add_context(ctx); - if (!egl_surface) { // useful for gl_start() - struct wld_window *xid = fl_xid(window); - float s = Fl::screen_scale(window->screen_num()); - egl_window = wl_egl_window_create(xid->wl_surface, window->w() * s, window->h() * s); - egl_surface = eglCreateWindowSurface(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, egl_window, NULL); - } return ctx; } void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { struct wld_window *win = fl_xid(w); - if (!win || !egl_surface) return; + if (!win) return; + Fl_Wayland_Window_Driver *dr = (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(w); + EGLSurface target_egl_surface = NULL; + if (egl_surface) target_egl_surface = egl_surface; + else if (dr->gl_start_support_) target_egl_surface = dr->gl_start_support_->egl_surface; + if (!target_egl_surface) { // useful for gl_start() + dr->gl_start_support_ = new struct gl_start_support; + float s = Fl::screen_scale(w->screen_num()); + Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); + // the GL scene will be a transparent subsurface above the cairo-drawn surface + dr->gl_start_support_->surface = wl_compositor_create_surface(scr_driver->wl_compositor); + dr->gl_start_support_->subsurface = wl_subcompositor_get_subsurface( + scr_driver->wl_subcompositor, dr->gl_start_support_->surface, win->wl_surface); + wl_subsurface_set_position(dr->gl_start_support_->subsurface, w->x() * s, w->y() * s); + wl_subsurface_place_above(dr->gl_start_support_->subsurface, win->wl_surface); + dr->gl_start_support_->egl_window = wl_egl_window_create( + dr->gl_start_support_->surface, w->w() * s, w->h() * s); + target_egl_surface = dr->gl_start_support_->egl_surface = eglCreateWindowSurface( + egl_display, wld_egl_conf, dr->gl_start_support_->egl_window, NULL); + } if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - if (eglMakeCurrent(egl_display, egl_surface, egl_surface, (EGLContext)context)) { + if (eglMakeCurrent(egl_display, target_egl_surface, target_egl_surface, (EGLContext)context)) { //fprintf(stderr, "EGLContext %p made current\n", context); } else { Fl::error("eglMakeCurrent() failed\n"); @@ -333,6 +355,13 @@ public: eglTerminate(Fl_Wayland_Gl_Window_Driver::egl_display); } } + virtual void destroy(struct gl_start_support *gl_start_support_) { + eglDestroySurface(Fl_Wayland_Gl_Window_Driver::egl_display, gl_start_support_->egl_surface); + wl_egl_window_destroy(gl_start_support_->egl_window); + wl_subsurface_destroy(gl_start_support_->subsurface); + wl_surface_destroy(gl_start_support_->surface); + delete gl_start_support_; + } }; static Fl_Wayland_Gl_Plugin Gl_Overlay_Plugin; @@ -358,11 +387,14 @@ char Fl_Wayland_Gl_Window_Driver::swap_type() { } -void Fl_Wayland_Gl_Window_Driver::waitGL() { - struct wld_window *window = fl_xid(Fl_Window::current()); - window->buffer->draw_buffer_needs_commit = false; +void Fl_Wayland_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) { + Fl_Gl_Window_Driver::gl_visual(c); + wld_egl_conf = ((Fl_Wayland_Gl_Choice*)c)->egl_conf; } +static void delayed_redraw(Fl_Window *win) { + win->redraw(); +} void Fl_Wayland_Gl_Window_Driver::gl_start() { struct wld_window *win = fl_xid(Fl_Window::current()); @@ -370,8 +402,12 @@ void Fl_Wayland_Gl_Window_Driver::gl_start() { int W = Fl_Window::current()->w() * f; int H = Fl_Window::current()->h() * f; int W2, H2; - wl_egl_window_get_attached_size(egl_window, &W2, &H2); - if (W2 != W || H2 != H) wl_egl_window_resize(egl_window, W, H, 0, 0); + Fl_Wayland_Window_Driver *dr = (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(Fl_Window::current()); + wl_egl_window_get_attached_size(dr->gl_start_support_->egl_window, &W2, &H2); + if (W2 != W || H2 != H) { + wl_egl_window_resize(dr->gl_start_support_->egl_window, W, H, 0, 0); + Fl::add_timeout(0.01, (Fl_Timeout_Handler)delayed_redraw, Fl_Window::current()); + } glClearColor(0., 0., 0., 0.); glClear(GL_COLOR_BUFFER_BIT); } diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H index faa45b6fa..ad3c3ad37 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H @@ -46,6 +46,7 @@ typedef struct _cairo_pattern cairo_pattern_t; class FL_EXPORT Fl_Wayland_Window_Driver : public Fl_Window_Driver { friend class Fl_X; + friend class Fl_Wayland_Gl_Window_Driver; private: struct shape_data_type { int lw_; ///< width of shape image @@ -56,6 +57,7 @@ private: static bool in_flush; // useful for progressive window drawing struct wl_cursor *cursor_; void delete_cursor_(); + struct gl_start_support *gl_start_support_; // for support of gl_start/gl_finish public: struct wl_cursor *cursor() { return cursor_; }; bool in_handle_configure; // distinguish OS and user window resize @@ -156,6 +158,7 @@ public: virtual void do_swap(Fl_Window*) = 0; virtual void invalidate(Fl_Window*) = 0; virtual void terminate() = 0; + virtual void destroy(struct gl_start_support *) = 0; }; #endif // FL_WAYLAND_WINDOW_DRIVER_H diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index dae93b1b5..2c9402061 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -67,6 +67,7 @@ Fl_Wayland_Window_Driver::Fl_Wayland_Window_Driver(Fl_Window *win) : Fl_Window_D cursor_ = NULL; in_handle_configure = false; screen_num_ = -1; + gl_start_support_ = NULL; } void Fl_Wayland_Window_Driver::delete_cursor_() { @@ -98,6 +99,16 @@ Fl_Wayland_Window_Driver::~Fl_Wayland_Window_Driver() delete shape_data_; } delete_cursor_(); + if (gl_start_support_) { // occurs only if gl_start/gl_finish was used + static Fl_Wayland_Plugin *plugin = NULL; + if (!plugin) { + Fl_Plugin_Manager pm("wayland.fltk.org"); + plugin = (Fl_Wayland_Plugin*)pm.plugin("gl.wayland.fltk.org"); + } + if (plugin) { + plugin->destroy(gl_start_support_); + } + } } |
