Mesa (master): vega: implement handler/ pointer conversion using a hash table

Brian Paul brianp at kemper.freedesktop.org
Tue Jan 25 01:13:12 UTC 2011


Module: Mesa
Branch: master
Commit: 99c67f27d35a4bbbbefada8117d5972c7583cf42
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=99c67f27d35a4bbbbefada8117d5972c7583cf42

Author: Brian Paul <brianp at vmware.com>
Date:   Sun Jan 23 11:47:03 2011 -0700

vega: implement handler/pointer conversion using a hash table

Before, we were just casting between 32-bit VGHandles and 64-bit pointers.

---

 src/gallium/state_trackers/vega/Makefile     |    1 +
 src/gallium/state_trackers/vega/SConscript   |    1 +
 src/gallium/state_trackers/vega/api_path.c   |    2 +-
 src/gallium/state_trackers/vega/handle.c     |   99 ++++++++++++++++++++++++++
 src/gallium/state_trackers/vega/handle.h     |   55 ++++++++++++--
 src/gallium/state_trackers/vega/image.c      |    2 +
 src/gallium/state_trackers/vega/vg_context.c |   11 +++-
 src/gallium/state_trackers/vega/vg_context.h |    9 +++
 src/gallium/state_trackers/vega/vg_manager.c |    4 +
 9 files changed, 175 insertions(+), 9 deletions(-)

diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 7e05678..3e8ad49 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -26,6 +26,7 @@ C_SOURCES = \
            api_transform.c \
            arc.c \
            bezier.c \
+           handle.c \
            image.c \
            mask.c \
            paint.c \
diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript
index e810388..f3732aa 100644
--- a/src/gallium/state_trackers/vega/SConscript
+++ b/src/gallium/state_trackers/vega/SConscript
@@ -28,6 +28,7 @@ vega_sources = [
     'api_transform.c',
     'arc.c',
     'bezier.c',
+    'handle.c',
     'image.c',
     'mask.c',
     'paint.c',
diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c
index e89c948..ab6ce95 100644
--- a/src/gallium/state_trackers/vega/api_path.c
+++ b/src/gallium/state_trackers/vega/api_path.c
@@ -170,7 +170,7 @@ void vegaAppendPathData(VGPath dstPath,
 
    p = handle_to_path(dstPath);
 
-   if (!pathData || !is_aligned_to(pathData, path_datatype_size(p))) {
+   if (!p || !is_aligned_to(p, path_datatype_size(p))) {
       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
       return;
    }
diff --git a/src/gallium/state_trackers/vega/handle.c b/src/gallium/state_trackers/vega/handle.c
new file mode 100644
index 0000000..5ec4d71
--- /dev/null
+++ b/src/gallium/state_trackers/vega/handle.c
@@ -0,0 +1,99 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "handle.h"
+#include "util/u_hash.h"
+#include "util/u_hash_table.h"
+
+
+/**
+ * Hash keys are 32-bit VGHandles
+ */
+
+struct util_hash_table *handle_hash = NULL;
+
+
+static unsigned next_handle = 1;
+
+
+static unsigned
+hash_func(void *key)
+{
+   /* XXX this kind of ugly */
+   intptr_t ip = pointer_to_intptr(key);
+   return (unsigned) (ip & 0xffffffff);
+}
+
+
+static int
+compare(void *key1, void *key2)
+{
+   if (key1 < key2)
+      return -1;
+   else if (key1 > key2)
+      return +1;
+   else
+      return 0;
+}
+
+
+void
+init_handles(void)
+{
+   if (!handle_hash)
+      handle_hash = util_hash_table_create(hash_func, compare);
+}
+
+
+void
+free_handles(void)
+{
+   /* XXX destroy */
+}
+
+
+VGHandle
+create_handle(void *object)
+{
+   VGHandle h = next_handle++;
+   util_hash_table_set(handle_hash, intptr_to_pointer(h), object);
+#if DEBUG
+   {
+      void *v = handle_to_object(h);
+      assert(v == object);
+   }
+#endif
+   return h;
+}
+
+
+void
+destroy_handle(VGHandle h)
+{
+   util_hash_table_remove(handle_hash, intptr_to_pointer(h));
+}
+
diff --git a/src/gallium/state_trackers/vega/handle.h b/src/gallium/state_trackers/vega/handle.h
index 7023004..9ed326d 100644
--- a/src/gallium/state_trackers/vega/handle.h
+++ b/src/gallium/state_trackers/vega/handle.h
@@ -34,8 +34,15 @@
 #ifndef HANDLE_H
 #define HANDLE_H
 
-#include "VG/openvg.h"
 #include "pipe/p_compiler.h"
+#include "util/u_hash_table.h"
+#include "util/u_pointer.h"
+
+#include "VG/openvg.h"
+#include "vg_context.h"
+
+
+extern struct util_hash_table *handle_hash;
 
 
 struct vg_mask_layer;
@@ -45,43 +52,77 @@ struct vg_paint;
 struct path;
 
 
+extern void
+init_handles(void);
+
+
+extern void
+free_handles(void);
+
+
+extern VGHandle
+create_handle(void *object);
+
+
+extern void
+destroy_handle(VGHandle h);
+
+
+static INLINE VGHandle
+object_to_handle(struct vg_object *obj)
+{
+   return obj ? obj->handle : VG_INVALID_HANDLE;
+}
+
+
 static INLINE VGHandle
 image_to_handle(struct vg_image *img)
 {
-   return (VGHandle) img;
+   /* vg_image is derived from vg_object */
+   return object_to_handle((struct vg_object *) img);
 }
 
 
 static INLINE VGHandle
 masklayer_to_handle(struct vg_mask_layer *mask)
 {
-   return (VGHandle) mask;
+   /* vg_object is derived from vg_object */
+   return object_to_handle((struct vg_object *) mask);
 }
 
 
 static INLINE VGHandle
 font_to_handle(struct vg_font *font)
 {
-   return (VGHandle) font;
+   return object_to_handle((struct vg_object *) font);
 }
 
+
 static INLINE VGHandle
 paint_to_handle(struct vg_paint *paint)
 {
-   return (VGHandle) paint;
+   return object_to_handle((struct vg_object *) paint);
 }
 
+
 static INLINE VGHandle
 path_to_handle(struct path *path)
 {
-   return (VGHandle) path;
+   return object_to_handle((struct vg_object *) path);
 }
 
 
 static INLINE void *
 handle_to_pointer(VGHandle h)
 {
-   return (void *) h;
+   void *v = util_hash_table_get(handle_hash, intptr_to_pointer(h));
+#ifdef DEBUG
+   if (v) {
+      struct vg_object *obj = (struct vg_object *) v;
+      assert(obj->handle == h);
+   }
+#endif
+   return v;
 }
 
 
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 318ea94..73351b6 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -349,6 +349,8 @@ void image_destroy(struct vg_image *img)
       array_destroy(img->children_array);
    }
 
+   vg_free_object(&img->base);
+
    pipe_sampler_view_reference(&img->sampler_view, NULL);
    FREE(img);
 }
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index a573577..cd25183 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -183,6 +183,15 @@ void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_objec
 {
    obj->type = type;
    obj->ctx = ctx;
+   obj->handle = create_handle(obj);
+}
+
+/** free object resources, but not the object itself */
+void vg_free_object(struct vg_object *obj)
+{
+   obj->type = 0;
+   obj->ctx = NULL;
+   destroy_handle(obj->handle);
 }
 
 VGboolean vg_context_is_object_valid(struct vg_context *ctx,
@@ -416,7 +425,7 @@ void vg_validate_state(struct vg_context *ctx)
 VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type)
 {
    struct vg_object *obj = handle_to_object(object);
-   if (object && is_aligned(obj) && obj->type == type)
+   if (obj && is_aligned(obj) && obj->type == type)
       return VG_TRUE;
    else
       return VG_FALSE;
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index bee7acc..45e5985 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -129,11 +129,20 @@ struct vg_context
    struct blit_state *blit;
 };
 
+
+/**
+ *  Base class for VG objects like paths, images, fonts.
+ */
 struct vg_object {
    enum vg_object_type type;
+   VGHandle handle;
    struct vg_context *ctx;
 };
+
+
 void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_object_type type);
+void vg_free_object(struct vg_object *obj);
+
 VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type);
 
 struct vg_context *vg_create_context(struct pipe_context *pipe,
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index ec713b7..44d2996 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -40,6 +40,7 @@
 #include "vg_manager.h"
 #include "vg_context.h"
 #include "api.h"
+#include "handle.h"
 
 static boolean
 vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
@@ -172,6 +173,9 @@ vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
    if (attribs->major > 1 || (attribs->major == 1 && attribs->minor > 0))
       return NULL;
 
+   /* for VGHandle / pointer lookups */
+   init_handles();
+
    pipe = smapi->screen->context_create(smapi->screen, NULL);
    if (!pipe)
       return NULL;




More information about the mesa-commit mailing list