mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-22 06:47:12 -04:00
Merge upstream
This commit is contained in:
commit
c673b684a0
203 changed files with 6752 additions and 4861 deletions
|
|
@ -3,15 +3,34 @@
|
|||
#include <stdlib.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/backend.h"
|
||||
#include "render/allocator/allocator.h"
|
||||
#include "render/swapchain.h"
|
||||
#include "types/wlr_output.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
static bool output_set_hardware_cursor(struct wlr_output *output,
|
||||
struct wlr_buffer *buffer, int hotspot_x, int hotspot_y) {
|
||||
if (!output->impl->set_cursor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!output->impl->set_cursor(output, buffer, hotspot_x, hotspot_y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wlr_buffer_unlock(output->cursor_front_buffer);
|
||||
output->cursor_front_buffer = NULL;
|
||||
|
||||
if (buffer != NULL) {
|
||||
output->cursor_front_buffer = wlr_buffer_lock(buffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void output_cursor_damage_whole(struct wlr_output_cursor *cursor);
|
||||
|
||||
void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
|
||||
|
|
@ -26,8 +45,7 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
|
|||
output->software_cursor_locks);
|
||||
|
||||
if (output->software_cursor_locks > 0 && output->hardware_cursor != NULL) {
|
||||
assert(output->impl->set_cursor);
|
||||
output->impl->set_cursor(output, NULL, 0, 0);
|
||||
output_set_hardware_cursor(output, NULL, 0, 0);
|
||||
output_cursor_damage_whole(output->hardware_cursor);
|
||||
output->hardware_cursor = NULL;
|
||||
}
|
||||
|
|
@ -38,7 +56,7 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
|
|||
}
|
||||
|
||||
static void output_scissor(struct wlr_output *output, pixman_box32_t *rect) {
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
assert(renderer);
|
||||
|
||||
struct wlr_box box = {
|
||||
|
|
@ -71,8 +89,7 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor,
|
|||
|
||||
static void output_cursor_render(struct wlr_output_cursor *cursor,
|
||||
pixman_region32_t *damage) {
|
||||
struct wlr_renderer *renderer =
|
||||
wlr_backend_get_renderer(cursor->output->backend);
|
||||
struct wlr_renderer *renderer = cursor->output->renderer;
|
||||
assert(renderer);
|
||||
|
||||
struct wlr_texture *texture = cursor->texture;
|
||||
|
|
@ -195,7 +212,7 @@ static void output_cursor_update_visible(struct wlr_output_cursor *cursor) {
|
|||
}
|
||||
|
||||
static struct wlr_drm_format *output_pick_cursor_format(struct wlr_output *output) {
|
||||
struct wlr_allocator *allocator = backend_get_allocator(output->backend);
|
||||
struct wlr_allocator *allocator = output->allocator;
|
||||
assert(allocator != NULL);
|
||||
|
||||
const struct wlr_drm_format_set *display_formats = NULL;
|
||||
|
|
@ -208,7 +225,7 @@ static struct wlr_drm_format *output_pick_cursor_format(struct wlr_output *outpu
|
|||
}
|
||||
}
|
||||
|
||||
return output_pick_format(output, display_formats);
|
||||
return output_pick_format(output, display_formats, DRM_FORMAT_ARGB8888);
|
||||
}
|
||||
|
||||
static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor) {
|
||||
|
|
@ -226,17 +243,9 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
if (renderer == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get backend renderer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_allocator *allocator = backend_get_allocator(output->backend);
|
||||
if (allocator == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get backend allocator");
|
||||
return NULL;
|
||||
}
|
||||
struct wlr_allocator *allocator = output->allocator;
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
assert(allocator != NULL && renderer != NULL);
|
||||
|
||||
int width = texture->width;
|
||||
int height = texture->height;
|
||||
|
|
@ -355,14 +364,10 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
|||
wlr_output_transform_invert(output->transform),
|
||||
buffer ? buffer->width : 0, buffer ? buffer->height : 0);
|
||||
|
||||
bool ok = output->impl->set_cursor(cursor->output, buffer,
|
||||
hotspot.x, hotspot.y);
|
||||
bool ok = output_set_hardware_cursor(output, buffer, hotspot.x, hotspot.y);
|
||||
wlr_buffer_unlock(buffer);
|
||||
if (ok) {
|
||||
wlr_buffer_unlock(output->cursor_front_buffer);
|
||||
output->cursor_front_buffer = buffer;
|
||||
output->hardware_cursor = cursor;
|
||||
} else {
|
||||
wlr_buffer_unlock(buffer);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
|
@ -370,8 +375,7 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
|||
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
|
||||
const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
|
||||
int32_t hotspot_x, int32_t hotspot_y) {
|
||||
struct wlr_renderer *renderer =
|
||||
wlr_backend_get_renderer(cursor->output->backend);
|
||||
struct wlr_renderer *renderer = cursor->output->renderer;
|
||||
if (!renderer) {
|
||||
// if the backend has no renderer, we can't draw a cursor, but this is
|
||||
// actually okay, for ex. with the noop backend
|
||||
|
|
@ -476,9 +480,8 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
|
|||
wlr_output_transform_invert(cursor->output->transform),
|
||||
buffer ? buffer->width : 0, buffer ? buffer->height : 0);
|
||||
|
||||
assert(cursor->output->impl->set_cursor);
|
||||
cursor->output->impl->set_cursor(cursor->output,
|
||||
buffer, hotspot.x, hotspot.y);
|
||||
output_set_hardware_cursor(cursor->output, buffer,
|
||||
hotspot.x, hotspot.y);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -501,8 +504,7 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
|
|||
cursor->height = 0;
|
||||
|
||||
if (cursor->output->hardware_cursor == cursor) {
|
||||
assert(cursor->output->impl->set_cursor);
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0);
|
||||
output_set_hardware_cursor(cursor->output, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -563,9 +565,7 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) {
|
|||
wlr_signal_emit_safe(&cursor->events.destroy, cursor);
|
||||
if (cursor->output->hardware_cursor == cursor) {
|
||||
// If this cursor was the hardware cursor, disable it
|
||||
if (cursor->output->impl->set_cursor) {
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0);
|
||||
}
|
||||
output_set_hardware_cursor(cursor->output, NULL, 0, 0);
|
||||
cursor->output->hardware_cursor = NULL;
|
||||
}
|
||||
wlr_texture_destroy(cursor->texture);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <assert.h>
|
||||
#include <backend/backend.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "render/allocator/allocator.h"
|
||||
#include "render/swapchain.h"
|
||||
#include "types/wlr_output.h"
|
||||
#include "util/global.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
#define OUTPUT_VERSION 3
|
||||
#define OUTPUT_VERSION 4
|
||||
|
||||
static void send_geometry(struct wl_resource *resource) {
|
||||
struct wlr_output *output = wlr_output_from_resource(resource);
|
||||
|
|
@ -40,6 +43,23 @@ static void send_scale(struct wl_resource *resource) {
|
|||
}
|
||||
}
|
||||
|
||||
static void send_name(struct wl_resource *resource) {
|
||||
struct wlr_output *output = wlr_output_from_resource(resource);
|
||||
uint32_t version = wl_resource_get_version(resource);
|
||||
if (version >= WL_OUTPUT_NAME_SINCE_VERSION) {
|
||||
wl_output_send_name(resource, output->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_description(struct wl_resource *resource) {
|
||||
struct wlr_output *output = wlr_output_from_resource(resource);
|
||||
uint32_t version = wl_resource_get_version(resource);
|
||||
if (output->description != NULL &&
|
||||
version >= WL_OUTPUT_DESCRIPTION_SINCE_VERSION) {
|
||||
wl_output_send_description(resource, output->description);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_done(struct wl_resource *resource) {
|
||||
uint32_t version = wl_resource_get_version(resource);
|
||||
if (version >= WL_OUTPUT_DONE_SINCE_VERSION) {
|
||||
|
|
@ -84,6 +104,8 @@ static void output_bind(struct wl_client *wl_client, void *data,
|
|||
send_geometry(resource);
|
||||
send_current_mode(resource);
|
||||
send_scale(resource);
|
||||
send_name(resource);
|
||||
send_description(resource);
|
||||
send_done(resource);
|
||||
|
||||
struct wlr_output_event_bind evt = {
|
||||
|
|
@ -118,7 +140,7 @@ void wlr_output_destroy_global(struct wlr_output *output) {
|
|||
wl_list_init(wl_resource_get_link(resource));
|
||||
}
|
||||
|
||||
wlr_global_destroy_safe(output->global, output->display);
|
||||
wlr_global_destroy_safe(output->global);
|
||||
output->global = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -128,10 +150,7 @@ static void schedule_done_handle_idle_timer(void *data) {
|
|||
|
||||
struct wl_resource *resource;
|
||||
wl_resource_for_each(resource, &output->resources) {
|
||||
uint32_t version = wl_resource_get_version(resource);
|
||||
if (version >= WL_OUTPUT_DONE_SINCE_VERSION) {
|
||||
wl_output_send_done(resource);
|
||||
}
|
||||
send_done(resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -296,6 +315,16 @@ void wlr_output_enable_adaptive_sync(struct wlr_output *output, bool enabled) {
|
|||
output->pending.adaptive_sync_enabled = enabled;
|
||||
}
|
||||
|
||||
void wlr_output_set_render_format(struct wlr_output *output, uint32_t format) {
|
||||
if (output->render_format == format) {
|
||||
output->pending.committed &= ~WLR_OUTPUT_STATE_RENDER_FORMAT;
|
||||
return;
|
||||
}
|
||||
|
||||
output->pending.committed |= WLR_OUTPUT_STATE_RENDER_FORMAT;
|
||||
output->pending.render_format = format;
|
||||
}
|
||||
|
||||
void wlr_output_set_subpixel(struct wlr_output *output,
|
||||
enum wl_output_subpixel subpixel) {
|
||||
if (output->subpixel == subpixel) {
|
||||
|
|
@ -311,6 +340,13 @@ void wlr_output_set_subpixel(struct wlr_output *output,
|
|||
wlr_output_schedule_done(output);
|
||||
}
|
||||
|
||||
void wlr_output_set_name(struct wlr_output *output, const char *name) {
|
||||
assert(output->global == NULL);
|
||||
|
||||
free(output->name);
|
||||
output->name = strdup(name);
|
||||
}
|
||||
|
||||
void wlr_output_set_description(struct wlr_output *output, const char *desc) {
|
||||
if (output->description != NULL && desc != NULL &&
|
||||
strcmp(output->description, desc) == 0) {
|
||||
|
|
@ -324,6 +360,12 @@ void wlr_output_set_description(struct wlr_output *output, const char *desc) {
|
|||
output->description = NULL;
|
||||
}
|
||||
|
||||
struct wl_resource *resource;
|
||||
wl_resource_for_each(resource, &output->resources) {
|
||||
send_description(resource);
|
||||
}
|
||||
wlr_output_schedule_done(output);
|
||||
|
||||
wlr_signal_emit_safe(&output->events.description, output);
|
||||
}
|
||||
|
||||
|
|
@ -343,6 +385,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
|||
output->impl = impl;
|
||||
output->display = display;
|
||||
wl_list_init(&output->modes);
|
||||
output->render_format = DRM_FORMAT_XRGB8888;
|
||||
output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
output->scale = 1;
|
||||
output->commit_seq = 0;
|
||||
|
|
@ -379,9 +422,6 @@ void wlr_output_destroy(struct wlr_output *output) {
|
|||
return;
|
||||
}
|
||||
|
||||
wlr_buffer_unlock(output->front_buffer);
|
||||
output->front_buffer = NULL;
|
||||
|
||||
wl_list_remove(&output->display_destroy.link);
|
||||
wlr_output_destroy_global(output);
|
||||
output_clear_back_buffer(output);
|
||||
|
|
@ -409,6 +449,7 @@ void wlr_output_destroy(struct wlr_output *output) {
|
|||
wl_event_source_remove(output->idle_done);
|
||||
}
|
||||
|
||||
free(output->name);
|
||||
free(output->description);
|
||||
|
||||
pixman_region32_fini(&output->pending.damage);
|
||||
|
|
@ -542,6 +583,22 @@ static bool output_basic_test(struct wlr_output *output) {
|
|||
}
|
||||
}
|
||||
|
||||
if (output->pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
||||
struct wlr_allocator *allocator = output->allocator;
|
||||
assert(allocator != NULL);
|
||||
|
||||
const struct wlr_drm_format_set *display_formats =
|
||||
wlr_output_get_primary_formats(output, allocator->buffer_caps);
|
||||
struct wlr_drm_format *format = output_pick_format(output, display_formats,
|
||||
output->pending.render_format);
|
||||
if (format == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to pick primary buffer format for output");
|
||||
return false;
|
||||
}
|
||||
|
||||
free(format);
|
||||
}
|
||||
|
||||
bool enabled = output->enabled;
|
||||
if (output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
|
||||
enabled = output->pending.enabled;
|
||||
|
|
@ -569,6 +626,10 @@ static bool output_basic_test(struct wlr_output *output) {
|
|||
wlr_log(WLR_DEBUG, "Tried to enable adaptive sync on a disabled output");
|
||||
return false;
|
||||
}
|
||||
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
||||
wlr_log(WLR_DEBUG, "Tried to set format for a disabled output");
|
||||
return false;
|
||||
}
|
||||
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_GAMMA_LUT) {
|
||||
wlr_log(WLR_DEBUG, "Tried to set the gamma lut on a disabled output");
|
||||
return false;
|
||||
|
|
@ -578,6 +639,9 @@ static bool output_basic_test(struct wlr_output *output) {
|
|||
}
|
||||
|
||||
bool wlr_output_test(struct wlr_output *output) {
|
||||
bool had_buffer = output->pending.committed & WLR_OUTPUT_STATE_BUFFER;
|
||||
bool success;
|
||||
|
||||
if (!output_basic_test(output)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -587,7 +651,13 @@ bool wlr_output_test(struct wlr_output *output) {
|
|||
if (!output->impl->test) {
|
||||
return true;
|
||||
}
|
||||
return output->impl->test(output);
|
||||
|
||||
success = output->impl->test(output);
|
||||
|
||||
if (!had_buffer) {
|
||||
output_clear_back_buffer(output);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool wlr_output_commit(struct wlr_output *output) {
|
||||
|
|
@ -642,6 +712,10 @@ bool wlr_output_commit(struct wlr_output *output) {
|
|||
}
|
||||
}
|
||||
|
||||
if (output->pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
||||
output->render_format = output->pending.render_format;
|
||||
}
|
||||
|
||||
output->commit_seq++;
|
||||
|
||||
bool scale_updated = output->pending.committed & WLR_OUTPUT_STATE_SCALE;
|
||||
|
|
@ -669,13 +743,13 @@ bool wlr_output_commit(struct wlr_output *output) {
|
|||
wlr_output_schedule_done(output);
|
||||
}
|
||||
|
||||
// Unset the front-buffer when a new buffer will replace it or when the
|
||||
// output is getting disabled
|
||||
if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) ||
|
||||
((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) &&
|
||||
!output->pending.enabled)) {
|
||||
wlr_buffer_unlock(output->front_buffer);
|
||||
output->front_buffer = NULL;
|
||||
// Destroy the swapchains when an output is disabled
|
||||
if ((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) &&
|
||||
!output->pending.enabled) {
|
||||
wlr_swapchain_destroy(output->swapchain);
|
||||
output->swapchain = NULL;
|
||||
wlr_swapchain_destroy(output->cursor_swapchain);
|
||||
output->cursor_swapchain = NULL;
|
||||
}
|
||||
|
||||
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||
|
|
@ -685,8 +759,6 @@ bool wlr_output_commit(struct wlr_output *output) {
|
|||
|
||||
if (back_buffer != NULL) {
|
||||
wlr_swapchain_set_buffer_submitted(output->swapchain, back_buffer);
|
||||
wlr_buffer_unlock(output->front_buffer);
|
||||
output->front_buffer = back_buffer;
|
||||
}
|
||||
|
||||
uint32_t committed = output->pending.committed;
|
||||
|
|
@ -696,9 +768,14 @@ bool wlr_output_commit(struct wlr_output *output) {
|
|||
.output = output,
|
||||
.committed = committed,
|
||||
.when = &now,
|
||||
.buffer = back_buffer,
|
||||
};
|
||||
wlr_signal_emit_safe(&output->events.commit, &event);
|
||||
|
||||
if (back_buffer != NULL) {
|
||||
wlr_buffer_unlock(back_buffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -819,3 +896,21 @@ void wlr_output_damage_whole(struct wlr_output *output) {
|
|||
|
||||
pixman_region32_fini(&damage);
|
||||
}
|
||||
|
||||
const struct wlr_drm_format_set *wlr_output_get_primary_formats(
|
||||
struct wlr_output *output, uint32_t buffer_caps) {
|
||||
if (!output->impl->get_primary_formats) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct wlr_drm_format_set *formats =
|
||||
output->impl->get_primary_formats(output, buffer_caps);
|
||||
if (formats == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get primary display formats");
|
||||
|
||||
static const struct wlr_drm_format_set empty_format_set = {0};
|
||||
return &empty_format_set;
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,33 @@
|
|||
#include "render/drm_format_set.h"
|
||||
#include "render/swapchain.h"
|
||||
#include "render/wlr_renderer.h"
|
||||
#include "render/pixel_format.h"
|
||||
#include "types/wlr_output.h"
|
||||
|
||||
bool wlr_output_init_render(struct wlr_output *output,
|
||||
struct wlr_allocator *allocator, struct wlr_renderer *renderer) {
|
||||
assert(output->allocator == NULL && allocator != NULL);
|
||||
assert(output->renderer == NULL && renderer != NULL);
|
||||
|
||||
uint32_t backend_caps = backend_get_buffer_caps(output->backend);
|
||||
uint32_t renderer_caps = renderer_get_render_buffer_caps(renderer);
|
||||
|
||||
if (!(backend_caps & allocator->buffer_caps)) {
|
||||
wlr_log(WLR_ERROR, "output backend and allocator buffer capabilities "
|
||||
"don't match");
|
||||
return false;
|
||||
} else if (!(renderer_caps & allocator->buffer_caps)) {
|
||||
wlr_log(WLR_ERROR, "renderer and allocator buffer capabilities "
|
||||
"don't match");
|
||||
return false;
|
||||
}
|
||||
|
||||
output->allocator = allocator;
|
||||
output->renderer = renderer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the output has a suitable swapchain. The swapchain is re-created if
|
||||
* necessary.
|
||||
|
|
@ -23,39 +48,40 @@ static bool output_create_swapchain(struct wlr_output *output,
|
|||
int width, height;
|
||||
output_pending_resolution(output, &width, &height);
|
||||
|
||||
if (output->swapchain != NULL && output->swapchain->width == width &&
|
||||
output->swapchain->height == height &&
|
||||
(allow_modifiers || output->swapchain->format->len == 0)) {
|
||||
return true;
|
||||
}
|
||||
struct wlr_allocator *allocator = output->allocator;
|
||||
assert(allocator != NULL);
|
||||
|
||||
struct wlr_allocator *allocator = backend_get_allocator(output->backend);
|
||||
if (allocator == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get backend allocator");
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct wlr_drm_format_set *display_formats = NULL;
|
||||
if (output->impl->get_primary_formats) {
|
||||
display_formats =
|
||||
output->impl->get_primary_formats(output, allocator->buffer_caps);
|
||||
if (display_formats == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get primary display formats");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct wlr_drm_format *format = output_pick_format(output, display_formats);
|
||||
const struct wlr_drm_format_set *display_formats =
|
||||
wlr_output_get_primary_formats(output, allocator->buffer_caps);
|
||||
struct wlr_drm_format *format = output_pick_format(output, display_formats,
|
||||
output->render_format);
|
||||
if (format == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to pick primary buffer format for output '%s'",
|
||||
output->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output->swapchain != NULL && output->swapchain->width == width &&
|
||||
output->swapchain->height == height &&
|
||||
output->swapchain->format->format == format->format &&
|
||||
(allow_modifiers || output->swapchain->format->len == 0)) {
|
||||
// no change, keep existing swapchain
|
||||
free(format);
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Choosing primary buffer format 0x%"PRIX32" for output '%s'",
|
||||
format->format, output->name);
|
||||
|
||||
if (!allow_modifiers && (format->len != 1 || format->modifiers[0] != DRM_FORMAT_MOD_LINEAR)) {
|
||||
if (!wlr_drm_format_has(format, DRM_FORMAT_MOD_INVALID)) {
|
||||
wlr_log(WLR_DEBUG, "Implicit modifiers not supported");
|
||||
free(format);
|
||||
return false;
|
||||
}
|
||||
|
||||
format->len = 0;
|
||||
wlr_drm_format_add(&format, DRM_FORMAT_MOD_INVALID);
|
||||
}
|
||||
|
||||
struct wlr_swapchain *swapchain =
|
||||
|
|
@ -80,7 +106,7 @@ static bool output_attach_back_buffer(struct wlr_output *output,
|
|||
return false;
|
||||
}
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
assert(renderer != NULL);
|
||||
|
||||
struct wlr_buffer *buffer =
|
||||
|
|
@ -103,7 +129,7 @@ void output_clear_back_buffer(struct wlr_output *output) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
assert(renderer != NULL);
|
||||
|
||||
renderer_bind_buffer(renderer, NULL);
|
||||
|
|
@ -130,7 +156,7 @@ static bool output_attach_empty_buffer(struct wlr_output *output) {
|
|||
int width, height;
|
||||
output_pending_resolution(output, &width, &height);
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
wlr_renderer_begin(renderer, width, height);
|
||||
wlr_renderer_clear(renderer, (float[]){0, 0, 0, 0});
|
||||
wlr_renderer_end(renderer);
|
||||
|
|
@ -149,6 +175,9 @@ bool output_ensure_buffer(struct wlr_output *output) {
|
|||
if (output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
||||
needs_new_buffer = true;
|
||||
}
|
||||
if (output->pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
||||
needs_new_buffer = true;
|
||||
}
|
||||
if (!needs_new_buffer ||
|
||||
(output->pending.committed & WLR_OUTPUT_STATE_BUFFER)) {
|
||||
return true;
|
||||
|
|
@ -210,9 +239,10 @@ void wlr_output_lock_attach_render(struct wlr_output *output, bool lock) {
|
|||
}
|
||||
|
||||
struct wlr_drm_format *output_pick_format(struct wlr_output *output,
|
||||
const struct wlr_drm_format_set *display_formats) {
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
struct wlr_allocator *allocator = backend_get_allocator(output->backend);
|
||||
const struct wlr_drm_format_set *display_formats,
|
||||
uint32_t fmt) {
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
struct wlr_allocator *allocator = output->allocator;
|
||||
assert(renderer != NULL && allocator != NULL);
|
||||
|
||||
const struct wlr_drm_format_set *render_formats =
|
||||
|
|
@ -222,41 +252,31 @@ struct wlr_drm_format *output_pick_format(struct wlr_output *output,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_drm_format *format = NULL;
|
||||
const uint32_t candidates[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 };
|
||||
for (size_t i = 0; i < sizeof(candidates) / sizeof(candidates[0]); i++) {
|
||||
uint32_t fmt = candidates[i];
|
||||
|
||||
const struct wlr_drm_format *render_format =
|
||||
wlr_drm_format_set_get(render_formats, fmt);
|
||||
if (render_format == NULL) {
|
||||
wlr_log(WLR_DEBUG, "Renderer doesn't support format 0x%"PRIX32, fmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (display_formats != NULL) {
|
||||
const struct wlr_drm_format *display_format =
|
||||
wlr_drm_format_set_get(display_formats, fmt);
|
||||
if (display_format == NULL) {
|
||||
wlr_log(WLR_DEBUG, "Output doesn't support format 0x%"PRIX32, fmt);
|
||||
continue;
|
||||
}
|
||||
format = wlr_drm_format_intersect(display_format, render_format);
|
||||
} else {
|
||||
// The output can display any format
|
||||
format = wlr_drm_format_dup(render_format);
|
||||
}
|
||||
|
||||
if (format == NULL) {
|
||||
wlr_log(WLR_DEBUG, "Failed to intersect display and render "
|
||||
"modifiers for format 0x%"PRIX32, fmt);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
const struct wlr_drm_format *render_format =
|
||||
wlr_drm_format_set_get(render_formats, fmt);
|
||||
if (render_format == NULL) {
|
||||
wlr_log(WLR_DEBUG, "Renderer doesn't support format 0x%"PRIX32, fmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_drm_format *format = NULL;
|
||||
if (display_formats != NULL) {
|
||||
const struct wlr_drm_format *display_format =
|
||||
wlr_drm_format_set_get(display_formats, fmt);
|
||||
if (display_format == NULL) {
|
||||
wlr_log(WLR_DEBUG, "Output doesn't support format 0x%"PRIX32, fmt);
|
||||
return NULL;
|
||||
}
|
||||
format = wlr_drm_format_intersect(display_format, render_format);
|
||||
} else {
|
||||
// The output can display any format
|
||||
format = wlr_drm_format_dup(render_format);
|
||||
}
|
||||
|
||||
if (format == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to choose a format for output '%s'",
|
||||
output->name);
|
||||
wlr_log(WLR_DEBUG, "Failed to intersect display and render "
|
||||
"modifiers for format 0x%"PRIX32 " on output '%s",
|
||||
fmt, output->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +284,9 @@ struct wlr_drm_format *output_pick_format(struct wlr_output *output,
|
|||
}
|
||||
|
||||
uint32_t wlr_output_preferred_read_format(struct wlr_output *output) {
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
assert(renderer != NULL);
|
||||
|
||||
if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) {
|
||||
return DRM_FORMAT_INVALID;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue