vega: implement handler/pointer conversion using a hash table
Before, we were just casting between 32-bit VGHandles and 64-bit pointers.
This commit is contained in:
@@ -26,6 +26,7 @@ C_SOURCES = \
|
||||
api_transform.c \
|
||||
arc.c \
|
||||
bezier.c \
|
||||
handle.c \
|
||||
image.c \
|
||||
mask.c \
|
||||
paint.c \
|
||||
|
||||
@@ -28,6 +28,7 @@ vega_sources = [
|
||||
'api_transform.c',
|
||||
'arc.c',
|
||||
'bezier.c',
|
||||
'handle.c',
|
||||
'image.c',
|
||||
'mask.c',
|
||||
'paint.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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user