diff options
author | Dave Airlie <airlied@gmail.com> | 2013-02-05 16:35:18 +1000 |
---|---|---|
committer | Dave Airlie <airlied@gmail.com> | 2013-02-05 16:35:18 +1000 |
commit | 4bff2830749a1ac4a27686959cef9b53c219c4fd (patch) | |
tree | a4d37bbff1af16dc728df487e286b9ac070f9a5a | |
parent | 1e63f955dae558fa0f1d7e204c8d99eaa30f9469 (diff) |
qxl: cache image bo inside surfacebo-abs1
-rw-r--r-- | src/qxl.h | 1 | ||||
-rw-r--r-- | src/qxl_kms.c | 7 | ||||
-rw-r--r-- | src/qxl_mem.c | 7 | ||||
-rw-r--r-- | src/qxl_surface.c | 53 | ||||
-rw-r--r-- | src/qxl_surface.h | 1 |
5 files changed, 47 insertions, 22 deletions
@@ -152,6 +152,7 @@ struct qxl_bo_funcs { void *(*bo_map)(struct qxl_bo *bo); void (*bo_unmap)(struct qxl_bo *bo); void (*bo_decref)(qxl_screen_t *qxl, struct qxl_bo *bo); + void (*bo_incref)(qxl_screen_t *qxl, struct qxl_bo *bo); void (*bo_output_bo_reloc)(qxl_screen_t *qxl, uint32_t dst_offset, struct qxl_bo *dst_bo, struct qxl_bo *src_bo); void (*write_command)(qxl_screen_t *qxl, uint32_t type, struct qxl_bo *bo); diff --git a/src/qxl_kms.c b/src/qxl_kms.c index 1e4d83e..949010d 100644 --- a/src/qxl_kms.c +++ b/src/qxl_kms.c @@ -446,6 +446,12 @@ static void qxl_bo_unmap(struct qxl_bo *_bo) { } +static void qxl_bo_incref(qxl_screen_t *qxl, struct qxl_bo *_bo) +{ + struct qxl_kms_bo *bo = (struct qxl_kms_bo *)_bo; + bo->refcnt++; +} + static void qxl_bo_decref(qxl_screen_t *qxl, struct qxl_bo *_bo) { struct qxl_kms_bo *bo = (struct qxl_kms_bo *)_bo; @@ -735,6 +741,7 @@ struct qxl_bo_funcs qxl_kms_bo_funcs = { qxl_bo_map, qxl_bo_unmap, qxl_bo_decref, + qxl_bo_incref, qxl_bo_output_bo_reloc, qxl_bo_write_command, qxl_bo_update_area, diff --git a/src/qxl_mem.c b/src/qxl_mem.c index 325740a..da675b9 100644 --- a/src/qxl_mem.c +++ b/src/qxl_mem.c @@ -570,6 +570,12 @@ struct qxl_bo *qxl_ums_lookup_phy_addr(qxl_screen_t *qxl, uint64_t phy_addr) return (struct qxl_bo *)found; } +static void qxl_bo_incref(qxl_screen_t *qxl, struct qxl_bo *_bo) +{ + struct qxl_ums_bo *bo = (struct qxl_ums_bo *)_bo; + bo->refcnt++; +} + static void qxl_bo_decref(qxl_screen_t *qxl, struct qxl_bo *_bo) { struct qxl_ums_bo *bo = (struct qxl_ums_bo *)_bo; @@ -700,6 +706,7 @@ struct qxl_bo_funcs qxl_ums_bo_funcs = { qxl_bo_map, qxl_bo_unmap, qxl_bo_decref, + qxl_bo_incref, qxl_bo_output_bo_reloc, qxl_bo_write_command, qxl_bo_update_area, diff --git a/src/qxl_surface.c b/src/qxl_surface.c index 90090c1..24dfa6a 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -1262,6 +1262,32 @@ qxl_surface_prepare_copy (qxl_surface_t *dest, return TRUE; } +static struct qxl_bo * +image_from_surface_internal(qxl_screen_t *qxl, + qxl_surface_t *surface) +{ + struct qxl_bo *image_bo = qxl->bo_funcs->bo_alloc (qxl, sizeof(struct QXLImage), "image struct for surface"); + struct QXLImage *image = qxl->bo_funcs->bo_map(image_bo); + + image->descriptor.id = 0; + image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE; + image->descriptor.width = 0; + image->descriptor.height = 0; + qxl->bo_funcs->bo_output_surf_reloc(qxl, offsetof(struct QXLImage, surface_image.surface_id), image_bo, surface); + qxl->bo_funcs->bo_unmap(image_bo); + return image_bo; +} + +struct qxl_bo *image_from_surface(qxl_screen_t *qxl, qxl_surface_t *dest) +{ + struct qxl_bo *image_bo; + + if (!dest->image_bo) { + dest->image_bo = image_from_surface_internal(qxl, dest); + } + qxl->bo_funcs->bo_incref(qxl, dest->image_bo); + return dest->image_bo; +} void qxl_surface_copy (qxl_surface_t *dest, int src_x1, int src_y1, @@ -1297,19 +1323,10 @@ qxl_surface_copy (qxl_surface_t *dest, } else { - struct qxl_bo *image_bo = qxl->bo_funcs->bo_alloc(qxl, sizeof (struct QXLImage), "surface image struct"); - struct QXLImage *image; - + struct qxl_bo *image_bo; dest->u.copy_src->ref_count++; - image = qxl->bo_funcs->bo_map(image_bo); - image->descriptor.id = 0; - image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE; - image->descriptor.width = 0; - image->descriptor.height = 0; - qxl->bo_funcs->bo_unmap(image_bo); - - qxl->bo_funcs->bo_output_surf_reloc(qxl, offsetof(struct QXLImage, surface_image.surface_id), image_bo, dest->u.copy_src); + image_bo = image_from_surface(qxl, dest->u.copy_src); drawable_bo = make_drawable (qxl, dest, QXL_DRAW_COPY, &qrect); @@ -1377,22 +1394,14 @@ image_from_picture (qxl_screen_t *qxl, qxl_surface_t *surface, int *force_opaque) { - struct qxl_bo *image_bo = qxl->bo_funcs->bo_alloc (qxl, sizeof(struct QXLImage), "image struct for picture"); - struct QXLImage *image = qxl->bo_funcs->bo_map(image_bo); + struct qxl_bo *image_bo; - image->descriptor.id = 0; - image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE; - image->descriptor.width = 0; - image->descriptor.height = 0; - qxl->bo_funcs->bo_output_surf_reloc(qxl, offsetof(struct QXLImage, surface_image.surface_id), image_bo, surface); - if (picture->format == PICT_x8r8g8b8) *force_opaque = TRUE; else *force_opaque = FALSE; - - qxl->bo_funcs->bo_unmap(image_bo); - return image_bo; + + return image_from_surface(qxl, surface); } static struct qxl_bo * diff --git a/src/qxl_surface.h b/src/qxl_surface.h index 45f6ebb..7679d43 100644 --- a/src/qxl_surface.h +++ b/src/qxl_surface.h @@ -48,6 +48,7 @@ struct qxl_surface_t struct qxl_surface_t *dest; } composite; } u; + struct qxl_bo *image_bo; }; #endif |