diff options
-rw-r--r-- | backend/drm/drm.c | 7 | ||||
-rw-r--r-- | backend/drm/renderer.c | 11 | ||||
-rw-r--r-- | backend/headless/output.c | 3 | ||||
-rw-r--r-- | backend/meson.build | 30 | ||||
-rw-r--r-- | backend/wayland/output.c | 11 | ||||
-rw-r--r-- | backend/x11/backend.c | 10 | ||||
-rw-r--r-- | include/backend/drm/renderer.h | 11 | ||||
-rw-r--r-- | include/wlr/interfaces/wlr_output.h | 2 | ||||
-rw-r--r-- | include/wlr/render/egl.h | 7 | ||||
-rw-r--r-- | meson.build | 32 | ||||
-rw-r--r-- | meson_options.txt | 6 | ||||
-rw-r--r-- | render/egl.c | 39 | ||||
-rw-r--r-- | render/glapi.txt | 2 | ||||
-rw-r--r-- | rootston/config.c | 2 | ||||
-rw-r--r-- | types/wlr_output.c | 10 |
15 files changed, 117 insertions, 66 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 15be16bc..56a78851 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -195,7 +195,8 @@ static bool wlr_drm_connector_make_current(struct wlr_output *output, return wlr_drm_surface_make_current(&conn->crtc->primary->surf, buffer_age); } -static bool wlr_drm_connector_swap_buffers(struct wlr_output *output) { +static bool wlr_drm_connector_swap_buffers(struct wlr_output *output, + pixman_region32_t *damage) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; if (!drm->session->active) { @@ -208,7 +209,7 @@ static bool wlr_drm_connector_swap_buffers(struct wlr_output *output) { } struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&plane->surf); + struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&plane->surf, damage); if (drm->parent) { bo = wlr_drm_surface_mgpu_copy(&plane->mgpu_surf, bo); } @@ -653,7 +654,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, GL_UNSIGNED_BYTE, bo_data); glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); - wlr_drm_surface_swap_buffers(&plane->surf); + wlr_drm_surface_swap_buffers(&plane->surf, NULL); gbm_bo_unmap(bo, bo_data); diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 0310a96a..80d3bd9a 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -133,14 +133,13 @@ bool wlr_drm_surface_make_current(struct wlr_drm_surface *surf, return wlr_egl_make_current(&surf->renderer->egl, surf->egl, buffer_damage); } -struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf) { +struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf, + pixman_region32_t *damage) { if (surf->front) { gbm_surface_release_buffer(surf->gbm, surf->front); } - if (!eglSwapBuffers(surf->renderer->egl.display, surf->egl)) { - wlr_log(L_ERROR, "eglSwapBuffers failed"); - } + wlr_egl_swap_buffers(&surf->renderer->egl, surf->egl, damage); surf->front = surf->back; surf->back = gbm_surface_lock_front_buffer(surf->gbm); @@ -156,7 +155,7 @@ struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf) { glViewport(0, 0, surf->width, surf->height); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - return wlr_drm_surface_swap_buffers(surf); + return wlr_drm_surface_swap_buffers(surf, NULL); } void wlr_drm_surface_post(struct wlr_drm_surface *surf) { @@ -244,7 +243,7 @@ struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, glClear(GL_COLOR_BUFFER_BIT); wlr_render_with_matrix(dest->renderer->wlr_rend, tex, &matrix); - return wlr_drm_surface_swap_buffers(dest); + return wlr_drm_surface_swap_buffers(dest, NULL); } bool wlr_drm_plane_surfaces_init(struct wlr_drm_plane *plane, struct wlr_drm_backend *drm, diff --git a/backend/headless/output.c b/backend/headless/output.c index aac7cc20..507595a5 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -55,7 +55,8 @@ static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) buffer_age); } -static bool output_swap_buffers(struct wlr_output *wlr_output) { +static bool output_swap_buffers(struct wlr_output *wlr_output, + pixman_region32_t *damage) { return true; // No-op } diff --git a/backend/meson.build b/backend/meson.build index 9c8f5852..beb3841c 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -27,34 +27,36 @@ backend_files = files( 'x11/backend.c', ) +backend_deps = [ + wayland_server, + egl, + gbm, + libinput, + wlr_render, + wlr_protos, + drm, + pixman, +] + if host_machine.system().startswith('freebsd') backend_files += files('session/direct-freebsd.c') else backend_files += files('session/direct.c') endif -if systemd.found() and get_option('enable_systemd') +if conf_data.get('WLR_HAS_SYSTEMD', false) backend_files += files('session/logind.c') + backend_deps += systemd endif -if elogind.found() and get_option('enable_elogind') +if conf_data.get('WLR_HAS_ELOGIND', false) backend_files += files('session/logind.c') + backend_deps += elogind endif lib_wlr_backend = static_library( 'wlr_backend', backend_files, include_directories: wlr_inc, - dependencies: [ - wayland_server, - egl, - gbm, - libinput, - systemd, - elogind, - wlr_render, - wlr_protos, - drm, - pixman, - ], + dependencies: backend_deps, ) diff --git a/backend/wayland/output.c b/backend/wayland/output.c index a9140ff7..0bbf6d42 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -47,7 +47,8 @@ static bool wlr_wl_output_make_current(struct wlr_output *wlr_output, buffer_age); } -static bool wlr_wl_output_swap_buffers(struct wlr_output *wlr_output) { +static bool wlr_wl_output_swap_buffers(struct wlr_output *wlr_output, + pixman_region32_t *damage) { struct wlr_wl_backend_output *output = (struct wlr_wl_backend_output *)wlr_output; @@ -59,12 +60,8 @@ static bool wlr_wl_output_swap_buffers(struct wlr_output *wlr_output) { output->frame_callback = wl_surface_frame(output->surface); wl_callback_add_listener(output->frame_callback, &frame_listener, output); - if (!eglSwapBuffers(output->backend->egl.display, output->egl_surface)) { - wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error()); - return false; - } - - return true; + return wlr_egl_swap_buffers(&output->backend->egl, output->egl_surface, + damage); } static void wlr_wl_output_transform(struct wlr_output *_output, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 44e29be1..411d0ef6 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -401,16 +401,12 @@ static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) return wlr_egl_make_current(&x11->egl, output->surf, buffer_age); } -static bool output_swap_buffers(struct wlr_output *wlr_output) { +static bool output_swap_buffers(struct wlr_output *wlr_output, + pixman_region32_t *damage) { struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; struct wlr_x11_backend *x11 = output->x11; - if (!eglSwapBuffers(x11->egl.display, output->surf)) { - wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error()); - return false; - } - - return true; + return wlr_egl_swap_buffers(&x11->egl, output->surf, damage); } static struct wlr_output_impl output_impl = { diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index a3f19fc3..bf0165bc 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -41,14 +41,17 @@ bool wlr_drm_surface_init(struct wlr_drm_surface *surf, struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); -bool wlr_drm_plane_surfaces_init(struct wlr_drm_plane *plane, struct wlr_drm_backend *drm, - int32_t width, uint32_t height, uint32_t format); +bool wlr_drm_plane_surfaces_init(struct wlr_drm_plane *plane, + struct wlr_drm_backend *drm, int32_t width, uint32_t height, + uint32_t format); void wlr_drm_surface_finish(struct wlr_drm_surface *surf); bool wlr_drm_surface_make_current(struct wlr_drm_surface *surf, int *buffer_age); -struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf); +struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf, + pixman_region32_t *damage); struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf); void wlr_drm_surface_post(struct wlr_drm_surface *surf); -struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, struct gbm_bo *src); +struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, + struct gbm_bo *src); #endif diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 652be45e..a01f8901 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -19,7 +19,7 @@ struct wlr_output_impl { bool (*move_cursor)(struct wlr_output *output, int x, int y); void (*destroy)(struct wlr_output *output); bool (*make_current)(struct wlr_output *output, int *buffer_age); - bool (*swap_buffers)(struct wlr_output *output); + bool (*swap_buffers)(struct wlr_output *output, pixman_region32_t *damage); void (*set_gamma)(struct wlr_output *output, uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b); uint32_t (*get_gamma_size)(struct wlr_output *output); diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h index 6979fd9b..1facc6b8 100644 --- a/include/wlr/render/egl.h +++ b/include/wlr/render/egl.h @@ -1,9 +1,10 @@ #ifndef WLR_EGL_H #define WLR_EGL_H +#include <stdbool.h> #include <EGL/egl.h> #include <EGL/eglext.h> -#include <stdbool.h> +#include <pixman.h> #include <wayland-server.h> struct wlr_egl { @@ -16,6 +17,7 @@ struct wlr_egl { struct { bool buffer_age; + bool swap_buffers_with_damage; } egl_exts; struct wl_display *wl_display; @@ -72,4 +74,7 @@ const char *egl_error(void); bool wlr_egl_make_current(struct wlr_egl *egl, EGLSurface surface, int *buffer_age); +bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface, + pixman_region32_t *damage); + #endif diff --git a/meson.build b/meson.build index 236abd6b..6c8a3a8b 100644 --- a/meson.build +++ b/meson.build @@ -65,29 +65,33 @@ xcb_image = dependency('xcb-image') xcb_render = dependency('xcb-render') xcb_icccm = dependency('xcb-icccm', required: false) x11_xcb = dependency('x11-xcb') -libcap = dependency('libcap', required: false) -systemd = dependency('libsystemd', required: false) -elogind = dependency('libelogind', required: false) +libcap = dependency('libcap', required: get_option('enable_libcap') == 'true') +systemd = dependency('libsystemd', required: get_option('enable_systemd') == 'true') +elogind = dependency('libelogind', required: get_option('enable_elogind') == 'true') math = cc.find_library('m', required: false) +exclude_headers = [] +wlr_parts = [] +wlr_deps = [] + if xcb_icccm.found() conf_data.set('WLR_HAS_XCB_ICCCM', true) endif -if libcap.found() and get_option('enable_libcap') +if libcap.found() and get_option('enable_libcap') != 'false' conf_data.set('WLR_HAS_LIBCAP', true) + wlr_deps += libcap endif -if systemd.found() and get_option('enable_systemd') +if systemd.found() and get_option('enable_systemd') != 'false' conf_data.set('WLR_HAS_SYSTEMD', true) + wlr_deps += systemd endif -if elogind.found() and get_option('enable_elogind') +if elogind.found() and get_option('enable_elogind') != 'false' conf_data.set('WLR_HAS_ELOGIND', true) endif -exclude_headers = [] -wlr_parts = [] if get_option('enable_xwayland') subdir('xwayland') wlr_parts += [lib_wlr_xwayland] @@ -117,7 +121,7 @@ wlr_parts += [ lib_wlr_xcursor, ] -wlr_deps = [ +wlr_deps += [ wayland_server, wayland_client, wayland_egl, @@ -133,8 +137,6 @@ wlr_deps = [ xcb, xcb_composite, x11_xcb, - libcap, - systemd, math, ] @@ -159,10 +161,10 @@ summary = [ '----------------', 'wlroots @0@'.format(meson.project_version()), '', - ' libcap: @0@'.format(get_option('enable_libcap')), - ' systemd: @0@'.format(get_option('enable_systemd')), - ' elogind: @0@'.format(get_option('enable_elogind')), - ' xwayland: @0@'.format(get_option('enable_xwayland')), + ' libcap: @0@'.format(conf_data.get('WLR_HAS_LIBCAP', false)), + ' systemd: @0@'.format(conf_data.get('WLR_HAS_SYSTEMD', false)), + ' elogind: @0@'.format(conf_data.get('WLR_HAS_ELOGIND', false)), + ' xwayland: @0@'.format(conf_data.get('WLR_HAS_XWAYLAND', false)), '----------------', '' ] diff --git a/meson_options.txt b/meson_options.txt index b1e64bd9..6434b43d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,4 @@ -option('enable_libcap', type: 'boolean', value: true, description: 'Enable support for capabilities') -option('enable_systemd', type: 'boolean', value: true, description: 'Enable support for logind') -option('enable_elogind', type: 'boolean', value: true, description: 'Enable support for logind') +option('enable_libcap', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for capabilities') +option('enable_systemd', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for logind') +option('enable_elogind', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for logind') option('enable_xwayland', type: 'boolean', value: true, description: 'Enable support X11 applications') diff --git a/render/egl.c b/render/egl.c index 9ac0b307..328726ba 100644 --- a/render/egl.c +++ b/render/egl.c @@ -1,8 +1,8 @@ #include <assert.h> +#include <stdlib.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES2/gl2.h> -#include <stdlib.h> #include <wlr/util/log.h> #include <wlr/render/egl.h> #include "glapi.h" @@ -143,6 +143,9 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, egl->egl_exts.buffer_age = strstr(egl->egl_exts_str, "EGL_EXT_buffer_age") != NULL; + egl->egl_exts.swap_buffers_with_damage = + strstr(egl->egl_exts_str, "EGL_EXT_swap_buffers_with_damage") != NULL || + strstr(egl->egl_exts_str, "EGL_KHR_swap_buffers_with_damage") != NULL; return true; @@ -242,3 +245,37 @@ bool wlr_egl_make_current(struct wlr_egl *egl, EGLSurface surface, } return true; } + +bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface, + pixman_region32_t *damage) { + EGLBoolean ret; + if (damage != NULL && egl->egl_exts.swap_buffers_with_damage) { + int nrects; + pixman_box32_t *rects = + pixman_region32_rectangles(damage, &nrects); + EGLint egl_damage[4 * nrects]; + for (int i = 0; i < nrects; ++i) { + egl_damage[4*i] = rects[i].x1; + egl_damage[4*i + 1] = rects[i].y1; + egl_damage[4*i + 2] = rects[i].x2 - rects[i].x1; + egl_damage[4*i + 3] = rects[i].y2 - rects[i].y1; + } + + assert(eglSwapBuffersWithDamageEXT || eglSwapBuffersWithDamageKHR); + if (eglSwapBuffersWithDamageEXT) { + ret = eglSwapBuffersWithDamageEXT(egl->display, surface, egl_damage, + nrects); + } else { + ret = eglSwapBuffersWithDamageKHR(egl->display, surface, egl_damage, + nrects); + } + } else { + ret = eglSwapBuffers(egl->display, surface); + } + + if (!ret) { + wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error()); + return false; + } + return true; +} diff --git a/render/glapi.txt b/render/glapi.txt index 81791204..0b0b452c 100644 --- a/render/glapi.txt +++ b/render/glapi.txt @@ -6,3 +6,5 @@ eglCreatePlatformWindowSurfaceEXT -eglBindWaylandDisplayWL -eglUnbindWaylandDisplayWL -glEGLImageTargetTexture2DOES +-eglSwapBuffersWithDamageEXT +-eglSwapBuffersWithDamageKHR diff --git a/rootston/config.c b/rootston/config.c index 31bde2b0..26cbd12d 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -281,7 +281,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, oc->y = strtol(value, NULL, 10); } else if (strcmp(name, "scale") == 0) { oc->scale = strtof(value, NULL); - assert(oc->scale >= 1); + assert(oc->scale > 0); } else if (strcmp(name, "rotate") == 0) { if (strcmp(value, "normal") == 0) { oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; diff --git a/types/wlr_output.c b/types/wlr_output.c index 13561d43..5f7dca28 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -507,8 +507,14 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when, } } - // TODO: provide `damage` (not `render_damage`) to backend - if (!output->impl->swap_buffers(output)) { + // Transform damage into renderer coordinates, ie. upside down + enum wl_output_transform transform = wlr_output_transform_compose( + wlr_output_transform_invert(output->transform), + WL_OUTPUT_TRANSFORM_FLIPPED_180); + wlr_region_transform(&render_damage, &render_damage, transform, width, + height); + + if (!output->impl->swap_buffers(output, damage ? &render_damage : NULL)) { return false; } |