diff options
Diffstat (limited to 'backend')
-rw-r--r-- | backend/drm/backend.c | 2 | ||||
-rw-r--r-- | backend/drm/drm.c | 110 | ||||
-rw-r--r-- | backend/drm/renderer.c | 48 | ||||
-rw-r--r-- | backend/headless/output.c | 16 | ||||
-rw-r--r-- | backend/wayland/output.c | 21 | ||||
-rw-r--r-- | backend/wayland/wl_seat.c | 17 | ||||
-rw-r--r-- | backend/x11/backend.c | 9 |
7 files changed, 117 insertions, 106 deletions
diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 75b44210..43a8d017 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -173,7 +173,7 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, } if (!wlr_egl_bind_display(&drm->renderer.egl, display)) { - wlr_log(L_INFO, "Failed to bind egl/wl display: %s", egl_error()); + wlr_log(L_INFO, "Failed to bind egl/wl display"); } drm->display_destroy.notify = handle_display_destroy; diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 3b714300..524e80bb 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -15,9 +15,9 @@ #include <wayland-util.h> #include <wlr/backend/interface.h> #include <wlr/interfaces/wlr_output.h> -#include <wlr/render.h> #include <wlr/render/gles2.h> -#include <wlr/render/matrix.h> +#include <wlr/render/wlr_renderer.h> +#include <wlr/types/wlr_matrix.h> #include <wlr/util/log.h> #include <xf86drm.h> #include <xf86drmMode.h> @@ -544,10 +544,10 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, if (!crtc) { return false; } - struct wlr_drm_plane *plane = crtc->cursor; - // We don't have a real cursor plane, so we make a fake one + struct wlr_drm_plane *plane = crtc->cursor; if (!plane) { + // We don't have a real cursor plane, so we make a fake one plane = calloc(1, sizeof(*plane)); if (!plane) { wlr_log_errno(L_ERROR, "Allocation failed"); @@ -556,16 +556,6 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, crtc->cursor = plane; } - if (!buf && update_pixels) { - // Hide the cursor - plane->cursor_enabled = false; - if (!drm->session->active) { - return true; - } - return drm->iface->crtc_set_cursor(drm, crtc, NULL); - } - plane->cursor_enabled = true; - if (!plane->surf.gbm) { int ret; uint64_t w, h; @@ -592,13 +582,10 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, return false; } - // OpenGL will read the pixels out upside down, - // so we need to flip the image vertically - enum wl_output_transform transform = wlr_output_transform_compose( - wlr_output_transform_invert(output->transform), - WL_OUTPUT_TRANSFORM_FLIPPED_180); - wlr_matrix_texture(plane->matrix, plane->surf.width, plane->surf.height, - transform); + enum wl_output_transform transform = + wlr_output_transform_invert(output->transform); + wlr_matrix_projection(plane->matrix, plane->surf.width, + plane->surf.height, transform); plane->wlr_tex = wlr_render_texture_create(plane->surf.renderer->wlr_rend); @@ -607,62 +594,71 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, } } - struct wlr_box hotspot = { - .x = hotspot_x, - .y = hotspot_y, - }; + struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y }; enum wl_output_transform transform = wlr_output_transform_invert(output->transform); wlr_box_transform(&hotspot, transform, plane->surf.width, plane->surf.height, &hotspot); - plane->cursor_hotspot_x = hotspot.x; - plane->cursor_hotspot_y = hotspot.y; + + if (plane->cursor_hotspot_x != hotspot.x || + plane->cursor_hotspot_y != hotspot.y) { + // Update cursor hotspot + conn->cursor_x -= hotspot.x - plane->cursor_hotspot_x; + conn->cursor_y -= hotspot.y - plane->cursor_hotspot_y; + plane->cursor_hotspot_x = hotspot.x; + plane->cursor_hotspot_y = hotspot.y; + + if (!drm->iface->crtc_move_cursor(drm, conn->crtc, conn->cursor_x, + conn->cursor_y)) { + return false; + } + + wlr_output_update_needs_swap(output); + } if (!update_pixels) { - // Only update the cursor hotspot + // Don't update cursor image return true; } - struct gbm_bo *bo = plane->cursor_bo; - uint32_t bo_width = gbm_bo_get_width(bo); - uint32_t bo_height = gbm_bo_get_height(bo); - uint32_t bo_stride; - void *bo_data; + plane->cursor_enabled = buf != NULL; - if (!gbm_bo_map(bo, 0, 0, bo_width, bo_height, - GBM_BO_TRANSFER_WRITE, &bo_stride, &bo_data)) { - wlr_log_errno(L_ERROR, "Unable to map buffer"); - return false; - } + if (buf != NULL) { + uint32_t bo_width = gbm_bo_get_width(plane->cursor_bo); + uint32_t bo_height = gbm_bo_get_height(plane->cursor_bo); - wlr_drm_surface_make_current(&plane->surf, NULL); + uint32_t bo_stride; + void *bo_data; + if (!gbm_bo_map(plane->cursor_bo, 0, 0, bo_width, bo_height, + GBM_BO_TRANSFER_WRITE, &bo_stride, &bo_data)) { + wlr_log_errno(L_ERROR, "Unable to map buffer"); + return false; + } - wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, - stride, width, height, buf); + wlr_drm_surface_make_current(&plane->surf, NULL); - glViewport(0, 0, plane->surf.width, plane->surf.height); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); + wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, + stride, width, height, buf); - float matrix[16]; - wlr_texture_get_matrix(plane->wlr_tex, &matrix, &plane->matrix, 0, 0); - wlr_render_with_matrix(plane->surf.renderer->wlr_rend, plane->wlr_tex, - &matrix, 1.0f); + struct wlr_renderer *rend = plane->surf.renderer->wlr_rend; + wlr_renderer_begin(rend, plane->surf.width, plane->surf.height); + wlr_renderer_clear(rend, (float[]){ 0.0, 0.0, 0.0, 0.0 }); + wlr_render_texture(rend, plane->wlr_tex, plane->matrix, 0, 0, 1.0f); + wlr_renderer_end(rend); - glFinish(); - glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, bo_stride); - glReadPixels(0, 0, plane->surf.width, plane->surf.height, GL_BGRA_EXT, - GL_UNSIGNED_BYTE, bo_data); - glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); + wlr_renderer_read_pixels(rend, WL_SHM_FORMAT_ARGB8888, bo_stride, + plane->surf.width, plane->surf.height, 0, 0, 0, 0, bo_data); - wlr_drm_surface_swap_buffers(&plane->surf, NULL); + wlr_drm_surface_swap_buffers(&plane->surf, NULL); - gbm_bo_unmap(bo, bo_data); + gbm_bo_unmap(plane->cursor_bo, bo_data); + } if (!drm->session->active) { - return true; + return true; // will be committed when session is resumed } + struct gbm_bo *bo = plane->cursor_enabled ? plane->cursor_bo : NULL; bool ok = drm->iface->crtc_set_cursor(drm, crtc, bo); if (ok) { wlr_output_update_needs_swap(output); @@ -697,7 +693,7 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output, conn->cursor_y = box.y; if (!drm->session->active) { - return true; + return true; // will be committed when session is resumed } bool ok = drm->iface->crtc_move_cursor(drm, conn->crtc, box.x, box.y); diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 7ee13843..b2998b5f 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -1,15 +1,15 @@ +#include <assert.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <gbm.h> -#include <GLES2/gl2.h> #include <stdbool.h> #include <stdlib.h> #include <unistd.h> #include <wayland-util.h> -#include <wlr/render.h> #include <wlr/render/egl.h> #include <wlr/render/gles2.h> -#include <wlr/render/matrix.h> +#include <wlr/render/wlr_renderer.h> +#include <wlr/types/wlr_matrix.h> #include <wlr/util/log.h> #include "backend/drm/drm.h" #include "glapi.h" @@ -106,9 +106,6 @@ void wlr_drm_surface_finish(struct wlr_drm_surface *surf) { return; } - eglMakeCurrent(surf->renderer->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - if (surf->front) { gbm_surface_release_buffer(surf->gbm, surf->front); } @@ -150,9 +147,10 @@ struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *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); + struct wlr_renderer *renderer = surf->renderer->wlr_rend; + wlr_renderer_begin(renderer, surf->width, surf->height); + wlr_renderer_clear(renderer, (float[]){ 0.0, 0.0, 0.0, 1.0 }); + wlr_renderer_end(renderer); return wlr_drm_surface_swap_buffers(surf, NULL); } @@ -177,12 +175,15 @@ static void free_eglimage(struct gbm_bo *bo, void *data) { free(tex); } -static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, struct gbm_bo *bo) { +static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, + struct gbm_bo *bo) { struct tex *tex = gbm_bo_get_user_data(bo); if (tex) { return tex->tex; } + // TODO: use wlr_texture_upload_dmabuf instead + tex = malloc(sizeof(*tex)); if (!tex) { wlr_log_errno(L_ERROR, "Allocation failed"); @@ -209,7 +210,7 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, str tex->img = eglCreateImageKHR(renderer->egl.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (!tex->img) { - wlr_log(L_ERROR, "Failed to create EGL image: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL image"); abort(); } @@ -226,26 +227,23 @@ struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, wlr_drm_surface_make_current(dest, NULL); struct wlr_texture *tex = get_tex_for_bo(dest->renderer, src); + assert(tex); - static const float matrix[16] = { - [0] = 2.0f, - [3] = -1.0f, - [5] = 2.0f, - [7] = -1.0f, - [10] = 1.0f, - [15] = 1.0f, - }; + float mat[9]; + wlr_matrix_projection(mat, 1, 1, WL_OUTPUT_TRANSFORM_FLIPPED_180); - glViewport(0, 0, dest->width, dest->height); - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - wlr_render_with_matrix(dest->renderer->wlr_rend, tex, &matrix, 1.0f); + struct wlr_renderer *renderer = dest->renderer->wlr_rend; + wlr_renderer_begin(renderer, dest->width, dest->height); + wlr_renderer_clear(renderer, (float[]){ 0.0, 0.0, 0.0, 1.0 }); + wlr_render_texture_with_matrix(renderer, tex, mat, 1.0f); + wlr_renderer_end(renderer); return wlr_drm_surface_swap_buffers(dest, NULL); } -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) { if (!drm->parent) { return wlr_drm_surface_init(&plane->surf, &drm->renderer, width, height, format, GBM_BO_USE_SCANOUT); diff --git a/backend/headless/output.c b/backend/headless/output.c index 6ce8fc35..a13ed22c 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -1,8 +1,8 @@ #include <EGL/egl.h> #include <EGL/eglext.h> -#include <GLES2/gl2.h> #include <stdlib.h> #include <wlr/interfaces/wlr_output.h> +#include <wlr/render/wlr_renderer.h> #include <wlr/util/log.h> #include "backend/headless.h" #include "util/signal.h" @@ -13,7 +13,7 @@ static EGLSurface egl_create_surface(struct wlr_egl *egl, unsigned int width, EGLSurface surf = eglCreatePbufferSurface(egl->display, egl->config, attribs); if (surf == EGL_NO_SURFACE) { - wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL surface"); return EGL_NO_SURFACE; } return surf; @@ -120,16 +120,14 @@ struct wlr_output *wlr_headless_add_output(struct wlr_backend *wlr_backend, snprintf(wlr_output->name, sizeof(wlr_output->name), "HEADLESS-%d", wl_list_length(&backend->outputs) + 1); - 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()); + if (!wlr_egl_make_current(&output->backend->egl, output->egl_surface, + NULL)) { goto error; } - glViewport(0, 0, wlr_output->width, wlr_output->height); - glClearColor(1.0, 1.0, 1.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); + wlr_renderer_begin(backend->renderer, wlr_output->width, wlr_output->height); + wlr_renderer_clear(backend->renderer, (float[]){ 1.0, 1.0, 1.0, 1.0 }); + wlr_renderer_end(backend->renderer); struct wl_event_loop *ev = wl_display_get_event_loop(backend->display); output->frame_timer = wl_event_loop_add_timer(ev, signal_frame, output); diff --git a/backend/wayland/output.c b/backend/wayland/output.c index fc40dea0..d528c888 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -1,5 +1,4 @@ #include <assert.h> -#include <GLES2/gl2.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -9,6 +8,7 @@ #include <unistd.h> #include <wayland-client.h> #include <wlr/interfaces/wlr_output.h> +#include <wlr/render/wlr_renderer.h> #include <wlr/util/log.h> #include "backend/wayland.h" #include "util/signal.h" @@ -313,27 +313,26 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { output->egl_window = wl_egl_window_create(output->surface, wlr_output->width, wlr_output->height); - output->egl_surface = wlr_egl_create_surface(&backend->egl, output->egl_window); + output->egl_surface = wlr_egl_create_surface(&backend->egl, + output->egl_window); wl_display_roundtrip(output->backend->remote_display); // start rendering loop per callbacks by rendering first frame - 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()); + if (!wlr_egl_make_current(&output->backend->egl, output->egl_surface, + NULL)) { goto error; } - glViewport(0, 0, wlr_output->width, wlr_output->height); - glClearColor(1.0, 1.0, 1.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); + wlr_renderer_begin(backend->renderer, wlr_output->width, wlr_output->height); + wlr_renderer_clear(backend->renderer, (float[]){ 1.0, 1.0, 1.0, 1.0 }); + wlr_renderer_end(backend->renderer); 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()); + if (!wlr_egl_swap_buffers(&output->backend->egl, output->egl_surface, + NULL)) { goto error; } diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 841e693d..6ca59130 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -26,6 +26,11 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, // GNOME sends a pointer enter when the surface is being destroyed return; } + if (wlr_wl_pointer->current_output) { + wl_list_remove(&wlr_wl_pointer->output_destroy_listener.link); + } + wl_signal_add(&output->wlr_output.events.destroy, + &wlr_wl_pointer->output_destroy_listener); wlr_wl_pointer->current_output = output; output->enter_serial = serial; wlr_wl_output_update_cursor(output); @@ -49,7 +54,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, struct wlr_wl_pointer *wlr_wl_pointer = (struct wlr_wl_pointer *)dev->pointer; if (!wlr_wl_pointer->current_output) { - wlr_log(L_ERROR, "pointer motion event without current output"); + wlr_log(L_DEBUG, "pointer motion event without current output"); return; } @@ -231,6 +236,14 @@ static struct wlr_input_device *allocate_device(struct wlr_wl_backend *backend, return wlr_device; } +static void wlr_wl_pointer_handle_output_destroy(struct wl_listener *listener, + void *data) { + struct wlr_wl_pointer *wlr_wl_pointer = + wl_container_of(listener, wlr_wl_pointer, output_destroy_listener); + wlr_wl_pointer->current_output = NULL; + wl_list_remove(&wlr_wl_pointer->output_destroy_listener.link); +} + static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { struct wlr_wl_backend *backend = data; @@ -243,6 +256,8 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, wlr_log(L_ERROR, "Unable to allocate wlr_wl_pointer"); return; } + wlr_wl_pointer->output_destroy_listener.notify = + wlr_wl_pointer_handle_output_destroy; struct wlr_input_device *wlr_device; if (!(wlr_device = allocate_device(backend, WLR_INPUT_DEVICE_POINTER))) { diff --git a/backend/x11/backend.c b/backend/x11/backend.c index cb29e518..36d72d9e 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -143,6 +143,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); + free(pointer); break; } case XCB_CLIENT_MESSAGE: { @@ -317,12 +318,17 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { wlr_signal_emit_safe(&backend->events.destroy, backend); + if (x11->event_source) { + wl_event_source_remove(x11->event_source); + } wl_list_remove(&x11->display_destroy.link); wl_event_source_remove(x11->frame_timer); wlr_egl_finish(&x11->egl); - xcb_disconnect(x11->xcb_conn); + if (x11->xlib_conn) { + XCloseDisplay(x11->xlib_conn); + } free(x11); } @@ -419,7 +425,6 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, error_event: wl_event_source_remove(x11->event_source); error_x11: - xcb_disconnect(x11->xcb_conn); XCloseDisplay(x11->xlib_conn); free(x11); return NULL; |