summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2013-02-05 16:35:18 +1000
committerDave Airlie <airlied@gmail.com>2013-02-05 16:35:18 +1000
commit4bff2830749a1ac4a27686959cef9b53c219c4fd (patch)
treea4d37bbff1af16dc728df487e286b9ac070f9a5a
parent1e63f955dae558fa0f1d7e204c8d99eaa30f9469 (diff)
qxl: cache image bo inside surfacebo-abs1
-rw-r--r--src/qxl.h1
-rw-r--r--src/qxl_kms.c7
-rw-r--r--src/qxl_mem.c7
-rw-r--r--src/qxl_surface.c53
-rw-r--r--src/qxl_surface.h1
5 files changed, 47 insertions, 22 deletions
diff --git a/src/qxl.h b/src/qxl.h
index e1d838e..164cc65 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -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