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>
dev
Pekka Paalanen 13 years ago
parent 45fab0e8e6
commit a1d57dba87
  1. 5
      src/compositor-drm.c
  2. 5
      src/compositor-wayland.c
  3. 5
      src/compositor-x11.c
  4. 8
      src/compositor.c
  5. 1
      src/compositor.h
  6. 42
      src/screenshooter.c

@ -1052,8 +1052,9 @@ drm_output_read_pixels(struct weston_output *output_base, void *data)
eglMakeCurrent(compositor->base.display, output->egl_surface,
output->egl_surface, compositor->base.context);
glReadPixels(0, 0, output_base->current->width, output_base->current->height,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
glReadPixels(0, 0, output_base->current->width,
output_base->current->height,
compositor->base.read_format, GL_UNSIGNED_BYTE, data);
}
static int

@ -387,8 +387,9 @@ wayland_output_read_pixels(struct weston_output *output_base, void *data)
eglMakeCurrent(compositor->base.display, output->egl_surface,
output->egl_surface, compositor->base.context);
glReadPixels(0, 0, output_base->current->width, output_base->current->height,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
glReadPixels(0, 0, output_base->current->width,
output_base->current->height,
compositor->base.read_format, GL_UNSIGNED_BYTE, data);
}
static int

@ -354,8 +354,9 @@ x11_output_read_pixels(struct weston_output *output_base, void *data)
eglMakeCurrent(compositor->base.display, output->egl_surface,
output->egl_surface, compositor->base.context);
glReadPixels(0, 0, output_base->current->width, output_base->current->height,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
glReadPixels(0, 0, output_base->current->width,
output_base->current->height,
compositor->base.read_format, GL_UNSIGNED_BYTE, data);
}
static int

@ -2391,10 +2391,10 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
return -1;
}
if (!strstr(extensions, "GL_EXT_read_format_bgra")) {
fprintf(stderr, "GL_EXT_read_format_bgra not available\n");
return -1;
}
if (strstr(extensions, "GL_EXT_read_format_bgra"))
ec->read_format = GL_BGRA_EXT;
else
ec->read_format = GL_RGBA;
if (strstr(extensions, "GL_EXT_unpack_subimage"))
ec->has_unpack_subimage = 1;

@ -223,6 +223,7 @@ struct weston_compositor {
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
int has_unpack_subimage;
GLenum read_format;
PFNEGLBINDWAYLANDDISPLAYWL bind_display;
PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;

@ -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
screenshooter_shoot(struct wl_client *client,
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 +
output->x * 4;
s = tmp + output_stride * (output->current->height - 1);
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);
}

Loading…
Cancel
Save