/**************************************************************************
 * 
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 **************************************************************************/

#include "intel_screen.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_buffers.h"
#include "intel_chipset.h"
#include "intel_depthstencil.h"
#include "intel_fbo.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
#include "intel_reg.h"
#include "context.h"
#include "utils.h"
#include "drirenderbuffer.h"
#include "framebuffer.h"
#include "swrast/swrast.h"
#include "vblank.h"
#include "i915_drm.h"

/* This block can be removed when libdrm >= 2.3.1 is required */

#ifndef DRM_IOCTL_I915_FLIP

#define DRM_VBLANK_FLIP 0x8000000

typedef struct drm_i915_flip {
   int pipes;
} drm_i915_flip_t;

#undef DRM_IOCTL_I915_FLIP
#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \
				    drm_i915_flip_t)

#endif

#define FILE_DEBUG_FLAG DEBUG_BLIT

/**
 * XXX move this into a new dri/common/cliprects.c file.
 */
GLboolean
intel_intersect_cliprects(drm_clip_rect_t * dst,
                          const drm_clip_rect_t * a,
                          const drm_clip_rect_t * b)
{
   GLint bx = b->x1;
   GLint by = b->y1;
   GLint bw = b->x2 - bx;
   GLint bh = b->y2 - by;

   if (bx < a->x1)
      bw -= a->x1 - bx, bx = a->x1;
   if (by < a->y1)
      bh -= a->y1 - by, by = a->y1;
   if (bx + bw > a->x2)
      bw = a->x2 - bx;
   if (by + bh > a->y2)
      bh = a->y2 - by;
   if (bw <= 0)
      return GL_FALSE;
   if (bh <= 0)
      return GL_FALSE;

   dst->x1 = bx;
   dst->y1 = by;
   dst->x2 = bx + bw;
   dst->y2 = by + bh;

   return GL_TRUE;
}

/**
 * Return pointer to current color drawing region, or NULL.
 */
struct intel_region *
intel_drawbuf_region(struct intel_context *intel)
{
   struct intel_renderbuffer *irbColor =
      intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);
   if (irbColor)
      return irbColor->region;
   else
      return NULL;
}

/**
 * Return pointer to current color reading region, or NULL.
 */
struct intel_region *
intel_readbuf_region(struct intel_context *intel)
{
   struct intel_renderbuffer *irb
      = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
   if (irb)
      return irb->region;
   else
      return NULL;
}



/**
 * Update the following fields for rendering to a user-created FBO:
 *   intel->numClipRects
 *   intel->pClipRects
 *   intel->drawX
 *   intel->drawY
 */
static void
intelSetRenderbufferClipRects(struct intel_context *intel)
{
   assert(intel->ctx.DrawBuffer->Width > 0);
   assert(intel->ctx.DrawBuffer->Height > 0);
   intel->fboRect.x1 = 0;
   intel->fboRect.y1 = 0;
   intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
   intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;
   intel->numClipRects = 1;
   intel->pClipRects = &intel->fboRect;
   intel->drawX = 0;
   intel->drawY = 0;
}


/**
 * As above, but for rendering to front buffer of a window.
 * \sa intelSetRenderbufferClipRects
 */
static void
intelSetFrontClipRects(struct intel_context *intel)
{
   __DRIdrawablePrivate *dPriv = intel->driDrawable;

   if (!dPriv)
      return;

   intel->numClipRects = dPriv->numClipRects;
   intel->pClipRects = dPriv->pClipRects;
   intel->drawX = dPriv->x;
   intel->drawY = dPriv->y;
}


/**
 * As above, but for rendering to back buffer of a window.
 */
static void
intelSetBackClipRects(struct intel_context *intel)
{
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   struct intel_framebuffer *intel_fb;

   if (!dPriv)
      return;

   intel_fb = dPriv->driverPrivate;

   if (intel_fb->pf_active || dPriv->numBackClipRects == 0) {
      /* use the front clip rects */
      intel->numClipRects = dPriv->numClipRects;
      intel->pClipRects = dPriv->pClipRects;
      intel->drawX = dPriv->x;
      intel->drawY = dPriv->y;
   }
   else {
      /* use the back clip rects */
      intel->numClipRects = dPriv->numBackClipRects;
      intel->pClipRects = dPriv->pBackClipRects;
      intel->drawX = dPriv->backX;
      intel->drawY = dPriv->backY;
   }
}

static void
intelUpdatePageFlipping(struct intel_context *intel,
			GLint areaA, GLint areaB)
{
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
   GLboolean pf_active;
   GLint pf_planes;

   /* Update page flipping info */
   pf_planes = 0;

   if (areaA > 0)
      pf_planes |= 1;

   if (areaB > 0)
      pf_planes |= 2;

   intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
				(intel_fb->pf_planes & 0x2)) & 0x3;

   intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2;

   pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes;

   if (INTEL_DEBUG & DEBUG_LOCK)
      if (pf_active != intel_fb->pf_active)
	 _mesa_printf("%s - Page flipping %sactive\n", __progname,
		      pf_active ? "" : "in");

   if (pf_active) {
      /* Sync pages between planes if flipping on both at the same time */
      if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes &&
	  (intel->sarea->pf_current_page & 0x3) !=
	  (((intel->sarea->pf_current_page) >> 2) & 0x3)) {
	 drm_i915_flip_t flip;

	 if (intel_fb->pf_current_page ==
	     (intel->sarea->pf_current_page & 0x3)) {
	    /* XXX: This is ugly, but emitting two flips 'in a row' can cause
	     * lockups for unknown reasons.
	     */
	    intel->sarea->pf_current_page =
	       intel->sarea->pf_current_page & 0x3;
	    intel->sarea->pf_current_page |=
	       ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
		intel_fb->pf_num_pages) << 2;

	    flip.pipes = 0x2;
	 } else {
	    intel->sarea->pf_current_page =
	       intel->sarea->pf_current_page & (0x3 << 2);
	    intel->sarea->pf_current_page |=
	       (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
	       intel_fb->pf_num_pages;

	    flip.pipes = 0x1;
	 }

	 drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
      }

      intel_fb->pf_planes = pf_planes;
   }

   intel_fb->pf_active = pf_active;
   intel_flip_renderbuffers(intel_fb);
   intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
}

/**
 * This will be called whenever the currently bound window is moved/resized.
 * XXX: actually, it seems to NOT be called when the window is only moved (BP).
 */
void
intelWindowMoved(struct intel_context *intel)
{
   GLcontext *ctx = &intel->ctx;
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;

   if (!intel->ctx.DrawBuffer) {
      /* when would this happen? -BP */
      intelSetFrontClipRects(intel);
   }
   else if (intel->ctx.DrawBuffer->Name != 0) {
      /* drawing to user-created FBO - do nothing */
      /* Cliprects would be set from intelDrawBuffer() */
   }
   else {
      /* drawing to a window */
      switch (intel_fb->Base._ColorDrawBufferIndexes[0]) {
      case BUFFER_FRONT_LEFT:
         intelSetFrontClipRects(intel);
         break;
      case BUFFER_BACK_LEFT:
         intelSetBackClipRects(intel);
         break;
      default:
         intelSetFrontClipRects(intel);
      }
	
   }

   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
      volatile struct drm_i915_sarea *sarea = intel->sarea;
      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
				     .x2 = sarea->planeA_x + sarea->planeA_w,
				     .y2 = sarea->planeA_y + sarea->planeA_h };
      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
				     .x2 = sarea->planeB_x + sarea->planeB_w,
				     .y2 = sarea->planeB_y + sarea->planeB_h };
      GLint areaA = driIntersectArea( drw_rect, planeA_rect );
      GLint areaB = driIntersectArea( drw_rect, planeB_rect );
      GLuint flags = dPriv->vblFlags;

      intelUpdatePageFlipping(intel, areaA, areaB);

      /* Update vblank info
       */
      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
      } else {
	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
      }

      /* Check to see if we changed pipes */
      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
	 int64_t count;
	 drmVBlank vbl;
	 int i;

	 /*
	  * Deal with page flipping
	  */
	 vbl.request.type = DRM_VBLANK_ABSOLUTE;

	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
	    vbl.request.type |= DRM_VBLANK_SECONDARY;
	 }

	 for (i = 0; i < intel_fb->pf_num_pages; i++) {
	    if (!intel_fb->color_rb[i] ||
		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <=
		(1<<23))
	       continue;

	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending;
	    drmWaitVBlank(intel->driFd, &vbl);
	 }

	 /*
	  * Update msc_base from old pipe
	  */
	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
	 dPriv->msc_base = count;
	 /*
	  * Then get new vblank_base and vblSeq values
	  */
	 dPriv->vblFlags = flags;
	 driGetCurrentVBlank(dPriv);
	 dPriv->vblank_base = dPriv->vblSeq;

	 intel_fb->vbl_waited = dPriv->vblSeq;

	 for (i = 0; i < intel_fb->pf_num_pages; i++) {
	    if (intel_fb->color_rb[i])
	       intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited;
	 }
      }
   } else {
      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
   }

   /* Update Mesa's notion of window size */
   driUpdateFramebufferSize(ctx, dPriv);
   intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */

   /* Update hardware scissor */
   if (ctx->Driver.Scissor != NULL) {
      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
			  ctx->Scissor.Width, ctx->Scissor.Height);
   }

   /* Re-calculate viewport related state */
   if (ctx->Driver.DepthRange != NULL)
      ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
}



/* A true meta version of this would be very simple and additionally
 * machine independent.  Maybe we'll get there one day.
 */
static void
intelClearWithTris(struct intel_context *intel, GLbitfield mask)
{
   GLcontext *ctx = &intel->ctx;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   GLuint buf;

   intel->vtbl.install_meta_state(intel);

   /* Back and stencil cliprects are the same.  Try and do both
    * buffers at once:
    */
   if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) {
      struct intel_region *backRegion =
	 intel_get_rb_region(fb, BUFFER_BACK_LEFT);
      struct intel_region *depthRegion =
	 intel_get_rb_region(fb, BUFFER_DEPTH);

      intel->vtbl.meta_draw_region(intel, backRegion, depthRegion);

      if (mask & BUFFER_BIT_BACK_LEFT)
	 intel->vtbl.meta_color_mask(intel, GL_TRUE);
      else
	 intel->vtbl.meta_color_mask(intel, GL_FALSE);

      if (mask & BUFFER_BIT_STENCIL)
	 intel->vtbl.meta_stencil_replace(intel,
					  intel->ctx.Stencil.WriteMask[0],
					  intel->ctx.Stencil.Clear);
      else
	 intel->vtbl.meta_no_stencil_write(intel);

      if (mask & BUFFER_BIT_DEPTH)
	 intel->vtbl.meta_depth_replace(intel);
      else
	 intel->vtbl.meta_no_depth_write(intel);

      intel->vtbl.meta_draw_quad(intel,
				 fb->_Xmin,
				 fb->_Xmax,
				 fb->_Ymin,
				 fb->_Ymax,
				 intel->ctx.Depth.Clear,
				 intel->ClearColor8888,
				 0, 0, 0, 0);   /* texcoords */

      mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH);
   }

   /* clear the remaining (color) renderbuffers */
   for (buf = 0; buf < BUFFER_COUNT && mask; buf++) {
      const GLuint bufBit = 1 << buf;
      if (mask & bufBit) {
	 struct intel_renderbuffer *irbColor =
	    intel_renderbuffer(fb->Attachment[buf].Renderbuffer);

	 ASSERT(irbColor);

	 intel->vtbl.meta_no_depth_write(intel);
	 intel->vtbl.meta_no_stencil_write(intel);
	 intel->vtbl.meta_color_mask(intel, GL_TRUE);
	 intel->vtbl.meta_draw_region(intel, irbColor->region, NULL);

	 intel->vtbl.meta_draw_quad(intel,
				    fb->_Xmin,
				    fb->_Xmax,
				    fb->_Ymin,
				    fb->_Ymax,
				    0, intel->ClearColor8888,
				    0, 0, 0, 0);   /* texcoords */

	 mask &= ~bufBit;
      }
   }

   intel->vtbl.leave_meta_state(intel);
}

static const char *buffer_names[] = {
   [BUFFER_FRONT_LEFT] = "front",
   [BUFFER_BACK_LEFT] = "back",
   [BUFFER_FRONT_RIGHT] = "front right",
   [BUFFER_BACK_RIGHT] = "back right",
   [BUFFER_AUX0] = "aux0",
   [BUFFER_AUX1] = "aux1",
   [BUFFER_AUX2] = "aux2",
   [BUFFER_AUX3] = "aux3",
   [BUFFER_DEPTH] = "depth",
   [BUFFER_STENCIL] = "stencil",
   [BUFFER_ACCUM] = "accum",
   [BUFFER_COLOR0] = "color0",
   [BUFFER_COLOR1] = "color1",
   [BUFFER_COLOR2] = "color2",
   [BUFFER_COLOR3] = "color3",
   [BUFFER_COLOR4] = "color4",
   [BUFFER_COLOR5] = "color5",
   [BUFFER_COLOR6] = "color6",
   [BUFFER_COLOR7] = "color7",
};

/**
 * Called by ctx->Driver.Clear.
 */
static void
intelClear(GLcontext *ctx, GLbitfield mask)
{
   struct intel_context *intel = intel_context(ctx);
   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
   GLbitfield tri_mask = 0;
   GLbitfield blit_mask = 0;
   GLbitfield swrast_mask = 0;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   GLuint i;

   if (0)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* HW color buffers (front, back, aux, generic FBO, etc) */
   if (colorMask == ~0) {
      /* clear all R,G,B,A */
      /* XXX FBO: need to check if colorbuffers are software RBOs! */
      blit_mask |= (mask & BUFFER_BITS_COLOR);
   }
   else {
      /* glColorMask in effect */
      tri_mask |= (mask & BUFFER_BITS_COLOR);
   }

   /* HW stencil */
   if (mask & BUFFER_BIT_STENCIL) {
      const struct intel_region *stencilRegion
         = intel_get_rb_region(fb, BUFFER_STENCIL);
      if (stencilRegion) {
         /* have hw stencil */
         if (IS_965(intel->intelScreen->deviceID) ||
	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
	    /* We have to use the 3D engine if we're clearing a partial mask
	     * of the stencil buffer, or if we're on a 965 which has a tiled
	     * depth/stencil buffer in a layout we can't blit to.
	     */
            tri_mask |= BUFFER_BIT_STENCIL;
         }
         else {
            /* clearing all stencil bits, use blitting */
            blit_mask |= BUFFER_BIT_STENCIL;
         }
      }
   }

   /* HW depth */
   if (mask & BUFFER_BIT_DEPTH) {
      /* clear depth with whatever method is used for stencil (see above) */
      if (IS_965(intel->intelScreen->deviceID) ||
	  tri_mask & BUFFER_BIT_STENCIL)
         tri_mask |= BUFFER_BIT_DEPTH;
      else
         blit_mask |= BUFFER_BIT_DEPTH;
   }

   /* SW fallback clearing */
   swrast_mask = mask & ~tri_mask & ~blit_mask;

   for (i = 0; i < BUFFER_COUNT; i++) {
      GLuint bufBit = 1 << i;
      if ((blit_mask | tri_mask) & bufBit) {
         if (!fb->Attachment[i].Renderbuffer->ClassID) {
            blit_mask &= ~bufBit;
            tri_mask &= ~bufBit;
            swrast_mask |= bufBit;
         }
      }
   }

   if (blit_mask) {
      if (INTEL_DEBUG & DEBUG_BLIT) {
	 DBG("blit clear:");
	 for (i = 0; i < BUFFER_COUNT; i++) {
	    if (blit_mask & (1 << i))
	       DBG(" %s", buffer_names[i]);
	 }
	 DBG("\n");
      }
      intelClearWithBlit(ctx, blit_mask);
   }

   if (tri_mask) {
      if (INTEL_DEBUG & DEBUG_BLIT) {
	 DBG("tri clear:");
	 for (i = 0; i < BUFFER_COUNT; i++) {
	    if (tri_mask & (1 << i))
	       DBG(" %s", buffer_names[i]);
	 }
	 DBG("\n");
      }
      intelClearWithTris(intel, tri_mask);
   }

   if (swrast_mask) {
      if (INTEL_DEBUG & DEBUG_BLIT) {
	 DBG("swrast clear:");
	 for (i = 0; i < BUFFER_COUNT; i++) {
	    if (swrast_mask & (1 << i))
	       DBG(" %s", buffer_names[i]);
	 }
	 DBG("\n");
      }
      _swrast_Clear(ctx, swrast_mask);
   }
}


/* Emit wait for pending flips */
void
intel_wait_flips(struct intel_context *intel)
{
   struct intel_framebuffer *intel_fb =
      (struct intel_framebuffer *) intel->ctx.DrawBuffer;
   struct intel_renderbuffer *intel_rb =
      intel_get_renderbuffer(&intel_fb->Base,
			     intel_fb->Base._ColorDrawBufferIndexes[0] ==
			     BUFFER_FRONT_LEFT ? BUFFER_FRONT_LEFT :
			     BUFFER_BACK_LEFT);

   if (intel_fb->Base.Name == 0 && intel_rb &&
       intel_rb->pf_pending == intel_fb->pf_seq) {
      GLint pf_planes = intel_fb->pf_planes;
      BATCH_LOCALS;

      /* Wait for pending flips to take effect */
      BEGIN_BATCH(2, NO_LOOP_CLIPRECTS);
      OUT_BATCH(pf_planes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP)
		: 0);
      OUT_BATCH(pf_planes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP)
		: 0);
      ADVANCE_BATCH();

      intel_rb->pf_pending--;
   }
}


/* Flip the front & back buffers
 */
static GLboolean
intelPageFlip(const __DRIdrawablePrivate * dPriv)
{
   struct intel_context *intel;
   int ret;
   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;

   if (INTEL_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;

   if (intel->intelScreen->drmMinor < 9)
      return GL_FALSE;

   intelFlush(&intel->ctx);

   ret = 0;

   LOCK_HARDWARE(intel);

   if (dPriv->numClipRects && intel_fb->pf_active) {
      drm_i915_flip_t flip;

      flip.pipes = intel_fb->pf_planes;

      ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
   }

   UNLOCK_HARDWARE(intel);

   if (ret || !intel_fb->pf_active)
      return GL_FALSE;

   if (!dPriv->numClipRects) {
      usleep(10000);	/* throttle invisible client 10ms */
   }

   intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
				(intel_fb->pf_planes & 0x2)) & 0x3;

   if (dPriv->numClipRects != 0) {
      intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending =
      intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->pf_pending =
	 ++intel_fb->pf_seq;
   }

   intel_flip_renderbuffers(intel_fb);
   intel_draw_buffer(&intel->ctx, &intel_fb->Base);

   return GL_TRUE;
}

static GLboolean
intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
{
   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
   unsigned int interval;
   struct intel_context *intel =
      intelScreenContext(dPriv->driScreenPriv->private);
   const intelScreenPrivate *intelScreen = intel->intelScreen;
   unsigned int target;
   drm_i915_vblank_swap_t swap;
   GLboolean ret;

   if (!dPriv->vblFlags ||
       (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) ||
       intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
      return GL_FALSE;

   interval = driGetVBlankInterval(dPriv);

   swap.seqtype = DRM_VBLANK_ABSOLUTE;

   if (dPriv->vblFlags & VBLANK_FLAG_SYNC) {
      swap.seqtype |= DRM_VBLANK_NEXTONMISS;
   } else if (interval == 0)
      return GL_FALSE;

   swap.drawable = dPriv->hHWDrawable;
   target = swap.sequence = dPriv->vblSeq + interval;

   if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
      swap.seqtype |= DRM_VBLANK_SECONDARY;
   }

   LOCK_HARDWARE(intel);

   intel_batchbuffer_flush(intel->batch);

   if ( intel_fb->pf_active ) {
      swap.seqtype |= DRM_VBLANK_FLIP;

      intel_fb->pf_current_page = (((intel->sarea->pf_current_page >>
				     (intel_fb->pf_planes & 0x2)) & 0x3) + 1) %
				  intel_fb->pf_num_pages;
   }

   if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
			    sizeof(swap))) {
      dPriv->vblSeq = swap.sequence;
      swap.sequence -= target;
      *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);

      intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending =
	 intel_get_renderbuffer(&intel_fb->Base,
				BUFFER_FRONT_LEFT)->vbl_pending =
	 dPriv->vblSeq;

      if (swap.seqtype & DRM_VBLANK_FLIP) {
	 intel_flip_renderbuffers(intel_fb);
	 intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
      }

      ret = GL_TRUE;
   } else {
      if (swap.seqtype & DRM_VBLANK_FLIP) {
	 intel_fb->pf_current_page = ((intel->sarea->pf_current_page >>
					(intel_fb->pf_planes & 0x2)) & 0x3) %
				     intel_fb->pf_num_pages;
      }

      ret = GL_FALSE;
   }

   UNLOCK_HARDWARE(intel);

   return ret;
}
  
void
intelSwapBuffers(__DRIdrawablePrivate * dPriv)
{
   __DRIscreenPrivate *psp = dPriv->driScreenPriv;

   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
      GET_CURRENT_CONTEXT(ctx);
      struct intel_context *intel;

      if (ctx == NULL)
	 return;

      intel = intel_context(ctx);

      if (ctx->Visual.doubleBufferMode) {
	 GLboolean missed_target;
	 struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
	 int64_t ust;
         
	 _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */

         if (!intelScheduleSwap(dPriv, &missed_target)) {
	    driWaitForVBlank(dPriv, &missed_target);

	    /*
	     * Update each buffer's vbl_pending so we don't get too out of
	     * sync
	     */
	    intel_get_renderbuffer(&intel_fb->Base,
				   BUFFER_BACK_LEFT)->vbl_pending = 
		    intel_get_renderbuffer(&intel_fb->Base,
					   BUFFER_FRONT_LEFT)->vbl_pending =
		    dPriv->vblSeq;
	    if (!intelPageFlip(dPriv)) {
	       intelCopyBuffer(dPriv, NULL);
	    }
	 }

	 intel_fb->swap_count++;
	 (*psp->systemTime->getUST) (&ust);
	 if (missed_target) {
	    intel_fb->swap_missed_count++;
	    intel_fb->swap_missed_ust = ust - intel_fb->swap_ust;
	 }

	 intel_fb->swap_ust = ust;
      }
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
   }
}

void
intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
{
   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
      struct intel_context *intel =
         (struct intel_context *) dPriv->driContextPriv->driverPrivate;
      GLcontext *ctx = &intel->ctx;

      if (ctx->Visual.doubleBufferMode) {
         drm_clip_rect_t rect;
         rect.x1 = x + dPriv->x;
         rect.y1 = (dPriv->h - y - h) + dPriv->y;
         rect.x2 = rect.x1 + w;
         rect.y2 = rect.y1 + h;
         _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
         intelCopyBuffer(dPriv, &rect);
      }
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
   }
}


/**
 * Update the hardware state for drawing into a window or framebuffer object.
 *
 * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other
 * places within the driver.
 *
 * Basically, this needs to be called any time the current framebuffer
 * changes, the renderbuffers change, or we need to draw into different
 * color buffers.
 */
void
intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
{
   struct intel_context *intel = intel_context(ctx);
   struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL;
   struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;
   int front = 0;               /* drawing to front color buffer? */

   if (!fb) {
      /* this can happen during the initial context initialization */
      return;
   }

   /* Do this here, note core Mesa, since this function is called from
    * many places within the driver.
    */
   if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
      /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
      _mesa_update_framebuffer(ctx);
      /* this updates the DrawBuffer's Width/Height if it's a FBO */
      _mesa_update_draw_buffer_bounds(ctx);
   }

   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      /* this may occur when we're called by glBindFrameBuffer() during
       * the process of someone setting up renderbuffers, etc.
       */
      /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
      return;
   }

   if (fb->Name)
      intel_validate_paired_depth_stencil(ctx, fb);

   /* If the batch contents require looping over cliprects, flush them before
    * we go changing which cliprects get referenced when that happens.
    */
   if (intel->batch->cliprect_mode == LOOP_CLIPRECTS)
      intel_batchbuffer_flush(intel->batch);

   /*
    * How many color buffers are we drawing into?
    */
   if (fb->_NumColorDrawBuffers == 0) {
      /* writing to 0  */
      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
      colorRegions[0] = NULL;

      if (fb->Name != 0)
	 intelSetRenderbufferClipRects(intel);
   } else if (fb->_NumColorDrawBuffers > 1) {
       int i;
       struct intel_renderbuffer *irb;
       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);

       if (fb->Name != 0)
           intelSetRenderbufferClipRects(intel);
       for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
           irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
           colorRegions[i] = (irb && irb->region) ? irb->region : NULL;
       }
   }
   else {
      /* draw to exactly one color buffer */
      /*_mesa_debug(ctx, "Hardware rendering\n");*/
      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
      if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
         front = 1;
      }

      /*
       * Get the intel_renderbuffer for the colorbuffer we're drawing into.
       * And set up cliprects.
       */
      if (fb->Name == 0) {
	 /* drawing to window system buffer */
	 if (front) {
	    intelSetFrontClipRects(intel);
	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
	 }
	 else {
	    intelSetBackClipRects(intel);
	    colorRegions[0]= intel_get_rb_region(fb, BUFFER_BACK_LEFT);
	 }
      }
      else {
	 /* drawing to user-created FBO */
	 struct intel_renderbuffer *irb;
	 intelSetRenderbufferClipRects(intel);
	 irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
	 colorRegions[0] = (irb && irb->region) ? irb->region : NULL;
      }
   }

   /* Update culling direction which changes depending on the
    * orientation of the buffer:
    */
   if (ctx->Driver.FrontFace)
      ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
   else
      ctx->NewState |= _NEW_POLYGON;

   if (!colorRegions[0]) {
      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
   }
   else {
      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
   }

   /***
    *** Get depth buffer region and check if we need a software fallback.
    *** Note that the depth buffer is usually a DEPTH_STENCIL buffer.
    ***/
   if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
      irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
      if (irbDepth && irbDepth->region) {
         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
         depthRegion = irbDepth->region;
      }
      else {
         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
         depthRegion = NULL;
      }
   }
   else {
      /* not using depth buffer */
      FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
      depthRegion = NULL;
   }

   /***
    *** Stencil buffer
    *** This can only be hardware accelerated if we're using a
    *** combined DEPTH_STENCIL buffer (for now anyway).
    ***/
   if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
      irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped);
      if (irbStencil && irbStencil->region) {
         ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
         /* need to re-compute stencil hw state */
	 if (ctx->Driver.Enable != NULL)
	    ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
	 else
	    ctx->NewState |= _NEW_STENCIL;
         if (!depthRegion)
            depthRegion = irbStencil->region;
      }
      else {
         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
      }
   }
   else {
      /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */
      FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
      /* need to re-compute stencil hw state */
      if (ctx->Driver.Enable != NULL)
	 ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
      else
	 ctx->NewState |= _NEW_STENCIL;
   }

   /*
    * Update depth test state
    */
   if (ctx->Driver.Enable) {
      if (ctx->Depth.Test && fb->Visual.depthBits > 0) {
	 ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE);
      } else {
	 ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE);
      }
   } else {
      ctx->NewState |= _NEW_DEPTH;
   }

   intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, 
	fb->_NumColorDrawBuffers);

   /* update viewport since it depends on window size */
   if (ctx->Driver.Viewport) {
      ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
			   ctx->Viewport.Width, ctx->Viewport.Height);
   } else {
      ctx->NewState |= _NEW_VIEWPORT;
   }

   /* Set state we know depends on drawable parameters:
    */
   if (ctx->Driver.Scissor)
      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
			  ctx->Scissor.Width, ctx->Scissor.Height);
   intel->NewGLState |= _NEW_SCISSOR;

   if (ctx->Driver.DepthRange)
      ctx->Driver.DepthRange(ctx,
			     ctx->Viewport.Near,
			     ctx->Viewport.Far);
}


static void
intelDrawBuffer(GLcontext * ctx, GLenum mode)
{
   intel_draw_buffer(ctx, ctx->DrawBuffer);
}


static void
intelReadBuffer(GLcontext * ctx, GLenum mode)
{
   if (ctx->ReadBuffer == ctx->DrawBuffer) {
      /* This will update FBO completeness status.
       * A framebuffer will be incomplete if the GL_READ_BUFFER setting
       * refers to a missing renderbuffer.  Calling glReadBuffer can set
       * that straight and can make the drawing buffer complete.
       */
      intel_draw_buffer(ctx, ctx->DrawBuffer);
   }
   /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc)
    * reference ctx->ReadBuffer and do appropriate state checks.
    */
}


void
intelInitBufferFuncs(struct dd_function_table *functions)
{
   functions->Clear = intelClear;
   functions->DrawBuffer = intelDrawBuffer;
   functions->ReadBuffer = intelReadBuffer;
}
