diff options
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H | 10 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 35 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 20 |
4 files changed, 40 insertions, 27 deletions
diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H index c2a7d4c54..6a782c3c5 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H @@ -28,12 +28,10 @@ typedef struct _PangoLayout PangoLayout; typedef struct _PangoContext PangoContext; typedef struct _PangoFontDescription PangoFontDescription; -#if USE_PANGO - struct flCairoRegion { - int count; - struct _cairo_rectangle *rects; - }; // a region is the union of a series of rectangles -#endif +struct flCairoRegion { + int count; + struct _cairo_rectangle *rects; +}; // a region is the union of a series of rectangles class Fl_Cairo_Font_Descriptor : public Fl_Font_Descriptor { public: diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H index d736df9de..5e3b13f8b 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H @@ -78,7 +78,7 @@ public: void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) FL_OVERRIDE; static struct fl_wld_buffer *create_shm_buffer(int width, int height); static void buffer_release(struct wld_window *window); - static void buffer_commit(struct wld_window *window, bool need_damage = true); + static void buffer_commit(struct wld_window *window, struct flCairoRegion *r = NULL); static void cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format); void *gc() FL_OVERRIDE; void gc(void *gc) FL_OVERRIDE; diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index 608a8c004..a7b3610d8 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -92,15 +92,44 @@ static void surface_frame_done(void *data, struct wl_callback *cb, uint32_t time } -void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window, bool need_damage) { +// copy pixels in region r from the Cairo surface to the Wayland buffer +static void copy_region(struct wld_window *window, struct flCairoRegion *r) { + struct fl_wld_buffer *buffer = window->buffer; + float f = Fl::screen_scale(window->fl_win->screen_num()) * + Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale(); + for (int i = 0; i < r->count; i++) { + int left = r->rects[i].x * f; + int top = r->rects[i].y * f; + int width = r->rects[i].width * f; + int height = r->rects[i].height * f; + int offset = top * buffer->stride + 4 * left; + int W4 = 4 * width; + for (int l = 0; l < height; l++) { + if (offset + W4 >= buffer->data_size) { + W4 = buffer->data_size - offset; + if (W4 <= 0) break; + } + memcpy((uchar*)buffer->data + offset, buffer->draw_buffer + offset, W4); + offset += buffer->stride; + } + wl_surface_damage_buffer(window->wl_surface, left, top, width, height); + } +} + + +void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window, + struct flCairoRegion *r) { cairo_surface_t *surf = cairo_get_target(window->buffer->cairo_); cairo_surface_flush(surf); - memcpy(window->buffer->data, window->buffer->draw_buffer, window->buffer->data_size); + if (r) copy_region(window, r); + else { + memcpy(window->buffer->data, window->buffer->draw_buffer, window->buffer->data_size); + wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000); + } wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0); wl_surface_set_buffer_scale(window->wl_surface, Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale()); window->buffer->cb = wl_surface_frame(window->wl_surface); - if (need_damage) wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000); wl_callback_add_listener(window->buffer->cb, &surface_frame_listener, window); wl_surface_commit(window->wl_surface); window->buffer->draw_buffer_needs_commit = false; diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index d7031ace0..eee7892bf 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -395,27 +395,13 @@ void Fl_Wayland_Window_Driver::flush() { Fl_X *ip = Fl_X::flx(pWindow); struct flCairoRegion* r = (struct flCairoRegion*)ip->region; - float f = Fl::screen_scale(pWindow->screen_num()) * wld_scale(); - if (r && window->buffer) { - for (int i = 0; i < r->count; i++) { - int left = r->rects[i].x * f; - int top = r->rects[i].y * f; - int width = r->rects[i].width * f; - int height = r->rects[i].height * f; - wl_surface_damage_buffer(window->wl_surface, left, top, width, height); -//fprintf(stderr, "damage %dx%d %dx%d\n", left, top, width, height); - } - } else { - wl_surface_damage_buffer(window->wl_surface, 0, 0, - pWindow->w() * f, pWindow->h() * f); -//fprintf(stderr, "damage 0x0 %dx%d\n", pWindow->w() * f, pWindow->h() * f); - } + if (!window->buffer) r = NULL; Fl_Wayland_Window_Driver::in_flush = true; Fl_Window_Driver::flush(); Fl_Wayland_Window_Driver::in_flush = false; if (window->buffer->cb) wl_callback_destroy(window->buffer->cb); - Fl_Wayland_Graphics_Driver::buffer_commit(window, false); + Fl_Wayland_Graphics_Driver::buffer_commit(window, r); } @@ -667,7 +653,7 @@ static void surface_enter(void *data, struct wl_surface *wl_surface, struct wl_o window->fl_win->size(window->fl_win->w(), window->fl_win->h()); win_driver->is_a_rescale(false); } else if (window->buffer) { - Fl_Wayland_Graphics_Driver::buffer_commit(window, true); + Fl_Wayland_Graphics_Driver::buffer_commit(window); } if (window->fl_win->as_gl_window()) wl_surface_set_buffer_scale(window->wl_surface, output->wld_scale); |
