summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2010-02-06 09:32:00 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-02-06 09:32:00 -0500
commit73ef1f79a64595a8547c4f4d4f9161673a438319 (patch)
treeb84e8f9c71df9740f873a7bbffeac3899a5626f0
parent33f36098c766d86cb6f292e2806510d00e2caab6 (diff)
Do the undamage handling in qxl_copy_n_to_n()
Previously it would do it in both copy_window() and copy_area(). The problem with that, aside from duplication of a bit code, was that sometimes the copy operations would be empty, which meant that no damage was generated for the copy so that the pending damage region was actually corresponding to some earlier operation, and so discarding it caused rendering corruption. This change moves the damage handling into qxl_copy_n_to_n() and only does something when there is actually some copying going on.
-rw-r--r--src/qxl_driver.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index c850e68..9be3c82 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -359,7 +359,7 @@ make_drawable (qxl_screen_t *qxl, uint8_t type,
drawable->type = type;
- drawable->effect = QXL_EFFECT_OPAQUE;
+ drawable->effect = QXL_EFFECT_BLEND;
drawable->bitmap_offset = 0;
drawable->bitmap_area.top = 0;
drawable->bitmap_area.left = 0;
@@ -516,13 +516,13 @@ qxl_send_copies (qxl_screen_t *qxl)
nbox = REGION_NUM_RECTS (&qxl->to_be_sent);
pBox = REGION_RECTS (&qxl->to_be_sent);
-/* print_region ("send bits", &qxl->to_be_sent); */
-/* print_region ("unsent bits", &qxl->pending_copy); */
+/* if (REGION_NUM_RECTS (&qxl->to_be_sent) > 0) */
+/* print_region ("send bits", &qxl->to_be_sent); */
while (nbox--)
{
struct qxl_rect qrect;
-
+
qrect.top = pBox->y1;
qrect.left = pBox->x1;
qrect.bottom = pBox->y2;
@@ -610,9 +610,7 @@ qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure)
/* print_region ("damage", pRegion); */
-#if 0
- ErrorF ("damage\n");
-#endif
+/* print_region ("on_damage ", pRegion); */
accept_damage (qxl);
@@ -749,6 +747,33 @@ qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
/* ErrorF ("Accelerated copy: %d boxes\n", n); */
+ /* At this point we know that any pending damage must
+ * have been caused by whatever copy operation triggered us.
+ *
+ * Therefore we can clear it.
+ *
+ * We couldn't clear it at the toplevel function because
+ * the copy might end up being empty, in which case no
+ * damage would have been generated. Which means the
+ * pending damage would have been caused by some
+ * earlier operation.
+ */
+ if (n)
+ {
+/* ErrorF ("Clearing pending damage\n"); */
+ clear_pending_damage (qxl);
+
+ /* We have to do this because the copy will cause the damage
+ * to be sent to move.
+ *
+ * Instead of just sending the bits, we could also move
+ * the existing damage around; however that's a bit more
+ * complex, and the performance win is unlikely to be
+ * very big.
+ */
+ qxl_send_copies (qxl);
+ }
+
while (n--)
{
struct qxl_drawable *drawable;
@@ -793,20 +818,15 @@ qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
{
ScreenPtr pScreen = pSrcDrawable->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- qxl_screen_t *qxl = pScrn->driverPrivate;
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.
- */
- clear_pending_damage (qxl);
+/* ErrorF ("accelerated copy %d %d %d %d %d %d\n", */
+/* srcx, srcy, width, height, dstx, dsty); */
- qxl_send_copies (qxl);
-
res = fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
srcx, srcy, width, height, dstx, dsty,
qxl_copy_n_to_n, 0, NULL);
@@ -815,6 +835,9 @@ qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
}
else
{
+/* ErrorF ("Falling back %d %d %d %d %d %d\n", */
+/* srcx, srcy, width, height, dstx, dsty); */
+
return fbCopyArea (pSrcDrawable, pDstDrawable, pGC,
srcx, srcy, width, height, dstx, dsty);
}
@@ -879,18 +902,9 @@ qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- qxl_screen_t *qxl = pScrn->driverPrivate;
RegionRec rgnDst;
int dx, dy;
- /* We have to do this because the copy will cause the damage
- * to be sent to move, which means the "undamage" later will
- * remove the wrong damage.
- */
- clear_pending_damage (qxl);
-
- qxl_send_copies (qxl);
-
dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y;