compositor: make GL_EXT_read_format_bgra optional
Some GL implementations do not provide GL_EXT_read_format_bgra extension. Set a glReadPixels format based on whether the extensions is supported or not, and use that format in all backends. Add RGBA->BGRA swapping copy to screenshooter to keep the shm buffer data format as BGRA. Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit is contained in:
@@ -1052,8 +1052,9 @@ drm_output_read_pixels(struct weston_output *output_base, void *data)
|
|||||||
eglMakeCurrent(compositor->base.display, output->egl_surface,
|
eglMakeCurrent(compositor->base.display, output->egl_surface,
|
||||||
output->egl_surface, compositor->base.context);
|
output->egl_surface, compositor->base.context);
|
||||||
|
|
||||||
glReadPixels(0, 0, output_base->current->width, output_base->current->height,
|
glReadPixels(0, 0, output_base->current->width,
|
||||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
|
output_base->current->height,
|
||||||
|
compositor->base.read_format, GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -387,8 +387,9 @@ wayland_output_read_pixels(struct weston_output *output_base, void *data)
|
|||||||
eglMakeCurrent(compositor->base.display, output->egl_surface,
|
eglMakeCurrent(compositor->base.display, output->egl_surface,
|
||||||
output->egl_surface, compositor->base.context);
|
output->egl_surface, compositor->base.context);
|
||||||
|
|
||||||
glReadPixels(0, 0, output_base->current->width, output_base->current->height,
|
glReadPixels(0, 0, output_base->current->width,
|
||||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
|
output_base->current->height,
|
||||||
|
compositor->base.read_format, GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -354,8 +354,9 @@ x11_output_read_pixels(struct weston_output *output_base, void *data)
|
|||||||
eglMakeCurrent(compositor->base.display, output->egl_surface,
|
eglMakeCurrent(compositor->base.display, output->egl_surface,
|
||||||
output->egl_surface, compositor->base.context);
|
output->egl_surface, compositor->base.context);
|
||||||
|
|
||||||
glReadPixels(0, 0, output_base->current->width, output_base->current->height,
|
glReadPixels(0, 0, output_base->current->width,
|
||||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
|
output_base->current->height,
|
||||||
|
compositor->base.read_format, GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
+4
-4
@@ -2391,10 +2391,10 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strstr(extensions, "GL_EXT_read_format_bgra")) {
|
if (strstr(extensions, "GL_EXT_read_format_bgra"))
|
||||||
fprintf(stderr, "GL_EXT_read_format_bgra not available\n");
|
ec->read_format = GL_BGRA_EXT;
|
||||||
return -1;
|
else
|
||||||
}
|
ec->read_format = GL_RGBA;
|
||||||
|
|
||||||
if (strstr(extensions, "GL_EXT_unpack_subimage"))
|
if (strstr(extensions, "GL_EXT_unpack_subimage"))
|
||||||
ec->has_unpack_subimage = 1;
|
ec->has_unpack_subimage = 1;
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ struct weston_compositor {
|
|||||||
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
|
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
|
||||||
|
|
||||||
int has_unpack_subimage;
|
int has_unpack_subimage;
|
||||||
|
GLenum read_format;
|
||||||
|
|
||||||
PFNEGLBINDWAYLANDDISPLAYWL bind_display;
|
PFNEGLBINDWAYLANDDISPLAYWL bind_display;
|
||||||
PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;
|
PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;
|
||||||
|
|||||||
+44
-2
@@ -50,6 +50,37 @@ copy_bgra_yflip(uint8_t *dst, uint8_t *src, int height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_row_swap_RB(void *vdst, void *vsrc, int bytes)
|
||||||
|
{
|
||||||
|
uint32_t *dst = vdst;
|
||||||
|
uint32_t *src = vsrc;
|
||||||
|
uint32_t *end = dst + bytes / 4;
|
||||||
|
|
||||||
|
while (dst < end) {
|
||||||
|
uint32_t v = *src++;
|
||||||
|
/* A R G B */
|
||||||
|
uint32_t tmp = v & 0xff00ff00;
|
||||||
|
tmp |= (v >> 16) & 0x000000ff;
|
||||||
|
tmp |= (v << 16) & 0x00ff0000;
|
||||||
|
*dst++ = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_rgba_yflip(uint8_t *dst, uint8_t *src, int height,
|
||||||
|
int dst_stride, int src_stride)
|
||||||
|
{
|
||||||
|
uint8_t *end;
|
||||||
|
|
||||||
|
end = dst + height * dst_stride;
|
||||||
|
while (dst < end) {
|
||||||
|
copy_row_swap_RB(dst, src, src_stride);
|
||||||
|
dst += dst_stride;
|
||||||
|
src -= src_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screenshooter_shoot(struct wl_client *client,
|
screenshooter_shoot(struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
@@ -82,8 +113,19 @@ screenshooter_shoot(struct wl_client *client,
|
|||||||
d = wl_shm_buffer_get_data(buffer) + output->y * buffer_stride +
|
d = wl_shm_buffer_get_data(buffer) + output->y * buffer_stride +
|
||||||
output->x * 4;
|
output->x * 4;
|
||||||
s = tmp + output_stride * (output->current->height - 1);
|
s = tmp + output_stride * (output->current->height - 1);
|
||||||
copy_bgra_yflip(d, s, output->current->height,
|
|
||||||
buffer_stride, output_stride);
|
switch (output->compositor->read_format) {
|
||||||
|
case GL_BGRA_EXT:
|
||||||
|
copy_bgra_yflip(d, s, output->current->height,
|
||||||
|
buffer_stride, output_stride);
|
||||||
|
break;
|
||||||
|
case GL_RGBA:
|
||||||
|
copy_rgba_yflip(d, s, output->current->height,
|
||||||
|
buffer_stride, output_stride);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user