Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

Renderer v6, incremental version #2240

Merged
merged 14 commits into from
Nov 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 28 additions & 16 deletions backend/drm/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "backend/drm/drm.h"
#include "backend/drm/iface.h"
#include "backend/drm/util.h"
#include "render/swapchain.h"
#include "util/signal.h"

bool check_drm_features(struct wlr_drm_backend *drm) {
Expand Down Expand Up @@ -331,16 +332,25 @@ static bool drm_connector_attach_render(struct wlr_output *output,
return drm_surface_make_current(&conn->crtc->primary->surf, buffer_age);
}

static void drm_plane_set_committed(struct wlr_drm_plane *plane) {
drm_fb_move(&plane->queued_fb, &plane->pending_fb);

struct wlr_buffer *queued = plane->queued_fb.wlr_buf;
if (queued != NULL) {
wlr_swapchain_set_buffer_submitted(plane->surf.swapchain, queued);
}
}

static bool drm_crtc_commit(struct wlr_drm_connector *conn, uint32_t flags) {
struct wlr_drm_backend *drm =
get_drm_backend_from_backend(conn->output.backend);
struct wlr_drm_crtc *crtc = conn->crtc;
bool ok = drm->iface->crtc_commit(drm, conn, flags);
if (ok && !(flags & DRM_MODE_ATOMIC_TEST_ONLY)) {
memcpy(&crtc->current, &crtc->pending, sizeof(struct wlr_drm_crtc_state));
drm_fb_move(&crtc->primary->queued_fb, &crtc->primary->pending_fb);
drm_plane_set_committed(crtc->primary);
if (crtc->cursor != NULL) {
drm_fb_move(&crtc->cursor->queued_fb, &crtc->cursor->pending_fb);
drm_plane_set_committed(crtc->cursor);
}
} else {
memcpy(&crtc->pending, &crtc->current, sizeof(struct wlr_drm_crtc_state));
Expand All @@ -367,7 +377,7 @@ static bool drm_crtc_page_flip(struct wlr_drm_connector *conn) {
}

assert(crtc->pending.active);
assert(plane_get_next_fb(crtc->primary)->type != WLR_DRM_FB_TYPE_NONE);
assert(plane_get_next_fb(crtc->primary)->bo);
if (!drm_crtc_commit(conn, DRM_MODE_PAGE_FLIP_EVENT)) {
return false;
}
Expand Down Expand Up @@ -593,8 +603,8 @@ static bool drm_connector_commit(struct wlr_output *output) {
}

static void drm_connector_rollback_render(struct wlr_output *output) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend);
wlr_egl_unset_current(&drm->renderer.egl);
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
return drm_surface_unset_current(&conn->crtc->primary->surf);
}

size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm,
Expand Down Expand Up @@ -640,21 +650,21 @@ static bool drm_connector_export_dmabuf(struct wlr_output *output,
}

struct wlr_drm_fb *fb = &crtc->primary->queued_fb;
if (fb->type == WLR_DRM_FB_TYPE_NONE) {
if (fb->bo == NULL) {
fb = &crtc->primary->current_fb;
}
if (fb->type == WLR_DRM_FB_TYPE_NONE) {
if (fb->bo == NULL) {
return false;
}

return export_drm_bo(fb->bo, attribs);
}

struct wlr_drm_fb *plane_get_next_fb(struct wlr_drm_plane *plane) {
if (plane->pending_fb.type != WLR_DRM_FB_TYPE_NONE) {
if (plane->pending_fb.bo) {
return &plane->pending_fb;
}
if (plane->queued_fb.type != WLR_DRM_FB_TYPE_NONE) {
if (plane->queued_fb.bo) {
return &plane->queued_fb;
}
return &plane->current_fb;
Expand All @@ -670,8 +680,10 @@ static bool drm_connector_pageflip_renderer(struct wlr_drm_connector *conn) {

// drm_crtc_page_flip expects a FB to be available
struct wlr_drm_plane *plane = crtc->primary;
if (plane_get_next_fb(plane)->type == WLR_DRM_FB_TYPE_NONE) {
drm_surface_render_black_frame(&plane->surf);
if (!plane_get_next_fb(plane)->bo) {
if (!drm_surface_render_black_frame(&plane->surf)) {
return false;
}
if (!drm_fb_lock_surface(&plane->pending_fb, &plane->surf)) {
return false;
}
Expand Down Expand Up @@ -883,7 +895,7 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
return false;
}

if (!plane->surf.gbm) {
if (!plane->surf.swapchain) {
int ret;
uint64_t w, h;
ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &w);
Expand Down Expand Up @@ -1497,11 +1509,10 @@ static void page_flip_handler(int fd, unsigned seq,
}

struct wlr_drm_plane *plane = conn->crtc->primary;
if (plane->queued_fb.type != WLR_DRM_FB_TYPE_NONE) {
if (plane->queued_fb.bo) {
drm_fb_move(&plane->current_fb, &plane->queued_fb);
}
if (conn->crtc->cursor &&
conn->crtc->cursor->queued_fb.type != WLR_DRM_FB_TYPE_NONE) {
if (conn->crtc->cursor && conn->crtc->cursor->queued_fb.bo) {
drm_fb_move(&conn->crtc->cursor->current_fb,
&conn->crtc->cursor->queued_fb);
}
Expand All @@ -1512,7 +1523,8 @@ static void page_flip_handler(int fd, unsigned seq,
* data between the GPUs, even if we were using the direct scanout
* interface.
*/
if (!drm->parent && plane->current_fb.type == WLR_DRM_FB_TYPE_WLR_BUFFER) {
if (!drm->parent && plane->current_fb.wlr_buf &&
wlr_client_buffer_get(plane->current_fb.wlr_buf)) {
present_flags |= WLR_OUTPUT_PRESENT_ZERO_COPY;
}

Expand Down
Loading