Пример #1
0
static void
sna_present_unflip(ScreenPtr screen, uint64_t event_id)
{
	struct sna *sna = to_sna_from_screen(screen);
	struct kgem_bo *bo;

	DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id));
	if (sna->mode.front_active == 0 || sna->mode.shadow_active) {
		const struct ust_msc *swap;

		DBG(("%s: no CRTC active, perform no-op flip\n", __FUNCTION__));

notify:
		swap = sna_crtc_last_swap(sna_mode_first_crtc(sna));
		DBG(("%s: pipe=%d, tv=%d.%06d msc %lld, event %lld complete\n", __FUNCTION__,
		     -1,
		     swap->tv_sec, swap->tv_usec, (long long)swap->msc,
		     (long long)event_id));
		present_event_notify(event_id,
				     ust64(swap->tv_sec, swap->tv_usec),
				     swap->msc);
		return;
	}

	bo = get_flip_bo(screen->GetScreenPixmap(screen));
	if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) {
		DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__));
		xf86SetDesiredModes(sna->scrn);
		goto notify;
	}
}
Пример #2
0
/*
 * Queue a flip back to the normal frame buffer
 */
static void
intel_present_unflip(ScreenPtr screen, uint64_t event_id)
{
	ScrnInfoPtr                             scrn = xf86ScreenToScrn(screen);
	intel_screen_private                    *intel = intel_get_screen_private(scrn);
	PixmapPtr                               pixmap = screen->GetScreenPixmap(screen);
	struct intel_present_vblank_event       *event = NULL;
	dri_bo                                  *bo;

	if (!intel_present_check_flip(NULL, screen->root, pixmap, true))
		goto fail;

	bo = intel_get_pixmap_bo(pixmap);
	if (!bo)
		goto fail;

	event = calloc(1, sizeof(struct intel_present_vblank_event));
	if (!event)
		goto fail;

	event->event_id = event_id;

	if (!intel_do_pageflip(intel, bo, -1, FALSE, event,
			       intel_present_flip_event,
			       intel_present_flip_abort))
		goto fail;

	return;
fail:
	xf86SetDesiredModes(scrn);
	present_event_notify(event_id, 0, 0);
	free(event);
}
Пример #3
0
static Bool
XAPixmapIsOffscreen(PixmapPtr pPixmap)
{
	ScreenPtr pScreen = pPixmap->drawable.pScreen;
	struct xa_surface *surf = msm_get_pixmap_surf(pPixmap);

	if ((pScreen->GetScreenPixmap(pScreen) == pPixmap)) {
		return TRUE;
	}

	if (!surf) {
		/* because we are pretending to handle unaccel (1bpp, etc)
		 * pixmaps too..
		 * this is pretty lame, revisit using EXA_MIXED_PIXMAPS
		 */
		struct msm_pixmap_priv *priv =
			exaGetPixmapDriverPrivate(pPixmap);

		if (priv && priv->ptr) {
			return TRUE;
		}
	}

	if (surf)
		return TRUE;

	return FALSE;
}
Пример #4
0
static Bool
glamor_egl_close_screen(ScreenPtr screen)
{
    ScrnInfoPtr scrn;
    struct glamor_egl_screen_private *glamor_egl;
    PixmapPtr screen_pixmap;
    EGLImageKHR back_image;

    scrn = xf86ScreenToScrn(screen);
    glamor_egl = glamor_egl_get_screen_private(scrn);
    screen_pixmap = screen->GetScreenPixmap(screen);

    eglDestroyImageKHR(glamor_egl->display,glamor_egl->front_image);
    dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key,
                  NULL);
    glamor_egl->front_image = NULL;
    if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
        back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
                                      glamor_egl_pixmap_private_key);
        if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
            eglDestroyImageKHR(glamor_egl->display, back_image);
            dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
                          glamor_egl_pixmap_private_key, NULL);
        }
    }

    screen->CloseScreen = glamor_egl->saved_close_screen;

    return screen->CloseScreen(screen);
}
static void
nouveau_present_flip_stop(ScreenPtr screen, uint64_t event_id)
{
	PixmapPtr pixmap = screen->GetScreenPixmap(screen);
	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
	nouveau_present_flip_exec(scrn, event_id, 0, 0, pixmap, TRUE);
}
Пример #6
0
Bool
rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
                   CARD32 mmWidth, CARD32 mmHeight)
{
    PixmapPtr screenPixmap;
    BoxRec box;

    ErrorF("rdpRRScreenSetSize: width %d height %d mmWidth %d mmHeight %d\n",
           width, height, (int)mmWidth, (int)mmHeight);

    if ((width < 1) || (height < 1))
    {
        ErrorF("  error width %d height %d\n", width, height);
        return FALSE;
    }

    g_rdpScreen.width = width;
    g_rdpScreen.height = height;
    g_rdpScreen.paddedWidthInBytes =
        PixmapBytePad(g_rdpScreen.width, g_rdpScreen.depth);
    g_rdpScreen.sizeInBytes =
        g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height;
    pScreen->width = width;
    pScreen->height = height;
    pScreen->mmWidth = mmWidth;
    pScreen->mmHeight = mmHeight;

    screenPixmap = pScreen->GetScreenPixmap(pScreen);

    if (screenPixmap != 0)
    {
        ErrorF("  resizing screenPixmap [%p] to %dx%d, currently at %dx%d\n",
               (void *)screenPixmap, width, height,
               screenPixmap->drawable.width, screenPixmap->drawable.height);
        pScreen->ModifyPixmapHeader(screenPixmap, width, height,
                                    g_rdpScreen.depth, g_rdpScreen.bitsPerPixel,
                                    g_rdpScreen.paddedWidthInBytes,
                                    g_rdpScreen.pfbMemory);
        ErrorF("  pixmap resized to %dx%d\n",
               screenPixmap->drawable.width, screenPixmap->drawable.height);
    }

    DEBUG_OUT(("  root window %p\n", (void *)pScreen->root));
    box.x1 = 0;
    box.y1 = 0;
    box.x2 = width;
    box.y2 = height;
    RegionInit(&pScreen->root->winSize, &box, 1);
    RegionInit(&pScreen->root->borderSize, &box, 1);
    RegionReset(&pScreen->root->borderClip, &box);
    RegionBreak(&pScreen->root->clipList);
    pScreen->root->drawable.width = width;
    pScreen->root->drawable.height = height;
    ResizeChildrenWinSize(pScreen->root, 0, 0, 0, 0);
    RRGetInfo(pScreen, 1);
    rdpInvalidateArea(g_pScreen, 0, 0, g_rdpScreen.width, g_rdpScreen.height);
    ErrorF("  screen resized to %dx%d\n",
           pScreen->width, pScreen->height);
    return TRUE;
}
Пример #7
0
Bool
rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
                   CARD32 mmWidth, CARD32 mmHeight)
{
    WindowPtr root;
    PixmapPtr screenPixmap;
    BoxRec box;
    rdpPtr dev;

    LLOGLN(0, ("rdpRRScreenSetSize: width %d height %d mmWidth %d mmHeight %d",
           width, height, (int)mmWidth, (int)mmHeight));
    dev = rdpGetDevFromScreen(pScreen);
    root = rdpGetRootWindowPtr(pScreen);
    if ((width < 1) || (height < 1))
    {
        LLOGLN(10, ("  error width %d height %d", width, height));
        return FALSE;
    }
    dev->width = width;
    dev->height = height;
    dev->paddedWidthInBytes = PixmapBytePad(dev->width, dev->depth);
    dev->sizeInBytes = dev->paddedWidthInBytes * dev->height;
    pScreen->width = width;
    pScreen->height = height;
    pScreen->mmWidth = mmWidth;
    pScreen->mmHeight = mmHeight;
    screenPixmap = pScreen->GetScreenPixmap(pScreen);
    g_free(dev->pfbMemory_alloc);
    dev->pfbMemory_alloc = (char *) g_malloc(dev->sizeInBytes + 16, 1);
    dev->pfbMemory = (char *) RDPALIGN(dev->pfbMemory_alloc, 16);
    if (screenPixmap != 0)
    {
        pScreen->ModifyPixmapHeader(screenPixmap, width, height,
                                    -1, -1,
                                    dev->paddedWidthInBytes,
                                    dev->pfbMemory);
    }
    box.x1 = 0;
    box.y1 = 0;
    box.x2 = width;
    box.y2 = height;
    rdpRegionInit(&root->winSize, &box, 1);
    rdpRegionInit(&root->borderSize, &box, 1);
    rdpRegionReset(&root->borderClip, &box);
    rdpRegionBreak(&root->clipList);
    root->drawable.width = width;
    root->drawable.height = height;
    ResizeChildrenWinSize(root, 0, 0, 0, 0);
    RRGetInfo(pScreen, 1);
    LLOGLN(0, ("  screen resized to %dx%d", pScreen->width, pScreen->height));
    RRScreenSizeNotify(pScreen);
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
    xf86EnableDisableFBAccess(pScreen->myNum, FALSE);
    xf86EnableDisableFBAccess(pScreen->myNum, TRUE);
#else
    xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], FALSE);
    xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], TRUE);
#endif
    return TRUE;
}
Пример #8
0
/*
 * Queue a flip back to the normal frame buffer
 */
static void
intel_present_unflip(ScreenPtr screen, uint64_t event_id)
{
	ScrnInfoPtr                             scrn = xf86ScreenToScrn(screen);
	intel_screen_private                    *intel = intel_get_screen_private(scrn);
	struct intel_present_vblank_event       *event;
	PixmapPtr                               pixmap = screen->GetScreenPixmap(screen);
	dri_bo                                  *bo;
	Bool                                    ret;

	if (!intel_present_check_flip(NULL, screen->root, pixmap, true))
		return;

	bo = intel_get_pixmap_bo(pixmap);
	if (!bo)
		return;

	event = calloc(1, sizeof(struct intel_present_vblank_event));
	if (!event)
		return;

	event->event_id = event_id;

	ret = intel_do_pageflip(intel, bo, -1, FALSE, event, intel_present_flip_event, intel_present_flip_abort);
	if (!ret) {
		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
			   "present unflip failed\n");
	}
}
Пример #9
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;
    }
}
Пример #10
0
static int
y_flip(PixmapPtr pixmap, int y)
{
	ScreenPtr screen = pixmap->drawable.pScreen;
	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);

	if (pixmap == screen_pixmap)
		return (pixmap->drawable.height - 1) - y;
	else
		return y;
}
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;
}
Пример #12
0
static Bool
NestedCreateScreenResources(ScreenPtr pScreen) {
    xf86DrvMsg(pScreen->myNum, X_INFO, "NestedCreateScreenResources\n");
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    NestedPrivatePtr pNested = PNESTED(pScrn);
    Bool ret;

    pScreen->CreateScreenResources = pNested->CreateScreenResources;
    ret = pScreen->CreateScreenResources(pScreen);
    pScreen->CreateScreenResources = NestedCreateScreenResources;

    shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), pNested->update,
              /*pNested->window*/ 0, 0, 0);
}
Пример #13
0
Bool
glamor_close_screen(ScreenPtr screen)
{
    glamor_screen_private *glamor_priv;
    PixmapPtr screen_pixmap;
    int flags;

#ifdef RENDER
    PictureScreenPtr ps = GetPictureScreenIfSet(screen);
#endif
    glamor_priv = glamor_get_screen_private(screen);
    flags = glamor_priv->flags;
    glamor_sync_close(screen);
    glamor_glyphs_fini(screen);
    screen->CloseScreen = glamor_priv->saved_procs.close_screen;
    screen->CreateScreenResources =
        glamor_priv->saved_procs.create_screen_resources;
    if (flags & GLAMOR_USE_SCREEN) {

        screen->CreateGC = glamor_priv->saved_procs.create_gc;
        screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
        screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
        screen->GetSpans = glamor_priv->saved_procs.get_spans;
        screen->ChangeWindowAttributes =
            glamor_priv->saved_procs.change_window_attributes;
        screen->CopyWindow = glamor_priv->saved_procs.copy_window;
        screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
    }
#ifdef RENDER
    if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {

        ps->Composite = glamor_priv->saved_procs.composite;
        ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
        ps->Triangles = glamor_priv->saved_procs.triangles;
        ps->CreatePicture = glamor_priv->saved_procs.create_picture;
    }
    ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
    ps->Glyphs = glamor_priv->saved_procs.glyphs;
    ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
    screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
#endif
    screen_pixmap = screen->GetScreenPixmap(screen);
    glamor_set_pixmap_private(screen_pixmap, NULL);
    if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
        glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);

    glamor_release_screen_priv(screen);

    return screen->CloseScreen(screen);
}
Пример #14
0
static Bool
NestedCloseScreen(int scrnIndex, ScreenPtr pScreen) {
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];

    xf86DrvMsg(scrnIndex, X_INFO, "NestedCloseScreen\n");

    shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));

    TimerFree(PNESTED(pScrn)->timer);
    NestedClientCloseScreen(PCLIENTDATA(pScrn));

    pScreen->CloseScreen = PNESTED(pScrn)->CloseScreen;
    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
Пример #15
0
static void *
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
    ScreenPtr pScreen = crtc->scrn->pScreen;
    PixmapPtr rootpix = pScreen->GetScreenPixmap(pScreen);

    /*
     * Use the same depth as for the root pixmap.
     * The associated kms fb will be created on demand once this pixmap
     * is used as scanout by a crtc.
     */

    return pScreen->CreatePixmap(pScreen, width, height,
				 rootpix->drawable.depth, 0);
}
Пример #16
0
static Bool maliPixmapIsOffscreen(PixmapPtr pPix)
{
	ScreenPtr pScreen = pPix->drawable.pScreen;
	PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPix);

	if (pScreen->GetScreenPixmap(pScreen) == pPix)
	{
		return TRUE;
	}

	if (privPixmap)
	{
		return pPix->devPrivate.ptr ? FALSE : TRUE;
	}

	return FALSE;
}
Пример #17
0
/*
 * Queue a flip back to the normal frame buffer
 */
static void
ms_present_unflip(ScreenPtr screen, uint64_t event_id)
{
    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
    PixmapPtr pixmap = screen->GetScreenPixmap(screen);
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
    int i;
    struct ms_present_vblank_event *event;

    event = calloc(1, sizeof(struct ms_present_vblank_event));
    if (!event)
        return;

    event->event_id = event_id;

    if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE) &&
        ms_do_pageflip(screen, pixmap, event, -1, FALSE)) {
        return;
    }

    for (i = 0; i < config->num_crtc; i++) {
        xf86CrtcPtr crtc = config->crtc[i];
	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;

	if (!crtc->enabled)
	    continue;

	/* info->drmmode.fb_id still points to the FB for the last flipped BO.
	 * Clear it, drmmode_set_mode_major will re-create it
	 */
	if (drmmode_crtc->drmmode->fb_id) {
		drmModeRmFB(drmmode_crtc->drmmode->fd,
			    drmmode_crtc->drmmode->fb_id);
		drmmode_crtc->drmmode->fb_id = 0;
	}

	if (drmmode_crtc->dpms_mode == DPMSModeOn)
	    crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation,
					crtc->x, crtc->y);
	else
	    drmmode_crtc->need_modeset = TRUE;
    }

    present_event_notify(event_id, 0, 0);
}
Пример #18
0
Bool
glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
{
    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
    struct glamor_egl_screen_private *glamor_egl;
    PixmapPtr screen_pixmap;

    glamor_egl = glamor_egl_get_screen_private(scrn);
    screen_pixmap = screen->GetScreenPixmap(screen);

    if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
                   "Failed to create textured screen.");
        return FALSE;
    }

    glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
                                               glamor_egl_pixmap_private_key);
    glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
    return TRUE;
}
Пример #19
0
Bool
glamor_close_screen(ScreenPtr screen)
{
    glamor_screen_private *glamor_priv;
    PixmapPtr screen_pixmap;
    PictureScreenPtr ps = GetPictureScreenIfSet(screen);

    glamor_priv = glamor_get_screen_private(screen);
    glamor_sync_close(screen);
    glamor_composite_glyphs_fini(screen);
    screen->CloseScreen = glamor_priv->saved_procs.close_screen;
    screen->CreateScreenResources =
        glamor_priv->saved_procs.create_screen_resources;

    screen->CreateGC = glamor_priv->saved_procs.create_gc;
    screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
    screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
    screen->GetSpans = glamor_priv->saved_procs.get_spans;
    screen->ChangeWindowAttributes =
        glamor_priv->saved_procs.change_window_attributes;
    screen->CopyWindow = glamor_priv->saved_procs.copy_window;
    screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
    screen->BlockHandler = glamor_priv->saved_procs.block_handler;

    ps->Composite = glamor_priv->saved_procs.composite;
    ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
    ps->Triangles = glamor_priv->saved_procs.triangles;
    ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
    ps->Glyphs = glamor_priv->saved_procs.glyphs;

    screen_pixmap = screen->GetScreenPixmap(screen);
    glamor_pixmap_destroy_fbo(screen_pixmap);

    glamor_release_screen_priv(screen);

    return screen->CloseScreen(screen);
}
Пример #20
0
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;
}
Пример #21
0
static Bool
crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
		    Rotation rotation, int x, int y)
{
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
    modesettingPtr ms = modesettingPTR(crtc->scrn);
    ScreenPtr pScreen = crtc->scrn->pScreen;
    xf86OutputPtr output = NULL;
    struct crtc_private *crtcp = crtc->driver_private;
    drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
    drmModeModeInfo drm_mode;
    int i, ret;
    unsigned int connector_id;
    PixmapPtr pixmap;

    for (i = 0; i < config->num_output; output = NULL, i++) {
	output = config->output[i];

	if (output->crtc == crtc)
	    break;
    }

    if (!output) {
	LogMessage(X_ERROR, "No output for this crtc.\n");
	return FALSE;
    }

    connector_id = xorg_output_get_id(output);

    drm_mode.clock = mode->Clock;
    drm_mode.hdisplay = mode->HDisplay;
    drm_mode.hsync_start = mode->HSyncStart;
    drm_mode.hsync_end = mode->HSyncEnd;
    drm_mode.htotal = mode->HTotal;
    drm_mode.vdisplay = mode->VDisplay;
    drm_mode.vsync_start = mode->VSyncStart;
    drm_mode.vsync_end = mode->VSyncEnd;
    drm_mode.vtotal = mode->VTotal;
    drm_mode.flags = mode->Flags;
    drm_mode.hskew = mode->HSkew;
    drm_mode.vscan = mode->VScan;
    drm_mode.vrefresh = mode->VRefresh;
    if (!mode->name)
	xf86SetModeDefaultName(mode);
    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
    drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0';

    /*
     * Check if we need to scanout from something else than the root
     * pixmap. In that case, xf86CrtcRotate will take care of allocating
     * new opaque scanout buffer data "crtc->rotatedData".
     * However, it will not wrap
     * that data into pixmaps until the first rotated damage composite.
     * In out case, the buffer data is actually already a pixmap.
     */

    if (!xf86CrtcRotate(crtc))
	return FALSE;

    if (crtc->transform_in_use && crtc->rotatedData) {
	x = 0;
	y = 0;
	pixmap = (PixmapPtr) crtc->rotatedData;
    } else
	pixmap = pScreen->GetScreenPixmap(pScreen);

    if (crtcp->entry.pixmap != pixmap) {
	if (crtcp->entry.pixmap)
	    vmwgfx_scanout_unref(&crtcp->entry);

	crtcp->entry.pixmap = pixmap;
	crtcp->scanout_id = vmwgfx_scanout_ref(&crtcp->entry);
	if (crtcp->scanout_id == -1) {
	    LogMessage(X_ERROR, "Failed to convert pixmap to scanout.\n");
	    return FALSE;
	}
    }
    ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, crtcp->scanout_id, x, y,
			 &connector_id, 1, &drm_mode);
    if (ret)
	return FALSE;

    vmwgfx_scanout_refresh(pixmap);

    /* Only set gamma when needed, to avoid unneeded delays. */
#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3
    if (!crtc->active && crtc->version >= 3)
	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
			       crtc->gamma_blue, crtc->gamma_size);
    crtc->active = TRUE;
#endif

    return TRUE;
}
Пример #22
0
/** Resize the virtual framebuffer.  After resizing we reset all modes
 * (X.Org 1.3+) to adjust them to the new framebuffer.
 */
Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
{
    ScreenPtr pScreen = pScrn->pScreen;
    PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
    VBOXPtr pVBox = VBOXGetRec(pScrn);
    uint64_t cbLine = vboxLineLength(pScrn, width);
    int displayWidth = vboxDisplayPitch(pScrn, cbLine);

    TRACE_LOG("width=%d, height=%d\n", width, height);
    if (   width == pScrn->virtualX
        && height == pScrn->virtualY
        && displayWidth == pScrn->displayWidth)
        return TRUE;
    if (!pPixmap) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "Failed to get the screen pixmap.\n");
        return FALSE;
    }
    if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax)
    {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available.  Please increase the video memory size.\n",
                   width, height, pVBox->cbFBMax / 1024, pScrn->videoRam);
        return FALSE;
    }
    pScreen->ModifyPixmapHeader(pPixmap, width, height,
                                pScrn->depth, vboxBPP(pScrn), cbLine,
                                pVBox->base);
    vboxClearVRAM(pScrn, width, height);
    pScrn->virtualX = width;
    pScrn->virtualY = height;
    pScrn->displayWidth = displayWidth;
    pVBox->cbLine = cbLine;
#ifdef VBOX_DRI
    if (pVBox->useDRI)
        VBOXDRIUpdateStride(pScrn, pVBox);
#endif
#ifdef VBOXVIDEO_13
    /* Write the new values to the hardware */
    {
        unsigned i;
        for (i = 0; i < pVBox->cScreens; ++i)
            VBOXSetMode(pScrn, i, pVBox->aScreenLocation[i].cx,
                            pVBox->aScreenLocation[i].cy,
                            pVBox->aScreenLocation[i].x,
                            pVBox->aScreenLocation[i].y);
    }
#endif
#ifdef RT_OS_SOLARIS
    /* Tell the virtual mouse device about the new virtual desktop size. */
    {
        int rc;
        int hMouse = open("/dev/mouse", O_RDWR);
        if (hMouse >= 0)
        {
            do {
                Ms_screen_resolution Res = { height, width };
                rc = ioctl(hMouse, MSIOSRESOLUTION, &Res);
            } while ((rc != 0) && (errno == EINTR));
            close(hMouse);
        }
    }
#endif
    return TRUE;
}
Пример #23
0
static Bool vncRandRScreenSetSize(ScreenPtr pScreen,
                                  CARD16 width, CARD16 height,
                                  CARD32 mmWidth, CARD32 mmHeight)
{
    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
    vfbFramebufferInfo fb;
    rrScrPrivPtr rp = rrGetScrPriv(pScreen);
    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
    void *pbits;
    Bool ret;
    int oldwidth, oldheight, oldmmWidth, oldmmHeight;

    /* Prevent updates while we fiddle */
    xf86SetRootClip(pScreen, FALSE);

    /* Store current state in case we fail */
    oldwidth = pScreen->width;
    oldheight = pScreen->height;
    oldmmWidth = pScreen->mmWidth;
    oldmmHeight = pScreen->mmHeight;

    /* Then set the new dimensions */
    pScreen->width = width;
    pScreen->height = height;
    pScreen->mmWidth = mmWidth;
    pScreen->mmHeight = mmHeight;

    /* Allocate a new framebuffer */
    memset(&fb, 0, sizeof(vfbFramebufferInfo));

    fb.width = pScreen->width;
    fb.height = pScreen->height;
    fb.depth = pvfb->fb.depth;

    pbits = vfbAllocateFramebufferMemory(&fb);
    if (!pbits) {
        /* Allocation failed. Restore old state */
        pScreen->width = oldwidth;
        pScreen->height = oldheight;
        pScreen->mmWidth = oldmmWidth;
        pScreen->mmHeight = oldmmHeight;

        xf86SetRootClip(pScreen, TRUE);

        return FALSE;
    }

    /* Update root pixmap with the new dimensions and buffer */
    ret = pScreen->ModifyPixmapHeader(rootPixmap, fb.width, fb.height,
                                      -1, -1, fb.paddedBytesWidth, pbits);
    if (!ret) {
        /* Update failed. Free the new framebuffer and restore old state */
        vfbFreeFramebufferMemory(&fb);

        pScreen->width = oldwidth;
        pScreen->height = oldheight;
        pScreen->mmWidth = oldmmWidth;
        pScreen->mmHeight = oldmmHeight;

        xf86SetRootClip(pScreen, TRUE);

        return FALSE;
    }

    /* Free the old framebuffer and keep the info about the new one */
    vfbFreeFramebufferMemory(&pvfb->fb);
    memcpy(&pvfb->fb, &fb, sizeof(vfbFramebufferInfo));

    /* Let VNC get the new framebuffer (actual update is in vncHooks.cc) */
    vncFbptr[pScreen->myNum] = pbits;
    vncFbstride[pScreen->myNum] = fb.paddedWidth;

    /* Restore ability to update screen, now with new dimensions */
    xf86SetRootClip(pScreen, TRUE);

    /*
     * Let RandR know we changed something (it doesn't assume that
     * TRUE means something changed for some reason...).
     */
    RRScreenSizeNotify(pScreen);

    /* Crop all CRTCs to the new screen */
    for (int i = 0;i < rp->numCrtcs;i++) {
        RRCrtcPtr crtc;
        RRModePtr mode;

        crtc = rp->crtcs[i];

        /* Disabled? */
        if (crtc->mode == NULL)
            continue;

        /* Fully inside? */
        if ((crtc->x + crtc->mode->mode.width <= width) &&
            (crtc->y + crtc->mode->mode.height <= height))
            continue;

        /* Fully outside? */
        if ((crtc->x >= width) || (crtc->y >= height)) {
            /* Disable it */
            ret = vncRandRCrtcSet(pScreen, crtc, NULL,
                                  crtc->x, crtc->y, crtc->rotation, 0, NULL);
            if (!ret)
                ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions");
            continue;
        }

        /* Just needs to be resized to a temporary mode */
        mode = vncRandRModeGet(width - crtc->x, height - crtc->y);
        if (mode == NULL) {
            ErrorF("Warning: Unable to create custom mode for %dx%d",
                   width - crtc->x, height - crtc->y);
            continue;
        }

        ret = vncRandRCrtcSet(pScreen, crtc, mode,
                              crtc->x, crtc->y, crtc->rotation,
                              crtc->numOutputs, crtc->outputs);
        RRModeDestroy(mode);
        if (!ret)
            ErrorF("Warning: Unable to crop CRTC to new screen dimensions");
    }

    return TRUE;
}