From 9f9d1468ec6b7b8bda1df4d8eed13eb0fae668e2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 23 Jan 2011 11:47:03 -0700 Subject: [PATCH 3/3] 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(-) create mode 100644 src/gallium/state_trackers/vega/handle.c 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; -- 1.7.3.4