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); } }
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; }