diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-01-11 04:58:25 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-01-11 06:00:53 -0500 |
commit | 0bfbd317c6ca16437c8d0fb7ab4a706fd98c4bae (patch) | |
tree | a36bec363c2cb5500896ed4336278b17852a59ee | |
parent | 24e525d36b9feb4adff4db76e8838c28d0027dbe (diff) |
asdfrhel5
-rw-r--r-- | src/qxl.h | 7 | ||||
-rw-r--r-- | src/qxl_driver.c | 76 |
2 files changed, 69 insertions, 14 deletions
@@ -515,6 +515,7 @@ struct _qxl_screen_t DamagePtr damage; RegionRec pending_copy; + RegionRec to_be_sent; int16_t cur_x; int16_t cur_y; @@ -563,14 +564,14 @@ void qxl_ring_wait_idle (struct qxl_ring *ring); /* * Images */ -struct qxl_image *qxl_image_create (qxl_screen_t *qxl, +struct qxl_image *qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, int x, int y, int width, int height, int stride); -void qxl_image_destroy (qxl_screen_t *qxl, +void qxl_image_destroy (qxl_screen_t *qxl, struct qxl_image *image); void qxl_drop_image_cache (qxl_screen_t *qxl); @@ -587,7 +588,7 @@ void * qxl_alloc (struct qxl_mem *mem, void qxl_free (struct qxl_mem *mem, void *d); void qxl_mem_free_all (struct qxl_mem *mem); -void * qxl_allocnf (qxl_screen_t *qxl, +void * qxl_allocnf (qxl_screen_t *qxl, unsigned long size); diff --git a/src/qxl_driver.c b/src/qxl_driver.c index d1b425c..0e595a1 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -466,6 +466,15 @@ print_region (const char *header, RegionPtr pRegion) } static void +accept_damage (qxl_screen_t *qxl) +{ + REGION_UNION (qxl->pScrn->pScreen, &(qxl->to_be_sent), &(qxl->to_be_sent), + &(qxl->pending_copy)); + + REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy)); +} + +static void undamage (qxl_screen_t *qxl) { REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy)); @@ -474,11 +483,14 @@ undamage (qxl_screen_t *qxl) static void qxl_send_copies (qxl_screen_t *qxl) { - BoxPtr pBox = REGION_RECTS(&qxl->pending_copy); - int nbox = REGION_NUM_RECTS(&qxl->pending_copy); + BoxPtr pBox; + int nbox; + + nbox = REGION_NUM_RECTS (&qxl->to_be_sent); + pBox = REGION_RECTS (&qxl->to_be_sent); #if 0 - print_region ("send bits", &qxl->pending_copy); + print_region ("send bits", &qxl->to_be_sent); #endif while (nbox--) @@ -495,7 +507,7 @@ qxl_send_copies (qxl_screen_t *qxl) pBox++; } - REGION_EMPTY(qxl->pScrn->pScreen, &qxl->pending_copy); + REGION_EMPTY(qxl->pScrn->pScreen, &qxl->to_be_sent); } static void @@ -529,6 +541,7 @@ qxl_block_handler(pointer data, OSTimePtr pTimeout, pointer pRead) qxl_screen_t *qxl = (qxl_screen_t *) data; qxl_sanity_check(qxl); + accept_damage (qxl); qxl_send_copies (qxl); } @@ -537,6 +550,29 @@ qxl_wakeup_handler(pointer data, int i, pointer LastSelectMask) { } +/* Damage Handling + * + * When something is drawn, X first generates a damage callback, then + * it calls the GC function to actually draw it. In most cases, we want + * to simply draw into the shadow framebuffer, then submit a copy to the + * device, but when the operation is hardware accelerated, we don't want + * to submit the copy. So, damage is first accumulated into 'pending_copy', + * then if we accelerated the operation, that damage is deleted. + * + * If we _didn't_ accelerate, we need to union the pending_copy damage + * onto the to_be_sent damage, and then submit a copy command in the block + * handler. + * + * This means that when new damage happens, if there is already pending + * damage, that must first be unioned onto to_be_sent, and then the new + * damage must be stored in pending_copy. + * + * The qxl_screen_t struct contains two regions, "pending_copy" and + * "to_be_sent". + * + * Pending copy is + * + */ static void qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure) { @@ -545,8 +581,8 @@ qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure) #if 0 ErrorF ("damage\n"); #endif - - qxl_send_copies (qxl); + + accept_damage (qxl); REGION_COPY (qxl->pScrn->pScreen, &(qxl->pending_copy), pRegion); } @@ -576,6 +612,11 @@ qxl_create_screen_resources(ScreenPtr pScreen) if (!RegisterBlockAndWakeupHandlers(qxl_block_handler, qxl_wakeup_handler, qxl)) return FALSE; + + REGION_INIT (pScreen, &(qxl->pending_copy), NullBox, 0); + + ErrorF ("initialized\n"); + REGION_INIT (pScreen, &(qxl->to_be_sent), NullBox, 0); DamageRegister (&pPixmap->drawable, qxl->damage); return TRUE; @@ -725,11 +766,19 @@ qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, if (pSrcDrawable->type == DRAWABLE_WINDOW && pDstDrawable->type == DRAWABLE_WINDOW) { + RegionPtr *res; + + /* We have to do this because the copy will cause the damage + * to be sent to move. + */ + qxl_send_copies (qxl); + + res = fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, dstx, dsty, + qxl_copy_n_to_n, 0, NULL); undamage (qxl); - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, dstx, dsty, - qxl_copy_n_to_n, 0, NULL); + return res; } else { @@ -803,6 +852,11 @@ qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) RegionRec rgnDst; int dx, dy; + /* We have to do this because the copy will cause the damage + * to be sent to move. + */ + qxl_send_copies (qxl); + dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; @@ -812,10 +866,10 @@ qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc); - undamage (qxl); - fbCopyRegion (&pWin->drawable, &pWin->drawable, NULL, &rgnDst, dx, dy, qxl_copy_n_to_n, 0, NULL); + + undamage (qxl); #if 0 REGION_TRANSLATE (pScreen, prgnSrc, dx, dy); |