summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-02-28 13:02:16 -0500
committerZhigang Gong <zhigang.gong@gmail.com>2014-03-13 21:52:28 +0800
commit7a4d37e3722dfec029e8e2d32d944ee3b12d9078 (patch)
treec5e7f45ca47c50041f0aece8173cff5ec3a2a33f
parentb68a6f00dbe9ea7b7bf622fc50a6e67e50ce3f9a (diff)
glamor: Allow nested mapping of pixmaps.
The common pattern is to do nested if statements making calls to prepare_access() and then popping those mappings back off in each set of braces. Some cases checked for src == dst to avoid leaking mapping, but others didn't. Others didn't even do the nested mappings, so a failure in the outer would result in trying to umap the inner and failing. By allowing nested mappings, we can fix both problems by not requiring the care from the caller, plus we can allow a simpler nesting of all the prepares in one if statement. Ported from Eric's xserver glamor tree. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--src/glamor_core.c20
-rw-r--r--src/glamor_priv.h6
2 files changed, 25 insertions, 1 deletions
diff --git a/src/glamor_core.c b/src/glamor_core.c
index eb1a08d..33cbb72 100644
--- a/src/glamor_core.c
+++ b/src/glamor_core.c
@@ -107,6 +107,20 @@ 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.mapped_for_write);
+ return TRUE;
+ }
+ pixmap_priv->base.mapped_for_write = (access == GLAMOR_ACCESS_RW);
+
return glamor_download_pixmap_to_cpu(pixmap, access);
}
@@ -326,7 +340,11 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
return;
- if (access_mode != GLAMOR_ACCESS_RO) {
+ /* If we are doing a series of unmaps from a nested map, we're done. */
+ if (!pixmap->devPrivate.ptr)
+ return;
+
+ if (pixmap_priv->base.mapped_for_write) {
glamor_restore_pixmap_to_texture(pixmap);
}
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 844bd7a..359604e 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -425,6 +425,12 @@ typedef struct glamor_pixmap_clipped_regions{
typedef struct glamor_pixmap_private_base {
glamor_pixmap_type_t type;
enum glamor_fbo_state gl_fbo;
+ /**
+ * If devPrivate.ptr is non-NULL (meaning we're within
+ * glamor_prepare_access), determies whether we should re-upload
+ * that data on glamor_finish_access().
+ */
+ Bool mapped_for_write;
unsigned char is_picture:1;
unsigned char gl_tex:1;
glamor_pixmap_fbo *fbo;