aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/glamor/glamor_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/glamor/glamor_core.c')
-rw-r--r--xorg-server/glamor/glamor_core.c202
1 files changed, 84 insertions, 118 deletions
diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c
index b34943761..737b2744b 100644
--- a/xorg-server/glamor/glamor_core.c
+++ b/xorg-server/glamor/glamor_core.c
@@ -114,27 +114,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
}
}
-Bool
-glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
-{
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- if (pixmap->devPrivate.ptr) {
- /* Already mapped, nothing needs to be done. Note that we
- * aren't allowing promotion from RO to RW, because it would
- * require re-mapping the PBO.
- */
- assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) ||
- access == GLAMOR_ACCESS_RO ||
- pixmap_priv->base.map_access == GLAMOR_ACCESS_RW);
- return TRUE;
- }
- pixmap_priv->base.map_access = access;
-
- return glamor_download_pixmap_to_cpu(pixmap, access);
-}
-
/*
* When downloading a unsupported color format to CPU memory,
we need to shuffle the color elements and then use a supported
@@ -313,102 +292,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
glDeleteProgram(glamor_priv->finish_access_prog[1]);
}
-void
-glamor_finish_access(DrawablePtr drawable)
-{
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(drawable->pScreen);
-
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
- return;
-
- /* If we are doing a series of unmaps from a nested map, we're
- * done. None of the callers do any rendering to maps after
- * starting an unmap sequence, so we don't need to delay until the
- * last nested unmap.
- */
- if (!pixmap->devPrivate.ptr)
- return;
-
- if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) {
- glamor_restore_pixmap_to_texture(pixmap);
- }
-
- if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
- assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-
- glamor_make_current(glamor_priv);
- glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
-
- pixmap_priv->base.fbo->pbo_valid = FALSE;
- pixmap_priv->base.fbo->pbo = 0;
- }
- else {
- free(pixmap->devPrivate.ptr);
- }
-
- if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
- pixmap->devKind = pixmap_priv->base.drm_stride;
-
- if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
- pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
-
- pixmap->devPrivate.ptr = NULL;
-}
-
-/**
- * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
- * current fill style.
- *
- * Solid doesn't use an extra pixmap source, so we don't worry about them.
- * Stippled/OpaqueStippled are 1bpp and can be in fb, so we should worry
- * about them.
- */
-Bool
-glamor_prepare_access_gc(GCPtr gc)
-{
- if (gc->stipple) {
- if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
- return FALSE;
- }
- if (gc->fillStyle == FillTiled) {
- if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
- GLAMOR_ACCESS_RO)) {
- if (gc->stipple)
- glamor_finish_access(&gc->stipple->drawable);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/**
- * Finishes access to the tile in the GC, if used.
- */
-void
-glamor_finish_access_gc(GCPtr gc)
-{
- if (gc->fillStyle == FillTiled)
- glamor_finish_access(&gc->tile.pixmap->drawable);
- if (gc->stipple)
- glamor_finish_access(&gc->stipple->drawable);
-}
-
-Bool
-glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
- int x, int y, int width, int height,
- unsigned char alu, unsigned long planemask,
- unsigned long fg_pixel, unsigned long bg_pixel,
- int stipple_x, int stipple_y)
-{
- glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
- return FALSE;
-}
-
GCOps glamor_gc_ops = {
.FillSpans = glamor_fill_spans,
.SetSpans = glamor_set_spans,
@@ -432,6 +315,58 @@ GCOps glamor_gc_ops = {
.PushPixels = glamor_push_pixels,
};
+/*
+ * When the stipple is changed or drawn to, invalidate any
+ * cached copy
+ */
+static void
+glamor_invalidate_stipple(GCPtr gc)
+{
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ if (gc_priv->stipple) {
+ if (gc_priv->stipple_damage)
+ DamageUnregister(gc_priv->stipple_damage);
+ glamor_destroy_pixmap(gc_priv->stipple);
+ gc_priv->stipple = NULL;
+ }
+}
+
+static void
+glamor_stipple_damage_report(DamagePtr damage, RegionPtr region,
+ void *closure)
+{
+ GCPtr gc = closure;
+
+ glamor_invalidate_stipple(gc);
+}
+
+static void
+glamor_stipple_damage_destroy(DamagePtr damage, void *closure)
+{
+ GCPtr gc = closure;
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ gc_priv->stipple_damage = NULL;
+ glamor_invalidate_stipple(gc);
+}
+
+void
+glamor_track_stipple(GCPtr gc)
+{
+ if (gc->stipple) {
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ if (!gc_priv->stipple_damage)
+ gc_priv->stipple_damage = DamageCreate(glamor_stipple_damage_report,
+ glamor_stipple_damage_destroy,
+ DamageReportNonEmpty,
+ TRUE, gc->pScreen, gc);
+ if (gc_priv->stipple_damage)
+ DamageRegister(&gc->stipple->drawable, gc_priv->stipple_damage);
+ }
+}
+
/**
* uxa_validate_gc() sets the ops to glamor's implementations, which may be
* accelerated or may sync the card and fall back to fb.
@@ -502,6 +437,9 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
changes &= ~GCTile;
}
+ if (changes & GCStipple)
+ glamor_invalidate_stipple(gc);
+
if (changes & GCStipple && gc->stipple) {
/* We can't inline stipple handling like we do for GCTile because
* it sets fbgc privates.
@@ -515,14 +453,38 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
fbValidateGC(gc, changes, drawable);
}
+ if (changes & GCDashList) {
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ if (gc_priv->dash) {
+ glamor_destroy_pixmap(gc_priv->dash);
+ gc_priv->dash = NULL;
+ }
+ }
+
gc->ops = &glamor_gc_ops;
}
+void
+glamor_destroy_gc(GCPtr gc)
+{
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ if (gc_priv->dash) {
+ glamor_destroy_pixmap(gc_priv->dash);
+ gc_priv->dash = NULL;
+ }
+ glamor_invalidate_stipple(gc);
+ if (gc_priv->stipple_damage)
+ DamageDestroy(gc_priv->stipple_damage);
+ miDestroyGC(gc);
+}
+
static GCFuncs glamor_gc_funcs = {
glamor_validate_gc,
miChangeGC,
miCopyGC,
- miDestroyGC,
+ glamor_destroy_gc,
miChangeClip,
miDestroyClip,
miCopyClip
@@ -535,6 +497,10 @@ static GCFuncs glamor_gc_funcs = {
int
glamor_create_gc(GCPtr gc)
{
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ gc_priv->dash = NULL;
+ gc_priv->stipple = NULL;
if (!fbCreateGC(gc))
return FALSE;