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; } }
/* * 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); }
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; }
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); }
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; }
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; }
/* * 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"); } }
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; } }
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; }
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); }
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); }
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); }
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); }
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; }
/* * 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); }
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; }
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); }
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; }
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; }
/** 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; }
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; }