diff options
author | Søren Sandmann <ssp@redhat.com> | 2010-09-28 09:26:34 -0400 |
---|---|---|
committer | Søren Sandmann <ssp@redhat.com> | 2010-09-28 09:26:34 -0400 |
commit | dd72990159822b69a6ee25efe78058c5fdbdc579 (patch) | |
tree | 9fefcda735ad3ce3e53c42b6030aabfecebff858 | |
parent | 4c59498c7f719105e680a5039241bd184b22e6b2 (diff) |
Initial (buggy) support for copy area from offscreens
-rw-r--r-- | src/qxl.h | 5 | ||||
-rw-r--r-- | src/qxl_driver.c | 10 | ||||
-rw-r--r-- | src/qxl_surface.c | 94 |
3 files changed, 80 insertions, 29 deletions
@@ -169,6 +169,10 @@ typedef enum { QXL_IMAGE_TYPE_LZ_RGB, QXL_IMAGE_TYPE_GLZ_RGB, QXL_IMAGE_TYPE_FROM_CACHE, + QXL_IMAGE_TYPE_SURFACE, + QXL_IMAGE_TYPE_JPEG, + QXL_IMAGE_TYPE_FROM_CACHE_LOSSLESS, + QXL_IMAGE_TYPE_JPEG_ALPHA } qxl_image_type; typedef enum { @@ -238,6 +242,7 @@ struct qxl_image { union { struct qxl_bitmap bitmap; + uint32_t surface_id; } u; }; diff --git a/src/qxl_driver.c b/src/qxl_driver.c index e948a6b..fd47b7f 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -87,7 +87,15 @@ garbage_collect (qxl_screen_t *qxl) struct qxl_image *image = virtual_address ( qxl, u64_to_pointer (drawable->u.copy.src_bitmap), qxl->main_mem_slot); - qxl_image_destroy (qxl, image); + if (image->descriptor.type == QXL_IMAGE_TYPE_SURFACE) + { + qxl_surface_unref (image->u.surface_id); + qxl_free (qxl->mem, image); + } + else + { + qxl_image_destroy (qxl, image); + } } else if (is_surface && surface_cmd->type == QXL_SURFACE_CMD_DESTROY) { diff --git a/src/qxl_surface.c b/src/qxl_surface.c index 5a58a31..456bf23 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -17,6 +17,7 @@ struct qxl_surface_t qxl_surface_t * next; int in_use; int Bpp; + int ref_count; union { @@ -82,6 +83,7 @@ surface_new (void) result->next = NULL; result->in_use = TRUE; + result->ref_count = 1; return result; } @@ -197,7 +199,7 @@ qxl_surface_create (qxl_screen_t *qxl, if (++count < 200) return NULL; - + #if 0 ErrorF (" qxl_surface: attempting to allocate %d x %d @ %d\n", width, height, bpp); #endif @@ -236,6 +238,7 @@ retry: #if 0 ErrorF (" Surface allocated: %u\n", surface->id); #endif + ErrorF ("Allocated %d\n", surface->id); if (width == 0 || height == 0) { @@ -334,38 +337,45 @@ qxl_surface_destroy (qxl_surface_t *surface) ErrorF ("About to free %d\n", surface->id); #endif - if (surface->dev_image) - pixman_image_unref (surface->dev_image); - if (surface->host_image) - pixman_image_unref (surface->host_image); - - if (surface->id != 0) + if (--surface->ref_count == 0) { - struct qxl_surface_cmd *cmd; -#if 0 - ErrorF ("%d free address %lx from %p\n", surface->id, surface->address, surface->qxl->surf_mem); -#endif - cmd = make_surface_cmd (qxl, surface->id, QXL_SURFACE_CMD_DESTROY); - + if (surface->dev_image) + pixman_image_unref (surface->dev_image); + if (surface->host_image) + pixman_image_unref (surface->host_image); + + if (surface->id != 0) + { + struct qxl_surface_cmd *cmd; #if 0 - ErrorF (" pushing destroy command %lx\n", cmd->release_info.id); + ErrorF ("%d free address %lx from %p\n", surface->id, surface->address, surface->qxl->surf_mem); #endif + cmd = make_surface_cmd (qxl, surface->id, QXL_SURFACE_CMD_DESTROY); + #if 0 - ErrorF ("destroy %d\n", cmd->surface_id); + ErrorF (" pushing destroy command %lx\n", cmd->release_info.id); #endif - - push_surface_cmd (qxl, cmd); + ErrorF ("destroy %d\n", cmd->surface_id); + + push_surface_cmd (qxl, cmd); + } } } void +qxl_surface_unref (uint32_t id) +{ + qxl_surface_t *surface = all_surfaces + id; + + qxl_surface_destroy (surface); +} + +void qxl_surface_recycle (uint32_t id) { qxl_surface_t *surface = all_surfaces + id; -#if 0 ErrorF ("recycle %d\n", id); -#endif qxl_free (surface->qxl->surf_mem, surface->address); surface_free (surface); @@ -746,7 +756,7 @@ Bool qxl_surface_prepare_solid (qxl_surface_t *destination, Pixel fg) { - destination->u.solid_pixel = fg ^ (rand() >> 16); + destination->u.solid_pixel = fg; // ^ (rand() >> 16); return TRUE; } @@ -775,9 +785,6 @@ Bool qxl_surface_prepare_copy (qxl_surface_t *dest, qxl_surface_t *source) { - if (source->id != 0) - return FALSE; - dest->u.copy_src = source; return TRUE; } @@ -797,13 +804,44 @@ qxl_surface_copy (qxl_surface_t *dest, qrect.left = dest_x1; qrect.right = dest_x1 + width; + if (dest->id == dest->u.copy_src->id) + { /* ErrorF (" Translate %d %d %d %d by %d %d (offsets %d %d)\n", */ /* b->x1, b->y1, b->x2, b->y2, */ /* dx, dy, dst_xoff, dst_yoff); */ - - drawable = make_drawable (qxl, dest->id, QXL_COPY_BITS, &qrect); - drawable->u.copy_bits.src_pos.x = src_x1; - drawable->u.copy_bits.src_pos.y = src_y1; - + + drawable = make_drawable (qxl, dest->id, QXL_COPY_BITS, &qrect); + drawable->u.copy_bits.src_pos.x = src_x1; + drawable->u.copy_bits.src_pos.y = src_y1; + } + else + { + struct qxl_image *image = qxl_allocnf (qxl, sizeof *image); + + ErrorF ("Copy %d to %d\n", dest->u.copy_src->id, dest->id); + + dest->u.copy_src->ref_count++; + + image->descriptor.id = 0; + image->descriptor.type = QXL_IMAGE_TYPE_SURFACE; + image->descriptor.width = 0; + image->descriptor.height = 0; + image->u.surface_id = dest->u.copy_src->id; + + drawable = make_drawable (qxl, dest->id, QXL_DRAW_COPY, &qrect); + + drawable->u.copy.src_bitmap = physical_address (qxl, image, qxl->main_mem_slot); + drawable->u.copy.src_area.left = src_x1; + drawable->u.copy.src_area.top = src_y1; + drawable->u.copy.src_area.right = src_x1 + width; + drawable->u.copy.src_area.bottom = src_y1 + height; + drawable->u.copy.rop_descriptor = ROPD_OP_PUT; + drawable->u.copy.scale_mode = 0; + drawable->u.copy.mask.flags = 0; + drawable->u.copy.mask.pos.x = 0; + drawable->u.copy.mask.pos.y = 0; + drawable->u.copy.mask.bitmap = 0; + } + push_drawable (qxl, drawable); } |