aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/drm/backend.c2
-rw-r--r--backend/drm/drm.c110
-rw-r--r--backend/drm/renderer.c48
-rw-r--r--backend/headless/output.c16
-rw-r--r--backend/wayland/output.c21
-rw-r--r--backend/wayland/wl_seat.c17
-rw-r--r--backend/x11/backend.c9
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;