/** * exaCreatePixmap() creates a new pixmap. * * If width and height are 0, this won't be a full-fledged pixmap and it will * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because * ModifyPixmapHeader() would break migration. These types of pixmaps are used * for scratch pixmaps, or to represent the visible screen. */ static PixmapPtr exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; int bpp; ExaScreenPriv(pScreen); if (w > 32767 || h > 32767) return NullPixmap; pPixmap = fbCreatePixmap (pScreen, w, h, depth); if (!pPixmap) return NULL; pExaPixmap = ExaGetPixmapPriv(pPixmap); bpp = pPixmap->drawable.bitsPerPixel; /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; pExaPixmap->area = NULL; pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; pExaPixmap->sys_pitch = pPixmap->devKind; pExaPixmap->fb_ptr = NULL; if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8; else pExaPixmap->fb_pitch = w * bpp / 8; pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, pExaScr->info->pixmapPitchAlign); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; if (pExaPixmap->fb_pitch > 131071) { fbDestroyPixmap(pPixmap); return NULL; } /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE, pScreen, pPixmap); if (pExaPixmap->pDamage == NULL) { fbDestroyPixmap (pPixmap); return NULL; } DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); /* None of the pixmap bits are valid initially */ REGION_NULL(pScreen, &pExaPixmap->validReg); return pPixmap; }
Bool compAllocPixmap (WindowPtr pWin) { int bw = (int) pWin->borderWidth; int x = pWin->drawable.x - bw; int y = pWin->drawable.y - bw; int w = pWin->drawable.width + (bw << 1); int h = pWin->drawable.height + (bw << 1); PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h); CompWindowPtr cw = GetCompWindow (pWin); if (!pPixmap) return FALSE; if (cw->update == CompositeRedirectAutomatic) pWin->redirectDraw = RedirectDrawAutomatic; else pWin->redirectDraw = RedirectDrawManual; compSetPixmap (pWin, pPixmap); cw->oldx = COMP_ORIGIN_INVALID; cw->oldy = COMP_ORIGIN_INVALID; cw->damageRegistered = FALSE; if (cw->update == CompositeRedirectAutomatic) { DamageRegister (&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; } return TRUE; }
static void xf86RotatePrepare(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int c; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->rotatedData && !crtc->rotatedPixmap) { crtc->rotatedPixmap = crtc->funcs->shadow_create(crtc, crtc->rotatedData, crtc->mode. HDisplay, crtc->mode. VDisplay); if (!xf86_config->rotation_damage_registered) { /* Hook damage to screen pixmap */ DamageRegister(&pScreen->root->drawable, xf86_config->rotation_damage); xf86_config->rotation_damage_registered = TRUE; EnableLimitedSchedulingLatency(); } xf86CrtcDamageShadow(crtc); } } }
static int ProcDamageCreate(ClientPtr client) { DrawablePtr pDrawable; DamageExtPtr pDamageExt; DamageReportLevel level; RegionPtr pRegion; REQUEST(xDamageCreateReq); REQUEST_SIZE_MATCH(xDamageCreateReq); LEGAL_NEW_RESOURCE(stuff->damage, client); SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess); switch (stuff->level) { case XDamageReportRawRectangles: level = DamageReportRawRegion; break; case XDamageReportDeltaRectangles: level = DamageReportDeltaRegion; break; case XDamageReportBoundingBox: level = DamageReportBoundingBox; break; case XDamageReportNonEmpty: level = DamageReportNonEmpty; break; default: client->errorValue = stuff->level; return BadValue; } pDamageExt = malloc(sizeof(DamageExtRec)); if (!pDamageExt) return BadAlloc; pDamageExt->id = stuff->damage; pDamageExt->pDrawable = pDrawable; pDamageExt->level = level; pDamageExt->pClient = client; pDamageExt->pDamage = DamageCreate(DamageExtReport, DamageExtDestroy, level, FALSE, pDrawable->pScreen, pDamageExt); if (!pDamageExt->pDamage) { free(pDamageExt); return BadAlloc; } if (!AddResource(stuff->damage, DamageExtType, (pointer) pDamageExt)) return BadAlloc; DamageRegister(pDamageExt->pDrawable, pDamageExt->pDamage); if (pDrawable->type == DRAWABLE_WINDOW) { pRegion = &((WindowPtr) pDrawable)->borderClip; DamageDamageRegion(pDrawable, pRegion); } return (client->noClientException); }
/* * Free one of the per-client per-window resources, clearing * redirect and the per-window pointer as appropriate */ void compFreeClientWindow (WindowPtr pWin, XID id) { ScreenPtr pScreen = pWin->drawable.pScreen; CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw, *prev; Bool anyMarked = FALSE; WindowPtr pLayerWin; PixmapPtr pPixmap = NULL; if (!cw) return; for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { *prev = ccw->next; if (ccw->update == CompositeRedirectManual) cw->update = CompositeRedirectAutomatic; free(ccw); break; } } if (!cw->clients) { anyMarked = compMarkWindows (pWin, &pLayerWin); if (pWin->redirectDraw != RedirectDrawNone) { pPixmap = (*pScreen->GetWindowPixmap) (pWin); compSetParentPixmap (pWin); } if (cw->damage) DamageDestroy (cw->damage); RegionUninit(&cw->borderClip); dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); free(cw); } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) { anyMarked = compMarkWindows (pWin, &pLayerWin); DamageRegister (&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; pWin->redirectDraw = RedirectDrawAutomatic; DamageDamageRegion(&pWin->drawable, &pWin->borderSize); } if (anyMarked) compHandleMarkedWindows (pWin, pLayerWin); if (pPixmap) { compRestoreWindow (pWin, pPixmap); (*pScreen->DestroyPixmap) (pPixmap); } }
/* * Free one of the per-client per-window resources, clearing * redirect and the per-window pointer as appropriate */ void compFreeClientWindow (WindowPtr pWin, XID id) { CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw, *prev; Bool wasMapped = pWin->mapped; if (!cw) return; for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { *prev = ccw->next; if (ccw->update == CompositeRedirectManual) cw->update = CompositeRedirectAutomatic; free(ccw); break; } } if (!cw->clients) { if (wasMapped) { DisableMapUnmapEvents (pWin); UnmapWindow (pWin, FALSE); EnableMapUnmapEvents (pWin); } if (pWin->redirectDraw != RedirectDrawNone) compFreePixmap (pWin); if (cw->damage) DamageDestroy (cw->damage); RegionUninit(&cw->borderClip); dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); free(cw); } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) { DamageRegister (&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; pWin->redirectDraw = RedirectDrawAutomatic; DamageRegionAppend(&pWin->drawable, &pWin->borderSize); } if (wasMapped && !pWin->mapped) { Bool overrideRedirect = pWin->overrideRedirect; pWin->overrideRedirect = TRUE; DisableMapUnmapEvents (pWin); MapWindow (pWin, clients[CLIENT_ID(id)]); EnableMapUnmapEvents (pWin); pWin->overrideRedirect = overrideRedirect; } }
static Bool TegraCreateScreenResources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); TegraPtr tegra = TegraPTR(pScrn); PixmapPtr rootPixmap; Bool ret; void *pixels; pScreen->CreateScreenResources = tegra->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = TegraCreateScreenResources; if (!drmmode_set_desired_modes(pScrn, &tegra->drmmode)) return FALSE; drmmode_uevent_init(pScrn, &tegra->drmmode); if (!tegra->drmmode.want_sw_cursor) drmmode_map_cursor_bos(pScrn, &tegra->drmmode); pixels = drmmode_map_front_bo(&tegra->drmmode); if (!pixels) return FALSE; rootPixmap = pScreen->GetScreenPixmap(pScreen); if (tegra->drmmode.shadow_enable) pixels = tegra->drmmode.shadow_fb; if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) FatalError("Couldn't adjust screen pixmap\n"); if (tegra->drmmode.shadow_enable) { if (!shadowAdd(pScreen, rootPixmap, shadowUpdatePackedWeak(), TegraShadowWindow, 0, 0)) return FALSE; } tegra->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, rootPixmap); if (tegra->damage) { DamageRegister(&rootPixmap->drawable, tegra->damage); tegra->dirty_enabled = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to create screen damage record\n"); return FALSE; } return ret; }
Bool ephyrSetInternalDamage(ScreenPtr pScreen) { KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; PixmapPtr pPixmap = NULL; scrpriv->pDamage = DamageCreate((DamageReportFunc) 0, (DamageDestroyFunc) 0, DamageReportNone, TRUE, pScreen, pScreen); pPixmap = (*pScreen->GetScreenPixmap) (pScreen); DamageRegister(&pPixmap->drawable, scrpriv->pDamage); return TRUE; }
Bool saa_add_damage(PixmapPtr pixmap) { ScreenPtr pScreen = pixmap->drawable.pScreen; struct saa_pixmap *spix = saa_get_saa_pixmap(pixmap); if (spix->damage) return TRUE; spix->damage = DamageCreate(saa_report_damage, NULL, DamageReportRawRegion, TRUE, pScreen, pixmap); if (!spix->damage) return FALSE; DamageRegister(&pixmap->drawable, spix->damage); DamageSetReportAfterOp(spix->damage, TRUE); return TRUE; }
Bool shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update, ShadowWindowProc window, ShadowPreupdateProc preupdate, int randr, void *closure) { shadowBuf(pScreen); if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler, (pointer)pScreen)) return FALSE; /* * Map simple rotation values to bitmasks; fortunately, * these are all unique */ switch (randr) { case 0: randr = SHADOW_ROTATE_0; break; case 90: randr = SHADOW_ROTATE_90; break; case 180: randr = SHADOW_ROTATE_180; break; case 270: randr = SHADOW_ROTATE_270; break; } pBuf->update = update; pBuf->window = window; if (preupdate) pBuf->ready_to_update = preupdate; else pBuf->ready_to_update = dummyPreupdate; pBuf->randr = randr; pBuf->closure = 0; pBuf->pPixmap = pPixmap; DamageRegister(&pPixmap->drawable, pBuf->pDamage); return TRUE; }
Bool ephyrSetInternalDamage(ScreenPtr pScreen) { KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; PixmapPtr pPixmap = NULL; scrpriv->pDamage = DamageCreate((DamageReportFunc) 0, (DamageDestroyFunc) 0, DamageReportNone, TRUE, pScreen, pScreen); if (!RegisterBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler, ephyrInternalDamageWakeupHandler, (void *) pScreen)) return FALSE; pPixmap = (*pScreen->GetScreenPixmap) (pScreen); DamageRegister(&pPixmap->drawable, scrpriv->pDamage); return TRUE; }
Bool omap_screen_resources_create(struct omap_screen_info *omaps) { PixmapPtr pixmap; ENTER(); /* Set up our damage listener to update the window by hand. */ omaps->timer_active = 0; omaps->empty_updates = 0; omaps->damage = DamageCreate(damage_report_hook, damage_destroy_hook, DamageReportNonEmpty, TRUE, omaps->screen->pScreen, omaps); if (!omaps->damage) FatalError("omapCreateDrawResources: couldn't create damage\n"); pixmap = omaps->screen->pScreen->GetScreenPixmap(omaps->screen->pScreen); if (!pixmap) FatalError("omapCreateDrawResources: couldn't get screen pixmap\n"); omaps->pixmap = pixmap; reset_damage(omaps); DamageRegister(&pixmap->drawable, omaps->damage); omaps->pixel_doubled = 0; omaps->individual_updates = 0; #ifdef XSP XSPSetEventCallback(omaps->screen->pScreen->myNum, xsp_event, omaps); #endif omaps->tmp_region = REGION_CREATE(omaps->screen->pScreen, NullBox, 0); if (!omaps->tmp_region) FatalError("omapCreateDrawResources: couldn't create temp region\n"); LEAVE(); return TRUE; }
/** * exaCreatePixmap() creates a new pixmap. * * If width and height are 0, this won't be a full-fledged pixmap and it will * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because * ModifyPixmapHeader() would break migration. These types of pixmaps are used * for scratch pixmaps, or to represent the visible screen. */ PixmapPtr exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; BoxRec box; int bpp; ExaScreenPriv(pScreen); if (w > 32767 || h > 32767) return NullPixmap; swap(pExaScr, pScreen, CreatePixmap); pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint); swap(pExaScr, pScreen, CreatePixmap); if (!pPixmap) return NULL; pExaPixmap = ExaGetPixmapPriv(pPixmap); pExaPixmap->driverPriv = NULL; bpp = pPixmap->drawable.bitsPerPixel; pExaPixmap->driverPriv = NULL; /* Scratch pixmaps may have w/h equal to zero, and may not be * migrated. */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; pExaPixmap->sys_pitch = pPixmap->devKind; pPixmap->devPrivate.ptr = NULL; pExaPixmap->use_gpu_copy = FALSE; pExaPixmap->fb_ptr = NULL; exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; if (pExaPixmap->fb_pitch > 131071) { swap(pExaScr, pScreen, DestroyPixmap); pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return NULL; } /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, pPixmap); if (pExaPixmap->pDamage == NULL) { swap(pExaScr, pScreen, DestroyPixmap); pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return NULL; } DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage); /* This ensures that pending damage reflects the current operation. */ /* This is used by exa to optimize migration. */ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); pExaPixmap->area = NULL; /* We set the initial pixmap as completely valid for a simple reason. * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which * could form single pixel rects as part of a region. Setting the complete region * as valid is a natural defragmentation of the region. */ box.x1 = 0; box.y1 = 0; box.x2 = w; box.y2 = h; RegionInit(&pExaPixmap->validSys, &box, 0); RegionInit(&pExaPixmap->validFB, &box, 0); exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp); /* During a fallback we must prepare access. */ if (pExaScr->fallback_counter) exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); return pPixmap; }
/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we * use the DownloadFromScreen hook to retrieve contents to a copy in system * memory, perform software rendering on that and move back the results with the * UploadToScreen hook (see exaDamageReport_mixed). */ void exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) { ExaPixmapPriv(pPixmap); Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); Bool success; success = ExaDoPrepareAccess(pPixmap, index); if (success && has_gpu_copy && pExaPixmap->pDamage) { /* You cannot do accelerated operations while a buffer is mapped. */ exaFinishAccess(&pPixmap->drawable, index); /* Update the gpu view of both deferred destination pixmaps and of * source pixmaps that were migrated with a bounding region. */ exaMoveInPixmap_mixed(pPixmap); success = ExaDoPrepareAccess(pPixmap, index); if (success) { /* We have a gpu pixmap that can be accessed, we don't need the cpu * copy anymore. Drivers that prefer DFS, should fail prepare * access. */ DamageDestroy(pExaPixmap->pDamage); pExaPixmap->pDamage = NULL; free(pExaPixmap->sys_ptr); pExaPixmap->sys_ptr = NULL; return; } } if (!success) { ExaMigrationRec pixmaps[1]; /* Do we need to allocate our system buffer? */ if (!pExaPixmap->sys_ptr) { pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch * pPixmap->drawable.height); if (!pExaPixmap->sys_ptr) FatalError("EXA: malloc failed for size %d bytes\n", pExaPixmap->sys_pitch * pPixmap->drawable.height); } if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; } else { pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; } pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = pReg; if (!pExaPixmap->pDamage && (has_gpu_copy || !exaPixmapIsPinned(pPixmap))) { Bool as_dst = pixmaps[0].as_dst; /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL, DamageReportNonEmpty, TRUE, pPixmap->drawable.pScreen, pPixmap); if (pExaPixmap->pDamage) { DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage); /* This ensures that pending damage reflects the current * operation. This is used by exa to optimize migration. */ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); } if (has_gpu_copy) { exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); /* We don't know which region of the destination will be damaged, * have to assume all of it */ if (as_dst) { pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; pixmaps[0].pReg = NULL; } exaCopyDirtyToSys(pixmaps); } if (as_dst) exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); } else if (has_gpu_copy) exaCopyDirtyToSys(pixmaps); pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; pExaPixmap->use_gpu_copy = FALSE; } }
static int ProcDamageCreate (ClientPtr client) { DrawablePtr pDrawable; DamageExtPtr pDamageExt; DamageReportLevel level; RegionPtr pRegion; int rc; REQUEST(xDamageCreateReq); REQUEST_SIZE_MATCH(xDamageCreateReq); LEGAL_NEW_RESOURCE(stuff->damage, client); rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, DixGetAttrAccess|DixReadAccess); if (rc != Success) return rc; switch (stuff->level) { case XDamageReportRawRectangles: level = DamageReportRawRegion; break; case XDamageReportDeltaRectangles: level = DamageReportDeltaRegion; break; case XDamageReportBoundingBox: level = DamageReportBoundingBox; break; case XDamageReportNonEmpty: level = DamageReportNonEmpty; break; default: client->errorValue = stuff->level; return BadValue; } pDamageExt = malloc(sizeof (DamageExtRec)); if (!pDamageExt) return BadAlloc; pDamageExt->id = stuff->damage; pDamageExt->drawable = stuff->drawable; pDamageExt->pDrawable = pDrawable; pDamageExt->level = level; pDamageExt->pClient = client; pDamageExt->pDamage = DamageCreate (DamageExtReport, DamageExtDestroy, level, FALSE, pDrawable->pScreen, pDamageExt); if (!pDamageExt->pDamage) { free(pDamageExt); return BadAlloc; } if (!AddResource (stuff->damage, DamageExtType, (pointer) pDamageExt)) return BadAlloc; DamageSetReportAfterOp (pDamageExt->pDamage, TRUE); DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage); if (pDrawable->type == DRAWABLE_WINDOW) { pRegion = &((WindowPtr) pDrawable)->borderClip; DamageDamageRegion(pDrawable, pRegion); } return Success; }
static Bool CreateScreenResources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap; Bool ret; void *pixels = NULL; int err; pScreen->CreateScreenResources = ms->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = CreateScreenResources; if (!drmmode_set_desired_modes(pScrn, &ms->drmmode)) return FALSE; if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode)) return FALSE; drmmode_uevent_init(pScrn, &ms->drmmode); if (!ms->drmmode.sw_cursor) drmmode_map_cursor_bos(pScrn, &ms->drmmode); if (!ms->drmmode.gbm) { pixels = drmmode_map_front_bo(&ms->drmmode); if (!pixels) return FALSE; } rootPixmap = pScreen->GetScreenPixmap(pScreen); if (ms->drmmode.shadow_enable) pixels = ms->drmmode.shadow_fb; if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) FatalError("Couldn't adjust screen pixmap\n"); if (ms->drmmode.shadow_enable) { if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked, msShadowWindow, 0, 0)) return FALSE; } err = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, NULL, 0); if (err != -EINVAL && err != -ENOSYS) { ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, rootPixmap); if (ms->damage) { DamageRegister(&rootPixmap->drawable, ms->damage); ms->dirty_enabled = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to create screen damage record\n"); return FALSE; } } return ret; }