示例#1
0
void
xglValidateGC (GCPtr	     pGC,
	       unsigned long changes,
	       DrawablePtr   pDrawable)
{
    XGL_GC_PRIV (pGC);

    if (changes & GCTile)
    {
	if (!pGC->tileIsPixel &&
	    FbEvenTile (pGC->tile.pixmap->drawable.width *
			pDrawable->bitsPerPixel))
	    xglSyncBits (&pGC->tile.pixmap->drawable, NULL);
    }

    if (changes & GCStipple)
    {
	if (pGC->stipple)
	    xglSyncBits (&pGC->stipple->drawable, NULL);
    }

    XGL_GC_UNWRAP (funcs);
    XGL_GC_UNWRAP (ops);
    (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
    XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
    XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);

    if (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
    {
	XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

	if (pPixmapPriv->pVisual && pPixmapPriv->pVisual->format.surface)
	{
	    glitz_format_t *format;

	    format = pPixmapPriv->pVisual->format.surface;
	    if (format->id != pGCPriv->id)
	    {
		XGL_SCREEN_PRIV (pDrawable->pScreen);

		pGCPriv->flags |= xglGCSoftwareDrawableFlag;

		if (pGCPriv->fg)
		    glitz_surface_destroy (pGCPriv->fg);

		pGCPriv->fg = glitz_surface_create (pScreenPriv->drawable,
						    format, 1, 1, 0, NULL);
		if (pGCPriv->fg)
		    glitz_surface_set_fill (pGCPriv->fg, GLITZ_FILL_REPEAT);

		if (pGCPriv->bg)
		    glitz_surface_destroy (pGCPriv->bg);

		pGCPriv->bg = glitz_surface_create (pScreenPriv->drawable,
						    format, 1, 1, 0, NULL);
		if (pGCPriv->bg)
		    glitz_surface_set_fill (pGCPriv->bg, GLITZ_FILL_REPEAT);

		pGCPriv->id = format->id;

		if (pGCPriv->fg && pGCPriv->bg)
		{
		    changes |= (GCForeground | GCBackground);
		    pGCPriv->flags &= ~xglGCSoftwareDrawableFlag;
		}
	    }
	}
	else
	    pGCPriv->flags |= xglGCSoftwareDrawableFlag;
    }

    if (changes & GCFunction)
    {
	switch (pGC->alu) {
	case GXclear:
	    pGCPriv->op = GLITZ_OPERATOR_CLEAR;
	    pGCPriv->flags &= ~xglGCBadFunctionFlag;
	    break;
	case GXcopy:
	    pGCPriv->op = GLITZ_OPERATOR_SRC;
	    pGCPriv->flags &= ~xglGCBadFunctionFlag;
	    break;
	case GXnoop:
	    pGCPriv->op = GLITZ_OPERATOR_DST;
	    pGCPriv->flags &= ~xglGCBadFunctionFlag;
	    break;
	default:
	    pGCPriv->flags |= xglGCBadFunctionFlag;
	    break;
	}
    }

    if (changes & GCPlaneMask)
    {
	FbBits mask;

	mask = FbFullMask (pDrawable->depth);

	if ((pGC->planemask & mask) != mask)
	    pGCPriv->flags |= xglGCPlaneMaskFlag;
	else
	    pGCPriv->flags &= ~xglGCPlaneMaskFlag;
    }

    if (!(pGCPriv->flags & xglGCSoftwareDrawableFlag))
    {
	if (changes & (GCForeground | GCBackground))
	{
	    glitz_pixel_format_t format;
	    glitz_buffer_t	 *buffer;
	    CARD32		 pixel;

	    XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

	    format.fourcc	  = GLITZ_FOURCC_RGB;
	    format.masks	  = pPixmapPriv->pVisual->pPixel->masks;
	    format.xoffset	  = 0;
	    format.skip_lines     = 0;
	    format.bytes_per_line = sizeof (CARD32);
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;

	    buffer = glitz_buffer_create_for_data (&pixel);

	    if (changes & GCForeground)
	    {
		pixel = pGC->fgPixel;
		glitz_set_pixels (pGCPriv->fg, 0, 0, 1, 1, &format, buffer);
	    }

	    if (changes & GCBackground)
	    {
		pixel = pGC->bgPixel;
		glitz_set_pixels (pGCPriv->bg, 0, 0, 1, 1, &format, buffer);
	    }

	    glitz_buffer_destroy (buffer);
	}
    }
}
void
glitz_set_rectangles (glitz_surface_t         *dst,
		      const glitz_color_t     *color,
		      const glitz_rectangle_t *rects,
		      int                     n_rects)
{
    GLITZ_GL_SURFACE (dst);

    if (n_rects < 1)
	return;

    if (SURFACE_SOLID (dst))
    {
	glitz_color_t old = dst->solid;
	glitz_box_t   *clip  = dst->clip;
	int           n_clip = dst->n_clip;

	for (; n_clip; clip++, n_clip--)
	{
	    if (clip->x1 > 0 ||
		clip->y1 > 0 ||
		clip->x2 < 1 ||
		clip->y2 < 1)
		continue;

	    for (; n_rects; rects++, n_rects--)
	    {
		if (rects->x > 0 ||
		    rects->y > 0 ||
		    (rects->x + rects->width) < 1 ||
		    (rects->y + rects->height) < 1)
		    continue;

		STORE_16 (dst->solid.red,
			  dst->format->color.red_size,
			  color->red);
		STORE_16 (dst->solid.green,
			  dst->format->color.green_size,
			  color->green);
		STORE_16 (dst->solid.blue,
			  dst->format->color.blue_size,
			  color->blue);
		STORE_16 (dst->solid.alpha,
			  dst->format->color.alpha_size,
			  color->alpha);

		if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK)
		{
		    dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
		    glitz_surface_damage (dst, &dst->box,
					  GLITZ_DAMAGE_TEXTURE_MASK |
					  GLITZ_DAMAGE_DRAWABLE_MASK);
		}
		else
		{
		    if (dst->solid.red   != old.red   ||
			dst->solid.green != old.green ||
			dst->solid.blue  != old.blue  ||
			dst->solid.alpha != old.alpha)
			glitz_surface_damage (dst, &dst->box,
					      GLITZ_DAMAGE_TEXTURE_MASK |
					      GLITZ_DAMAGE_DRAWABLE_MASK);
		}
		break;
	    }
	    break;
	}
    }
    else
    {
	static glitz_pixel_format_t pf = {
	    GLITZ_FOURCC_RGB,
	    {
		32,
		0xff000000,
		0x00ff0000,
		0x0000ff00,
		0x000000ff
	    },
	    0, 0, 0,
	    GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
	};
	glitz_buffer_t *buffer = NULL;
	glitz_box_t    box;
	glitz_bool_t   drawable = 0;

	if (n_rects == 1 && rects->width <= 1 && rects->height <= 1)
	{
	    glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
	}
	else
	{
	    drawable = glitz_surface_push_current (dst,
						   GLITZ_DRAWABLE_CURRENT);
	}

	if (drawable)
	{
	    glitz_box_t *clip;
	    int         n_clip;

	    gl->clear_color (color->red   / (glitz_gl_clampf_t) 0xffff,
			     color->green / (glitz_gl_clampf_t) 0xffff,
			     color->blue  / (glitz_gl_clampf_t) 0xffff,
			     color->alpha / (glitz_gl_clampf_t) 0xffff);

	    while (n_rects--)
	    {
		clip = dst->clip;
		n_clip = dst->n_clip;
		while (n_clip--)
		{
		    box.x1 = clip->x1 + dst->x_clip;
		    box.y1 = clip->y1 + dst->y_clip;
		    box.x2 = clip->x2 + dst->x_clip;
		    box.y2 = clip->y2 + dst->y_clip;

		    if (dst->box.x1 > box.x1)
			box.x1 = dst->box.x1;
		    if (dst->box.y1 > box.y1)
			box.y1 = dst->box.y1;
		    if (dst->box.x2 < box.x2)
			box.x2 = dst->box.x2;
		    if (dst->box.y2 < box.y2)
			box.y2 = dst->box.y2;

		    if (rects->x > box.x1)
			box.x1 = rects->x;
		    if (rects->y > box.y1)
			box.y1 = rects->y;
		    if (rects->x + rects->width < box.x2)
			box.x2 = rects->x + rects->width;
		    if (rects->y + rects->height < box.y2)
			box.y2 = rects->y + rects->height;

		    if (box.x1 < box.x2 && box.y1 < box.y2)
		    {
			gl->scissor (box.x1,
				     dst->attached->height - dst->y - box.y2,
				     box.x2 - box.x1,
				     box.y2 - box.y1);

			gl->clear (GLITZ_GL_COLOR_BUFFER_BIT);

			glitz_surface_damage (dst, &box,
					      GLITZ_DAMAGE_TEXTURE_MASK |
					      GLITZ_DAMAGE_SOLID_MASK);
		    }

		    clip++;
		}
		rects++;
	    }
	}
	else
	{
	    unsigned int pixel =
		((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) |
		((((unsigned int) color->red   * 0xff) / 0xffff) << 16) |
		((((unsigned int) color->green * 0xff) / 0xffff) << 8) |
		((((unsigned int) color->blue  * 0xff) / 0xffff));
	    int x1, y1, x2, y2;

	    buffer = _glitz_minimum_buffer (dst, rects, n_rects, &pixel);
	    if (!buffer)
	    {
		glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
		return;
	    }

	    while (n_rects--)
	    {
		x1 = rects->x;
		y1 = rects->y;
		x2 = x1 + rects->width;
		y2 = y1 + rects->height;

		if (x1 < 0)
		    x1 = 0;
		if (y1 < 0)
		    y1 = 0;
		if (x2 > dst->box.x2)
		    x2 = dst->box.x2;
		if (y2 > dst->box.y2)
		    y2 = dst->box.y2;

		if (x1 < x2 && y1 < y2)
		    glitz_set_pixels (dst,
				      x1, y1,
				      x2 - x1, y2 - y1,
				      &pf, buffer);

		rects++;
	    }

	    if (buffer)
		glitz_buffer_destroy (buffer);
	}
	glitz_surface_pop_current (dst);
    }
}
示例#3
0
Bool
xglSyncSurface (DrawablePtr pDrawable)
{
    RegionPtr pRegion;

    XGL_DRAWABLE_PIXMAP (pDrawable);
    XGL_PIXMAP_PRIV (pPixmap);

    if (!pPixmapPriv->surface)
    {
	if (!xglCreatePixmapSurface (pPixmap))
	    return FALSE;
    }

    pRegion = DamageRegion (pPixmapPriv->pDamage);

    if (REGION_NOTEMPTY (pDrawable->pScreen, pRegion))
    {
	glitz_pixel_format_t format;
	BoxPtr		     pBox;
	BoxPtr		     pExt;
	int		     nBox;

	xglUnmapPixmapBits (pPixmap);

	nBox = REGION_NUM_RECTS (pRegion);
	pBox = REGION_RECTS (pRegion);
	pExt = REGION_EXTENTS (pDrawable->pScreen, pRegion);

	format.fourcc  = pPixmapPriv->pVisual->format.surface->color.fourcc;
	format.masks   = pPixmapPriv->pVisual->pPixel->masks;
	format.xoffset = pExt->x1;

	if (pPixmapPriv->stride < 0)
	{
	    format.skip_lines	  = pPixmap->drawable.height - pExt->y2;
	    format.bytes_per_line = -pPixmapPriv->stride;
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
	}
	else
	{
	    format.skip_lines	  = pExt->y1;
	    format.bytes_per_line = pPixmapPriv->stride;
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
	}

	glitz_surface_set_clip_region (pPixmapPriv->surface,
				       0, 0, (glitz_box_t *) pBox, nBox);

	glitz_set_pixels (pPixmapPriv->surface,
			  pExt->x1,
			  pExt->y1,
			  pExt->x2 - pExt->x1,
			  pExt->y2 - pExt->y1,
			  &format,
			  pPixmapPriv->buffer);

	glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, NULL, 0);

	REGION_EMPTY (pDrawable->pScreen, pRegion);
    }

    return TRUE;
}