summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/qxl_dri2.c13
-rw-r--r--src/qxl_kms.c1
-rw-r--r--src/qxl_surface.c63
-rw-r--r--src/qxl_surface.h3
-rw-r--r--src/qxl_surface_ums.c2
5 files changed, 80 insertions, 2 deletions
diff --git a/src/qxl_dri2.c b/src/qxl_dri2.c
index e4242d6..ebd4976 100644
--- a/src/qxl_dri2.c
+++ b/src/qxl_dri2.c
@@ -82,9 +82,22 @@ qxl_dri2_create_buffer2(ScreenPtr screen, DrawablePtr draw, unsigned int attachm
return NULL;
if (attachment == DRI2BufferFrontLeft) {
+ struct qxl_surface_t *surf;
ppix = get_drawable_pixmap(draw);
if (ppix)
ppix->refcnt++;
+
+ /* okay flip */
+
+ /* get name */
+ surf = get_surface(ppix);
+ if (ppix->usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP) {
+ if (!surf->dri2_sw_rendered) {
+ qxl_flip_surface(surf);
+ }
+ surf->dri2_sw_rendered = TRUE;
+
+ }
} else {
int bpp;
unsigned int usage_hint = 0;
diff --git a/src/qxl_kms.c b/src/qxl_kms.c
index 319f056..4c89141 100644
--- a/src/qxl_kms.c
+++ b/src/qxl_kms.c
@@ -688,6 +688,7 @@ qxl_kms_surface_create(qxl_screen_t *qxl,
surface->qxl = qxl;
surface->id = bo->handle;
surface->image_bo = NULL;
+ surface->dri2_sw_rendered = FALSE;
if (usage_hint & QXL_CREATE_PIXMAP_DRI2)
surface->is_dri2_surf = TRUE;
else
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 0c70416..55f18b6 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -160,6 +160,19 @@ qxl_surface_prepare_access (qxl_surface_t *surface,
if (!pScrn->vtSema)
return FALSE;
+ if (surface->dri2_sw_rendered || surface->is_dri2_surf) {
+ void *map = surface->qxl->bo_funcs->bo_map(surface->bo);
+
+ pScreen->ModifyPixmapHeader(
+ pixmap,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ -1, -1, -1, map);
+
+ pixmap->devKind = abs(pixman_image_get_stride (surface->host_image));
+ return TRUE;
+ }
+
REGION_INIT (NULL, &new, (BoxPtr)NULL, 0);
REGION_SUBTRACT (NULL, &new, region, &surface->access_region);
@@ -343,6 +356,11 @@ qxl_surface_finish_access (qxl_surface_t *surface, PixmapPtr pixmap)
int n_boxes;
BoxPtr boxes;
+ if (surface->dri2_sw_rendered) {
+ pScreen->ModifyPixmapHeader(pixmap, w, h, -1, -1, 0, NULL);
+ surface->qxl->bo_funcs->bo_unmap(surface->bo);
+ return;
+ }
n_boxes = REGION_NUM_RECTS (&surface->access_region);
boxes = REGION_RECTS (&surface->access_region);
@@ -404,6 +422,9 @@ Bool
qxl_surface_prepare_solid (qxl_surface_t *destination,
Pixel fg)
{
+ if (destination->dri2_sw_rendered)
+ return FALSE;
+
if (!REGION_NIL (&(destination->access_region)))
{
ErrorF (" solid not in vmem\n");
@@ -444,6 +465,8 @@ Bool
qxl_surface_prepare_copy (qxl_surface_t *dest,
qxl_surface_t *source)
{
+ if (dest->dri2_sw_rendered || source->dri2_sw_rendered)
+ return FALSE;
if (!REGION_NIL (&(dest->access_region)) ||
!REGION_NIL (&(source->access_region)))
{
@@ -604,6 +627,14 @@ qxl_surface_prepare_composite (int op,
qxl_surface_t * mask,
qxl_surface_t * dest)
{
+
+ if (dest->dri2_sw_rendered)
+ return FALSE;
+ if (src && src->dri2_sw_rendered)
+ return FALSE;
+ if (mask && mask->dri2_sw_rendered)
+ return FALSE;
+
dest->u.composite.op = op;
dest->u.composite.src_picture = src_picture;
dest->u.composite.mask_picture = mask_picture;
@@ -806,6 +837,8 @@ qxl_surface_put_image (qxl_surface_t *dest,
struct QXLRect rect;
struct qxl_bo *image_bo;
+ if (dest->dri2_sw_rendered)
+ return FALSE;
rect.left = x;
rect.right = x + width;
rect.top = y;
@@ -869,3 +902,33 @@ qxl_get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat)
break;
}
}
+
+void
+qxl_flip_surface(struct qxl_surface_t *surf)
+{
+ int width, height;
+ pixman_image_t *temp;
+ void *dev_addr;
+ pixman_format_code_t format;
+
+ width = pixman_image_get_width (surf->host_image);
+ height = pixman_image_get_height (surf->host_image);
+ format = pixman_image_get_format (surf->host_image);
+ /* flip this surface up the right way */
+ qxl_download_box(surf, 0, 0, width, height);
+
+ dev_addr = surf->qxl->bo_funcs->bo_map(surf->bo);
+ temp = pixman_image_create_bits (format, width, height,
+ (uint32_t *)dev_addr, abs(pixman_image_get_stride(surf->host_image)));
+
+
+ pixman_image_composite (PIXMAN_OP_SRC,
+ surf->host_image,
+ NULL,
+ temp,
+ 0, 0, 0, 0, 0, 0,
+ width, height);
+ pixman_image_unref(temp);
+ surf->qxl->bo_funcs->bo_unmap(surf->bo);
+
+}
diff --git a/src/qxl_surface.h b/src/qxl_surface.h
index 2188098..213a04e 100644
--- a/src/qxl_surface.h
+++ b/src/qxl_surface.h
@@ -28,6 +28,7 @@ struct qxl_surface_t
PixmapPtr pixmap;
+ Bool dri2_sw_rendered;
struct evacuated_surface_t *evacuated;
union
@@ -51,5 +52,5 @@ struct qxl_surface_t
void qxl_download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2);
void qxl_upload_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2);
-
+void qxl_flip_surface(struct qxl_surface_t *surf);
#endif
diff --git a/src/qxl_surface_ums.c b/src/qxl_surface_ums.c
index f6364d1..7b562a0 100644
--- a/src/qxl_surface_ums.c
+++ b/src/qxl_surface_ums.c
@@ -343,7 +343,7 @@ qxl_surface_cache_create_primary (qxl_screen_t *qxl,
surface->bo = bo;
surface->image_bo = NULL;
surface->is_dri2_surf = FALSE;
-
+ surface->dri2_sw_rendered = FALSE;
REGION_INIT (NULL, &(surface->access_region), (BoxPtr)NULL, 0);
surface->access_type = UXA_ACCESS_RO;