Beispiel #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;
}
static DRI2Buffer2Ptr
vivante_dri2_CreateBuffer(DrawablePtr drawable, unsigned int attachment,
	unsigned int format)
{
	struct vivante_dri2_buffer *buf;
	struct vivante_pixmap *vpix;
	ScreenPtr pScreen = drawable->pScreen;
	PixmapPtr pixmap = NULL;
	uint32_t name;

fprintf(stderr, "%s: %p %u %u\n", __func__, drawable, attachment, format);
	if (attachment == DRI2BufferFrontLeft) {
		pixmap = vivante_dri2_get_front_pixmap(drawable);
		if (!pixmap) {
			drawable = &pixmap->drawable;
			pixmap = NULL;
		}
	}

	if (pixmap == NULL) {
		int width = drawable->width;
		int height = drawable->height;
		int depth = format ? format : drawable->depth;

		pixmap = pScreen->CreatePixmap(pScreen, width, height, depth, 0);
		if (!pixmap)
			goto err;
	}

	vpix = vivante_get_pixmap_priv(pixmap);
	if (!vpix)
		goto err;

	buf = calloc(1, sizeof *buf);
	if (!buf)
		goto err;

	if (!vpix->bo || drm_armada_bo_flink(vpix->bo, &name)) {
		free(buf);
		goto err;
	}

	buf->dri2.attachment = attachment;
	buf->dri2.name = name;
	buf->dri2.pitch = pixmap->devKind;
	buf->dri2.cpp = pixmap->drawable.bitsPerPixel / 8;
	buf->dri2.flags = 0;
	buf->dri2.format = format;
	buf->dri2.driverPrivate = buf;
	buf->pixmap = pixmap;
	buf->ref = 1;

	return &buf->dri2;

 err:
	if (pixmap)
		pScreen->DestroyPixmap(pixmap);

	return NULL;
}
static PixmapPtr
createpix(DrawablePtr pDraw)
{
	ScreenPtr pScreen = pDraw->pScreen;
	return pScreen->CreatePixmap(pScreen,
			pDraw->width, pDraw->height, pDraw->depth,
			CREATE_PIXMAP_USAGE_DRI2);
}
static PixmapPtr
createpix(DrawablePtr pDraw)
{
	ScreenPtr pScreen = pDraw->pScreen;
	int flags = canflip(pDraw) ? ARMSOC_CREATE_PIXMAP_SCANOUT : 0;
	return pScreen->CreatePixmap(pScreen,
			pDraw->width, pDraw->height, pDraw->depth, flags);
}
Beispiel #5
0
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth)
{
    rdpPtr dev;
    PixmapPtr rv;

    LLOGLN(10, ("rdpCreatePixmap: width %d height %d depth %d",
           width, height, depth));
    dev = rdpGetDevFromScreen(pScreen);
    pScreen->CreatePixmap = dev->CreatePixmap;
    rv = pScreen->CreatePixmap(pScreen, width, height, depth);
    pScreen->CreatePixmap = rdpCreatePixmap;
    return rv;
}
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);
}
Beispiel #7
0
Bool
shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window)
{
    PixmapPtr pPixmap;
    
    pPixmap = pScreen->CreatePixmap(pScreen, pScreen->width, pScreen->height,
				    pScreen->rootDepth);
    if (!pPixmap)
	return FALSE;
    
    if (!shadowSetup(pScreen)) {
	pScreen->DestroyPixmap(pPixmap);
	return FALSE;
    }

    shadowAdd(pScreen, pPixmap, update, window, NULL, SHADOW_ROTATE_0, 0);

    return TRUE;
}
Beispiel #8
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 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;
}
Beispiel #9
0
Bool
CreateDefaultStipple(int screenNum)
{
    ScreenPtr pScreen;
    ChangeGCVal tmpval[3];
    xRectangle rect;
    CARD16 w, h;
    GCPtr pgcScratch;

    pScreen = screenInfo.screens[screenNum];

    w = 16;
    h = 16;
    (*pScreen->QueryBestSize) (StippleShape, &w, &h, pScreen);
    if (!(pScreen->defaultStipple = pScreen->CreatePixmap(pScreen, w, h, 1, 0)))
        return FALSE;
    /* fill stipple with 1 */
    tmpval[0].val = GXcopy;
    tmpval[1].val = 1;
    tmpval[2].val = FillSolid;
    pgcScratch = GetScratchGC(1, pScreen);
    if (!pgcScratch) {
        (*pScreen->DestroyPixmap) (pScreen->defaultStipple);
        return FALSE;
    }
    (void) ChangeGC(NullClient, pgcScratch,
                    GCFunction | GCForeground | GCFillStyle, tmpval);
    ValidateGC((DrawablePtr) pScreen->defaultStipple, pgcScratch);
    rect.x = 0;
    rect.y = 0;
    rect.width = w;
    rect.height = h;
    (*pgcScratch->ops->PolyFillRect) ((DrawablePtr) pScreen->defaultStipple,
                                      pgcScratch, 1, &rect);
    FreeScratchGC(pgcScratch);
    return TRUE;
}
Beispiel #10
0
/**
 * exaCreatePixmap() creates a new pixmap.
 *
 * If width and height are 0, this won't be a full-fledged pixmap and it will
 * get ModifyPixmapHeader() called on it later.  So, we mark it as pinned, because
 * ModifyPixmapHeader() would break migration.  These types of pixmaps are used
 * for scratch pixmaps, or to represent the visible screen.
 */
PixmapPtr
exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
                        unsigned usage_hint)
{
    PixmapPtr pPixmap;
    ExaPixmapPrivPtr pExaPixmap;
    BoxRec box;
    int bpp;

    ExaScreenPriv(pScreen);

    if (w > 32767 || h > 32767)
        return NullPixmap;

    swap(pExaScr, pScreen, CreatePixmap);
    pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
    swap(pExaScr, pScreen, CreatePixmap);

    if (!pPixmap)
        return NULL;

    pExaPixmap = ExaGetPixmapPriv(pPixmap);
    pExaPixmap->driverPriv = NULL;

    bpp = pPixmap->drawable.bitsPerPixel;

    pExaPixmap->driverPriv = NULL;
    /* Scratch pixmaps may have w/h equal to zero, and may not be
     * migrated.
     */
    if (!w || !h)
        pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
    else
        pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;

    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
    pExaPixmap->sys_pitch = pPixmap->devKind;

    pPixmap->devPrivate.ptr = NULL;
    pExaPixmap->use_gpu_copy = FALSE;

    pExaPixmap->fb_ptr = NULL;
    exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
    pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;

    if (pExaPixmap->fb_pitch > 131071) {
        swap(pExaScr, pScreen, DestroyPixmap);
        pScreen->DestroyPixmap(pPixmap);
        swap(pExaScr, pScreen, DestroyPixmap);
        return NULL;
    }

    /* Set up damage tracking */
    pExaPixmap->pDamage = DamageCreate(NULL, NULL,
                                       DamageReportNone, TRUE,
                                       pScreen, pPixmap);

    if (pExaPixmap->pDamage == NULL) {
        swap(pExaScr, pScreen, DestroyPixmap);
        pScreen->DestroyPixmap(pPixmap);
        swap(pExaScr, pScreen, DestroyPixmap);
        return NULL;
    }

    DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
    /* This ensures that pending damage reflects the current operation. */
    /* This is used by exa to optimize migration. */
    DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);

    pExaPixmap->area = NULL;

    /* We set the initial pixmap as completely valid for a simple reason.
     * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which
     * could form single pixel rects as part of a region. Setting the complete region
     * as valid is a natural defragmentation of the region.
     */
    box.x1 = 0;
    box.y1 = 0;
    box.x2 = w;
    box.y2 = h;
    RegionInit(&pExaPixmap->validSys, &box, 0);
    RegionInit(&pExaPixmap->validFB, &box, 0);

    exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);

    /* During a fallback we must prepare access. */
    if (pExaScr->fallback_counter)
        exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);

    return pPixmap;
}
Beispiel #11
0
void
I915DisplayVideoTextured(ScrnInfoPtr scrn,
			 intel_adaptor_private *adaptor_priv, int id,
			 RegionPtr dstRegion,
			 short width, short height, int video_pitch,
			 int video_pitch2,
			 short src_w, short src_h, short drw_w, short drw_h,
			 PixmapPtr pixmap)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);
	uint32_t format, ms3, s5, tiling;
	BoxPtr pbox = REGION_RECTS(dstRegion);
	int nbox_total = REGION_NUM_RECTS(dstRegion);
	int nbox_this_time;
	int dxo, dyo, pix_xoff, pix_yoff;
	PixmapPtr target;

#if 0
	ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
	       video_pitch);
#endif

	dxo = dstRegion->extents.x1;
	dyo = dstRegion->extents.y1;

	if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048 ||
	    !intel_uxa_check_pitch_3d(pixmap)) {
		ScreenPtr screen = pixmap->drawable.pScreen;

		target = screen->CreatePixmap(screen,
					      dstRegion->extents.x2 - dxo,
					      dstRegion->extents.y2 - dyo,
					      pixmap->drawable.depth,
					      CREATE_PIXMAP_USAGE_SCRATCH);
		if (target == NULL)
			return;

		if (intel_uxa_get_pixmap_bo(target) == NULL) {
			screen->DestroyPixmap(target);
			return;
		}

		pix_xoff = -dxo;
		pix_yoff = -dyo;
	} else {
		target = pixmap;

		/* Set up the offset for translating from the given region
		 * (in screen coordinates) to the backing pixmap.
		 */
#ifdef COMPOSITE
		pix_xoff = -target->screen_x + target->drawable.x;
		pix_yoff = -target->screen_y + target->drawable.y;
#else
		pix_xoff = 0;
		pix_yoff = 0;
#endif
	}

#define BYTES_FOR_BOXES(n)	((200 + (n) * 20) * 4)
#define BOXES_IN_BYTES(s)	((((s)/4) - 200) / 20)
#define BATCH_BYTES(p)		((p)->batch_bo->size - 16)

	while (nbox_total) {
		nbox_this_time = nbox_total;
		if (BYTES_FOR_BOXES(nbox_this_time) > BATCH_BYTES(intel))
			nbox_this_time = BOXES_IN_BYTES(BATCH_BYTES(intel));
		nbox_total -= nbox_this_time;

		intel_batch_start_atomic(scrn, 200 + 20 * nbox_this_time);

		IntelEmitInvarientState(scrn);
		intel->last_3d = LAST_3D_VIDEO;

		/* draw rect -- just clipping */
		OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
		OUT_BATCH(DRAW_DITHER_OFS_X(pixmap->drawable.x & 3) |
			  DRAW_DITHER_OFS_Y(pixmap->drawable.y & 3));
		OUT_BATCH(0x00000000);	/* ymin, xmin */
		/* ymax, xmax */
		OUT_BATCH((target->drawable.width - 1) |
			  (target->drawable.height - 1) << 16);
		OUT_BATCH(0x00000000);	/* yorigin, xorigin */

		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
			  I1_LOAD_S(5) | I1_LOAD_S(6) | 2);
		OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
			  S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
		s5 = 0x0;
		if (intel->cpp == 2)
			s5 |= S5_COLOR_DITHER_ENABLE;
		OUT_BATCH(s5);	/* S5 - enable bits */
		OUT_BATCH((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
			  (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
			  (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) |
			  S6_COLOR_WRITE_ENABLE | (2 << S6_TRISTRIP_PV_SHIFT));

		OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD);
		OUT_BATCH(0x00000000);

		OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
		if (intel->cpp == 2)
			format = COLR_BUF_RGB565;
		else
			format =
			    COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;

		OUT_BATCH(LOD_PRECLAMP_OGL |
			  DSTORG_HORT_BIAS(0x8) |
			  DSTORG_VERT_BIAS(0x8) | format);

		/* front buffer, pitch, offset */
		if (intel_uxa_pixmap_tiled(target)) {
			tiling = BUF_3D_TILED_SURFACE;
			if (intel_uxa_get_pixmap_private(target)->tiling == I915_TILING_Y)
				tiling |= BUF_3D_TILE_WALK_Y;
		} else
			tiling = 0;
		OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
		OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling |
			  BUF_3D_PITCH(intel_pixmap_pitch(target)));
		OUT_RELOC_PIXMAP(target, I915_GEM_DOMAIN_RENDER,
				 I915_GEM_DOMAIN_RENDER, 0);

		if (!is_planar_fourcc(id)) {
			FS_LOCALS();

			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4);
			OUT_BATCH(0x0000001);	/* constant 0 */
			/* constant 0: brightness/contrast */
			OUT_BATCH_F(adaptor_priv->brightness / 128.0);
			OUT_BATCH_F(adaptor_priv->contrast / 255.0);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(0.0);

			OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3);
			OUT_BATCH(0x00000001);
			OUT_BATCH(SS2_COLORSPACE_CONVERSION |
				  (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);

			OUT_BATCH(_3DSTATE_MAP_STATE | 3);
			OUT_BATCH(0x00000001);	/* texture map #1 */
			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->YBufOffset);
			else
				OUT_BATCH(adaptor_priv->YBufOffset);

			ms3 = MAPSURF_422;
			switch (id) {
			case FOURCC_YUY2:
				ms3 |= MT_422_YCRCB_NORMAL;
				break;
			case FOURCC_UYVY:
				ms3 |= MT_422_YCRCB_SWAPY;
				break;
			}
			ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);

			FS_BEGIN();
			i915_fs_dcl(FS_S0);
			i915_fs_dcl(FS_T0);
			i915_fs_texld(FS_OC, FS_S0, FS_T0);
			if (adaptor_priv->brightness != 0) {
				i915_fs_add(FS_OC,
					    i915_fs_operand_reg(FS_OC),
					    i915_fs_operand(FS_C0, X, X, X,
							    ZERO));
			}
			FS_END();
		} else {
			FS_LOCALS();

			/* For the planar formats, we set up three samplers --
			 * one for each plane, in a Y8 format.  Because I
			 * couldn't get the special PLANAR_TO_PACKED
			 * shader setup to work, I did the manual pixel shader:
			 *
			 * y' = y - .0625
			 * u' = u - .5
			 * v' = v - .5;
			 *
			 * r = 1.1643 * y' + 0.0     * u' + 1.5958  * v'
			 * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
			 * b = 1.1643 * y' + 2.017   * u' + 0.0     * v'
			 *
			 * register assignment:
			 * r0 = (y',u',v',0)
			 * r1 = (y,y,y,y)
			 * r2 = (u,u,u,u)
			 * r3 = (v,v,v,v)
			 * OC = (r,g,b,1)
			 */
			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2));
			OUT_BATCH(0x000001f);	/* constants 0-4 */
			/* constant 0: normalization offsets */
			OUT_BATCH_F(-0.0625);
			OUT_BATCH_F(-0.5);
			OUT_BATCH_F(-0.5);
			OUT_BATCH_F(0.0);
			/* constant 1: r coefficients */
			OUT_BATCH_F(1.1643);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(1.5958);
			OUT_BATCH_F(0.0);
			/* constant 2: g coefficients */
			OUT_BATCH_F(1.1643);
			OUT_BATCH_F(-0.39173);
			OUT_BATCH_F(-0.81290);
			OUT_BATCH_F(0.0);
			/* constant 3: b coefficients */
			OUT_BATCH_F(1.1643);
			OUT_BATCH_F(2.017);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(0.0);
			/* constant 4: brightness/contrast */
			OUT_BATCH_F(adaptor_priv->brightness / 128.0);
			OUT_BATCH_F(adaptor_priv->contrast / 255.0);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(0.0);

			OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9);
			OUT_BATCH(0x00000007);
			/* sampler 0 */
			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);
			/* sampler 1 */
			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (1 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);
			/* sampler 2 */
			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (2 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);

			OUT_BATCH(_3DSTATE_MAP_STATE | 9);
			OUT_BATCH(0x00000007);

			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->YBufOffset);
			else
				OUT_BATCH(adaptor_priv->YBufOffset);

			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
			ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			/* check to see if Y has special pitch than normal
			 * double u/v pitch, e.g i915 XvMC hw requires at
			 * least 1K alignment, so Y pitch might
			 * be same as U/V's.*/
			if (video_pitch2)
				OUT_BATCH(((video_pitch2 / 4) -
					   1) << MS4_PITCH_SHIFT);
			else
				OUT_BATCH(((video_pitch * 2 / 4) -
					   1) << MS4_PITCH_SHIFT);

			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->UBufOffset);
			else
				OUT_BATCH(adaptor_priv->UBufOffset);

			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
			ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);

			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->VBufOffset);
			else
				OUT_BATCH(adaptor_priv->VBufOffset);

			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
			ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);

			FS_BEGIN();
			/* Declare samplers */
			i915_fs_dcl(FS_S0);	/* Y */
			i915_fs_dcl(FS_S1);	/* U */
			i915_fs_dcl(FS_S2);	/* V */
			i915_fs_dcl(FS_T0);	/* normalized coords */

			/* Load samplers to temporaries. */
			i915_fs_texld(FS_R1, FS_S0, FS_T0);
			i915_fs_texld(FS_R2, FS_S1, FS_T0);
			i915_fs_texld(FS_R3, FS_S2, FS_T0);

			/* Move the sampled YUV data in R[123] to the first
			 * 3 channels of R0.
			 */
			i915_fs_mov_masked(FS_R0, MASK_X,
					   i915_fs_operand_reg(FS_R1));
			i915_fs_mov_masked(FS_R0, MASK_Y,
					   i915_fs_operand_reg(FS_R2));
			i915_fs_mov_masked(FS_R0, MASK_Z,
					   i915_fs_operand_reg(FS_R3));

			/* Normalize the YUV data */
			i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C0));
			/* dot-product the YUV data in R0 by the vectors of
			 * coefficients for calculating R, G, and B, storing
			 * the results in the R, G, or B channels of the output
			 * color.  The OC results are implicitly clamped
			 * at the end of the program.
			 */
			i915_fs_dp3(FS_OC, MASK_X,
				    i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C1));
			i915_fs_dp3(FS_OC, MASK_Y,
				    i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C2));
			i915_fs_dp3(FS_OC, MASK_Z,
				    i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C3));
			/* Set alpha of the output to 1.0, by wiring W to 1
			 * and not actually using the source.
			 */
			i915_fs_mov_masked(FS_OC, MASK_W,
					   i915_fs_operand_one());

			if (adaptor_priv->brightness != 0) {
				i915_fs_add(FS_OC,
					    i915_fs_operand_reg(FS_OC),
					    i915_fs_operand(FS_C4, X, X, X,
							    ZERO));
			}
			FS_END();
		}

		OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1));
		while (nbox_this_time--) {
			int box_x1 = pbox->x1;
			int box_y1 = pbox->y1;
			int box_x2 = pbox->x2;
			int box_y2 = pbox->y2;
			float src_scale_x, src_scale_y;

			pbox++;

			src_scale_x = ((float)src_w / width) / drw_w;
			src_scale_y = ((float)src_h / height) / drw_h;

			/* vertex data - rect list consists of bottom right,
			 * bottom left, and top left vertices.
			 */

			/* bottom right */
			OUT_BATCH_F(box_x2 + pix_xoff);
			OUT_BATCH_F(box_y2 + pix_yoff);
			OUT_BATCH_F((box_x2 - dxo) * src_scale_x);
			OUT_BATCH_F((box_y2 - dyo) * src_scale_y);

			/* bottom left */
			OUT_BATCH_F(box_x1 + pix_xoff);
			OUT_BATCH_F(box_y2 + pix_yoff);
			OUT_BATCH_F((box_x1 - dxo) * src_scale_x);
			OUT_BATCH_F((box_y2 - dyo) * src_scale_y);

			/* top left */
			OUT_BATCH_F(box_x1 + pix_xoff);
			OUT_BATCH_F(box_y1 + pix_yoff);
			OUT_BATCH_F((box_x1 - dxo) * src_scale_x);
			OUT_BATCH_F((box_y1 - dyo) * src_scale_y);
		}

		intel_batch_end_atomic(scrn);
	}

	if (target != pixmap) {
		GCPtr gc;

		gc = GetScratchGC(pixmap->drawable.depth,
				  pixmap->drawable.pScreen);
		if (gc) {
			gc->subWindowMode = ClipByChildren;

			if (REGION_NUM_RECTS(dstRegion) > 1) {
				RegionPtr tmp;

				tmp = REGION_CREATE(pixmap->drawable.pScreen, NULL, 0);
				if (tmp) {
					REGION_COPY(pixmap->drawable.pScreen, tmp, dstRegion);
					gc->funcs->ChangeClip(gc, CT_REGION, tmp, 0);
				}
			}

			ValidateGC(&pixmap->drawable, gc);
			gc->ops->CopyArea(&target->drawable, &pixmap->drawable, gc,
					  0, 0,
					  target->drawable.width,
					  target->drawable.height,
					  -pix_xoff, -pix_yoff);
			FreeScratchGC(gc);
		}

		target->drawable.pScreen->DestroyPixmap(target);
	}

	intel_uxa_debug_flush(scrn);
}
static int
uxa_glyphs_via_mask(CARD8 op,
		    PicturePtr pSrc,
		    PicturePtr pDst,
		    PictFormatPtr maskFormat,
		    INT16 xSrc, INT16 ySrc,
		    int nlist, GlyphListPtr list, GlyphPtr * glyphs)
{
	ScreenPtr screen = pDst->pDrawable->pScreen;
	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
	CARD32 component_alpha;
	PixmapPtr pixmap, white_pixmap;
	PicturePtr glyph_atlas, mask, white;
	int xDst = list->xOff, yDst = list->yOff;
	int x, y, width, height;
	int dst_off_x, dst_off_y;
	int n, error;
	BoxRec box;

	uxa_glyph_extents(nlist, list, glyphs, &box);
	if (box.x2 <= box.x1 || box.y2 <= box.y1)
		return 0;

	dst_off_x = box.x1;
	dst_off_y = box.y1;

	width  = box.x2 - box.x1;
	height = box.y2 - box.y1;
	x = -box.x1;
	y = -box.y1;

	if (maskFormat->depth == 1) {
		PictFormatPtr a8Format =
			PictureMatchFormat(screen, 8, PICT_a8);

		if (!a8Format)
			return -1;

		maskFormat = a8Format;
	}

	pixmap = screen->CreatePixmap(screen, width, height,
				      maskFormat->depth,
				      CREATE_PIXMAP_USAGE_SCRATCH);
	if (!pixmap)
		return 1;

	if (!uxa_pixmap_is_offscreen(pixmap)) {
		screen->DestroyPixmap(pixmap);
		return -1;
	}

	white_pixmap = NULL;
	white = create_white_solid(screen);
	if (white)
		white_pixmap = uxa_get_drawable_pixmap(white->pDrawable);
	if (!white_pixmap) {
		if (white)
			FreePicture(white, 0);
		screen->DestroyPixmap(pixmap);
		return -1;
	}

	uxa_clear_pixmap(screen, uxa_screen, pixmap);

	component_alpha = NeedsComponent(maskFormat->format);
	mask = CreatePicture(0, &pixmap->drawable,
			      maskFormat, CPComponentAlpha,
			      &component_alpha, serverClient, &error);
	screen->DestroyPixmap(pixmap);

	if (!mask) {
		FreePicture(white, 0);
		return 1;
	}

	ValidatePicture(mask);

	glyph_atlas = NULL;
	while (nlist--) {
		x += list->xOff;
		y += list->yOff;
		n = list->len;
		while (n--) {
			GlyphPtr glyph = *glyphs++;
			PicturePtr this_atlas;
			int glyph_x, glyph_y;
			struct uxa_glyph *priv;

			if (glyph->info.width == 0 || glyph->info.height == 0)
				goto next_glyph;

			priv = uxa_glyph_get_private(glyph);
			if (priv != NULL) {
				glyph_x = priv->x;
				glyph_y = priv->y;
				this_atlas = priv->cache->picture;
			} else {
				if (glyph_atlas) {
					uxa_screen->info->done_composite(pixmap);
					glyph_atlas = NULL;
				}
				this_atlas = uxa_glyph_cache(screen, glyph, &glyph_x, &glyph_y);
				if (this_atlas == NULL) {
					/* no cache for this glyph */
					this_atlas = GetGlyphPicture(glyph, screen);
					glyph_x = glyph_y = 0;
				}
			}

			if (this_atlas != glyph_atlas) {
				PixmapPtr glyph_pixmap;

				if (glyph_atlas)
					uxa_screen->info->done_composite(pixmap);

				glyph_pixmap =
					uxa_get_drawable_pixmap(this_atlas->pDrawable);
				if (!uxa_pixmap_is_offscreen(glyph_pixmap) ||
				    !uxa_screen->info->prepare_composite(PictOpAdd,
									 white, this_atlas, mask,
									 white_pixmap, glyph_pixmap, pixmap)) {
					FreePicture(white, 0);
					FreePicture(mask, 0);
					return -1;
				}

				glyph_atlas = this_atlas;
			}

			uxa_screen->info->composite(pixmap,
						    0, 0,
						    glyph_x, glyph_y,
						    x - glyph->info.x,
						    y - glyph->info.y,
						    glyph->info.width,
						    glyph->info.height);

next_glyph:
			x += glyph->info.xOff;
			y += glyph->info.yOff;
		}
		list++;
	}
	if (glyph_atlas)
		uxa_screen->info->done_composite(pixmap);

	uxa_composite(op,
		      pSrc, mask, pDst,
		      dst_off_x + xSrc - xDst,
		      dst_off_y + ySrc - yDst,
		      0, 0,
		      dst_off_x, dst_off_y,
		      width, height);

	FreePicture(white, 0);
	FreePicture(mask, 0);
	return 0;
}
/* The most efficient thing to way to upload the glyph to the screen
 * is to use CopyArea; uxa pixmaps are always offscreen.
 */
static void
uxa_glyph_cache_upload_glyph(ScreenPtr screen,
			     uxa_glyph_cache_t * cache,
			     GlyphPtr glyph,
			     int x, int y)
{
	PicturePtr pGlyphPicture = GetGlyphPicture(glyph, screen);
	PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
	PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
	PixmapPtr scratch;
	GCPtr gc;

	gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
	if (!gc)
		return;

	ValidateGC(&pCachePixmap->drawable, gc);

	scratch = pGlyphPixmap;
	/* Create a temporary bo to stream the updates to the cache */
	if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth ||
	    !uxa_pixmap_is_offscreen(scratch)) {
		scratch = screen->CreatePixmap(screen,
					       glyph->info.width,
					       glyph->info.height,
					       pCachePixmap->drawable.depth,
					       UXA_CREATE_PIXMAP_FOR_MAP);
		if (scratch) {
			if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
				PicturePtr picture;
				int error;

				picture = CreatePicture(0, &scratch->drawable,
							PictureMatchFormat(screen,
									   pCachePixmap->drawable.depth,
									   cache->picture->format),
							0, NULL,
							serverClient, &error);
				if (picture) {
					ValidatePicture(picture);
					uxa_composite(PictOpSrc, pGlyphPicture, NULL, picture,
						      0, 0,
						      0, 0,
						      0, 0,
						      glyph->info.width, glyph->info.height);
					FreePicture(picture, 0);
				}
			} else {
				uxa_copy_area(&pGlyphPixmap->drawable,
					      &scratch->drawable,
					      gc,
					      0, 0,
					      glyph->info.width, glyph->info.height,
					      0, 0);
			}
		} else {
			scratch = pGlyphPixmap;
		}
	}

	uxa_copy_area(&scratch->drawable, &pCachePixmap->drawable, gc,
		      0, 0,
		      glyph->info.width, glyph->info.height,
		      x, y);

	if (scratch != pGlyphPixmap)
		screen->DestroyPixmap(scratch);

	FreeScratchGC(gc);
}
/* All caches for a single format share a single pixmap for glyph storage,
 * allowing mixing glyphs of different sizes without paying a penalty
 * for switching between source pixmaps. (Note that for a size of font
 * right at the border between two sizes, we might be switching for almost
 * every glyph.)
 *
 * This function allocates the storage pixmap, and then fills in the
 * rest of the allocated structures for all caches with the given format.
 */
static Bool uxa_realize_glyph_caches(ScreenPtr pScreen)
{
	uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
	unsigned int formats[] = {
		PIXMAN_a8,
		PIXMAN_a8r8g8b8,
	};
	int i;

	if (uxa_screen->glyph_cache_initialized)
		return TRUE;

	uxa_screen->glyph_cache_initialized = TRUE;
	memset(uxa_screen->glyphCaches, 0, sizeof(uxa_screen->glyphCaches));

	for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
		uxa_glyph_cache_t *cache = &uxa_screen->glyphCaches[i];
		PixmapPtr pixmap;
		PicturePtr picture;
		CARD32 component_alpha;
		int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
		int error;
		PictFormatPtr pPictFormat = PictureMatchFormat(pScreen, depth, formats[i]);
		if (!pPictFormat)
			goto bail;

		/* Now allocate the pixmap and picture */
		pixmap = pScreen->CreatePixmap(pScreen,
					       CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, depth,
					       INTEL_CREATE_PIXMAP_TILING_X);
		if (!pixmap)
			goto bail;
		if (!uxa_pixmap_is_offscreen(pixmap)) {
			/* Presume shadow is in-effect */
			pScreen->DestroyPixmap(pixmap);
			uxa_unrealize_glyph_caches(pScreen);
			return TRUE;
		}

		component_alpha = NeedsComponent(pPictFormat->format);
		picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
					CPComponentAlpha, &component_alpha,
					serverClient, &error);

		pScreen->DestroyPixmap(pixmap);

		if (!picture)
			goto bail;

		ValidatePicture(picture);

		cache->picture = picture;
		cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE);
		if (!cache->glyphs)
			goto bail;

		cache->evict = rand() % GLYPH_CACHE_SIZE;
	}
	assert(i == UXA_NUM_GLYPH_CACHE_FORMATS);

	return TRUE;

bail:
	uxa_unrealize_glyph_caches(pScreen);
	return FALSE;
}
Beispiel #15
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
}
DRI2BufferPtr
nouveau_dri2_create_buffer2(ScreenPtr pScreen, DrawablePtr pDraw, unsigned int attachment,
			   unsigned int format)
{
	NVPtr pNv = NVPTR(xf86ScreenToScrn(pScreen));
	struct nouveau_dri2_buffer *nvbuf;
	struct nouveau_pixmap *nvpix;
	PixmapPtr ppix = NULL;

	nvbuf = calloc(1, sizeof(*nvbuf));
	if (!nvbuf)
		return NULL;

	if (attachment == DRI2BufferFrontLeft) {
		ppix = get_drawable_pixmap(pDraw);
		if (pScreen != ppix->drawable.pScreen)
			ppix = NULL;

		if (pDraw->type == DRAWABLE_WINDOW) {
#if DRI2INFOREC_VERSION >= 6
			/* Set initial swap limit on drawable. */
			DRI2SwapLimit(pDraw, pNv->swap_limit);
#endif
		}
		if (ppix)
			ppix->refcnt++;
	} else {
		int bpp;
		unsigned int usage_hint = NOUVEAU_CREATE_PIXMAP_TILED;

		/* 'format' is just depth (or 0, or maybe it depends on the caller) */
		bpp = round_up_pow2(format ? format : pDraw->depth);

		if (attachment == DRI2BufferDepth ||
		    attachment == DRI2BufferDepthStencil)
			usage_hint |= NOUVEAU_CREATE_PIXMAP_ZETA;
		else
			usage_hint |= NOUVEAU_CREATE_PIXMAP_SCANOUT;

		ppix = pScreen->CreatePixmap(pScreen, pDraw->width,
					     pDraw->height, bpp,
					     usage_hint);
	}

	if (ppix) {
		pNv->exa_force_cp = TRUE;
		exaMoveInPixmap(ppix);
		pNv->exa_force_cp = FALSE;

		nvbuf->base.pitch = ppix->devKind;
		nvbuf->base.cpp = ppix->drawable.bitsPerPixel / 8;
	}

	nvbuf->base.attachment = attachment;
	nvbuf->base.driverPrivate = nvbuf;
	nvbuf->base.format = format;
	nvbuf->base.flags = 0;
	nvbuf->ppix = ppix;

	if (ppix) {
		nvpix = nouveau_pixmap(ppix);
		if (!nvpix || !nvpix->bo ||
		    nouveau_bo_name_get(nvpix->bo, &nvbuf->base.name)) {
			pScreen->DestroyPixmap(nvbuf->ppix);
			free(nvbuf);
			return NULL;
		}
	}
	return &nvbuf->base;
}