restrict blitted area to size of rendered area
authorRoland Scheidegger <sroland@tungstengraphics.com>
Wed, 11 Jul 2007 18:18:51 +0000 (20:18 +0200)
committerRoland Scheidegger <sroland@tungstengraphics.com>
Wed, 11 Jul 2007 18:18:51 +0000 (20:18 +0200)
src/mesa/drivers/dri/i915tex/intel_blit.c
src/mesa/drivers/dri/i915tex/intel_blit.h
src/mesa/drivers/dri/i915tex/intel_buffers.c

index c755eac6b2c43d5f8001e10d6752d3ef26c815b2..3e42d799808c05e7cf8edaabf90a442a2c231a50 100644 (file)
@@ -49,7 +49,7 @@
  * Used for SwapBuffers().
  */
 void
-intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
+intelCopyBuffer(__DRIdrawablePrivate * dPriv,
                 const drm_clip_rect_t * rect)
 {
 
@@ -94,6 +94,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
         = intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT ?
           intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT) :
           intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT);
+      const int backWidth = intel_fb->Base.Width;
+      const int backHeight = intel_fb->Base.Height;
       const int nbox = dPriv->numClipRects;
       const drm_clip_rect_t *pbox = dPriv->pClipRects;
       const int pitch = frontRegion->pitch;
@@ -134,32 +136,42 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
         box = *pbox;
 
         if (rect) {
-           if (rect->x1 > box.x1)
-              box.x1 = rect->x1;
-           if (rect->y1 > box.y1)
-              box.y1 = rect->y1;
-           if (rect->x2 < box.x2)
-              box.x2 = rect->x2;
-           if (rect->y2 < box.y2)
-              box.y2 = rect->y2;
+           drm_clip_rect_t rrect;
+
+           rrect.x1 = dPriv->x + rect->x1;
+           rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
+           rrect.x2 = rect->x2 + rrect.x1;
+           rrect.y2 = rect->y2 + rrect.y1;
+           if (rrect.x1 > box.x1)
+              box.x1 = rrect.x1;
+           if (rrect.y1 > box.y1)
+              box.y1 = rrect.y1;
+           if (rrect.x2 < box.x2)
+              box.x2 = rrect.x2;
+           if (rrect.y2 < box.y2)
+              box.y2 = rrect.y2;
 
            if (box.x1 > box.x2 || box.y1 > box.y2)
               continue;
         }
 
+        /* restrict blit to size of actually rendered area */
+        if (box.x2 - box.x1 > backWidth)
+           box.x2 = backWidth + box.x1;
+        if (box.y2 - box.y1 > backHeight)
+           box.y2 = backHeight + box.y1;
+
         DBG("box x1 x2 y1 y2 %d %d %d %d\n",
              box.x1, box.x2, box.y1, box.y2);
 
-        /* XXX should make sure only the minimum area based on
-           old draw buffer and new front clip rects is copied */
         sbox.x1 = box.x1 - dPriv->x;
         sbox.y1 = box.y1 - dPriv->y;
 
         BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
         OUT_BATCH(CMD);
         OUT_BATCH(BR13);
-        OUT_BATCH((pbox->y1 << 16) | pbox->x1);
-        OUT_BATCH((pbox->y2 << 16) | pbox->x2);
+        OUT_BATCH((box.y1 << 16) | box.x1);
+        OUT_BATCH((box.y2 << 16) | box.x2);
 
         OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
                   DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
index e7bc280f58ad3a1c5be27e7205a169ebe05cf2b5..77686444fa0dcf90c01278097fc8032cf7c102d3 100644 (file)
@@ -32,7 +32,7 @@
 #include "intel_ioctl.h"
 #include "dri_bufmgr.h"
 
-extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv,
+extern void intelCopyBuffer(__DRIdrawablePrivate * dpriv,
                             const drm_clip_rect_t * rect);
 
 extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask);
index 5aed3ad0eccc71d37205e5dc3b464a533cd6f83e..20e9521105da1e64c3c7771083b0e8444819b9e5 100644 (file)
@@ -910,17 +910,11 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
 
       if (ctx->Visual.doubleBufferMode) {
          drm_clip_rect_t rect;
-#if 1
-         rect.x1 = x + dPriv->x;
-         rect.y1 = (dPriv->h - y - h) + dPriv->y;
-         rect.x2 = rect.x1 + w;
-         rect.y2 = rect.y1 + h;
-#else
+        /* fixup cliprect (driDrawable may have changed?) later */
          rect.x1 = x;
-         rect.y1 = dPriv->h - y;
-         rect.x2 = rect.x1 + w;
-         rect.y2 = rect.y1 + h;
-#endif
+         rect.y1 = y;
+         rect.x2 = w;
+         rect.y2 = h;
          _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
          intelCopyBuffer(dPriv, &rect);
       }