示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
/*
 * 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;
    }
}
示例#4
0
文件: rdpRandR.c 项目: RonYaari/xrdp
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;
}
示例#5
0
文件: rdprandr.c 项目: AsherBond/xrdp
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;
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
文件: rdpdraw.c 项目: piccolo/xrdp
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;
}
示例#11
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;
}
示例#12
0
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;
}
示例#13
0
/**
 * 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);
}
示例#14
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;
}
示例#15
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;
}
示例#16
0
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
}
示例#17
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;
}
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);
}