static Bool
TegraCloseScreen(CLOSE_SCREEN_ARGS_DECL)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    TegraPtr tegra = TegraPTR(pScrn);

    if (tegra->damage) {
        DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable,
                         tegra->damage);
        DamageDestroy(tegra->damage);
        tegra->damage = NULL;
    }

    if (tegra->drmmode.shadow_enable) {
        shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
        free(tegra->drmmode.shadow_fb);
        tegra->drmmode.shadow_fb = NULL;
    }

    drmmode_uevent_fini(pScrn, &tegra->drmmode);
    drmmode_free_bos(pScrn, &tegra->drmmode);

    if (pScrn->vtSema)
        TegraLeaveVT(VT_FUNC_ARGS);

    pScreen->CreateScreenResources = tegra->createScreenResources;
    pScreen->BlockHandler = tegra->BlockHandler;

    pScrn->vtSema = FALSE;
    pScreen->CloseScreen = tegra->CloseScreen;
    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
void
shadowRemove(ScreenPtr pScreen, PixmapPtr pPixmap)
{
    shadowBuf(pScreen);

    if (pBuf->pPixmap) {
	DamageUnregister(&pBuf->pPixmap->drawable, pBuf->pDamage);
	pBuf->update = 0;
	pBuf->window = 0;
	pBuf->randr = 0;
	pBuf->closure = 0;
	pBuf->pPixmap = 0;
    }

    RemoveBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler,
				 (pointer) pScreen);
}
Esempio n. 4
0
static void dispatch_dirty(ScreenPtr pScreen)
{
    ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
    modesettingPtr ms = modesettingPTR(scrn);
    PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen);
    int fb_id = ms->drmmode.fb_id;
    int ret;

    ret = dispatch_dirty_region(scrn, pixmap, ms->damage, fb_id);
    if (ret == -EINVAL || ret == -ENOSYS) {
	ms->dirty_enabled = FALSE;
	DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
	DamageDestroy(ms->damage);
	ms->damage = NULL;
	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n");
	return;
    }
}
Esempio n. 5
0
static int
FreeDamageExt(pointer value, XID did)
{
    DamageExtPtr pDamageExt = (DamageExtPtr) value;

    /*
     * Get rid of the resource table entry hanging from the window id
     */
    pDamageExt->id = 0;
    if (WindowDrawable(pDamageExt->pDrawable->type))
        FreeResourceByType(pDamageExt->pDrawable->id, DamageExtWinType, TRUE);
    if (pDamageExt->pDamage) {
        DamageUnregister(pDamageExt->pDrawable, pDamageExt->pDamage);
        DamageDestroy(pDamageExt->pDamage);
    }
    free(pDamageExt);
    return Success;
}
Esempio n. 6
0
static void
xf86RotateDestroy (xf86CrtcPtr crtc)
{
    ScrnInfoPtr		pScrn = crtc->scrn;
    ScreenPtr		pScreen = pScrn->pScreen;
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    int			c;
    
    /* Free memory from rotation */
    if (crtc->rotatedPixmap || crtc->rotatedData)
    {
	crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
	crtc->rotatedPixmap = NULL;
	crtc->rotatedData = NULL;
    }

    for (c = 0; c < xf86_config->num_crtc; c++)
	if (xf86_config->crtc[c]->rotatedPixmap ||
	    xf86_config->crtc[c]->rotatedData)
	    return;

    /*
     * Clean up damage structures when no crtcs are rotated
     */
    if (xf86_config->rotation_damage)
    {
	/* Free damage structure */
	if (xf86_config->rotation_damage_registered)
	{
	    DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
			      xf86_config->rotation_damage);
	    xf86_config->rotation_damage_registered = FALSE;
	}
	DamageDestroy (xf86_config->rotation_damage);
	xf86_config->rotation_damage = NULL;
    }
}
Esempio n. 7
0
/*
 * Redirect one window for one client
 */
int
compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
{
    CompWindowPtr	cw = GetCompWindow (pWin);
    CompClientWindowPtr	ccw;
    Bool		wasMapped = pWin->mapped;
    CompScreenPtr       cs = GetCompScreen(pWin->drawable.pScreen);
    
    if (pWin == cs->pOverlayWin) {
	return Success;
    }

    if (!pWin->parent)
	return BadMatch;

    /*
     * Only one Manual update is allowed
     */
    if (cw && update == CompositeRedirectManual)
	for (ccw = cw->clients; ccw; ccw = ccw->next)
	    if (ccw->update == CompositeRedirectManual)
		return BadAccess;
    
    /*
     * Allocate per-client per-window structure 
     * The client *could* allocate multiple, but while supported,
     * it is not expected to be common
     */
    ccw = malloc(sizeof (CompClientWindowRec));
    if (!ccw)
	return BadAlloc;
    ccw->id = FakeClientID (pClient->index);
    ccw->update = update;
    /*
     * Now make sure there's a per-window structure to hang this from
     */
    if (!cw)
    {
	cw = malloc(sizeof (CompWindowRec));
	if (!cw)
	{
	    free(ccw);
	    return BadAlloc;
	}
	cw->damage = DamageCreate (compReportDamage,
				   compDestroyDamage,
				   DamageReportNonEmpty,
				   FALSE,
				   pWin->drawable.pScreen,
				   pWin);
	if (!cw->damage)
	{
	    free(ccw);
	    free(cw);
	    return BadAlloc;
	}
	if (wasMapped)
	{
	    DisableMapUnmapEvents (pWin);
	    UnmapWindow (pWin, FALSE);
	    EnableMapUnmapEvents (pWin);
	}

	RegionNull(&cw->borderClip);
	cw->borderClipX = 0;
	cw->borderClipY = 0;
	cw->update = CompositeRedirectAutomatic;
	cw->clients = 0;
	cw->oldx = COMP_ORIGIN_INVALID;
	cw->oldy = COMP_ORIGIN_INVALID;
	cw->damageRegistered = FALSE;
	cw->damaged = FALSE;
	cw->pOldPixmap = NullPixmap;
	dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw);
    }
    ccw->next = cw->clients;
    cw->clients = ccw;
    if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
	return BadAlloc;
    if (ccw->update == CompositeRedirectManual)
    {
	/* If the window was CompositeRedirectAutomatic, then
	 * unmap the window so that the parent clip list will
	 * be correctly recomputed.
	 */
	if (pWin->mapped) 
	{
	    DisableMapUnmapEvents (pWin);
	    UnmapWindow (pWin, FALSE);
	    EnableMapUnmapEvents (pWin);
	}
	if (cw->damageRegistered)
	{
	    DamageUnregister (&pWin->drawable, cw->damage);
	    cw->damageRegistered = FALSE;
	}
	cw->update = CompositeRedirectManual;
    }

    if (!compCheckRedirect (pWin))
    {
	FreeResource (ccw->id, RT_NONE);
	return BadAlloc;
    }
    if (wasMapped && !pWin->mapped)
    {
	Bool	overrideRedirect = pWin->overrideRedirect;
	pWin->overrideRedirect = TRUE;
	DisableMapUnmapEvents (pWin);
	MapWindow (pWin, pClient);
	EnableMapUnmapEvents (pWin);
	pWin->overrideRedirect = overrideRedirect;
    }
    
    return Success;
}
Esempio n. 8
0
/*
 * Redirect one window for one client
 */
int
compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update)
{
    CompWindowPtr cw = GetCompWindow(pWin);
    CompClientWindowPtr ccw;
    CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
    WindowPtr pLayerWin = NULL;
    Bool anyMarked = FALSE;

    if (pWin == cs->pOverlayWin) {
        return Success;
    }

    if (!pWin->parent)
        return BadMatch;

    /*
     * Only one Manual update is allowed
     */
    if (cw && update == CompositeRedirectManual)
        for (ccw = cw->clients; ccw; ccw = ccw->next)
            if (ccw->update == CompositeRedirectManual)
                return BadAccess;

    /*
     * Allocate per-client per-window structure 
     * The client *could* allocate multiple, but while supported,
     * it is not expected to be common
     */
    ccw = malloc(sizeof(CompClientWindowRec));
    if (!ccw)
        return BadAlloc;
    ccw->id = FakeClientID(pClient->index);
    ccw->update = update;
    /*
     * Now make sure there's a per-window structure to hang this from
     */
    if (!cw) {
        cw = malloc(sizeof(CompWindowRec));
        if (!cw) {
            free(ccw);
            return BadAlloc;
        }
        cw->damage = DamageCreate(compReportDamage,
                                  compDestroyDamage,
                                  DamageReportNonEmpty,
                                  FALSE, pWin->drawable.pScreen, pWin);
        if (!cw->damage) {
            free(ccw);
            free(cw);
            return BadAlloc;
        }

        anyMarked = compMarkWindows(pWin, &pLayerWin);

        RegionNull(&cw->borderClip);
        cw->update = CompositeRedirectAutomatic;
        cw->clients = 0;
        cw->oldx = COMP_ORIGIN_INVALID;
        cw->oldy = COMP_ORIGIN_INVALID;
        cw->damageRegistered = FALSE;
        cw->damaged = FALSE;
        cw->pOldPixmap = NullPixmap;
        dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw);
    }
    ccw->next = cw->clients;
    cw->clients = ccw;
    if (!AddResource(ccw->id, CompositeClientWindowType, pWin))
        return BadAlloc;
    if (ccw->update == CompositeRedirectManual) {
        if (!anyMarked)
            anyMarked = compMarkWindows(pWin, &pLayerWin);

        if (cw->damageRegistered) {
            DamageUnregister(&pWin->drawable, cw->damage);
            cw->damageRegistered = FALSE;
        }
        cw->update = CompositeRedirectManual;
    }
    else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
        if (!anyMarked)
            anyMarked = compMarkWindows(pWin, &pLayerWin);
    }

    if (!compCheckRedirect(pWin)) {
        FreeResource(ccw->id, RT_NONE);
        return BadAlloc;
    }

    if (anyMarked)
        compHandleMarkedWindows(pWin, pLayerWin);

    return Success;
}
Esempio n. 9
0
Bool
xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
{
    ScrnInfoPtr		pScrn = crtc->scrn;
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    ScreenPtr		pScreen = pScrn->pScreen;
    
    if (rotation == RR_Rotate_0)
    {
	/* Free memory from rotation */
	if (crtc->rotatedPixmap || crtc->rotatedData)
	{
	    crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
	    crtc->rotatedPixmap = NULL;
	    crtc->rotatedData = NULL;
	}

	if (xf86_config->rotation_damage)
	{
	    /* Free damage structure */
	    DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
			      xf86_config->rotation_damage);
	    xf86_config->rotation_damage_registered = FALSE;
	    DamageDestroy (xf86_config->rotation_damage);
	    xf86_config->rotation_damage = NULL;
	    /* Free block/wakeup handler */
	    RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
					  xf86RotateWakeupHandler,
					  (pointer) pScreen);
	}
    }
    else
    {
	/* 
	 * these are the size of the shadow pixmap, which
	 * matches the mode, not the pre-rotated copy in the
	 * frame buffer
	 */
	int	    width = mode->HDisplay;
	int	    height = mode->VDisplay;
	void	    *shadowData = crtc->rotatedData;
	PixmapPtr   shadow = crtc->rotatedPixmap;
	int	    old_width = shadow ? shadow->drawable.width : 0;
	int	    old_height = shadow ? shadow->drawable.height : 0;
	
	/* Allocate memory for rotation */
	if (old_width != width || old_height != height)
	{
	    if (shadow || shadowData)
	    {
		crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
		crtc->rotatedPixmap = NULL;
		crtc->rotatedData = NULL;
	    }
	    shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
	    if (!shadowData)
		goto bail1;
	    crtc->rotatedData = shadowData;
	    /* shadow will be damaged in xf86RotatePrepare */
	}
	else
	{
	    /* mark shadowed area as damaged so it will be repainted */
	    xf86CrtcDamageShadow (crtc);
	}
	
	if (!xf86_config->rotation_damage)
	{
	    /* Create damage structure */
	    xf86_config->rotation_damage = DamageCreate (NULL, NULL,
						DamageReportNone,
						TRUE, pScreen, pScreen);
	    if (!xf86_config->rotation_damage)
		goto bail2;
	    
	    /* Assign block/wakeup handler */
	    if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
						 xf86RotateWakeupHandler,
						 (pointer) pScreen))
	    {
		goto bail3;
	    }
	}
	if (0)
	{
bail3:
	    DamageDestroy (xf86_config->rotation_damage);
	    xf86_config->rotation_damage = NULL;
	    
bail2:
	    if (shadow || shadowData)
	    {
		crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
		crtc->rotatedPixmap = NULL;
		crtc->rotatedData = NULL;
	    }
bail1:
	    if (old_width && old_height)
		crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
								  NULL,
								  old_width,
								  old_height);
	    return FALSE;
	}
    }
    
    /* All done */
    return TRUE;
}
Esempio n. 10
0
/* 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.
             */
            DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
            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);

            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;
    }
}