diff options
-rw-r--r-- | src/qxl_dri2.c | 13 | ||||
-rw-r--r-- | src/qxl_kms.c | 1 | ||||
-rw-r--r-- | src/qxl_surface.c | 63 | ||||
-rw-r--r-- | src/qxl_surface.h | 3 | ||||
-rw-r--r-- | src/qxl_surface_ums.c | 2 |
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; |