diff options
Diffstat (limited to 'backend')
-rw-r--r-- | backend/drm/drm.c | 37 | ||||
-rw-r--r-- | backend/drm/renderer.c | 17 | ||||
-rw-r--r-- | backend/headless/output.c | 13 | ||||
-rw-r--r-- | backend/meson.build | 13 | ||||
-rw-r--r-- | backend/wayland/output.c | 27 | ||||
-rw-r--r-- | backend/x11/backend.c | 11 |
6 files changed, 76 insertions, 42 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 47bd4e3a..4ba36bc4 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -183,18 +183,19 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) { free(drm->planes); } -static void wlr_drm_connector_make_current(struct wlr_output *output) { +static bool wlr_drm_connector_make_current(struct wlr_output *output, + int *buffer_age) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; - wlr_drm_surface_make_current(&conn->crtc->primary->surf); + return wlr_drm_surface_make_current(&conn->crtc->primary->surf, buffer_age); } -static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { +static bool wlr_drm_connector_swap_buffers(struct wlr_output *output) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; struct wlr_drm_crtc *crtc = conn->crtc; if (!crtc) { - return; + return false; } struct wlr_drm_plane *plane = crtc->primary; @@ -202,15 +203,21 @@ static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { if (drm->parent) { bo = wlr_drm_surface_mgpu_copy(&plane->mgpu_surf, bo); } - uint32_t fb_id = get_fb_for_bo(bo); + if (conn->pageflip_pending) { + wlr_log(L_ERROR, "Skipping pageflip"); + return true; + } + if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) { conn->pageflip_pending = true; } else { wl_event_source_timer_update(conn->retry_pageflip, - 1000.0f / conn->output.current_mode->refresh); + 1000000.0f / conn->output.current_mode->refresh); } + + return true; } static void wlr_drm_connector_set_gamma(struct wlr_output *output, @@ -247,7 +254,7 @@ void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn) { conn->pageflip_pending = true; } else { wl_event_source_timer_update(conn->retry_pageflip, - 1000.0f / conn->output.current_mode->refresh); + 1000000.0f / conn->output.current_mode->refresh); } } @@ -603,7 +610,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, return false; } - wlr_drm_surface_make_current(&plane->surf); + wlr_drm_surface_make_current(&plane->surf, NULL); wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, stride, width, height, buf); @@ -627,14 +634,18 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, gbm_bo_unmap(bo, bo_data); - return drm->iface->crtc_set_cursor(drm, crtc, bo); + bool ok = drm->iface->crtc_set_cursor(drm, crtc, bo); + if (ok) { + wlr_output_update_needs_swap(output); + } + return ok; } static bool wlr_drm_connector_move_cursor(struct wlr_output *output, int x, int y) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; - if (!conn || !conn->crtc) { + if (!conn->crtc) { return false; } struct wlr_drm_plane *plane = conn->crtc->cursor; @@ -654,8 +665,12 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output, transformed_box.y -= plane->cursor_hotspot_y; } - return drm->iface->crtc_move_cursor(drm, conn->crtc, transformed_box.x, + bool ok = drm->iface->crtc_move_cursor(drm, conn->crtc, transformed_box.x, transformed_box.y); + if (ok) { + wlr_output_update_needs_swap(output); + } + return ok; } static void wlr_drm_connector_destroy(struct wlr_output *output) { diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 00182c59..e2891057 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -113,9 +113,9 @@ void wlr_drm_surface_finish(struct wlr_drm_surface *surf) { memset(surf, 0, sizeof(*surf)); } -void wlr_drm_surface_make_current(struct wlr_drm_surface *surf) { - eglMakeCurrent(surf->renderer->egl.display, surf->egl, surf->egl, - surf->renderer->egl.context); +bool wlr_drm_surface_make_current(struct wlr_drm_surface *surf, + int *buffer_damage) { + 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) { @@ -123,7 +123,9 @@ struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf) { gbm_surface_release_buffer(surf->gbm, surf->front); } - eglSwapBuffers(surf->renderer->egl.display, surf->egl); + if (!eglSwapBuffers(surf->renderer->egl.display, surf->egl)) { + wlr_log(L_ERROR, "eglSwapBuffers failed"); + } surf->front = surf->back; surf->back = gbm_surface_lock_front_buffer(surf->gbm); @@ -135,7 +137,7 @@ struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf) { return surf->front; } - wlr_drm_surface_make_current(surf); + wlr_drm_surface_make_current(surf, NULL); glViewport(0, 0, surf->width, surf->height); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); @@ -207,8 +209,9 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, str return tex->tex; } -struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, struct gbm_bo *src) { - wlr_drm_surface_make_current(dest); +struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, + struct gbm_bo *src) { + wlr_drm_surface_make_current(dest, NULL); struct wlr_texture *tex = get_tex_for_bo(dest->renderer, src); diff --git a/backend/headless/output.c b/backend/headless/output.c index 9fc92e88..a9a538ed 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -48,18 +48,15 @@ static void output_transform(struct wlr_output *wlr_output, output->wlr_output.transform = transform; } -static void output_make_current(struct wlr_output *wlr_output) { +static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) { struct wlr_headless_output *output = (struct wlr_headless_output *)wlr_output; - if (!eglMakeCurrent(output->backend->egl.display, - output->egl_surface, output->egl_surface, - output->backend->egl.context)) { - wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error()); - } + return wlr_egl_make_current(&output->backend->egl, output->egl_surface, + buffer_age); } -static void output_swap_buffers(struct wlr_output *wlr_output) { - // No-op +static bool output_swap_buffers(struct wlr_output *wlr_output) { + return true; // No-op } static void output_destroy(struct wlr_output *wlr_output) { diff --git a/backend/meson.build b/backend/meson.build index b8084448..9931f546 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -45,5 +45,16 @@ 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], + dependencies: [ + wayland_server, + egl, + gbm, + libinput, + systemd, + elogind, + wlr_render, + wlr_protos, + drm, + pixman, + ], ) diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 52791679..5de18d41 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -18,10 +18,12 @@ int os_create_anonymous_file(off_t size); static struct wl_callback_listener frame_listener; static void surface_frame_callback(void *data, struct wl_callback *cb, uint32_t time) { - struct wlr_output *wlr_output = data; + struct wlr_wl_backend_output *output = data; + struct wlr_output *wlr_output = (struct wlr_output *)output; assert(wlr_output); wl_signal_emit(&wlr_output->events.frame, wlr_output); wl_callback_destroy(cb); + output->frame_callback = NULL; } static struct wl_callback_listener frame_listener = { @@ -36,22 +38,27 @@ static bool wlr_wl_output_set_custom_mode(struct wlr_output *_output, return true; } -static void wlr_wl_output_make_current(struct wlr_output *_output) { - struct wlr_wl_backend_output *output = (struct wlr_wl_backend_output *)_output; - if (!eglMakeCurrent(output->backend->egl.display, - output->egl_surface, output->egl_surface, - output->backend->egl.context)) { - wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error()); - } +static bool wlr_wl_output_make_current(struct wlr_output *wlr_output, + int *buffer_age) { + struct wlr_wl_backend_output *output = + (struct wlr_wl_backend_output *)wlr_output; + return wlr_egl_make_current(&output->backend->egl, output->egl_surface, + buffer_age); } -static void wlr_wl_output_swap_buffers(struct wlr_output *_output) { - struct wlr_wl_backend_output *output = (struct wlr_wl_backend_output *)_output; +static bool wlr_wl_output_swap_buffers(struct wlr_output *wlr_output) { + struct wlr_wl_backend_output *output = + (struct wlr_wl_backend_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; } static void wlr_wl_output_transform(struct wlr_output *_output, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index e1622d06..b9ea7d0f 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -379,22 +379,23 @@ static void output_destroy(struct wlr_output *wlr_output) { // output has been allocated on the stack, do not free it } -static void output_make_current(struct wlr_output *wlr_output) { +static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) { struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; struct wlr_x11_backend *x11 = output->x11; - if (!eglMakeCurrent(x11->egl.display, output->surf, output->surf, x11->egl.context)) { - wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error()); - } + return wlr_egl_make_current(&x11->egl, output->surf, buffer_age); } -static void output_swap_buffers(struct wlr_output *wlr_output) { +static bool output_swap_buffers(struct wlr_output *wlr_output) { 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; } static struct wlr_output_impl output_impl = { |