output: fix attach_buffer semantics
This commit is contained in:
parent
1d222309b8
commit
afe7b207d5
|
@ -301,11 +301,44 @@ static bool drm_connector_commit(struct wlr_output *output) {
|
||||||
damage = &output->pending.damage;
|
damage = &output->pending.damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gbm_bo *bo = swap_drm_surface_buffers(&plane->surf, damage);
|
struct gbm_bo *bo;
|
||||||
if (drm->parent) {
|
uint32_t fb_id = 0;
|
||||||
bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
|
assert(output->pending.committed & WLR_OUTPUT_STATE_BUFFER);
|
||||||
|
switch (output->pending.buffer_type) {
|
||||||
|
case WLR_OUTPUT_STATE_BUFFER_RENDER:
|
||||||
|
bo = swap_drm_surface_buffers(&plane->surf, damage);
|
||||||
|
if (bo == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "swap_drm_surface_buffers failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drm->parent) {
|
||||||
|
bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
|
||||||
|
if (bo == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "copy_drm_surface_mgpu failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fb_id = get_fb_for_bo(bo, plane->drm_format);
|
||||||
|
if (fb_id == 0) {
|
||||||
|
wlr_log(WLR_ERROR, "get_fb_for_bo failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WLR_OUTPUT_STATE_BUFFER_SCANOUT:
|
||||||
|
bo = import_gbm_bo(&drm->renderer, &conn->pending_dmabuf);
|
||||||
|
if (bo == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "import_gbm_bo failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fb_id = get_fb_for_bo(bo, gbm_bo_get_format(bo));
|
||||||
|
if (fb_id == 0) {
|
||||||
|
wlr_log(WLR_ERROR, "get_fb_for_bo failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format);
|
|
||||||
|
|
||||||
if (conn->pageflip_pending) {
|
if (conn->pageflip_pending) {
|
||||||
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'", conn->output.name);
|
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'", conn->output.name);
|
||||||
|
@ -903,30 +936,7 @@ static bool drm_connector_attach_buffer(struct wlr_output *output,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gbm_bo *bo = import_gbm_bo(&drm->renderer, &attribs);
|
memcpy(&conn->pending_dmabuf, &attribs, sizeof(attribs));
|
||||||
if (bo == NULL) {
|
|
||||||
wlr_log(WLR_ERROR, "import_gbm_bo failed");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fb_id = get_fb_for_bo(bo, gbm_bo_get_format(bo));
|
|
||||||
if (fb_id == 0) {
|
|
||||||
wlr_log(WLR_ERROR, "get_fb_for_bo failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->pageflip_pending) {
|
|
||||||
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'", conn->output.name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) {
|
|
||||||
wlr_log(WLR_ERROR, "crtc_pageflip failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn->pageflip_pending = true;
|
|
||||||
wlr_output_update_enabled(output, true);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,8 @@ struct wlr_drm_connector {
|
||||||
bool pageflip_pending;
|
bool pageflip_pending;
|
||||||
struct wl_event_source *retry_pageflip;
|
struct wl_event_source *retry_pageflip;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
|
struct wlr_dmabuf_attributes pending_dmabuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_backend *get_drm_backend_from_backend(
|
struct wlr_drm_backend *get_drm_backend_from_backend(
|
||||||
|
|
|
@ -52,12 +52,21 @@ enum wlr_output_state_field {
|
||||||
WLR_OUTPUT_STATE_DAMAGE = 1 << 1,
|
WLR_OUTPUT_STATE_DAMAGE = 1 << 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wlr_output_state_buffer_type {
|
||||||
|
WLR_OUTPUT_STATE_BUFFER_RENDER,
|
||||||
|
WLR_OUTPUT_STATE_BUFFER_SCANOUT,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the double-buffered output state.
|
* Holds the double-buffered output state.
|
||||||
*/
|
*/
|
||||||
struct wlr_output_state {
|
struct wlr_output_state {
|
||||||
uint32_t committed; // enum wlr_output_state_field
|
uint32_t committed; // enum wlr_output_state_field
|
||||||
pixman_region32_t damage; // output-buffer-local coordinates
|
pixman_region32_t damage; // output-buffer-local coordinates
|
||||||
|
|
||||||
|
// only valid if WLR_OUTPUT_STATE_BUFFER
|
||||||
|
enum wlr_output_state_buffer_type buffer_type;
|
||||||
|
struct wlr_buffer *buffer; // if WLR_OUTPUT_STATE_BUFFER_SCANOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_output_impl;
|
struct wlr_output_impl;
|
||||||
|
|
|
@ -404,6 +404,7 @@ bool wlr_output_attach_render(struct wlr_output *output, int *buffer_age) {
|
||||||
}
|
}
|
||||||
|
|
||||||
output->pending.committed |= WLR_OUTPUT_STATE_BUFFER;
|
output->pending.committed |= WLR_OUTPUT_STATE_BUFFER;
|
||||||
|
output->pending.buffer_type = WLR_OUTPUT_STATE_BUFFER_RENDER;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,15 +481,6 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
|
|
||||||
bool wlr_output_attach_buffer(struct wlr_output *output,
|
bool wlr_output_attach_buffer(struct wlr_output *output,
|
||||||
struct wlr_buffer *buffer) {
|
struct wlr_buffer *buffer) {
|
||||||
if (output->frame_pending) {
|
|
||||||
wlr_log(WLR_ERROR, "Tried to swap buffers when a frame is pending");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (output->idle_frame != NULL) {
|
|
||||||
wl_event_source_remove(output->idle_frame);
|
|
||||||
output->idle_frame = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output->impl->attach_buffer) {
|
if (!output->impl->attach_buffer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -496,9 +488,8 @@ bool wlr_output_attach_buffer(struct wlr_output *output,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->frame_pending = true;
|
output->pending.committed |= WLR_OUTPUT_STATE_BUFFER;
|
||||||
output->needs_frame = false;
|
output->pending.buffer_type = WLR_OUTPUT_STATE_BUFFER_SCANOUT;
|
||||||
pixman_region32_clear(&output->damage);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue