mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-23 23:52:22 +00:00
render: Nuke old read pixels API
Sadly, the new API is not backwards compatible with the old API. Since we have already switched all users in wlroots to the new API compositors are already practically mandated to implement the new API. Let's get rid of the old one since there is no point.
This commit is contained in:
parent
b3575fedbc
commit
3ed1268f64
@ -31,11 +31,6 @@ struct wlr_renderer_impl {
|
||||
struct wlr_renderer *renderer);
|
||||
const struct wlr_drm_format_set *(*get_render_formats)(
|
||||
struct wlr_renderer *renderer);
|
||||
uint32_t (*preferred_read_format)(struct wlr_renderer *renderer);
|
||||
bool (*read_pixels)(struct wlr_renderer *renderer, uint32_t fmt,
|
||||
uint32_t stride, uint32_t width, uint32_t height,
|
||||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
|
||||
void *data);
|
||||
void (*destroy)(struct wlr_renderer *renderer);
|
||||
int (*get_drm_fd)(struct wlr_renderer *renderer);
|
||||
uint32_t (*get_render_buffer_caps)(struct wlr_renderer *renderer);
|
||||
|
@ -75,13 +75,6 @@ const uint32_t *wlr_renderer_get_shm_texture_formats(
|
||||
*/
|
||||
const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_texture_formats(
|
||||
struct wlr_renderer *renderer);
|
||||
/**
|
||||
* Reads out of pixels of the currently bound surface into data. `stride` is in
|
||||
* bytes.
|
||||
*/
|
||||
bool wlr_renderer_read_pixels(struct wlr_renderer *r, uint32_t fmt,
|
||||
uint32_t stride, uint32_t width, uint32_t height,
|
||||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, void *data);
|
||||
|
||||
/**
|
||||
* Initializes wl_shm, linux-dmabuf and other buffer factory protocols.
|
||||
|
@ -400,11 +400,6 @@ void wlr_output_effective_resolution(struct wlr_output *output,
|
||||
*/
|
||||
void wlr_output_attach_buffer(struct wlr_output *output,
|
||||
struct wlr_buffer *buffer);
|
||||
/**
|
||||
* Get the preferred format for reading pixels.
|
||||
* This function might change the current rendering context.
|
||||
*/
|
||||
uint32_t wlr_output_preferred_read_format(struct wlr_output *output);
|
||||
/**
|
||||
* Set the damage region for the frame to be submitted. This is the region of
|
||||
* the screen that has changed since the last frame.
|
||||
|
@ -288,90 +288,6 @@ static const struct wlr_drm_format_set *gles2_get_render_formats(
|
||||
return wlr_egl_get_dmabuf_render_formats(renderer->egl);
|
||||
}
|
||||
|
||||
static uint32_t gles2_preferred_read_format(
|
||||
struct wlr_renderer *wlr_renderer) {
|
||||
struct wlr_gles2_renderer *renderer =
|
||||
gles2_get_renderer_in_context(wlr_renderer);
|
||||
|
||||
push_gles2_debug(renderer);
|
||||
|
||||
GLint gl_format = -1, gl_type = -1, alpha_size = -1;
|
||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_format);
|
||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_type);
|
||||
glGetIntegerv(GL_ALPHA_BITS, &alpha_size);
|
||||
|
||||
pop_gles2_debug(renderer);
|
||||
|
||||
const struct wlr_gles2_pixel_format *fmt =
|
||||
get_gles2_format_from_gl(gl_format, gl_type, alpha_size > 0);
|
||||
if (fmt != NULL) {
|
||||
return fmt->drm_format;
|
||||
}
|
||||
|
||||
if (renderer->exts.EXT_read_format_bgra) {
|
||||
return DRM_FORMAT_XRGB8888;
|
||||
}
|
||||
return DRM_FORMAT_XBGR8888;
|
||||
}
|
||||
|
||||
static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer,
|
||||
uint32_t drm_format, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y,
|
||||
uint32_t dst_x, uint32_t dst_y, void *data) {
|
||||
struct wlr_gles2_renderer *renderer =
|
||||
gles2_get_renderer_in_context(wlr_renderer);
|
||||
|
||||
const struct wlr_gles2_pixel_format *fmt =
|
||||
get_gles2_format_from_drm(drm_format);
|
||||
if (fmt == NULL || !is_gles2_pixel_format_supported(renderer, fmt)) {
|
||||
wlr_log(WLR_ERROR, "Cannot read pixels: unsupported pixel format 0x%"PRIX32, drm_format);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fmt->gl_format == GL_BGRA_EXT && !renderer->exts.EXT_read_format_bgra) {
|
||||
wlr_log(WLR_ERROR,
|
||||
"Cannot read pixels: missing GL_EXT_read_format_bgra extension");
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct wlr_pixel_format_info *drm_fmt =
|
||||
drm_get_pixel_format_info(fmt->drm_format);
|
||||
assert(drm_fmt);
|
||||
if (pixel_format_info_pixels_per_block(drm_fmt) != 1) {
|
||||
wlr_log(WLR_ERROR, "Cannot read pixels: block formats are not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
push_gles2_debug(renderer);
|
||||
|
||||
// Make sure any pending drawing is finished before we try to read it
|
||||
glFinish();
|
||||
|
||||
glGetError(); // Clear the error flag
|
||||
|
||||
unsigned char *p = (unsigned char *)data + dst_y * stride;
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
uint32_t pack_stride = pixel_format_info_min_stride(drm_fmt, width);
|
||||
if (pack_stride == stride && dst_x == 0) {
|
||||
// Under these particular conditions, we can read the pixels with only
|
||||
// one glReadPixels call
|
||||
|
||||
glReadPixels(src_x, src_y, width, height, fmt->gl_format, fmt->gl_type, p);
|
||||
} else {
|
||||
// Unfortunately GLES2 doesn't support GL_PACK_ROW_LENGTH, so we have to read
|
||||
// the lines out row by row
|
||||
for (size_t i = 0; i < height; ++i) {
|
||||
uint32_t y = src_y + i;
|
||||
glReadPixels(src_x, y, width, 1, fmt->gl_format,
|
||||
fmt->gl_type, p + i * stride + dst_x * drm_fmt->bytes_per_block);
|
||||
}
|
||||
}
|
||||
|
||||
pop_gles2_debug(renderer);
|
||||
|
||||
return glGetError() == GL_NO_ERROR;
|
||||
}
|
||||
|
||||
static int gles2_get_drm_fd(struct wlr_renderer *wlr_renderer) {
|
||||
struct wlr_gles2_renderer *renderer =
|
||||
gles2_get_renderer(wlr_renderer);
|
||||
@ -536,8 +452,6 @@ static const struct wlr_renderer_impl renderer_impl = {
|
||||
.get_shm_texture_formats = gles2_get_shm_texture_formats,
|
||||
.get_dmabuf_texture_formats = gles2_get_dmabuf_texture_formats,
|
||||
.get_render_formats = gles2_get_render_formats,
|
||||
.preferred_read_format = gles2_preferred_read_format,
|
||||
.read_pixels = gles2_read_pixels,
|
||||
.get_drm_fd = gles2_get_drm_fd,
|
||||
.get_render_buffer_caps = gles2_get_render_buffer_caps,
|
||||
.texture_from_buffer = gles2_texture_from_buffer,
|
||||
|
@ -335,45 +335,6 @@ static void pixman_destroy(struct wlr_renderer *wlr_renderer) {
|
||||
free(renderer);
|
||||
}
|
||||
|
||||
static uint32_t pixman_preferred_read_format(
|
||||
struct wlr_renderer *wlr_renderer) {
|
||||
struct wlr_pixman_renderer *renderer = get_renderer(wlr_renderer);
|
||||
struct wlr_pixman_buffer *buffer = renderer->current_buffer;
|
||||
|
||||
pixman_format_code_t pixman_format = pixman_image_get_format(
|
||||
buffer->image);
|
||||
|
||||
return get_drm_format_from_pixman(pixman_format);
|
||||
}
|
||||
|
||||
static bool pixman_read_pixels(struct wlr_renderer *wlr_renderer,
|
||||
uint32_t drm_format, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y,
|
||||
uint32_t dst_x, uint32_t dst_y, void *data) {
|
||||
struct wlr_pixman_renderer *renderer = get_renderer(wlr_renderer);
|
||||
struct wlr_pixman_buffer *buffer = renderer->current_buffer;
|
||||
|
||||
pixman_format_code_t fmt = get_pixman_format_from_drm(drm_format);
|
||||
if (fmt == 0) {
|
||||
wlr_log(WLR_ERROR, "Cannot read pixels: unsupported pixel format");
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct wlr_pixel_format_info *drm_fmt =
|
||||
drm_get_pixel_format_info(drm_format);
|
||||
assert(drm_fmt);
|
||||
|
||||
pixman_image_t *dst = pixman_image_create_bits_no_clear(fmt, width, height,
|
||||
data, stride);
|
||||
|
||||
pixman_image_composite32(PIXMAN_OP_SRC, buffer->image, NULL, dst,
|
||||
src_x, src_y, 0, 0, dst_x, dst_y, width, height);
|
||||
|
||||
pixman_image_unref(dst);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t pixman_get_render_buffer_caps(struct wlr_renderer *renderer) {
|
||||
return WLR_BUFFER_CAP_DATA_PTR;
|
||||
}
|
||||
@ -405,8 +366,6 @@ static const struct wlr_renderer_impl renderer_impl = {
|
||||
.texture_from_buffer = pixman_texture_from_buffer,
|
||||
.bind_buffer = pixman_bind_buffer,
|
||||
.destroy = pixman_destroy,
|
||||
.preferred_read_format = pixman_preferred_read_format,
|
||||
.read_pixels = pixman_read_pixels,
|
||||
.get_render_buffer_caps = pixman_get_render_buffer_caps,
|
||||
.begin_buffer_pass = pixman_begin_buffer_pass,
|
||||
};
|
||||
|
@ -1015,18 +1015,6 @@ static const struct wlr_drm_format_set *vulkan_get_render_formats(
|
||||
return &renderer->dev->dmabuf_render_formats;
|
||||
}
|
||||
|
||||
static uint32_t vulkan_preferred_read_format(
|
||||
struct wlr_renderer *wlr_renderer) {
|
||||
struct wlr_vk_renderer *renderer = vulkan_get_renderer(wlr_renderer);
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(renderer->current_render_buffer->wlr_buffer,
|
||||
&dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "vulkan_preferred_read_format: Failed to get dmabuf of current render buffer");
|
||||
return DRM_FORMAT_INVALID;
|
||||
}
|
||||
return dmabuf.format;
|
||||
}
|
||||
|
||||
static void vulkan_destroy(struct wlr_renderer *wlr_renderer) {
|
||||
struct wlr_vk_renderer *renderer = vulkan_get_renderer(wlr_renderer);
|
||||
struct wlr_vk_device *dev = renderer->dev;
|
||||
@ -1116,18 +1104,6 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) {
|
||||
free(renderer);
|
||||
}
|
||||
|
||||
static bool vulkan_read_pixels_legacy(struct wlr_renderer *wlr_renderer,
|
||||
uint32_t drm_format, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y,
|
||||
uint32_t dst_x, uint32_t dst_y, void *data) {
|
||||
struct wlr_vk_renderer *vk_renderer = vulkan_get_renderer(wlr_renderer);
|
||||
VkFormat src_format = vk_renderer->current_render_buffer->render_setup->render_format->vk;
|
||||
VkImage src_image = vk_renderer->current_render_buffer->image;
|
||||
|
||||
return vulkan_read_pixels(vk_renderer, src_format, src_image, drm_format,
|
||||
stride, width, height, src_x, src_y, dst_x, dst_y, data);
|
||||
}
|
||||
|
||||
bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
|
||||
VkFormat src_format, VkImage src_image,
|
||||
uint32_t drm_format, uint32_t stride,
|
||||
@ -1396,8 +1372,6 @@ static const struct wlr_renderer_impl renderer_impl = {
|
||||
.get_shm_texture_formats = vulkan_get_shm_texture_formats,
|
||||
.get_dmabuf_texture_formats = vulkan_get_dmabuf_texture_formats,
|
||||
.get_render_formats = vulkan_get_render_formats,
|
||||
.preferred_read_format = vulkan_preferred_read_format,
|
||||
.read_pixels = vulkan_read_pixels_legacy,
|
||||
.destroy = vulkan_destroy,
|
||||
.get_drm_fd = vulkan_get_drm_fd,
|
||||
.get_render_buffer_caps = vulkan_get_render_buffer_caps,
|
||||
|
@ -120,17 +120,6 @@ uint32_t renderer_get_render_buffer_caps(struct wlr_renderer *r) {
|
||||
return r->impl->get_render_buffer_caps(r);
|
||||
}
|
||||
|
||||
bool wlr_renderer_read_pixels(struct wlr_renderer *r, uint32_t fmt,
|
||||
uint32_t stride, uint32_t width, uint32_t height,
|
||||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
|
||||
void *data) {
|
||||
if (!r->impl->read_pixels) {
|
||||
return false;
|
||||
}
|
||||
return r->impl->read_pixels(r, fmt, stride, width, height,
|
||||
src_x, src_y, dst_x, dst_y, data);
|
||||
}
|
||||
|
||||
bool wlr_renderer_init_wl_shm(struct wlr_renderer *r,
|
||||
struct wl_display *wl_display) {
|
||||
return wlr_shm_create_with_renderer(wl_display, 1, r) != NULL;
|
||||
|
@ -198,36 +198,6 @@ bool output_pick_format(struct wlr_output *output,
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t wlr_output_preferred_read_format(struct wlr_output *output) {
|
||||
struct wlr_renderer *renderer = output->renderer;
|
||||
assert(renderer != NULL);
|
||||
|
||||
if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) {
|
||||
return DRM_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
if (!wlr_output_configure_primary_swapchain(output, &output->pending, &output->swapchain)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_buffer *buffer = wlr_swapchain_acquire(output->swapchain, NULL);
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wlr_renderer_begin_with_buffer(renderer, buffer)) {
|
||||
wlr_buffer_unlock(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t fmt = renderer->impl->preferred_read_format(renderer);
|
||||
|
||||
wlr_renderer_end(renderer);
|
||||
wlr_buffer_unlock(buffer);
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
struct wlr_render_pass *wlr_output_begin_render_pass(struct wlr_output *output,
|
||||
struct wlr_output_state *state, int *buffer_age,
|
||||
struct wlr_buffer_pass_options *render_options) {
|
||||
|
Loading…
Reference in New Issue
Block a user