static int ProcDamageSubtract (ClientPtr client) { REQUEST(xDamageSubtractReq); DamageExtPtr pDamageExt; RegionPtr pRepair; RegionPtr pParts; REQUEST_SIZE_MATCH(xDamageSubtractReq); VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, SecurityWriteAccess); VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, SecurityWriteAccess); VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, SecurityWriteAccess); if (pDamageExt->level != DamageReportRawRegion) { DamagePtr pDamage = pDamageExt->pDamage; if (pRepair) { if (pParts) REGION_INTERSECT (prScreen, pParts, DamageRegion (pDamage), pRepair); if (DamageSubtract (pDamage, pRepair)) DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt); } else { if (pParts) REGION_COPY (prScreen, pParts, DamageRegion (pDamage)); DamageEmpty (pDamage); } } return (client->noClientException); }
void compFreePixmap (WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pRedirectPixmap, pParentPixmap; CompWindowPtr cw = GetCompWindow (pWin); if (cw->damageRegistered) { DamageUnregister (&pWin->drawable, cw->damage); cw->damageRegistered = FALSE; DamageEmpty (cw->damage); } /* * Move the parent-constrained border clip region back into * the window so that ValidateTree will handle the unmap * case correctly. Unmap adds the window borderClip to the * parent exposed area; regions beyond the parent cause crashes */ RegionCopy(&pWin->borderClip, &cw->borderClip); pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin); pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent); pWin->redirectDraw = RedirectDrawNone; compSetPixmap (pWin, pParentPixmap); (*pScreen->DestroyPixmap) (pRedirectPixmap); }
static CARD32 damage_timer(OsTimerPtr timer, CARD32 time, pointer arg) { struct omap_screen_info *omaps = arg; int needUpdate = 0; RegionPtr region = NULL; #ifdef XSP xspScrPrivPtr xsp_priv = NULL; #endif #ifdef XSP if (xspScrPrivateIndex > 0) { xsp_priv = xspGetScrPriv(omaps->screen->pScreen); if (xsp_priv && xsp_priv->dsp_enabled) needUpdate = 1; } #endif if (!omaps->damage) { omaps->timer_active = 0; omaps->empty_updates = 0; return 0; } #ifdef PROFILE_ME_HARDER omaps->updates++; if (omaps->updates > (5000 / OMAP_UPDATE_TIME)) video_stats(omaps, time); #endif region = DamageRegion(omaps->damage); if (REGION_NOTEMPTY(omaps->screen->pScreen, region)) { accumulate_damage(omaps, region); DamageEmpty(omaps->damage); } if (!region_is_null(omaps)) needUpdate = 1; if (needUpdate) { omaps->empty_updates = 0; update_screen(omaps); } else { omaps->empty_updates++; } #if !defined(PROFILE_ME_HARDER) && !defined(DEBUG) /* Kill the timer if we've gone more than 500ms without an update. */ if (omaps->empty_updates >= 500 / OMAP_UPDATE_TIME) { omaps->timer_active = 0; omaps->empty_updates = 0; return 0; } else #endif { return OMAP_UPDATE_TIME; } }
static void ephyrInternalDamageRedisplay(ScreenPtr pScreen) { KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; RegionPtr pRegion; if (!scrpriv || !scrpriv->pDamage) return; pRegion = DamageRegion(scrpriv->pDamage); if (RegionNotEmpty(pRegion)) { int nbox; BoxPtr pbox; if (ephyr_glamor) { ephyr_glamor_damage_redisplay(scrpriv->glamor, pRegion); } else { nbox = RegionNumRects(pRegion); pbox = RegionRects(pRegion); while (nbox--) { hostx_paint_rect(screen, pbox->x1, pbox->y1, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } } DamageEmpty(scrpriv->pDamage); } }
static int ProcDamageSubtract (ClientPtr client) { REQUEST(xDamageSubtractReq); DamageExtPtr pDamageExt; RegionPtr pRepair; RegionPtr pParts; REQUEST_SIZE_MATCH(xDamageSubtractReq); VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); if (pDamageExt->level != DamageReportRawRegion) { DamagePtr pDamage = pDamageExt->pDamage; if (pRepair) { if (pParts) RegionIntersect(pParts, DamageRegion (pDamage), pRepair); if (DamageSubtract (pDamage, pRepair)) DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt); } else { if (pParts) RegionCopy(pParts, DamageRegion (pDamage)); DamageEmpty (pDamage); } } return Success; }
static int dispatch_dirty_region(ScrnInfoPtr scrn, PixmapPtr pixmap, DamagePtr damage, int fb_id) { modesettingPtr ms = modesettingPTR(scrn); RegionPtr dirty = DamageRegion(damage); unsigned num_cliprects = REGION_NUM_RECTS(dirty); int ret = 0; if (num_cliprects) { drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip)); BoxPtr rect = REGION_RECTS(dirty); int i; if (!clip) return -ENOMEM; /* XXX no need for copy? */ for (i = 0; i < num_cliprects; i++, rect++) { clip[i].x1 = rect->x1; clip[i].y1 = rect->y1; clip[i].x2 = rect->x2; clip[i].y2 = rect->y2; } /* TODO query connector property to see if this is needed */ ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects); free(clip); DamageEmpty(damage); } return ret; }
/** * 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); }
static void saa_report_damage(DamagePtr damage, RegionPtr reg, void *closure) { PixmapPtr pixmap = (PixmapPtr) closure; struct saa_pixmap *spix = saa_get_saa_pixmap(pixmap); struct saa_driver *driver = saa_screen(pixmap->drawable.pScreen)->driver; if (spix->read_access || spix->write_access) LogMessage(X_ERROR, "Damage report inside prepare access.\n"); driver->operation_complete(driver, pixmap); DamageEmpty(damage); }
static void shadowRedisplay(ScreenPtr pScreen) { shadowBuf(pScreen); RegionPtr pRegion; if (!pBuf || !pBuf->pDamage || !pBuf->update) return; pRegion = DamageRegion(pBuf->pDamage); if (RegionNotEmpty(pRegion)) { (*pBuf->update) (pScreen, pBuf); DamageEmpty(pBuf->pDamage); } }
static Bool xf86RotateRedisplay(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); DamagePtr damage = xf86_config->rotation_damage; RegionPtr region; if (!damage) return FALSE; xf86RotatePrepare (pScreen); region = DamageRegion(damage); if (REGION_NOTEMPTY(pScreen, region)) { int c; SourceValidateProcPtr SourceValidate; /* * SourceValidate is used by the software cursor code * to pull the cursor off of the screen when reading * bits from the frame buffer. Bypassing this function * leaves the software cursor in place */ SourceValidate = pScreen->SourceValidate; pScreen->SourceValidate = NULL; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->rotation != RR_Rotate_0 && crtc->enabled) { RegionRec crtc_damage; /* compute portion of damage that overlaps crtc */ REGION_INIT(pScreen, &crtc_damage, &crtc->bounds, 1); REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region); /* update damaged region */ if (REGION_NOTEMPTY(pScreen, &crtc_damage)) xf86RotateCrtcRedisplay (crtc, &crtc_damage); REGION_UNINIT (pScreen, &crtc_damage); } } pScreen->SourceValidate = SourceValidate; DamageEmpty(damage); } return TRUE; }
static void shadowRedisplay(ScreenPtr pScreen) { shadowBuf(pScreen); RegionPtr pRegion; if (!pBuf || !pBuf->pDamage || !pBuf->update) return; /* allow deferral of updates, to minimize overdraw, etc. */ if (!pBuf->ready_to_update(pScreen, pBuf)) return; pRegion = DamageRegion(pBuf->pDamage); if (REGION_NOTEMPTY(pScreen, pRegion)) { (*pBuf->update)(pScreen, pBuf); DamageEmpty(pBuf->pDamage); } }
static void xf86RotateRedisplay(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); DamagePtr damage = xf86_config->rotation_damage; RegionPtr region; if (!damage) return; xf86RotatePrepare (pScreen); region = DamageRegion(damage); if (REGION_NOTEMPTY(pScreen, region)) { int c; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->rotation != RR_Rotate_0) { BoxRec box; RegionRec crtc_damage; /* compute portion of damage that overlaps crtc */ box.x1 = crtc->x; box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation); box.y1 = crtc->y; box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation); REGION_INIT(pScreen, &crtc_damage, &box, 1); REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region); /* update damaged region */ if (REGION_NOTEMPTY(pScreen, &crtc_damage)) xf86RotateCrtcRedisplay (crtc, &crtc_damage); REGION_UNINIT (pScreen, &crtc_damage); } } DamageEmpty(damage); } }
/** * 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); }