Exemplo n.º 1
0
void
radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
{

   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
      radeonContextPtr rmesa;
      GLcontext *ctx;
      rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
      ctx = rmesa->glCtx;
      if (ctx->Visual.doubleBufferMode) {
         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */

         if ( rmesa->doPageFlip ) {
            radeonPageFlip( dPriv );
         }
         else {
	     radeonCopyBuffer( dPriv, NULL );
         }
      }
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
   }
}
Exemplo n.º 2
0
void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
			 int x, int y, int w, int h )
{
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
	radeonContextPtr radeon;
	GLcontext *ctx;

	radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
	ctx = radeon->glCtx;

	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 */
	    radeonCopyBuffer(dPriv, &rect);
	}
    } else {
	/* XXX this shouldn't be an error but we can't handle it for now */
	_mesa_problem(NULL, "%s: drawable has no context!",
		      __FUNCTION__);
    }
}
void
MesaSoftwareRenderer::SwapBuffers(bool VSync)
{
	CALLED();

	if (!fBitmap)
		return;

	if (fVisual->doubleBufferMode)
		_mesa_notifySwapBuffers(fContext);

	if (!fDirectModeEnabled || fInfo == NULL) {
		if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
			GLView()->DrawBitmap(fBitmap, B_ORIGIN);
			GLView()->UnlockLooper();
		}
	} else {
		// TODO: Here the BGLView needs to be drawlocked.
		_CopyToDirect();
	}

	if (VSync) {
		BScreen screen(GLView()->Window());
		screen.WaitForRetrace();
	}
}
Exemplo n.º 4
0
BOOL sw_SwapBuffers(HDC hdc, struct wgl_dc_data* dc_data)
{
    struct sw_framebuffer* fb = dc_data->sw_data;
    struct sw_context* sw_ctx = (struct sw_context*)IntGetCurrentDHGLRC();
    
    /* Notify mesa */
    if(sw_ctx)
        _mesa_notifySwapBuffers(&sw_ctx->mesa);
    
    if(!(fb->flags & SW_FB_DOUBLEBUFFERED))
        return TRUE;

    /* Upload to the display */
    return (SetDIBitsToDevice(hdc,
        0,
        0,
        fb->bmi.bmiHeader.biWidth,
        fb->bmi.bmiHeader.biHeight,
        0,
        0,
        0,
        fb->bmi.bmiHeader.biHeight,
        fb->backbuffer.Buffer,
        &fb->bmi,
        DIB_RGB_COLORS) != 0);
}
Exemplo n.º 5
0
/*
 * Swap front/back buffers for current context if double buffered.
 */
void GLAPIENTRY
fxMesaSwapBuffers(void)
{
   if (TDFX_DEBUG & VERBOSE_DRIVER) {
      fprintf(stderr, "fxMesaSwapBuffers()\n");
   }

   if (fxMesaCurrentCtx) {
      _mesa_notifySwapBuffers(fxMesaCurrentCtx->glCtx);

      if (fxMesaCurrentCtx->haveDoubleBuffer) {

	 grBufferSwap(fxMesaCurrentCtx->swapInterval);

#if 0
	 /*
	  * Don't allow swap buffer commands to build up!
	  */
	 while (FX_grGetInteger(GR_PENDING_BUFFERSWAPS) >
		fxMesaCurrentCtx->maxPendingSwapBuffers)
	    /* The driver is able to sleep when waiting for the completation
	       of multiple swapbuffer operations instead of wasting
	       CPU time (NOTE: you must uncomment the following line in the
	       in order to enable this option) */
	    /* usleep(10000); */
	    ;
#endif

	 fxMesaCurrentCtx->stats.swapBuffer++;
      }
   }
}
Exemplo n.º 6
0
void
DMesaSwapBuffers (DMesaBuffer buffer)
{
    /* copy/swap back buffer to front if applicable */
    GET_CURRENT_CONTEXT(ctx);
    _mesa_notifySwapBuffers(ctx);
    vl_flip();
    (void)buffer;
}
Exemplo n.º 7
0
void MesaDriver::SwapBuffers() const
{
    _mesa_notifySwapBuffers(m_glcontext);

	if (m_bitmap) {
		m_bglview->LockLooper();
		m_bglview->DrawBitmap(m_bitmap);
		m_bglview->UnlockLooper();
	};
}
Exemplo n.º 8
0
Arquivo: xm_api.c Projeto: RAOF/mesa
/*
 * Copy the back buffer to the front buffer.  If there's no back buffer
 * this is a no-op.
 */
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
   GET_CURRENT_CONTEXT(ctx);

   if (!b->backxrb) {
      /* single buffered */
      return;
   }

   /* If we're swapping the buffer associated with the current context
    * we have to flush any pending rendering commands first.
    */
   if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
      _mesa_notifySwapBuffers(ctx);

   if (b->db_mode) {
      if (b->backxrb->ximage) {
	 /* Copy Ximage (back buf) from client memory to server window */
#if defined(USE_XSHM) 
	 if (b->shm) {
            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
	    XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
			  b->swapgc,
			  b->backxrb->ximage, 0, 0,
			  0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
                          False );
            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
	 }
	 else
#endif
         {
            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
            XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
			   b->swapgc,
			   b->backxrb->ximage, 0, 0,
			   0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height );
            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
         }
      }
      else if (b->backxrb->pixmap) {
	 /* Copy pixmap (back buf) to window (front buf) on server */
         /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
	 XMesaCopyArea( b->xm_visual->display,
			b->backxrb->pixmap,   /* source drawable */
			b->frontxrb->drawable,  /* dest. drawable */
			b->swapgc,
			0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
			0, 0                 /* dest region */
		      );
         /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
      }
   }
   XSync( b->xm_visual->display, False );
}
Exemplo n.º 9
0
void
MesaSoftwareRenderer::SwapBuffers(bool VSync)
{
	CALLED();

	if (!fBitmap)
		return;

	if (fVisual->doubleBufferMode)
		_mesa_notifySwapBuffers(fContext);

	if (!fDirectModeEnabled || fInfo == NULL) {
		if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
			GLView()->DrawBitmap(fBitmap, B_ORIGIN);
			GLView()->UnlockLooper();
		}
		return;
	}

	BAutolock lock(fInfoLocker);

	// check the bitmap size still matches the size
	if (fInfo->window_bounds.bottom - fInfo->window_bounds.top
		!= fBitmap->Bounds().IntegerHeight()
		|| fInfo->window_bounds.right - fInfo->window_bounds.left
			!= fBitmap->Bounds().IntegerWidth())
		return;
	uint8 bytesPerPixel = fInfo->bits_per_pixel / 8;
	uint32 bytesPerRow = fBitmap->BytesPerRow();
	for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
		clipping_rect *clip = &fInfo->clip_list[i];
		int32 height = clip->bottom - clip->top + 1;
		int32 bytesWidth
			= (clip->right - clip->left + 1) * bytesPerPixel;
		uint8 *p = (uint8 *)fInfo->bits + clip->top
			* fInfo->bytes_per_row + clip->left * bytesPerPixel;
		uint8 *b = (uint8 *)fBitmap->Bits()
			+ (clip->top - fInfo->window_bounds.top) * bytesPerRow
			+ (clip->left - fInfo->window_bounds.left)
				* bytesPerPixel;

		for (int y = 0; y < height; y++) {
			memcpy(p, b, bytesWidth);
			p += fInfo->bytes_per_row;
			b += bytesPerRow;
		}
	}

	if (VSync) {
		BScreen screen(GLView()->Window());
		screen.WaitForRetrace();
	}
}
Exemplo n.º 10
0
Arquivo: xm_api.c Projeto: RAOF/mesa
/*
 * Copy sub-region of back buffer to front buffer
 */
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
{
   GET_CURRENT_CONTEXT(ctx);

   /* If we're swapping the buffer associated with the current context
    * we have to flush any pending rendering commands first.
    */
   if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
      _mesa_notifySwapBuffers(ctx);

   if (!b->backxrb) {
      /* single buffered */
      return; 
   }

   if (b->db_mode) {
      int yTop = b->mesa_buffer.Height - y - height;
      if (b->backxrb->ximage) {
         /* Copy Ximage from host's memory to server's window */
#if defined(USE_XSHM) 
         if (b->shm) {
            /* XXX assuming width and height aren't too large! */
            XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
                          b->swapgc,
                          b->backxrb->ximage, x, yTop,
                          x, yTop, width, height, False );
            /* wait for finished event??? */
         }
         else
#endif
         {
            /* XXX assuming width and height aren't too large! */
            XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
			   b->swapgc,
			   b->backxrb->ximage, x, yTop,
			   x, yTop, width, height );
         }
      }
      else {
         /* Copy pixmap to window on server */
         XMesaCopyArea( b->xm_visual->display,
			b->backxrb->pixmap,           /* source drawable */
			b->frontxrb->drawable,        /* dest. drawable */
			b->swapgc,
			x, yTop, width, height,  /* source region */
			x, yTop                  /* dest region */
                      );
      }
   }
}
Exemplo n.º 11
0
/* If the backbuffer is on a videocard, this is extraordinarily slow!
 */
static EGLBoolean
fbSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
   fbContext *context = (fbContext *)_eglGetCurrentContext();
   fbSurface *fs =  Lookup_fbSurface(draw);
   struct gl_renderbuffer * front_renderbuffer = fs->mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
   void *frontBuffer = front_renderbuffer->Data;
   int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
   void *backBuffer = fs->mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;

   if (!_eglSwapBuffers(drv, dpy, draw))
      return EGL_FALSE;

   if (context) {
      GLcontext *ctx = context->glCtx;
      
      if (ctx->Visual.doubleBufferMode) {
	 int i;
	 int offset = 0;
         char *tmp = _mesa_malloc(currentPitch);

         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */

         ASSERT(frontBuffer);
         ASSERT(backBuffer);

	 for (i = 0; i < fs->Base.Height; i++) {
            _mesa_memcpy(tmp, (char *) backBuffer + offset,
                         currentPitch);
            _mesa_memcpy((char *) frontBuffer + offset, tmp,
                          currentPitch);
            offset += currentPitch;
	 }
	    
	 _mesa_free(tmp);
      }
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
      return EGL_FALSE;
   }
   return EGL_TRUE;
}
Exemplo n.º 12
0
/* If the backbuffer is on a videocard, this is extraordinarily slow!
 */
static void
fbSwapBuffers( __DRIdrawablePrivate *dPriv )
{
   struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate;
   struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
   void *frontBuffer = front_renderbuffer->Data;
   int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
   void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;

   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
      fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate;
      GLcontext *ctx = fbmesa->glCtx;
      
      if (ctx->Visual.doubleBufferMode) {
	 int i;
	 int offset = 0;
         char *tmp = _mesa_malloc(currentPitch);

         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering commands */

         ASSERT(frontBuffer);
         ASSERT(backBuffer);

	 for (i = 0; i < dPriv->h; i++) {
            _mesa_memcpy(tmp, (char *) backBuffer + offset,
                         currentPitch);
            _mesa_memcpy((char *) frontBuffer + offset, tmp,
                          currentPitch);
            offset += currentPitch;
	 }
	    
	 _mesa_free(tmp);
      }
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
   }
}
Exemplo n.º 13
0
void
glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
{
   GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
   struct GLFBDevRenderbufferRec *frontrb = (struct GLFBDevRenderbufferRec *)
      buffer->glframebuffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
   struct GLFBDevRenderbufferRec *backrb = (struct GLFBDevRenderbufferRec *)
      buffer->glframebuffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer;

   if (!buffer || !buffer->visual->glvisual.doubleBufferMode)
      return;

   /* check if swapping currently bound buffer */
   if (fbdevctx->drawBuffer == buffer) {
      /* flush pending rendering */
      _mesa_notifySwapBuffers(&fbdevctx->glcontext);
   }

   ASSERT(frontrb->Base.Data);
   ASSERT(backrb->Base.Data);
   memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
}
Exemplo n.º 14
0
/*
 * Swap front/back buffers for current context if double buffered.
 */
void ggiMesaSwapBuffers(void)
{
	GLcontext *ctx;
	ggi_mesa_context_t ggi_ctx;
	ctx = _mesa_get_current_context();
	ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
	
	GGIMESADPRINT_CORE("ggiMesaSwapBuffers() called\n");	
	
	_mesa_notifySwapBuffers(ctx);
	gl_ggiFlush(ctx);

	ggiSetDisplayFrame(ggi_ctx->ggi_visual,
			   !ggiGetDisplayFrame(ggi_ctx->ggi_visual));
	ggiSetWriteFrame(ggi_ctx->ggi_visual,
			 !ggiGetWriteFrame(ggi_ctx->ggi_visual));
	ggiSetReadFrame(ggi_ctx->ggi_visual,
			 !ggiGetReadFrame(ggi_ctx->ggi_visual));

	GGIMESADPRINT_CORE("swap disp: %d, write %d\n",
			   ggiGetDisplayFrame(ggi_ctx->ggi_visual),
			   ggiGetWriteFrame(ggi_ctx->ggi_visual));
}
Exemplo n.º 15
0
static void
dri_swap_buffers(__DRIdrawable * dPriv)
{
    __DRIscreen *sPriv = dPriv->driScreenPriv;

    GET_CURRENT_CONTEXT(ctx);

    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct gl_framebuffer *fb;
    struct swrast_renderbuffer *frontrb, *backrb;

    TRACE;

    fb = &drawable->Base;

    frontrb =
	swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
    backrb =
	swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);

    /* check for signle-buffered */
    if (backrb == NULL)
	return;

    /* check if swapping currently bound buffer */
    if (ctx && ctx->DrawBuffer == fb) {
	/* flush pending rendering */
	_mesa_notifySwapBuffers(ctx);
    }

    sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
				   0, 0,
				   frontrb->Base.Width,
				   frontrb->Base.Height,
				   backrb->Base.Data,
				   dPriv->loaderPrivate);
}
Exemplo n.º 16
0
/*
 * Correct a drawablePrivate's set of vblank flags WRT the current context.
 * When considering multiple crtcs.
 */
GLuint
intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv)
{
   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
      volatile drm_i915_sarea_t *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;

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

      /* Do the stupid test: Is one of them actually disabled?
       */
      if (sarea->planeA_w == 0 || sarea->planeA_h == 0) {
	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
      } else if (sarea->planeB_w == 0 || sarea->planeB_h == 0) {
	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
      }

      return flags;
   } else {
      return dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
   }
}


/**
 * Called from driSwapBuffers()
 */
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 */

	/*
	 * The old swapping ioctl was incredibly racy, just wait for vblank
	 * and do the swap ourselves.
	 */
	 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 = dPriv->vblSeq;
         intel_get_renderbuffer(&intel_fb->Base,
		   		BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq;

	 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;
      }
      drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE);
   }
   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__);
   }
}


/**
 * Called from driCopySubBuffer()
 */
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__);
   }
}


/**
 * 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->intelScreen->driScrnPriv->dri2.enabled &&
       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
      GLuint flags = intelFixupVblank(intel, dPriv);

      /* 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 < 2; 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 < 2; 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 );
}