I couldn't get the existing paths to work and they made no sense, so I just wrote new ones.
Signed-off-by: Keith Packard <[email protected]> --- glamor/Makefile.am | 2 + glamor/glamor_prepare.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ glamor/glamor_prepare.h | 38 +++++++++++ glamor/glamor_priv.h | 2 + 4 files changed, 209 insertions(+) create mode 100644 glamor/glamor_prepare.c create mode 100644 glamor/glamor_prepare.h diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 9544923..361c0d6 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -22,6 +22,8 @@ libglamor_la_SOURCES = \ glamor_setspans.c \ glamor_render.c \ glamor_gradient.c \ + glamor_prepare.c \ + glamor_prepare.h \ glamor_program.c \ glamor_transfer.c \ glamor_transfer.h \ diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c new file mode 100644 index 0000000..a653572 --- /dev/null +++ b/glamor/glamor_prepare.c @@ -0,0 +1,167 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "glamor_priv.h" +#include "glamor_prepare.h" +#include "glamor_transfer.h" + +/* + * Make a drawable ready to draw with fb by + * creating a PBO large enough for the whole object + * and downloading all of the FBOs into it. + */ + +Bool +glamor_prep_drawable(DrawablePtr drawable, Bool write) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + int gl_access, gl_usage; + RegionRec region; + BoxRec box; + int off_x, off_y; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + return TRUE; + + box.x1 = drawable->x; + box.x2 = box.x1 + drawable->width; + box.y1 = drawable->y; + box.y2 = box.y1 + drawable->height; + + RegionInit(®ion, &box, 1); + + /* See if it's already mapped */ + if (pixmap->devPrivate.ptr) { + if (write) + FatalError("attempt to remap buffer as writable"); + RegionSubtract(®ion, ®ion, &priv->base.pbo_region); + if (!RegionNotEmpty(®ion)) + return TRUE; + + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + + } else { + RegionInit(&priv->base.pbo_region, &box, 1); + + if (priv->base.pbo == 0) + glGenBuffers(1, &priv->base.pbo); + + if (write) + gl_usage = GL_DYNAMIC_DRAW; + else + gl_usage = GL_STREAM_READ; + + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo); + glBufferData(GL_PIXEL_PACK_BUFFER, pixmap->devKind * pixmap->drawable.height, NULL, gl_usage); + priv->base.map_access = write ? GLAMOR_ACCESS_RW : GLAMOR_ACCESS_RO; + } + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + glamor_download_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion), + off_x, off_y, off_x, off_y, NULL, pixmap->devKind); + + RegionUninit(®ion); + + if (priv->base.map_access == GLAMOR_ACCESS_RW) + gl_access = GL_READ_WRITE; + else + gl_access = GL_READ_ONLY; + + pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + return TRUE; +} + +/* + * When we're done with the drawable, unmap the PBO, reupload + * if we were writing to it and then unbind it to release the memory + */ + +void +glamor_fini_drawable(DrawablePtr drawable) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + return; + + if (!pixmap->devPrivate.ptr) + return; + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + pixmap->devPrivate.ptr = NULL; + + if (priv->base.map_access == GLAMOR_ACCESS_RW) { + int off_x, off_y; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + glamor_upload_boxes(pixmap, RegionRects(&priv->base.pbo_region), RegionNumRects(&priv->base.pbo_region), + off_x, off_y, off_x, off_y, NULL, pixmap->devKind); + } + + RegionUninit(&priv->base.pbo_region); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); +} + +/* + * Make a GC ready to use with fb. This just + * means making sure the appropriate fill pixmap is + * in CPU memory again + */ + +Bool +glamor_prep_gc(GCPtr gc) +{ + switch (gc->fillStyle) { + case FillTiled: + return glamor_prep_drawable(&gc->tile.pixmap->drawable, FALSE); + case FillStippled: + case FillOpaqueStippled: + return glamor_prep_drawable(&gc->stipple->drawable, FALSE); + } + return TRUE; +} + +/* + * Free any temporary CPU pixmaps for the GC + */ +void +glamor_fini_gc(GCPtr gc) +{ + switch (gc->fillStyle) { + case FillTiled: + glamor_fini_drawable(&gc->tile.pixmap->drawable); + break; + case FillStippled: + case FillOpaqueStippled: + glamor_fini_drawable(&gc->stipple->drawable); + break; + } +} diff --git a/glamor/glamor_prepare.h b/glamor/glamor_prepare.h new file mode 100644 index 0000000..70ecc4a --- /dev/null +++ b/glamor/glamor_prepare.h @@ -0,0 +1,38 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _GLAMOR_PREPARE_H_ +#define _GLAMOR_PREPARE_H_ + +Bool +glamor_prep_drawable(DrawablePtr drawable, Bool write); + +void +glamor_fini_drawable(DrawablePtr drawable); + +Bool +glamor_prep_gc(GCPtr gc); + +void +glamor_fini_gc(GCPtr gc); + +#endif /* _GLAMOR_PREPARE_H_ */ diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 5013799..1f6df3d 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -419,6 +419,8 @@ typedef struct glamor_pixmap_private_base { int drm_stride; glamor_screen_private *glamor_priv; PicturePtr picture; + GLuint pbo; + RegionRec pbo_region; #if GLAMOR_HAS_GBM EGLImageKHR image; #endif -- 1.9.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
