}
static void
+copy_bgra(uint8_t *dst, uint8_t *src, int height, int stride)
+{
+ /* TODO: optimize this out */
+ memcpy(dst, src, height * stride);
+}
+
+static void
copy_row_swap_RB(void *vdst, void *vsrc, int bytes)
{
uint32_t *dst = vdst;
}
static void
+copy_rgba(uint8_t *dst, uint8_t *src, int height, int stride)
+{
+ uint8_t *end;
+
+ end = dst + height * stride;
+ while (dst < end) {
+ copy_row_swap_RB(dst, src, stride);
+ dst += stride;
+ src += stride;
+ }
+}
+
+static void
screenshooter_frame_notify(struct wl_listener *listener, void *data)
{
struct screenshooter_frame_listener *l =
container_of(listener,
struct screenshooter_frame_listener, listener);
struct weston_output *output = data;
+ struct weston_compositor *compositor = output->compositor;
int32_t stride;
uint8_t *pixels, *d, *s;
output->disable_planes--;
wl_list_remove(&listener->link);
- stride = l->buffer->width * (PIXMAN_FORMAT_BPP(output->compositor->read_format) / 8);
+ stride = l->buffer->width * (PIXMAN_FORMAT_BPP(compositor->read_format) / 8);
pixels = malloc(stride * l->buffer->height);
if (pixels == NULL) {
return;
}
- output->compositor->renderer->read_pixels(output,
- output->compositor->read_format, pixels,
+ compositor->renderer->read_pixels(output,
+ compositor->read_format, pixels,
0, 0, output->current->width,
output->current->height);
d = wl_shm_buffer_get_data(l->buffer);
s = pixels + stride * (l->buffer->height - 1);
- switch (output->compositor->read_format) {
+ switch (compositor->read_format) {
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
- copy_bgra_yflip(d, s, output->current->height, stride);
+ if (compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP)
+ copy_bgra_yflip(d, s, output->current->height, stride);
+ else
+ copy_bgra(d, pixels, output->current->height, stride);
break;
case PIXMAN_x8b8g8r8:
case PIXMAN_a8b8g8r8:
- copy_rgba_yflip(d, s, output->current->height, stride);
+ if (compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP)
+ copy_rgba_yflip(d, s, output->current->height, stride);
+ else
+ copy_rgba(d, pixels, output->current->height, stride);
break;
default:
break;
struct weston_recorder {
struct weston_output *output;
uint32_t *frame, *rect;
+ uint32_t *tmpbuf;
uint32_t total;
int fd;
struct wl_listener frame_listener;
{
pixman_box32_t s = *r;
- switch(output->transform) {
+ switch (output->transform) {
case WL_OUTPUT_TRANSFORM_FLIPPED:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
break;
}
- switch(output->transform) {
+ switch (output->transform) {
case WL_OUTPUT_TRANSFORM_NORMAL:
case WL_OUTPUT_TRANSFORM_FLIPPED:
r->x1 = s.x1;
struct weston_recorder *recorder =
container_of(listener, struct weston_recorder, frame_listener);
struct weston_output *output = data;
+ struct weston_compositor *compositor = output->compositor;
uint32_t msecs = output->frame_time;
pixman_box32_t *r;
pixman_region32_t damage;
uint32_t nrects;
} header;
struct iovec v[2];
+ int do_yflip;
+ int y_orig;
+ uint32_t *outbuf;
+
+ do_yflip = !!(compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP);
+ if (do_yflip)
+ outbuf = recorder->rect;
+ else
+ outbuf = recorder->tmpbuf;
pixman_region32_init(&damage);
pixman_region32_intersect(&damage, &output->region,
for (i = 0; i < n; i++) {
width = r[i].x2 - r[i].x1;
height = r[i].y2 - r[i].y1;
- output->compositor->renderer->read_pixels(output,
- output->compositor->read_format, recorder->rect,
- r[i].x1, output->current->height - r[i].y2,
- width, height);
+
+ if (do_yflip)
+ y_orig = output->current->height - r[i].y2;
+ else
+ y_orig = r[i].y1;
+
+ compositor->renderer->read_pixels(output,
+ compositor->read_format, recorder->rect,
+ r[i].x1, y_orig, width, height);
s = recorder->rect;
- p = recorder->rect;
+ p = outbuf;
run = prev = 0; /* quiet gcc */
for (j = 0; j < height; j++) {
- d = recorder->frame +
- stride * (r[i].y2 - j - 1) + r[i].x1;
+ if (do_yflip)
+ y_orig = r[i].y2 - j - 1;
+ else
+ y_orig = r[i].y1 + j;
+ d = recorder->frame + stride * y_orig + r[i].x1;
+
for (k = 0; k < width; k++) {
next = *s++;
delta = component_delta(next, *d);
p = output_run(p, prev, run);
recorder->total += write(recorder->fd,
- recorder->rect,
- (p - recorder->rect) * 4);
+ outbuf, (p - outbuf) * 4);
#if 0
fprintf(stderr,
"%dx%d at %d,%d rle from %d to %d bytes (%f) total %dM\n",
width, height, r[i].x1, r[i].y1,
- width * height * 4, (int) (p - recorder->rect) * 4,
- (float) (p - recorder->rect) / (width * height),
+ width * height * 4, (int) (p - outbuf) * 4,
+ (float) (p - outbuf) / (width * height),
recorder->total / 1024 / 1024);
#endif
}
static void
weston_recorder_create(struct weston_output *output, const char *filename)
{
+ struct weston_compositor *compositor = output->compositor;
struct weston_recorder *recorder;
int stride, size;
struct { uint32_t magic, format, width, height; } header;
+ int do_yflip;
+
+ do_yflip = !!(compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP);
recorder = malloc(sizeof *recorder);
recorder->output = output;
memset(recorder->frame, 0, size);
+ if (do_yflip)
+ recorder->tmpbuf = NULL;
+ else
+ recorder->tmpbuf = malloc(size);
+
header.magic = WCAP_HEADER_MAGIC;
- switch (output->compositor->read_format) {
+ switch (compositor->read_format) {
case PIXMAN_a8r8g8b8:
header.format = WCAP_FORMAT_XRGB8888;
break;
{
wl_list_remove(&recorder->frame_listener.link);
close(recorder->fd);
+ free(recorder->tmpbuf);
free(recorder->frame);
free(recorder->rect);
recorder->output->disable_planes--;