PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint) { PixmapPtr rv; rdpPixmapRec* priv; int org_width; org_width = width; /* width must be a multiple of 4 in rdp */ width = (width + 3) & ~3; LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d", width, org_width)); pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); priv = GETPIXPRIV(rv); priv->rdpindex = -1; if ((rv->drawable.depth == g_rdpScreen.depth) && (org_width > 1) && (height > 1)) { priv->allocBytes = width * height * g_Bpp; priv->rdpindex = rdpup_add_os_bitmap(rv, priv); if (priv->rdpindex >= 0) { priv->status = 1; rdpup_create_os_surface(priv->rdpindex, width, height); } } pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->CreatePixmap = rdpCreatePixmap; return rv; }
static PixmapPtr gma_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned usage) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); gma500Ptr gma = gma500PTR(scrn); struct gma_bo *bo; PixmapPtr pixmap; if (uxa_swapped_out(screen)) { goto fallback; } if (!w || !h) { goto fallback; } bo = gma_bo_create_surface(gma->fd, w, h, depth, GMA_BO_BLIT, 0); if (bo) { pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); screen->ModifyPixmapHeader(pixmap, w, h, -1, -1, -1, NULL); pixmap->devKind = bo->pitch; gma_set_surface(pixmap, bo); } else { fallback: /* Software fallback */ pixmap = fbCreatePixmap(screen, w, h, depth, usage); } return pixmap; }
/* * RootlessUpdateScreenPixmap * miCreateScreenResources does not like a null framebuffer pointer, * it leaves the screen pixmap with an uninitialized data pointer. * Thus, rootless implementations typically set the framebuffer width * to zero so that miCreateScreenResources does not allocate a screen * pixmap for us. We allocate our own screen pixmap here since we need * the screen pixmap to be valid (e.g. CopyArea from the root window). */ void RootlessUpdateScreenPixmap(ScreenPtr pScreen) { RootlessScreenRec *s = SCREENREC(pScreen); PixmapPtr pPix; unsigned int rowbytes; pPix = (*pScreen->GetScreenPixmap)(pScreen); if (pPix == NULL) { pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); (*pScreen->SetScreenPixmap)(pPix); } rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth); if (s->pixmap_data_size < rowbytes) { free(s->pixmap_data); s->pixmap_data_size = rowbytes; s->pixmap_data = malloc(s->pixmap_data_size); if (s->pixmap_data == NULL) return; memset(s->pixmap_data, 0xFF, s->pixmap_data_size); pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height, pScreen->rootDepth, BitsPerPixel(pScreen->rootDepth), 0, s->pixmap_data); /* ModifyPixmapHeader ignores zero arguments, so install rowbytes by hand. */ pPix->devKind = 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; }
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; }
static Bool radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct radeon_surface surface; struct radeon_pixmap *priv; if (!radeon_set_shared_pixmap_backing(pixmap, handle, &surface)) return FALSE; priv = radeon_get_pixmap_private(pixmap); priv->surface = surface; if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to get PRIME drawable for glamor pixmap.\n"); return FALSE; } screen->ModifyPixmapHeader(pixmap, pixmap->drawable.width, pixmap->drawable.height, 0, 0, 0, NULL); return TRUE; }
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 PixmapPtr intel_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; PixmapPtr pixmap; dri_bo *bo; if (depth < 8) return NULL; switch (bpp) { case 8: case 16: case 32: break; default: return NULL; } pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); if (!pixmap) return NULL; if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL)) goto free_pixmap; bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, fd, (uint32_t)height * stride); if (bo == NULL) goto free_pixmap; intel_uxa_set_pixmap_bo(pixmap, bo); dri_bo_unreference(bo); priv = intel_uxa_get_pixmap_private(pixmap); if (priv == NULL) goto free_pixmap; priv->pinned |= PIN_DRI3; return pixmap; free_pixmap: fbDestroyPixmap(pixmap); return NULL; }
Bool rdpModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) { Bool rv; ScreenPtr pScreen; rdpPtr dev; LLOGLN(10, ("rdpModifyPixmapHeader:")); pScreen = pPixmap->drawable.pScreen; dev = rdpGetDevFromScreen(pScreen); pScreen->ModifyPixmapHeader = dev->ModifyPixmapHeader; rv = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); pScreen->ModifyPixmapHeader = rdpModifyPixmapHeader; return rv; }
PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint) { PixmapPtr rv; rdpPixmapRec *priv; int org_width; org_width = width; /* width must be a multiple of 4 in rdp */ width = (width + 3) & ~3; LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d depth %d screen depth %d", width, org_width, depth, g_rdpScreen.depth)); pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); priv = GETPIXPRIV(rv); priv->rdpindex = -1; priv->con_number = g_con_number; priv->kind_width = width; pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->CreatePixmap = rdpCreatePixmap; return rv; }
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; }
Bool exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData) { ScreenPtr pScreen; ExaScreenPrivPtr pExaScr; ExaPixmapPrivPtr pExaPixmap; Bool ret; if (!pPixmap) return FALSE; pScreen = pPixmap->drawable.pScreen; pExaScr = ExaGetScreenPriv(pScreen); pExaPixmap = ExaGetPixmapPriv(pPixmap); if (pExaPixmap) { if (pPixData) pExaPixmap->sys_ptr = pPixData; if (devKind > 0) pExaPixmap->sys_pitch = devKind; /* Classic EXA: * - Framebuffer. * - Scratch pixmap with gpu memory. */ if (pExaScr->info->memoryBase && pPixData) { if ((CARD8 *) pPixData >= pExaScr->info->memoryBase && ((CARD8 *) pPixData - pExaScr->info->memoryBase) < pExaScr->info->memorySize) { pExaPixmap->fb_ptr = pPixData; pExaPixmap->fb_pitch = devKind; pExaPixmap->use_gpu_copy = TRUE; } } if (width > 0 && height > 0 && bitsPerPixel > 0) { exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel); exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel); } /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or * gpu memory, so there's no need to track damage. */ if (pExaPixmap->pDamage) { DamageDestroy(pExaPixmap->pDamage); pExaPixmap->pDamage = NULL; } } swap(pExaScr, pScreen, ModifyPixmapHeader); ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); swap(pExaScr, pScreen, ModifyPixmapHeader); /* Always NULL this, we don't want lingering pointers. */ pPixmap->devPrivate.ptr = NULL; return ret; }
/** * glamor_trapezoids will generate trapezoid mask accumulating in * system memory. */ void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; BoxRec bounds; PicturePtr picture; INT16 x_dst, y_dst; INT16 x_rel, y_rel; int width, height, stride; PixmapPtr pixmap; pixman_image_t *image = NULL; /* If a mask format wasn't provided, we get to choose, but behavior should * be as if there was no temporary mask the traps were accumulated into. */ if (!mask_format) { if (dst->polyEdge == PolyEdgeSharp) mask_format = PictureMatchFormat(screen, 1, PICT_a1); else mask_format = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, 1, traps); return; } miTrapezoidBounds(ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; stride = PixmapBytePad(width, mask_format->depth); picture = glamor_create_mask_picture(screen, dst, mask_format, width, height); if (!picture) return; image = pixman_image_create_bits(picture->format, width, height, NULL, stride); if (!image) { FreePicture(picture, 0); return; } for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); pixmap = glamor_get_drawable_pixmap(picture->pDrawable); screen->ModifyPixmapHeader(pixmap, width, height, mask_format->depth, BitsPerPixel(mask_format->depth), PixmapBytePad(width, mask_format->depth), pixman_image_get_data(image)); x_rel = bounds.x1 + x_src - x_dst; y_rel = bounds.y1 + y_src - y_dst; CompositePicture(op, src, picture, dst, x_rel, y_rel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (image) pixman_image_unref(image); FreePicture(picture, 0); }
PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) { PixmapPtr pixmap; glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY; glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_fbo *fbo = NULL; int pitch; GLenum format; if (w > 32767 || h > 32767) return NullPixmap; if ((usage == GLAMOR_CREATE_PIXMAP_CPU || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64) || (w == 0 && h == 0) || !glamor_check_pixmap_fbo_depth(depth)) || (!GLAMOR_TEXTURED_LARGE_PIXMAP && !glamor_check_fbo_size(glamor_priv, w, h))) return fbCreatePixmap(screen, w, h, depth, usage); else pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); pixmap_priv = calloc(1, sizeof(*pixmap_priv)); if (!pixmap_priv) { fbDestroyPixmap(pixmap); return fbCreatePixmap(screen, w, h, depth, usage); } glamor_set_pixmap_private(pixmap, pixmap_priv); if (usage == GLAMOR_CREATE_PIXMAP_MAP) type = GLAMOR_MEMORY_MAP; pixmap_priv->base.pixmap = pixmap; pixmap_priv->base.glamor_priv = glamor_priv; format = gl_iformat_for_pixmap(pixmap); pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3; screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) { pixmap_priv->type = GLAMOR_TEXTURE_ONLY; pixmap_priv->base.box.x1 = 0; pixmap_priv->base.box.y1 = 0; pixmap_priv->base.box.x2 = w; pixmap_priv->base.box.y2 = h; return pixmap; } else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE || glamor_check_fbo_size(glamor_priv, w, h)) { pixmap_priv->type = type; pixmap_priv->base.box.x1 = 0; pixmap_priv->base.box.y1 = 0; pixmap_priv->base.box.x2 = w; pixmap_priv->base.box.y2 = h; fbo = glamor_create_fbo(glamor_priv, w, h, format, usage); } else { int tile_size = glamor_priv->max_fbo_size; DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size); pixmap_priv->type = GLAMOR_TEXTURE_LARGE; fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage, tile_size, tile_size, pixmap_priv); } if (fbo == NULL) { fbDestroyPixmap(pixmap); free(pixmap_priv); return fbCreatePixmap(screen, w, h, depth, usage); } glamor_pixmap_attach_fbo(pixmap, fbo); return pixmap; }
/** 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; }
PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { #ifdef GLAMOR_HAS_GBM ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl; struct gbm_bo *bo; EGLImageKHR image; PixmapPtr pixmap; Bool ret = FALSE; EGLint attribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, EGL_DMA_BUF_PLANE0_FD_EXT, 0, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, EGL_NONE }; glamor_egl = glamor_egl_get_screen_private(scrn); if (!glamor_egl->dri3_capable) return NULL; if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0) return NULL; attribs[1] = width; attribs[3] = height; attribs[7] = fd; attribs[11] = stride; image = eglCreateImageKHR(glamor_egl->display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (image == EGL_NO_IMAGE_KHR) return NULL; /* EGL_EXT_image_dma_buf_import can impose restrictions on the * usage of the image. Use gbm_bo to bypass the limitations. */ bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); eglDestroyImageKHR(glamor_egl->display, image); if (!bo) return NULL; pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL); ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); gbm_bo_destroy(bo); if (ret) return pixmap; else { screen->DestroyPixmap(pixmap); return NULL; } #else return NULL; #endif }
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; }
static PixmapPtr radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned usage) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); struct radeon_pixmap *priv; PixmapPtr pixmap, new_pixmap = NULL; if (!RADEON_CREATE_PIXMAP_SHARED(usage)) { if (info->shadow_primary) { if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) return fbCreatePixmap(screen, w, h, depth, usage); } else { pixmap = glamor_create_pixmap(screen, w, h, depth, usage); if (pixmap) return pixmap; } } if (w > 32767 || h > 32767) return NullPixmap; if (depth == 1) return fbCreatePixmap(screen, w, h, depth, usage); if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32) return fbCreatePixmap(screen, w, h, depth, usage); pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); if (pixmap == NullPixmap) return pixmap; if (w && h) { int stride; priv = calloc(1, sizeof (struct radeon_pixmap)); if (priv == NULL) goto fallback_pixmap; priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage, pixmap->drawable.bitsPerPixel, &stride, &priv->surface, &priv->tiling_flags); if (!priv->bo) goto fallback_priv; radeon_set_pixmap_private(pixmap, priv); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) goto fallback_glamor; pixmap->devPrivate.ptr = NULL; } return pixmap; fallback_glamor: if (RADEON_CREATE_PIXMAP_SHARED(usage)) { /* XXX need further work to handle the DRI2 failure case. * Glamor don't know how to handle a BO only pixmap. Put * a warning indicator here. */ xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Failed to create textured DRI2/PRIME pixmap."); return pixmap; } /* Create textured pixmap failed means glamor failed to * create a texture from current BO for some reasons. We turn * to create a new glamor pixmap and clean up current one. * One thing need to be noted, this new pixmap doesn't * has a priv and bo attached to it. It's glamor's responsbility * to take care of it. Glamor will mark this new pixmap as a * texture only pixmap and will never fallback to DDX layer * afterwards. */ new_pixmap = glamor_create_pixmap(screen, w, h, depth, usage); radeon_bo_unref(priv->bo); fallback_priv: free(priv); fallback_pixmap: fbDestroyPixmap(pixmap); if (new_pixmap) return new_pixmap; else return fbCreatePixmap(screen, w, h, depth, usage); }