Keith Packard <[email protected]> writes: > On Wed, 30 Mar 2011 11:34:09 -0400, Søren Sandmann <[email protected]> wrote: > >> This patch adds a new function RegionInitBoxes() and fixes those >> instances to call that instead. > > What's the memory allocation story here? Does RegionInitBoxes allocate > space and copy the provided boxes in (in which case a bit of error > detection is required)? Or does the region just end up pointing at the > provided boxes (in which case I'd like to see how the region gets > freed or resized)
RegionInitBoxes() allocates space and copies the boxes. If memory allocation fails, it will create a not-a-region which will generally survive anything you do with it. But it probably still does make sense to handle these errors explicitly. New patch below. Thanks, Soren commit 43e47433cf55c98db5308a51c1c514c59901f598 Author: Søren Sandmann Pedersen <[email protected]> Date: Tue Mar 29 13:06:36 2011 -0400 Add RegionInitBoxes(), and fix some buggy callers of RegionInit(). The interface to RegionInit(): RegionInit (RegionPtr pReg, BoxPtr rect, int size); is very confusing because it doesn't take a list of boxes, it takes *one* box, but if that box is NULL, it initializes an empty region with 'size' rectangles preallocated. Most callers of this function were correctly passing either NULL or just one box, but there were three confused cases, where the code seems to expect a region to be created from a list of boxes. This patch adds a new function RegionInitBoxes() and fixes those instances to call that instead. And yes, the pixman function to initialize a region from a list of boxes is called init_rects() because pixman is also awesome. V2: Make RegionInitBoxes() return a Bool indicating whether the call succeeded, and fix the callers to check this return value. Signed-off-by: Soren Sandmann <[email protected]> diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index bd533c4..078b91c 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -127,11 +127,10 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - if (pExaScr->prepare_access_reg) { + if (pExaScr->prepare_access_reg && RegionInitBoxes(®, pbox, nbox)) { PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc); exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); - RegionInit(®, pbox, nbox); RegionTranslate(®, xoff + dx, yoff + dy); pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); RegionUninit(®); @@ -140,11 +139,11 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, if (pExaScr->prepare_access_reg && !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle, - pGC->alu, pGC->clientClipType)) { + pGC->alu, pGC->clientClipType) && + RegionInitBoxes (®, pbox, nbox)) { PixmapPtr pPixmap = exaGetDrawablePixmap(pDst); exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); - RegionInit(®, pbox, nbox); RegionTranslate(®, xoff, yoff); pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); RegionUninit(®); diff --git a/glx/glxdri.c b/glx/glxdri.c index 3a57337..a2afbc2 100644 --- a/glx/glxdri.c +++ b/glx/glxdri.c @@ -831,11 +831,20 @@ static void __glXReportDamage(__DRIdrawable *driDraw, __glXenterServer(GL_FALSE); - RegionInit(®ion, (BoxPtr) rects, num_rects); - RegionTranslate(®ion, pDraw->x, pDraw->y); - DamageDamageRegion(pDraw, ®ion); - RegionUninit(®ion); - + if (RegionInitBoxes(®ion, (BoxPtr) rects, num_rects)) { + RegionTranslate(®ion, pDraw->x, pDraw->y); + DamageDamageRegion(pDraw, ®ion); + RegionUninit(®ion); + } + else { + while (num_rects--) { + RegionInit (®ion, (BoxPtr) rects++, 1); + RegionTranslate(®ion, pDraw->x, pDraw->y); + DamageDamageRegion(pDraw, ®ion); + RegionUninit(®ion); + } + } + __glXleaveServer(GL_FALSE); } diff --git a/include/regionstr.h b/include/regionstr.h index 3759fe1..3dfef5c 100644 --- a/include/regionstr.h +++ b/include/regionstr.h @@ -132,6 +132,11 @@ static inline void RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size) } } +static inline Bool RegionInitBoxes(RegionPtr pReg, BoxPtr boxes, int nBoxes) +{ + return pixman_region_init_rects (pReg, boxes, nBoxes); +} + static inline void RegionUninit(RegionPtr _pReg) { if ((_pReg)->data && (_pReg)->data->size) { _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
