示例#1
0
void
xglAddCurrentSurfaceDamage (DrawablePtr pDrawable)
{
    XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

    if (BOX_NOTEMPTY (&pPixmapPriv->damageBox))
    {
	RegionRec region;

	REGION_INIT (pDrawable->pScreen, &region, &pPixmapPriv->damageBox, 1);

	if (pPixmapPriv->pDamage)
	{
	    RegionPtr pDamageRegion;

	    pDamageRegion = DamageRegion (pPixmapPriv->pDamage);

	    REGION_UNION (pDrawable->pScreen,
			  pDamageRegion, pDamageRegion,
			  &region);
	}

	REGION_UNION (pDrawable->pScreen,
		      &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion,
		      &region);

	REGION_UNINIT (pDrawable->pScreen, &region);

	pPixmapPriv->damageBox = miEmptyBox;
    }
}
示例#2
0
void
xglAddSurfaceDamage (DrawablePtr pDrawable,
		     RegionPtr   pRegion)
{
    glitz_surface_t *surface;
    int		    xOff, yOff;

    XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

    pPixmapPriv->damageBox = miEmptyBox;

    XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);

    if (xOff || yOff)
	REGION_TRANSLATE (pDrawable->pScreen, pRegion, xOff, yOff);

    if (pPixmapPriv->pDamage)
    {
	RegionPtr pDamageRegion;

	pDamageRegion = DamageRegion (pPixmapPriv->pDamage);

	REGION_UNION (pDrawable->pScreen,
		      pDamageRegion, pDamageRegion,
		      pRegion);
    }

    REGION_UNION (pDrawable->pScreen,
		  &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion,
		  pRegion);

    if (xOff || yOff)
	REGION_TRANSLATE (pDrawable->pScreen, pRegion, -xOff, -yOff);
}
示例#3
0
/**
 * Append given rectangle to the client's list of dirty regions.
 */
void fn_client_add_rect(AIO_SLOT *slot, FB_RECT *rect)
{
  CL_SLOT *cl = (CL_SLOT *)slot;
  RegionRec add_region;
  BoxRec add_rect;
  int stored;
  int dx, dy;

  if (!cl->connected || cl->newfbsize_pending)
    return;

  /* If the framebuffer geometry has been changed, then we don't care
     about pending pixel updates any more, because all clients will
     want to update the whole framebuffer. */

  if (g_screen_info.width != cl->fb_width ||
      g_screen_info.height != cl->fb_height) {
    cl->newfbsize_pending = 1;
    REGION_EMPTY(&cl->pending_region);
    REGION_EMPTY(&cl->copy_region);
    return;
  }

  add_rect.x1 = rect->x;
  add_rect.y1 = rect->y;
  add_rect.x2 = add_rect.x1 + rect->w;
  add_rect.y2 = add_rect.y1 + rect->h;
  REGION_INIT(&add_region, &add_rect, 4);

  /* FIXME: Currently, CopyRect is stored in copy_region only if there
     were no other non-CopyRect updates pending for this client.
     Normally, that's ok, because VNC servers send CopyRect rectangles
     before non-CopyRect ones, but of course more elegant and
     efficient handling could be possible to implement here. */
  stored = 0;
  if (rect->enc == RFB_ENCODING_COPYRECT &&
      cl->enc_enable[RFB_ENCODING_COPYRECT] &&
      !REGION_NOTEMPTY(&cl->pending_region)) {
    dx = rect->x - rect->src_x;
    dy = rect->y - rect->src_y;
    if (!REGION_NOTEMPTY(&cl->copy_region) ||
        (dx == cl->copy_dx && dy == cl->copy_dy)) {
      REGION_UNION(&cl->copy_region, &cl->copy_region, &add_region);
      cl->copy_dx = dx;
      cl->copy_dy = dy;
      stored = 1;
    }
  }
  if (!stored)
    REGION_UNION(&cl->pending_region, &cl->pending_region, &add_region);

  REGION_UNINIT(&add_region);
}
示例#4
0
文件: vncspu.c 项目: alown/chromium
/**
 * Union the window's accum-dirty and prev-accum-dirty regions with the
 * incoming region.
 * Called by crHashtableWalk() via vncspuGetScreenRects().
 */
static void
WindowDirtyUnionCB(unsigned long key, void *windowData, void *regionData)
{
	WindowInfo *window = (WindowInfo *) windowData;
	RegionPtr regionUnion = (RegionPtr) regionData;
	RegionRec accumScrn; /* accumulated region, in screen coords */
	Bool overlap;

	miRegionInit(&accumScrn, NULL, 0); /* init local var */

	CRASSERT(miValidRegion(&window->accumDirtyRegion));
	CRASSERT(miValidRegion(&window->prevAccumDirtyRegion));

	/*
	crDebug("accum area: %d   prev accum: %d",
					miRegionArea(&window->accumDirtyRegion),
					miRegionArea(&window->prevAccumDirtyRegion));
	*/

	/* at first, accumScrn region is in window coords */
	REGION_UNION(&accumScrn,
							 &window->accumDirtyRegion,
							 &window->prevAccumDirtyRegion);

	/* intersect with window bounds */
	REGION_INTERSECT(&accumScrn,
									 &accumScrn,
									 &window->clipRegion);

	REGION_VALIDATE(&accumScrn, &overlap);

	/* change y=0=bottom to y=0=top */
	InvertRegion(&accumScrn, window->height ? window->height : 1);

	if (REGION_NUM_RECTS(&accumScrn) == 1 &&
			accumScrn.extents.x1 == 0 &&
			accumScrn.extents.y1 == 0 &&
			accumScrn.extents.x2 == 1 &&
			accumScrn.extents.y2 == 1) {
		/* empty / sentinal region */
	}
	else {
		/* add window offset */
		miTranslateRegion(&accumScrn, window->xPos, window->yPos);
	}

	/* now, accumScrn region is in screen coords */

	REGION_UNION(regionUnion, regionUnion, &accumScrn);

	REGION_UNINIT(&accumScrn); /* done with local var */
}
示例#5
0
文件: vncspu.c 项目: alown/chromium
/**
 * Vertically invert a region.
 */
static void
InvertRegion(RegionPtr reg, int height)
{
	const BoxPtr b = REGION_RECTS(reg);
	const int n = REGION_NUM_RECTS(reg);
	int i;
	RegionRec newRegion;

	miRegionInit(&newRegion, NULL, 0);

	CRASSERT(miValidRegion(reg));

	for (i = 0; i < n; i++) {
		BoxRec invBox;
		RegionRec invReg;
		invBox.x1 = b[i].x1;
		invBox.y1 = height - b[i].y2;
		invBox.x2 = b[i].x2;
		invBox.y2 = height - b[i].y1;

		CRASSERT(invBox.y1 <= invBox.y2);

		miRegionInit(&invReg, &invBox, 1);
		REGION_UNION(&newRegion, &newRegion, &invReg);
		REGION_UNINIT(&invReg);
	}

	CRASSERT(miValidRegion(&newRegion));

	REGION_COPY(reg, &newRegion);
	REGION_UNINIT(&newRegion);
}
示例#6
0
/**
 * Copies out important pixmap data and removes references to framebuffer area.
 * Called when the memory manager decides it's time to kick the pixmap out of
 * framebuffer entirely.
 */
void
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
{
    PixmapPtr pPixmap = area->privData;
    ExaPixmapPriv(pPixmap);
    RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage);

    DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
		  (void*)(ExaGetPixmapPriv(pPixmap)->area ?
                          ExaGetPixmapPriv(pPixmap)->area->offset : 0),
		  pPixmap->drawable.width,
		  pPixmap->drawable.height,
		  exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));

    if (exaPixmapIsOffscreen(pPixmap)) {
	exaCopyDirtyToSys (pPixmap);
	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
	pPixmap->devKind = pExaPixmap->sys_pitch;
	pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
    }

    pExaPixmap->fb_ptr = NULL;
    pExaPixmap->area = NULL;

    /* Mark all valid bits as damaged, so they'll get copied to FB next time */
    REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg,
		 &pExaPixmap->validReg);
}
示例#7
0
int
ProcXFixesCombineRegion (ClientPtr client)
{
    RegionPtr	pSource1, pSource2, pDestination;
    int		ret = Success;
    REQUEST (xXFixesCombineRegionReq);

    REQUEST_SIZE_MATCH (xXFixesCombineRegionReq);
    VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess);
    VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess);
    VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
    
    switch (stuff->xfixesReqType) {
    case X_XFixesUnionRegion:
	if (!REGION_UNION (0, pDestination, pSource1, pSource2))
	    ret = BadAlloc;
	break;
    case X_XFixesIntersectRegion:
	if (!REGION_INTERSECT (0, pDestination, pSource1, pSource2))
	    ret = BadAlloc;
	break;
    case X_XFixesSubtractRegion:
	if (!REGION_SUBTRACT (0, pDestination, pSource1, pSource2))
	    ret = BadAlloc;
	break;
    }
    
    if (ret == Success) 
	ret = client->noClientException;
    return ret;
}
示例#8
0
static void
ExaSrcValidate(DrawablePtr pDrawable,
	       int x,
	       int y,
	       int width,
	       int height)
{
    ScreenPtr pScreen = pDrawable->pScreen;
    ExaScreenPriv(pScreen);
    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
    BoxRec box;
    RegionRec reg;
    RegionPtr dst;
    int xoff, yoff;

    exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);

    box.x1 = x + xoff;
    box.y1 = y + yoff;
    box.x2 = box.x1 + width;
    box.y2 = box.y1 + height;

    dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
	&pExaScr->maskReg;

    REGION_INIT(pScreen, &reg, &box, 1);
    REGION_UNION(pScreen, dst, dst, &reg);
    REGION_UNINIT(pScreen, &reg);

    if (pExaScr->SavedSourceValidate) {
        swap(pExaScr, pScreen, SourceValidate);
        pScreen->SourceValidate(pDrawable, x, y, width, height);
        swap(pExaScr, pScreen, SourceValidate);
    }
}
示例#9
0
文件: xf86fbman.c 项目: aosm/X11
static void
localFreeOffscreenArea(FBAreaPtr area)
{
   FBManagerPtr offman;
   FBLinkPtr pLink, pLinkPrev = NULL;
   RegionRec FreedRegion;
   ScreenPtr pScreen;

   pScreen = area->pScreen;
   offman = pScreen->devPrivates[xf86FBScreenIndex].ptr;
       
   pLink = offman->UsedAreas;
   if(!pLink) return;  
 
   while(&(pLink->area) != area) {
	pLinkPrev = pLink;
	pLink = pLink->next;
	if(!pLink) return;
   }

   /* put the area back into the pool */
   REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1); 
   REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedRegion);
   REGION_UNINIT(pScreen, &FreedRegion); 

   if(pLinkPrev)
	pLinkPrev->next = pLink->next;
   else offman->UsedAreas = pLink->next;

   xfree(pLink); 
   offman->NumUsedAreas--;

   SendCallFreeBoxCallbacks(offman);
}
示例#10
0
/**
 * exaPixmapDirty() marks a pixmap as dirty, allowing for
 * optimizations in pixmap migration when no changes have occurred.
 */
void
exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
{
    ExaPixmapPriv(pPix);
    BoxRec box;
    RegionPtr pDamageReg;
    RegionRec region;

    if (!pExaPixmap)
	return;
	
    box.x1 = max(x1, 0);
    box.y1 = max(y1, 0);
    box.x2 = min(x2, pPix->drawable.width);
    box.y2 = min(y2, pPix->drawable.height);

    if (box.x1 >= box.x2 || box.y1 >= box.y2)
	return;

    pDamageReg = DamageRegion(pExaPixmap->pDamage);

    REGION_INIT(pScreen, &region, &box, 1);
    REGION_UNION(pScreen, pDamageReg, pDamageReg, &region);
    REGION_UNINIT(pScreen, &region);
}
示例#11
0
/**
 * If the pixmap is currently dirty, this copies at least the dirty area from
 * the system memory copy to the framebuffer memory copy.  Both areas must be
 * allocated.
 */
static void
exaCopyDirtyToFb (PixmapPtr pPixmap)
{
    ExaScreenPriv (pPixmap->drawable.pScreen);
    ExaPixmapPriv (pPixmap);
    RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
    CARD8 *save_ptr;
    int save_pitch;
    BoxPtr pBox = REGION_RECTS(pRegion);
    int nbox = REGION_NUM_RECTS(pRegion);
    Bool do_sync = FALSE;

    save_ptr = pPixmap->devPrivate.ptr;
    save_pitch = pPixmap->devKind;
    pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    pPixmap->devKind = pExaPixmap->fb_pitch;

    while (nbox--) {
	pBox->x1 = max(pBox->x1, 0);
	pBox->y1 = max(pBox->y1, 0);
	pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
	pBox->y2 = min(pBox->y2, pPixmap->drawable.height);

	if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
	    continue;

	if (pExaScr->info->UploadToScreen == NULL ||
	    !pExaScr->info->UploadToScreen (pPixmap,
					    pBox->x1, pBox->y1,
					    pBox->x2 - pBox->x1,
					    pBox->y2 - pBox->y1,
					    pExaPixmap->sys_ptr
					    + pBox->y1 * pExaPixmap->sys_pitch
					    + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
					    pExaPixmap->sys_pitch))
	{
	    exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
	    exaMemcpyBox (pPixmap, pBox,
			  pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
			  pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
	    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
	}
	else
	    do_sync = TRUE;

	pBox++;
    }

    if (do_sync)
	exaMarkSync (pPixmap->drawable.pScreen);

    pPixmap->devPrivate.ptr = save_ptr;
    pPixmap->devKind = save_pitch;

    /* The previously damaged bits are now no longer damaged but valid */
    REGION_UNION(pPixmap->drawable.pScreen,
		 &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
    DamageEmpty (pExaPixmap->pDamage);
}
示例#12
0
static void
shadowReportFunc(DamagePtr pDamage, RegionPtr pRegion, void *closure)
{
    ScreenPtr pScreen = closure;
    shadowBufPtr pBuf = pScreen->devPrivates[shadowScrPrivateIndex].ptr;

    /* Register the damaged region, use DamageReportNone below when we
     * want to break BC below... */
    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage, pRegion);

    /*
     * BC hack.  In 7.0 and earlier several drivers would inspect the
     * 'damage' member directly, so we have to keep it existing.
     */
    REGION_COPY(pScreen, &pBuf->damage, pRegion);
}
示例#13
0
文件: miwindow.c 项目: L3oV1nc3/VMGL
void
miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
{
    ScreenPtr pScreen;
    WindowPtr pChild;

    pScreen = pWin->drawable.pScreen;

    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
    {
	if (pChild->drawable.depth == depth)
	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);

	if (pChild->firstChild)
	    miSegregateChildren(pChild, pReg, depth);
    }
}
示例#14
0
int
ProcXFixesExpandRegion (ClientPtr client)
{
    RegionPtr	pSource, pDestination;
    int		ret = Success;
    REQUEST (xXFixesExpandRegionReq);
    BoxPtr	pTmp;
    BoxPtr	pSrc;
    int		nBoxes;
    int		i;

    REQUEST_SIZE_MATCH (xXFixesExpandRegionReq);
    VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
    VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
    
    nBoxes = REGION_NUM_RECTS(pSource);
    pSrc = REGION_RECTS(pSource);
    if (nBoxes)
    {
	pTmp = xalloc (nBoxes * sizeof (BoxRec));
	if (!pTmp)
	    return BadAlloc;
	for (i = 0; i < nBoxes; i++)
	{
	    pTmp[i].x1 = pSrc[i].x1 - stuff->left;
	    pTmp[i].x2 = pSrc[i].x2 + stuff->right;
	    pTmp[i].y1 = pSrc[i].y1 - stuff->top;
	    pTmp[i].y2 = pSrc[i].y2 + stuff->bottom;
	}
	REGION_EMPTY (pScreen, pDestination);
	for (i = 0; i < nBoxes; i++)
	{
	    RegionRec	r;
	    REGION_INIT (pScreen, &r, &pTmp[i], 0);
	    REGION_UNION (pScreen, pDestination, pDestination, &r);
	}
	xfree(pTmp);
    }
    if (ret == Success) 
	ret = client->noClientException;
    return ret;
}
示例#15
0
static void
SegregateChildrenBpp(WindowPtr pWin, RegionPtr pReg, int subtract, int bpp, int other_bpp)
{
	WindowPtr pChild;

	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
		if (pChild->drawable.bitsPerPixel == bpp) {
			if (subtract) {
				REGION_SUBTRACT(pWin->drawable.pScreen, pReg,
						pReg, &pChild->borderClip);
			} else {
				REGION_UNION(pWin->drawable.pScreen, pReg,
					     pReg, &pChild->borderClip);
			}
			if (pChild->firstChild)
				SegregateChildrenBpp(pChild, pReg,
						     !subtract, other_bpp, bpp);
		} else {
			if (pChild->firstChild)
				SegregateChildrenBpp(pChild, pReg,
						     subtract, bpp, other_bpp);
		}
	}
}
示例#16
0
static void rf_client_encodings_data(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  int i;
  int preferred_enc_set = 0;
  CARD32 enc;

  /* Reset encoding list (always enable raw encoding) */
  cl->enc_enable[RFB_ENCODING_RAW] = 1;
  cl->enc_prefer = RFB_ENCODING_RAW;
  cl->compress_level = -1;
  cl->jpeg_quality = -1;
  cl->enable_lastrect = 0;
  cl->enable_newfbsize = 0;
  cl->enable_cliprects_enc = 0;
  cl->enable_frame_sync = 0;
  for (i = 1; i < NUM_ENCODINGS; i++)
    cl->enc_enable[i] = 0;

  /* Read and store encoding list supplied by the client */
  for (i = 0; i < (int)cl->temp_count; i++) {
    enc = buf_get_CARD32(&cur_slot->readbuf[i * sizeof(CARD32)]);
    if (!preferred_enc_set) {
      if ( enc == RFB_ENCODING_RAW ||
           enc == RFB_ENCODING_HEXTILE ||
           enc == RFB_ENCODING_RAW24 ||
           enc == RFB_ENCODING_TIGHT ) {
        cl->enc_prefer = enc;
        preferred_enc_set = 1;
      }
    }
    if (enc >= 0 && enc < NUM_ENCODINGS) {
      cl->enc_enable[enc] = 1;
    } else if (enc >= RFB_ENCODING_COMPESSLEVEL0 &&
               enc <= RFB_ENCODING_COMPESSLEVEL9 &&
               cl->compress_level == -1) {
      cl->compress_level = (int)(enc - RFB_ENCODING_COMPESSLEVEL0);
      log_write(LL_DETAIL, "Compression level %d requested by client %s",
                cl->compress_level, cur_slot->name);
    } else if (enc >= RFB_ENCODING_QUALITYLEVEL0 &&
               enc <= RFB_ENCODING_QUALITYLEVEL9 &&
               cl->jpeg_quality == -1) {
      cl->jpeg_quality = (int)(enc - RFB_ENCODING_QUALITYLEVEL0);
      log_write(LL_DETAIL, "JPEG quality level %d requested by client %s",
                cl->jpeg_quality, cur_slot->name);
    } else if (enc == RFB_ENCODING_LASTRECT) {
      log_write(LL_DETAIL, "Client %s supports LastRect markers",
                cur_slot->name);
      cl->enable_lastrect = 1;
    } else if (enc == RFB_ENCODING_NEWFBSIZE) {
      cl->enable_newfbsize = 1;
      log_write(LL_DETAIL, "Client %s supports desktop geometry changes",
                cur_slot->name);
    } else if (enc == RFB_ENCODING_CLIPRECTS) {
      cl->enable_cliprects_enc = 1;
      log_write(LL_DETAIL, "Client %s supports cliprects",
                cur_slot->name);
    } else if (enc == RFB_ENCODING_HALF_REZ) {
      vnc_spu.half_rez = 1;
      log_write(LL_DETAIL, "Client %s supports half rez",
                cur_slot->name);
    } else if (enc == RFB_ENCODING_FRAME_SYNC) {
      cl->enable_frame_sync = 1;
      vnc_spu.frame_drop = 0; /* can't drop frames if trying to sync! */
      crDebug("Frame sync requested by client, disabling frame_drop");
      log_write(LL_DETAIL, "Client %s supports frame sync encoding",
                cur_slot->name);
    }
  }

  if (cl->compress_level < 0)
    cl->compress_level = 6;     /* default compression level */

  /* CopyRect was pending but the client does not want it any more. */
  if (!cl->enc_enable[RFB_ENCODING_COPYRECT] &&
      REGION_NOTEMPTY(&cl->copy_region)) {
    REGION_UNION(&cl->pending_region, &cl->pending_region, &cl->copy_region);
    REGION_EMPTY(&cl->copy_region);
  }

  crDebug("In rf_client_encodings_data(), cl->enc_prefer=0x%x pixel_size=%d",
          cl->enc_prefer, vnc_spu.pixel_size);

  if (cl->enc_prefer == RFB_ENCODING_RAW24) {
    if (vnc_spu.pixel_size == 0 || vnc_spu.pixel_size == 24) {
      /* not set, or already 24bpp */
      vnc_spu.pixel_size = 24;
      log_write(LL_DETAIL, "Using Raw24 encoding for client %s",
                cur_slot->name);
    }
    else if (vnc_spu.pixel_size == 32) {
      /* revert to regular 32bpp raw */
      cl->enc_prefer = RFB_ENCODING_RAW;
      log_write(LL_DETAIL, "Using Raw (32) encoding for client %s",
                cur_slot->name);
    }
  }
  else {
    vnc_spu.pixel_size = 32;
  }

  if (cl->enc_prefer == RFB_ENCODING_TIGHT)
     if (cl->jpeg_quality < 0)
        cl->jpeg_quality = 6;  /* default quality */

  log_write(LL_DETAIL, "Using encoding %s (0x%x)",
            encoding_string(cl->enc_prefer), cl->enc_prefer);
  crDebug("VNC SPU: Using %s encoding (0x%x) for new client",
          encoding_string(cl->enc_prefer), cl->enc_prefer);
  if (cl->enc_prefer == RFB_ENCODING_TIGHT) {
    crDebug("VNC SPU: Tight jpeg quality level %d, compression level %d",
            cl->jpeg_quality, cl->compress_level);
    crDebug("VNC SPU: Force JPEG encoding: %d", opt_force_tight_jpeg);
  }
  crDebug("VNC SPU: pixel_size = %d", vnc_spu.pixel_size);

  aio_setread(rf_client_msg, NULL, 1);
}
示例#17
0
文件: xf86fbman.c 项目: aosm/X11
static Bool
localResizeOffscreenArea(
   FBAreaPtr resize,
   int w, int h
){
   FBManagerPtr offman;
   ScreenPtr pScreen;
   BoxRec OrigArea;
   RegionRec FreedReg;
   FBAreaPtr area = NULL;
   FBLinkPtr pLink, newLink, pLinkPrev = NULL;

   pScreen = resize->pScreen;
   offman = pScreen->devPrivates[xf86FBScreenIndex].ptr;

   /* find this link */
   if(!(pLink = offman->UsedAreas))
	return FALSE;  
 
   while(&(pLink->area) != resize) {
	pLinkPrev = pLink;
	pLink = pLink->next;
	if(!pLink) return FALSE;
   }

   OrigArea.x1 = resize->box.x1;
   OrigArea.x2 = resize->box.x2;
   OrigArea.y1 = resize->box.y1;
   OrigArea.y2 = resize->box.y2;

   /* if it's smaller, this is easy */

   if((w <= (resize->box.x2 - resize->box.x1)) && 
      (h <= (resize->box.y2 - resize->box.y1))) {
	RegionRec NewReg;

	resize->box.x2 = resize->box.x1 + w;
	resize->box.y2 = resize->box.y1 + h;

        if((resize->box.y2 == OrigArea.y2) &&
	   (resize->box.x2 == OrigArea.x2))
		return TRUE;

	REGION_INIT(pScreen, &FreedReg, &OrigArea, 1); 
	REGION_INIT(pScreen, &NewReg, &(resize->box), 1); 
	REGION_SUBTRACT(pScreen, &FreedReg, &FreedReg, &NewReg);
	REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
	REGION_UNINIT(pScreen, &FreedReg); 
	REGION_UNINIT(pScreen, &NewReg); 

	SendCallFreeBoxCallbacks(offman);

	return TRUE;
   }


   /* otherwise we remove the old region */

   REGION_INIT(pScreen, &FreedReg, &OrigArea, 1); 
   REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
  
   /* remove the old link */
   if(pLinkPrev)
	pLinkPrev->next = pLink->next;
   else offman->UsedAreas = pLink->next;

   /* and try to add a new one */

   if((area = AllocateArea(offman, w, h, resize->granularity,
		resize->MoveAreaCallback, resize->RemoveAreaCallback,
		resize->devPrivate.ptr))) {

        /* copy data over to our link and replace the new with old */
	memcpy(resize, area, sizeof(FBArea));

        pLinkPrev = NULL;
 	newLink = offman->UsedAreas;

        while(&(newLink->area) != area) {
	    pLinkPrev = newLink;
	    newLink = newLink->next;
        }

	if(pLinkPrev)
	    pLinkPrev->next = newLink->next;
	else offman->UsedAreas = newLink->next;

        pLink->next = offman->UsedAreas;
        offman->UsedAreas = pLink;

	xfree(newLink);

	/* AllocateArea added one but we really only exchanged one */
	offman->NumUsedAreas--;  
   } else {
      /* reinstate the old region */
      REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
      REGION_UNINIT(pScreen, &FreedReg); 

      pLink->next = offman->UsedAreas;
      offman->UsedAreas = pLink;
      return FALSE;
   }


   REGION_UNINIT(pScreen, &FreedReg); 

   SendCallFreeBoxCallbacks(offman);

   return TRUE;
}
示例#18
0
static void send_update(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  BoxRec fb_rect;
  RegionRec fb_region, clip_region, outer_region;
  CARD8 msg_hdr[4] = {
    0, 0, 0, 1
  };
  CARD8 rect_hdr[12];
  int num_copy_rects, num_pending_rects, num_all_rects;
  int raw_bytes = 0, hextile_bytes = 0;
  int i, idx, rev_order;
  static int counter = 0;

#ifdef NETLOGGER
  aio_set_serial_number(&cl->s, cl->serial_number);
#endif

  counter++;
  vncspuLog(1, "Begin send update %d", counter);

  CRASSERT(vnc_spu.serverBuffer);

  /*crDebug("Enter send_update to %s", cur_slot->name);*/

  /* check if clipping has changed since we got the pixels and update
   * the pending region if needed.
   */
  if (NewClip) {
     /*crDebug("Getting updated cliprects");*/
     vncspuGetScreenRects(&cl->pending_region);
     num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
     /*crDebug("Now, %d rects", num_pending_rects);*/
     if (num_pending_rects == 0 && cl->enable_frame_sync) {
        /* always need to send _something_ for framesync to work */
        BoxRec b;
        b.x1 = 0;
        b.y1 = 0;
        b.x2 = 1;
        b.y2 = 1;
        REGION_UNINIT(&cl->pending_region);
        REGION_INIT(&cl->pending_region, &b, 1);
     }
     NewClip = 0;
  }
  /*PrintRegion("Sending", &cl->pending_region);*/


  /* Process framebuffer size change. */
  if (cl->newfbsize_pending) {
    /* Update framebuffer size, clear newfbsize_pending flag. */
    cl->fb_width = g_screen_info.width;
    cl->fb_height = g_screen_info.height;
    cl->newfbsize_pending = 0;
    log_write(LL_DEBUG, "Applying new framebuffer size (%dx%d) to %s",
              (int)cl->fb_width, (int)cl->fb_height, cur_slot->name);
    /* In any case, mark all the framebuffer contents as changed. */
    fb_rect.x1 = 0;
    fb_rect.y1 = 0;
    fb_rect.x2 = cl->fb_width;
    fb_rect.y2 = cl->fb_height;
    REGION_INIT(&fb_region, &fb_rect, 1);
    REGION_COPY(&cl->pending_region, &fb_region);
    REGION_UNINIT(&fb_region);
    REGION_EMPTY(&cl->copy_region);
    /* If NewFBSize is supported by the client, send only NewFBSize
       pseudo-rectangle, pixel data will be sent in the next update. */
    if (cl->enable_newfbsize) {
      send_newfbsize();
      vncspuUnlockFrameBuffer();
      return;
    }
  } else {
    /* Exclude CopyRect areas covered by pending_region. */
    REGION_SUBTRACT(&cl->copy_region, &cl->copy_region, &cl->pending_region);
  }

#if 00
  if (cl->enable_cliprects_enc && cl->new_cliprects) {
    send_new_cliprects();
    vncspuUnlockFrameBuffer();
    cl->new_cliprects = 0;
    return;
  }
#endif

  /* Clip regions to the rectangle requested by the client. */
  REGION_INIT(&clip_region, &cl->update_rect, 1);

  REGION_INTERSECT(&cl->pending_region, &cl->pending_region, &clip_region);
  if (REGION_NOTEMPTY(&cl->copy_region)) {
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);

    REGION_INIT(&outer_region, NullBox, 8);
    REGION_COPY(&outer_region, &cl->copy_region);
    REGION_TRANSLATE(&clip_region, cl->copy_dx, cl->copy_dy);
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);
    REGION_SUBTRACT(&outer_region, &outer_region, &cl->copy_region);
    REGION_UNION(&cl->pending_region, &cl->pending_region, &outer_region);
    REGION_UNINIT(&outer_region);
  }
  REGION_UNINIT(&clip_region);

  /* Reduce the number of rectangles if possible. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    region_pack(&cl->pending_region, 32);
  } else {
    region_pack(&cl->pending_region, 12);
  }

  /* Compute the number of rectangles in regions. */
  num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
  num_copy_rects = REGION_NUM_RECTS(&cl->copy_region);
  num_all_rects = num_pending_rects + num_copy_rects;
  if (num_all_rects == 0) {
    vncspuUnlockFrameBuffer();
    return;
  }

  log_write(LL_DEBUG, "Sending framebuffer update (min %d rects) to %s",
            num_all_rects, cur_slot->name);

  /* Prepare and send FramebufferUpdate message header. */
  /* FIXME: Enable Tight encoding even if LastRect is not supported. */
  /* FIXME: Do not send LastRect if all the rectangles are CopyRect. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    buf_put_CARD16(&msg_hdr[2], 0xFFFF);
  } else {
    buf_put_CARD16(&msg_hdr[2], num_all_rects);
  }
  aio_write(NULL, msg_hdr, 4);

  /* Determine the order in which CopyRect rectangles should be sent. */
  rev_order = (cl->copy_dy > 0 || (cl->copy_dy == 0 && cl->copy_dx > 0));

  /* For each CopyRect rectangle: */
  for (i = 0; i < num_copy_rects; i++) {
    FB_RECT rect;
    AIO_BLOCK *block;
    idx = (rev_order) ? num_copy_rects - i - 1 : i;
    rect.x = REGION_RECTS(&cl->copy_region)[idx].x1;
    rect.y = REGION_RECTS(&cl->copy_region)[idx].y1;
    rect.w = REGION_RECTS(&cl->copy_region)[idx].x2 - rect.x;
    rect.h = REGION_RECTS(&cl->copy_region)[idx].y2 - rect.y;
    rect.src_x = rect.x - cl->copy_dx;
    rect.src_y = rect.y - cl->copy_dy;
    rect.enc = RFB_ENCODING_COPYRECT;
    log_write(LL_DEBUG, "Sending CopyRect rectangle %dx%d at %d,%d to %s",
              (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
              cur_slot->name);

    /* Prepare the CopyRect rectangle. */
    block = rfb_encode_copyrect_block(cl, &rect);

    /* Send the rectangle.
       FIXME: Check for block == NULL? */
    aio_write_nocopy(NULL, block);
  }

  if (cl->enc_prefer == RFB_ENCODING_TIGHT) {
    /* needed for successful caching of zlib-compressed data (tight) */
    rfb_reset_tight_encoder(cl);
  }

  if (num_pending_rects) {
    /* Lock around fb access so other thread doesn't change contents while
     * we're encoding.
     */
#ifdef NETLOGGER
    if (vnc_spu.netlogger_url) {
      NL_info("vncspu", "spu.encode.begin",
              "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
    }
#endif

    /* For each of the usual pending rectangles: */
    for (i = 0; i < num_pending_rects; i++) {
      FB_RECT rect;
      AIO_BLOCK *block;
			/*
      crDebug("sending rect %d of %d: %d, %d .. %d, %d", i, num_pending_rects,
              REGION_RECTS(&cl->pending_region)[i].x1,
              REGION_RECTS(&cl->pending_region)[i].y1,
              REGION_RECTS(&cl->pending_region)[i].x2,
              REGION_RECTS(&cl->pending_region)[i].y2);
			*/
      rect.x = REGION_RECTS(&cl->pending_region)[i].x1;
      rect.y = REGION_RECTS(&cl->pending_region)[i].y1;
      rect.w = REGION_RECTS(&cl->pending_region)[i].x2 - rect.x;
      rect.h = REGION_RECTS(&cl->pending_region)[i].y2 - rect.y;
      log_write(LL_DEBUG, "Sending rectangle %dx%d at %d,%d to %s enc 0x%x",
                (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
                cur_slot->name, cl->enc_prefer);

      if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
        /* Use Tight encoding */
        rect.enc = RFB_ENCODING_TIGHT;
        /* lock to prevent glReadPixels in other thread changing data */
        rfb_encode_tight(cl, &rect);
        continue;                 /* Important! */
      } else if (cl->enc_prefer == RFB_ENCODING_RAW24) {
        rect.enc = RFB_ENCODING_RAW24;
        block = rfb_encode_raw24_block(cl, &rect);
      } else if ( cl->enc_prefer != RFB_ENCODING_RAW &&
                  cl->enc_enable[RFB_ENCODING_HEXTILE] ) {
        /* Use Hextile encoding */
        rect.enc = RFB_ENCODING_HEXTILE;
        block = rfb_encode_hextile_block(cl, &rect);
        if (block != NULL) {
          hextile_bytes += block->data_size;
          raw_bytes += rect.w * rect.h * (cl->format.bits_pixel / 8);
        }
      } else {
        /* Use Raw encoding */
        rect.enc = RFB_ENCODING_RAW;
        if (vnc_spu.half_rez) {
           block = rfb_encode_raw_block_halfrez(cl, &rect);
        }
        else {
           block = rfb_encode_raw_block(cl, &rect);
        }
      }

      /* Send the rectangle.
         FIXME: Check for block == NULL? */
      aio_write_nocopy(NULL, block);
    }

  } /* if num_pending_rects */


  REGION_EMPTY(&cl->pending_region);
  REGION_EMPTY(&cl->copy_region);

  /* Send LastRect marker. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    FB_RECT rect;
    rect.x = rect.y = rect.w = rect.h = 0;
    rect.enc = RFB_ENCODING_LASTRECT;
    put_rect_header(rect_hdr, &rect);
    aio_write(NULL, rect_hdr, 12);
  }

  /* Set the last block's callback function */
  /* All prev blocks had NULL callbacks */
  assert(cur_slot->outqueue_last);
  if (cur_slot->outqueue_last) {
    cur_slot->outqueue_last->func = wf_client_update_finished;
  }

  /* Something has been queued for sending. */
  cl->update_in_progress = 1;
  cl->update_requested = 0;

#ifdef NETLOGGER
  if (vnc_spu.netlogger_url) {
    NL_info("vncspu", "spu.encode.end",
            "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
  }
  aio_set_serial_number(&cl->s, 0);
#endif

  vncspuUnlockFrameBuffer(); /* encoder done with buffer */

  /*crDebug("Leave send_update");*/

  vncspuLog(1, "End send update %d", counter);
}
示例#19
0
文件: xf86fbman.c 项目: aosm/X11
static FBAreaPtr
AllocateArea(
   FBManagerPtr offman,
   int w, int h,
   int granularity,
   MoveAreaCallbackProcPtr moveCB,
   RemoveAreaCallbackProcPtr removeCB,
   pointer privData
){
   ScreenPtr pScreen = offman->pScreen;
   FBLinkPtr link = NULL;
   FBAreaPtr area = NULL;
   RegionRec NewReg;
   int i, x = 0, num;
   BoxPtr boxp;

   if(granularity <= 1) granularity = 0;

   boxp = REGION_RECTS(offman->FreeBoxes);
   num = REGION_NUM_RECTS(offman->FreeBoxes);

   /* look through the free boxes */
   for(i = 0; i < num; i++, boxp++) {
	x = boxp->x1;
	if(granularity) {
	    int tmp = x % granularity;
	    if(tmp) x += (granularity - tmp);
	}

	if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
	   continue;

	link = xalloc(sizeof(FBLink));
	if(!link) return NULL;

        area = &(link->area);
        link->next = offman->UsedAreas;
        offman->UsedAreas = link;
        offman->NumUsedAreas++;
	break;
   }

   /* try to boot a removeable one out if we are not expendable ourselves */
   if(!area && !removeCB) {
	link = offman->UsedAreas;

	while(link) {
	   if(!link->area.RemoveAreaCallback) {
		link = link->next;
		continue;
	   }

	   boxp = &(link->area.box);
	   x = boxp->x1;
 	   if(granularity) {
		int tmp = x % granularity;
		if(tmp) x += (granularity - tmp);
	   }

	   if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
		link = link->next;
		continue;
	   }

	   /* bye, bye */
	   (*link->area.RemoveAreaCallback)(&link->area);
	   REGION_INIT(pScreen, &NewReg, &(link->area.box), 1); 
	   REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
	   REGION_UNINIT(pScreen, &NewReg); 

           area = &(link->area);
	   break;
	}
   }

   if(area) {
	area->pScreen = pScreen;
	area->granularity = granularity;
	area->box.x1 = x;
	area->box.x2 = x + w;
	area->box.y1 = boxp->y1;
	area->box.y2 = boxp->y1 + h;
	area->MoveAreaCallback = moveCB;
	area->RemoveAreaCallback = removeCB;
	area->devPrivate.ptr = privData;

        REGION_INIT(pScreen, &NewReg, &(area->box), 1);
	REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
	REGION_UNINIT(pScreen, &NewReg);
   }

   return area;
}
示例#20
0
Bool
xglSyncBits (DrawablePtr pDrawable,
	     BoxPtr	 pExtents)
{
    RegionRec region;
    BoxRec    box;

    XGL_DRAWABLE_PIXMAP (pDrawable);
    XGL_PIXMAP_PRIV (pPixmap);

    if (pPixmapPriv->allBits)
	return xglMapPixmapBits (pPixmap);

    if (pPixmapPriv->target == xglPixmapTargetIn && pExtents)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pPixmap->drawable.width;
	box.y2 = pPixmap->drawable.height;
	if (pExtents->x1 > box.x1)
	    box.x1 = pExtents->x1;
	if (pExtents->y1 > box.y1)
	    box.y1 = pExtents->y1;
	if (pExtents->x2 < box.x2)
	    box.x2 = pExtents->x2;
	if (pExtents->y2 < box.y2)
	    box.y2 = pExtents->y2;

	if (box.x2 <= box.x1 || box.y2 <= box.y1)
	    return xglMapPixmapBits (pPixmap);

	if (REGION_NOTEMPTY (pDrawable->pScreen, &pPixmapPriv->bitRegion))
	{
	    switch (RECT_IN_REGION (pDrawable->pScreen,
				    &pPixmapPriv->bitRegion,
				    &box)) {
	    case rgnIN:
		REGION_INIT (pDrawable->pScreen, &region, NullBox, 0);
		break;
	    case rgnOUT:
		REGION_INIT (pDrawable->pScreen, &region, &box, 1);
		REGION_UNION (pDrawable->pScreen,
			      &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion,
			      &region);
		break;
	    case rgnPART:
		REGION_INIT (pDrawable->pScreen, &region, &box, 1);
		REGION_SUBTRACT (pDrawable->pScreen, &region, &region,
				 &pPixmapPriv->bitRegion);
		REGION_UNION (pDrawable->pScreen,
			      &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion,
			      &region);
		break;
	    }
	}
	else
	{
	    REGION_INIT (pDrawable->pScreen, &region, &box, 1);
	    REGION_SUBTRACT (pDrawable->pScreen, &pPixmapPriv->bitRegion,
			     &region, &pPixmapPriv->bitRegion);
	}

	if (REGION_NUM_RECTS (&pPixmapPriv->bitRegion) == 1)
	{
	    BoxPtr pBox;

	    pBox = REGION_RECTS (&pPixmapPriv->bitRegion);

	    if (pBox->x1 <= 0			    &&
		pBox->y1 <= 0			    &&
		pBox->x2 >= pPixmap->drawable.width &&
		pBox->y2 >= pPixmap->drawable.height)
		pPixmapPriv->allBits = TRUE;
	}
    }
    else
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pPixmap->drawable.width;
	box.y2 = pPixmap->drawable.height;

	REGION_INIT (pDrawable->pScreen, &region, &box, 1);
	REGION_SUBTRACT (pDrawable->pScreen, &region, &region,
			 &pPixmapPriv->bitRegion);

	pPixmapPriv->allBits = TRUE;
    }

    if (!pPixmapPriv->buffer)
	if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT))
	    return FALSE;

    if (REGION_NOTEMPTY (pDrawable->pScreen, &region) && pPixmapPriv->surface)
    {
	glitz_pixel_format_t format;
	BoxPtr		     pBox;
	BoxPtr		     pExt;
	int		     nBox;

	if (!xglSyncSurface (pDrawable))
	    FatalError (XGL_SW_FAILURE_STRING);

	xglUnmapPixmapBits (pPixmap);

	pBox = REGION_RECTS (&region);
	nBox = REGION_NUM_RECTS (&region);
	pExt = REGION_EXTENTS (pDrawable->pScreen, &region);

	format.fourcc  = GLITZ_FOURCC_RGB;
	format.masks   = pPixmapPriv->pVisual->pPixel->masks;
	format.xoffset = pExt->x1;

	if (pPixmapPriv->stride < 0)
	{
	    format.skip_lines	  = pPixmap->drawable.height - pExt->y2;
	    format.bytes_per_line = -pPixmapPriv->stride;
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
	}
	else
	{
	    format.skip_lines	  = pExt->y1;
	    format.bytes_per_line = pPixmapPriv->stride;
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
	}

	glitz_surface_set_clip_region (pPixmapPriv->surface,
				       0, 0, (glitz_box_t *) pBox, nBox);

	glitz_get_pixels (pPixmapPriv->surface,
			  pExt->x1,
			  pExt->y1,
			  pExt->x2 - pExt->x1,
			  pExt->y2 - pExt->y1,
			  &format,
			  pPixmapPriv->buffer);

	glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, NULL, 0);
    }

    REGION_UNINIT (pDrawable->pScreen, &region);

    if (pPixmapPriv->allBits)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pPixmap->drawable.width;
	box.y2 = pPixmap->drawable.height;

	REGION_UNINIT (pDrawable->pScreen, &pPixmapPriv->bitRegion);
	REGION_INIT (pDrawable->pScreen, &pPixmapPriv->bitRegion, &box, 1);
    }

    return xglMapPixmapBits (pPixmap);
}
示例#21
0
文件: miwindow.c 项目: L3oV1nc3/VMGL
void
miSlideAndSizeWindow(WindowPtr pWin,
                     int x, int y,
                     unsigned int w, unsigned int h,
                     WindowPtr pSib)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool)(pWin->viewable);
    unsigned short width = pWin->drawable.width,
		   height = pWin->drawable.height;
    short oldx = pWin->drawable.x,
	  oldy = pWin->drawable.y;
    int bw = wBorderWidth (pWin);
    short dw, dh;
    DDXPointRec oldpt;
    RegionPtr oldRegion = NULL;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr pFirstChange;
    WindowPtr pChild;
    RegionPtr	gravitate[StaticGravity + 1];
    unsigned g;
    int		nx, ny;		/* destination x,y */
    int		newx, newy;	/* new inner window position */
    RegionPtr	pRegion = NULL;
    RegionPtr	destClip;	/* portions of destination already written */
    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
    Bool	moved = FALSE;	/* window position changed */
    WindowPtr  pLayerWin;

    /* if this is a root window, can't be resized */
    if (!(pParent = pWin->parent))
	return ;

    pScreen = pWin->drawable.pScreen;
    newx = pParent->drawable.x + x + bw;
    newy = pParent->drawable.y + y + bw;
    if (WasViewable)
    {
	anyMarked = FALSE;
	/*
	 * save the visible region of the window
	 */
	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
	REGION_COPY(pScreen, oldRegion, &pWin->winSize);

	/*
	 * categorize child windows into regions to be moved
	 */
	for (g = 0; g <= StaticGravity; g++)
	    gravitate[g] = (RegionPtr) NULL;
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    g = pChild->winGravity;
	    if (g != UnmapGravity)
	    {
		if (!gravitate[g])
		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
		REGION_UNION(pScreen, gravitate[g],
				   gravitate[g], &pChild->borderClip);
	    }
	    else
	    {
		UnmapWindow(pChild, TRUE);
		anyMarked = TRUE;
	    }
	}
	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
						       &pLayerWin);

	oldWinClip = NULL;
	if (pWin->bitGravity != ForgetGravity)
	{
	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
	}
	/*
	 * if the window is changing size, borderExposed
	 * can't be computed correctly without some help.
	 */
	if (pWin->drawable.height > h || pWin->drawable.width > w)
	    shrunk = TRUE;

	if (newx != oldx || newy != oldy)
	    moved = TRUE;

	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
	    HasBorder (pWin))
	{
	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
	    /* for tiled borders, we punt and draw the whole thing */
	    if (pWin->borderIsPixel || !moved)
	    {
		if (shrunk || moved)
		    REGION_SUBTRACT(pScreen, borderVisible,
					  &pWin->borderClip,
					  &pWin->winSize);
		else
		    REGION_COPY(pScreen, borderVisible,
					    &pWin->borderClip);
	    }
	}
    }
    pWin->origin.x = x + bw;
    pWin->origin.y = y + bw;
    pWin->drawable.height = h;
    pWin->drawable.width = w;

    x = pWin->drawable.x = newx;
    y = pWin->drawable.y = newy;

    SetWinSize (pWin);
    SetBorderSize (pWin);

    dw = (int)w - (int)width;
    dh = (int)h - (int)height;
    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

    /* let the hardware adjust background and border pixmaps, if any */
    (*pScreen->PositionWindow)(pWin, x, y);

    pFirstChange = MoveWindowInStack(pWin, pSib);

    if (WasViewable)
    {
	pRegion = REGION_CREATE(pScreen, NullBox, 1);

	if (pLayerWin == pWin)
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
						NULL);
	else
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
						NULL);

	if (pWin->valdata)
	{
	    pWin->valdata->before.resized = TRUE;
	    pWin->valdata->before.borderVisible = borderVisible;
	}


	if (anyMarked)
	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
	/*
	 * the entire window is trashed unless bitGravity
	 * recovers portions of it
	 */
	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
    }

    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);

    if (WasViewable)
    {
	/* avoid the border */
	if (HasBorder (pWin))
	{
	    int	offx, offy, dx, dy;

	    /* kruft to avoid double translates for each gravity */
	    offx = 0;
	    offy = 0;
	    for (g = 0; g <= StaticGravity; g++)
	    {
		if (!gravitate[g])
		    continue;

		/* align winSize to gravitate[g].
		 * winSize is in new coordinates,
		 * gravitate[g] is still in old coordinates */
		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
		
		dx = (oldx - nx) - offx;
		dy = (oldy - ny) - offy;
		if (dx || dy)
		{
		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
		    offx += dx;
		    offy += dy;
		}
		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
				 &pWin->winSize);
	    }
	    /* get winSize back where it belongs */
	    if (offx || offy)
		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
	}
	/*
	 * add screen bits to the appropriate bucket
	 */

	if (oldWinClip)
	{
	    /*
	     * clip to new clipList
	     */
	    REGION_COPY(pScreen, pRegion, oldWinClip);
	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
	    /*
	     * don't step on any gravity bits which will be copied after this
	     * region.	Note -- this assumes that the regions will be copied
	     * in gravity order.
	     */
	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
	    {
		if (gravitate[g])
		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
					gravitate[g]);
	    }
	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
	    g = pWin->bitGravity;
	    if (!gravitate[g])
		gravitate[g] = oldWinClip;
	    else
	    {
		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
		REGION_DESTROY(pScreen, oldWinClip);
	    }
	}

	/*
	 * move the bits on the screen
	 */

	destClip = NULL;

	for (g = 0; g <= StaticGravity; g++)
	{
	    if (!gravitate[g])
		continue;

	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);

	    oldpt.x = oldx + (x - nx);
	    oldpt.y = oldy + (y - ny);

	    /* Note that gravitate[g] is *translated* by CopyWindow */

	    /* only copy the remaining useful bits */

	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);

	    /* clip to not overwrite already copied areas */

	    if (destClip) {
		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
	    }

	    /* and move those bits */

	    if (oldpt.x != x || oldpt.y != y
#ifdef COMPOSITE
		|| pWin->redirectDraw
#endif
		)
	    {
		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
	    }

	    /* remove any overwritten bits from the remaining useful bits */

	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);

	    /*
	     * recompute exposed regions of child windows
	     */
	
	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	    {
		if (pChild->winGravity != g)
		    continue;
		REGION_INTERSECT(pScreen, pRegion,
				       &pChild->borderClip, gravitate[g]);
		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
	    }

	    /*
	     * remove the successfully copied regions of the
	     * window from its exposed region
	     */

	    if (g == pWin->bitGravity)
		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
				     &pWin->valdata->after.exposed, gravitate[g]);
	    if (!destClip)
		destClip = gravitate[g];
	    else
	    {
		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
		REGION_DESTROY(pScreen, gravitate[g]);
	    }
	}

	REGION_DESTROY(pScreen, oldRegion);
	REGION_DESTROY(pScreen, pRegion);
	if (destClip)
	    REGION_DESTROY(pScreen, destClip);
	if (anyMarked)
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
示例#22
0
void region_pack(RegionPtr pregion, int threshold)
{
    int i, num_rects;
    int height, overhead, area1, area2, area3;
    int joins = 0, sum_overhead = 0;
    BoxRec prev_rect, this_rect, tmp_rect;
    RegionRec tmp_region, add_region;

    num_rects = REGION_NUM_RECTS(pregion);

    if (num_rects < 2) {
        return;                     /* nothing to optimize */
    }

    REGION_INIT(&add_region, NullBox, 16);
    prev_rect = REGION_RECTS(pregion)[0];

    for (i = 1; i < num_rects; i++) {
        this_rect = REGION_RECTS(pregion)[i];

        if (this_rect.y1 == prev_rect.y1 && this_rect.y2 == prev_rect.y2) {

            /* Try to join two rectangles of the same "band" */

            if (prev_rect.x2 > this_rect.x1) {
                report_bad_rect_order();
                REGION_UNINIT(&add_region);
                return;
            }
            height = this_rect.y2 - this_rect.y1;
            overhead = (this_rect.x1 - prev_rect.x2) * height;
            if (overhead < threshold) {
                tmp_rect.y1 = prev_rect.y1;
                tmp_rect.y2 = prev_rect.y2;
                tmp_rect.x1 = prev_rect.x2;
                tmp_rect.x2 = this_rect.x1;
                REGION_INIT(&tmp_region, &tmp_rect, 1);
                REGION_UNION(&add_region, &add_region, &tmp_region);
                REGION_UNINIT(&tmp_region);
                joins++;
                sum_overhead += overhead;
            }

        } else {

            /* Try to join two rectangles of neighboring "bands" */

            area1 = (prev_rect.x2 - prev_rect.x1) * (prev_rect.y2 - prev_rect.y1);
            area2 = (this_rect.x2 - this_rect.x1) * (this_rect.y2 - this_rect.y1);
            tmp_rect.x1 = min(prev_rect.x1, this_rect.x1);
            tmp_rect.x2 = max(prev_rect.x2, this_rect.x2);
            tmp_rect.y1 = min(prev_rect.y1, this_rect.y1);
            tmp_rect.y2 = max(prev_rect.y2, this_rect.y2);
            area3 = (tmp_rect.x2 - tmp_rect.x1) * (tmp_rect.y2 - tmp_rect.y1);
            overhead = area3 - area2 - area1;
            if (overhead < threshold || overhead < (area1 + area2) / 100) {
                REGION_INIT(&tmp_region, &tmp_rect, 1);
                REGION_UNION(&add_region, &add_region, &tmp_region);
                REGION_UNINIT(&tmp_region);
                joins++;
                sum_overhead += overhead;
                this_rect = tmp_rect;   /* copy the joined one to prev_rect */
            }

        }

        prev_rect = this_rect;
    }

    if (sum_overhead) {
        REGION_UNION(pregion, pregion, &add_region);
        log_write(LL_DEBUG, "Joined rectangles: %d -> %d, overhead %d",
                  num_rects, (int)(REGION_NUM_RECTS(pregion)), sum_overhead);
    }

    REGION_UNINIT(&add_region);
}
示例#23
0
文件: exa_accel.c 项目: L3oV1nc3/VMGL
static Bool
exaFillRegionSolid (DrawablePtr	pDrawable, RegionPtr pRegion, Pixel pixel,
		    CARD32 planemask, CARD32 alu, unsigned int clientClipType)
{
    ExaScreenPriv(pDrawable->pScreen);
    PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
    ExaPixmapPriv (pPixmap);
    int xoff, yoff;
    Bool ret = FALSE;

    exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
    REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);

    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
	goto out;

    if (pExaScr->do_migration) {
	ExaMigrationRec pixmaps[1];

	pixmaps[0].as_dst = TRUE;
	pixmaps[0].as_src = FALSE;
	pixmaps[0].pPix = pPixmap;
	pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
						alu, clientClipType) ? NULL : pRegion;

	exaDoMigration (pixmaps, 1, TRUE);
    }

    if (exaPixmapIsOffscreen (pPixmap) &&
	(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
    {
	int nbox;
	BoxPtr pBox;

	nbox = REGION_NUM_RECTS (pRegion);
	pBox = REGION_RECTS (pRegion);

	while (nbox--)
	{
	    (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
				     pBox->y2);
	    pBox++;
	}
	(*pExaScr->info->DoneSolid) (pPixmap);
	exaMarkSync(pDrawable->pScreen);

	if (pExaPixmap->pDamage &&
	    pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
	    pDrawable->width == 1 && pDrawable->height == 1 &&
	    pDrawable->bitsPerPixel != 24) {
	    ExaPixmapPriv(pPixmap);

	    switch (pDrawable->bitsPerPixel) {
	    case 32:
		*(CARD32*)pExaPixmap->sys_ptr = pixel;
		break;
	    case 16:
		*(CARD16*)pExaPixmap->sys_ptr = pixel;
		break;
	    case 8:
		*(CARD8*)pExaPixmap->sys_ptr = pixel;
	    }

	    REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
			 pRegion);
	}

	ret = TRUE;
    }

out:
    REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);

    return ret;
}
示例#24
0
/**
 * Handle an incoming rfbFramebufferUpdateRequest message.
 * Determine the dirty regions and send pixel rect data to the client.
 */
static void rf_client_updatereq(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  RegionRec tmp_region;
  BoxRec rect;

  /*crDebug("Got Update request from %s", cur_slot->name);*/
#ifdef NETLOGGER
  if (vnc_spu.netlogger_url) {
    cl->serial_number++;
    NL_info("vncspu", "spu.fbrequest.receive",
            "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
  }
#endif

  /* the requested region of interest */
  rect.x1 = buf_get_CARD16(&cur_slot->readbuf[1]);
  rect.y1 = buf_get_CARD16(&cur_slot->readbuf[3]);
  rect.x2 = rect.x1 + buf_get_CARD16(&cur_slot->readbuf[5]);
  rect.y2 = rect.y1 + buf_get_CARD16(&cur_slot->readbuf[7]);

  /* Make sure the rectangle bounds fit the framebuffer. */
  if (rect.x1 > cl->fb_width)
    rect.x1 = cl->fb_width;
  if (rect.y1 > cl->fb_height)
    rect.y1 = cl->fb_height;
  if (rect.x2 > cl->fb_width)
    rect.x2 = cl->fb_width;
  if (rect.y2 > cl->fb_height)
    rect.y2 = cl->fb_height;

  cl->update_rect = rect;
  cl->update_requested = 1;

  cl->num_update_requests++;

  if (!cur_slot->readbuf[0]) {
    log_write(LL_DEBUG, "Received framebuffer update request (full) from %s",
              cur_slot->name);
    if (!cl->newfbsize_pending) {
      REGION_INIT(&tmp_region, &rect, 1);
#if 0
      /* Disabling this code prevents the region from outside the GL
       * window (garbage) from being sent to the viewer.
       */
      REGION_UNION(&cl->pending_region, &cl->pending_region, &tmp_region);
#endif
      REGION_UNION(&cl->pending_region, &cl->pending_region, &cl->copy_region);
      REGION_EMPTY(&cl->copy_region);
      REGION_UNINIT(&tmp_region);
    }
  } else {
    log_write(LL_DEBUG, "Received framebuffer update request from %s",
              cur_slot->name);
  }

  if (!cl->update_in_progress) {
    int k = (cl->newfbsize_pending ||
             cl->new_cliprects ||
             REGION_NOTEMPTY(&cl->copy_region) ||
             vncspuWaitDirtyRects(&cl->pending_region, &cl->update_rect,
                                  cl->serial_number));
    if (k) {
      send_update();
    }
  }

  aio_setread(rf_client_msg, NULL, 1);
}
示例#25
0
/**
 * If the pixmap is currently dirty, this copies at least the dirty area from
 * the framebuffer  memory copy to the system memory copy.  Both areas must be
 * allocated.
 */
static void
exaCopyDirtyToSys (PixmapPtr pPixmap)
{
    ExaScreenPriv (pPixmap->drawable.pScreen);
    ExaPixmapPriv (pPixmap);
    RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
    CARD8 *save_ptr;
    int save_pitch;
    BoxPtr pBox = REGION_RECTS(pRegion);
    int nbox = REGION_NUM_RECTS(pRegion);
    Bool do_sync = FALSE;

    save_ptr = pPixmap->devPrivate.ptr;
    save_pitch = pPixmap->devKind;
    pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    pPixmap->devKind = pExaPixmap->fb_pitch;

    while (nbox--) {
	pBox->x1 = max(pBox->x1, 0);
	pBox->y1 = max(pBox->y1, 0);
	pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
	pBox->y2 = min(pBox->y2, pPixmap->drawable.height);

	if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
	    continue;

	if (pExaScr->info->DownloadFromScreen == NULL ||
	    !pExaScr->info->DownloadFromScreen (pPixmap,
						pBox->x1, pBox->y1,
						pBox->x2 - pBox->x1,
						pBox->y2 - pBox->y1,
						pExaPixmap->sys_ptr
						+ pBox->y1 * pExaPixmap->sys_pitch
						+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
						pExaPixmap->sys_pitch))
	{
	    exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
	    exaMemcpyBox (pPixmap, pBox,
			  pExaPixmap->fb_ptr, pExaPixmap->fb_pitch,
			  pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
	    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
	}
	else
	    do_sync = TRUE;

	pBox++;
    }

    /* Make sure the bits have actually landed, since we don't necessarily sync
     * when accessing pixmaps in system memory.
     */
    if (do_sync)
	exaWaitSync (pPixmap->drawable.pScreen);

    pPixmap->devPrivate.ptr = save_ptr;
    pPixmap->devKind = save_pitch;

    /* The previously damaged bits are now no longer damaged but valid */
    REGION_UNION(pPixmap->drawable.pScreen,
		 &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
    DamageEmpty (pExaPixmap->pDamage);
}