os/graphics/graphicscomposition/openwfcompositionengine/common/src/owfattributes.c
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicscomposition/openwfcompositionengine/common/src/owfattributes.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1064 @@
1.4 +/* Copyright (c) 2009-2010 The Khronos Group Inc.
1.5 + * Portions copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies)
1.6 + *
1.7 + * Permission is hereby granted, free of charge, to any person obtaining a
1.8 + * copy of this software and/or associated documentation files (the
1.9 + * "Materials"), to deal in the Materials without restriction, including
1.10 + * without limitation the rights to use, copy, modify, merge, publish,
1.11 + * distribute, sublicense, and/or sell copies of the Materials, and to
1.12 + * permit persons to whom the Materials are furnished to do so, subject to
1.13 + * the following conditions:
1.14 + *
1.15 + * The above copyright notice and this permission notice shall be included
1.16 + * in all copies or substantial portions of the Materials.
1.17 + *
1.18 + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1.19 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1.20 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1.21 + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1.22 + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1.23 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1.24 + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
1.25 + */
1.26 +
1.27 +
1.28 +
1.29 +#ifdef __cplusplus
1.30 +extern "C" {
1.31 +#endif
1.32 +
1.33 +
1.34 +#include <stdio.h>
1.35 +#include <stdlib.h>
1.36 +#include <string.h>
1.37 +#include <math.h>
1.38 +
1.39 +#include "owfattributes.h"
1.40 +#include "owfmemory.h"
1.41 +#include "owfdebug.h"
1.42 +
1.43 +#define OWF_ATTRIB_RANGE_START (0)
1.44 +#define OWF_ATTRIB_RANGE_UNINITIALIZED (-1)
1.45 +
1.46 +static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom);
1.47 +
1.48 + /*
1.49 + This attribute class is not used for WFC element attributes because elements are
1.50 + completely cloned in the committed scene.
1.51 + [This class could be replaced with 3 copies of a much simpler writable attributes raw
1.52 + structure with simple data members, and the whole structure copied each commit.]
1.53 + Normal attribute values have three pointers indexed via an array:
1.54 + COMMITTED_ATTR_VALUE_INDEX:
1.55 + Attribute values used by the scene
1.56 + - points to named variables directly used by the compositor
1.57 + WORKING_ATTR_VALUE_INDEX:
1.58 + Attribute values that may be set by the client, if they are not read-only.
1.59 + SNAPSHOT_ATTR_VALUE_INDEX
1.60 + A copy of the client-set attribute values following a client call to wfcCommit
1.61 + The copy is then protected against further modification by the client until
1.62 + the committed scene is updated and displayed.
1.63 + The Working and Snapshot writable attributes require additional cache storage,
1.64 + which is managed by the lifetime of the attribute list.
1.65 + Read-only attributes point all three pointers at the named compositor variables.
1.66 + Currently, there are relatively few writable attributes so it is reasonable
1.67 + to individually dynamically allocate each cache. It would be better to allocate
1.68 + a single block sized after the attributes have been registered.
1.69 +
1.70 + Internal code is expected to read or write to member variables that are abstracted
1.71 + by read-only attributes. However they must not write directly to member variables
1.72 + masked by writable attributes after the initial "commit" to working. The code does
1.73 + not currently use const instances to enforce this behavior.
1.74 + */
1.75 +#define COND_FAIL_NR(ctx, condition, error) \
1.76 + if (!(condition)) { \
1.77 + if (ctx) { \
1.78 + (ctx)->last_error = error; \
1.79 + } \
1.80 + return; \
1.81 + }
1.82 +
1.83 +#define COND_FAIL(ctx, condition, error, r) \
1.84 + if (!(condition)) { \
1.85 + if (ctx) { \
1.86 + (ctx)->last_error = error; \
1.87 + } \
1.88 + return r; \
1.89 + }
1.90 +
1.91 +// NS here means No Set as we are not setting the last_error member of the context.
1.92 +// These are used when we are testing the context itself so setting the last_error
1.93 +// member is itself is an error
1.94 +#define COND_FAIL_NR_NS(condition) \
1.95 + if (!(condition)) { \
1.96 + return; \
1.97 + }
1.98 +
1.99 +#define COND_FAIL_NS(condition, r) \
1.100 + if (!(condition)) { \
1.101 + return r; \
1.102 + }
1.103 +
1.104 +#define CHECK_INDEX_NR(ctx, index, error) \
1.105 + if (index < (ctx)->range_start || index > (ctx)->range_end) { \
1.106 + (ctx)->last_error = error; \
1.107 + return; \
1.108 + }
1.109 +
1.110 +#define CHECK_INDEX(ctx, index, error, r) \
1.111 + if (index < (ctx)->range_start || index > (ctx)->range_end) { \
1.112 + (ctx)->last_error = error; \
1.113 + return r; \
1.114 + }
1.115 +
1.116 +#define CHECK_BAD_NR(ctx, index) \
1.117 + CHECK_INDEX_NR(ctx, index, ATTR_ERROR_INVALID_ATTRIBUTE); \
1.118 + if ((ctx)->attributes[index-(ctx)->range_start].attr_info.type == AT_UNDEFINED) { \
1.119 + (ctx)->last_error = ATTR_ERROR_INVALID_ATTRIBUTE; \
1.120 + return; \
1.121 + }
1.122 +
1.123 +#define CHECK_BAD(ctx, index, r) \
1.124 + CHECK_INDEX(ctx, index, ATTR_ERROR_INVALID_ATTRIBUTE, r); \
1.125 + if ((ctx)->attributes[index-(ctx)->range_start].attr_info.type == AT_UNDEFINED) { \
1.126 + (ctx)->last_error = ATTR_ERROR_INVALID_ATTRIBUTE; \
1.127 + return r; \
1.128 + }
1.129 +
1.130 +#define SET_ERROR(ctx, err) \
1.131 + if ((ctx)->last_error == ATTR_ERROR_NONE) { \
1.132 + (ctx)->last_error = err; \
1.133 + }
1.134 +
1.135 +
1.136 +/*
1.137 +=============================================================================
1.138 +ATTRIBUTE CONTEXT MANAGEMENT FUNCTIONS
1.139 +=============================================================================
1.140 +*/
1.141 +
1.142 +/*!
1.143 + * \brief Initializes attribute context
1.144 + *
1.145 + * \param aContext Attribute context to initialize
1.146 + * \param aStart Attribute range start
1.147 + * \param aEnd Attribute range end. Must be greater than range start.
1.148 + *
1.149 + * \return ATTR_ERROR_INVALID_ARGUMENT
1.150 + * ATTR_ERROR_NO_MEMORY
1.151 + */
1.152 +OWF_API_CALL void
1.153 +OWF_AttributeList_Create(OWF_ATTRIBUTE_LIST* aContext,
1.154 + OWFint aStart,
1.155 + OWFint aEnd)
1.156 +{
1.157 + OWF_ATTRIBUTE* temp = NULL;
1.158 +
1.159 + COND_FAIL_NR_NS(aContext);
1.160 + COND_FAIL_NR(aContext, aEnd >= 0, ATTR_ERROR_INVALID_ARGUMENT);
1.161 + COND_FAIL_NR(aContext, aEnd >= aStart, ATTR_ERROR_INVALID_ARGUMENT);
1.162 +
1.163 + aContext->range_start = OWF_ATTRIB_RANGE_START;
1.164 + aContext->range_end = OWF_ATTRIB_RANGE_UNINITIALIZED;
1.165 +
1.166 + temp = (OWF_ATTRIBUTE*) xalloc(aEnd - aStart + 1, sizeof(OWF_ATTRIBUTE));
1.167 + COND_FAIL_NR(aContext, temp, ATTR_ERROR_NO_MEMORY);
1.168 +
1.169 + memset(aContext, 0, sizeof(OWF_ATTRIBUTE_LIST));
1.170 +
1.171 + aContext->range_start = aStart;
1.172 + aContext->range_end = aEnd;
1.173 + aContext->attributes = temp;
1.174 +
1.175 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.176 + return;
1.177 +}
1.178 +
1.179 +/*!
1.180 + * \brief Destroy attribute context and free any resources (memory
1.181 + * blocks) allocated to it. All attributes are destroyed.
1.182 + *
1.183 + * \param aContext Attribute context to destroy
1.184 + *
1.185 + * \return ATTR_ERROR_INVALID_ARGUMENT
1.186 + * ATTR_ERROR_INVALID_CONTEXT
1.187 + */
1.188 +OWF_API_CALL void
1.189 +OWF_AttributeList_Destroy(OWF_ATTRIBUTE_LIST* aContext)
1.190 +{
1.191 + OWFint count = 0;
1.192 + OWFint at = 0;
1.193 + OWFint cache = 0;
1.194 +
1.195 + COND_FAIL_NR_NS(aContext);
1.196 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.197 +
1.198 + count = aContext->range_end - aContext->range_start;
1.199 + for (at = 0; at <= count; at++) {
1.200 +
1.201 + OWF_ATTRIBUTE* attr = &aContext->attributes[at];
1.202 + if (!attr->attr_info.readonly)
1.203 + {
1.204 + for (cache=0;cache<NUM_ATTR_VALUE_COPIES;cache++)
1.205 + {
1.206 + if (cache!=COMMITTED_ATTR_VALUE_INDEX)
1.207 + {
1.208 + xfree(attr->attr_value[cache].gen_ptr);
1.209 + }
1.210 + }
1.211 + }
1.212 + }
1.213 +
1.214 + xfree(aContext->attributes);
1.215 + memset(aContext, 0, sizeof(OWF_ATTRIBUTE_LIST));
1.216 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.217 + return;
1.218 +}
1.219 +
1.220 +/*
1.221 +
1.222 +
1.223 + */
1.224 +OWF_API_CALL OWF_ATTRIBUTE_LIST_STATUS
1.225 +OWF_AttributeList_GetError(OWF_ATTRIBUTE_LIST* aContext)
1.226 +{
1.227 + OWF_ATTRIBUTE_LIST_STATUS error;
1.228 +
1.229 + if (!aContext) {
1.230 + return ATTR_ERROR_INVALID_ARGUMENT;
1.231 + }
1.232 + error = aContext->last_error;
1.233 + aContext->last_error = ATTR_ERROR_NONE;
1.234 + return error;
1.235 +}
1.236 +
1.237 +/*
1.238 +=============================================================================
1.239 +INITIALIZATION FUNCTIONS
1.240 +=============================================================================
1.241 +*/
1.242 +
1.243 +static void OWF_Attribute_Init(OWF_ATTRIBUTE_LIST* aContext,
1.244 + OWFint aName,
1.245 + OWF_ATTRIBUTE_TYPE aType,
1.246 + OWFint aLength,
1.247 + void* aValue,
1.248 + OWFboolean aRdOnly)
1.249 +{
1.250 + OWF_ATTRIBUTE* attr = NULL;
1.251 + void* cache = NULL;
1.252 + OWFint itemSize;
1.253 + OWFint arraySize;
1.254 + OWFint copy;
1.255 + OWFint index;
1.256 +
1.257 + COND_FAIL_NR_NS(aContext);
1.258 + CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE);
1.259 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.260 + COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE);
1.261 + COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT);
1.262 +
1.263 + index = aName - aContext->range_start;
1.264 +
1.265 + attr = &aContext->attributes[index];
1.266 +
1.267 + memset(attr, 0, sizeof(OWF_ATTRIBUTE));
1.268 +
1.269 + /* when allocin', size DOES matter */
1.270 + if (aType == AT_INTEGER || aType == AT_BOOLEAN) {
1.271 + itemSize = sizeof(OWFint);
1.272 + } else {
1.273 + itemSize = sizeof(OWFfloat);
1.274 + }
1.275 + arraySize=itemSize*aLength;
1.276 +
1.277 + /* don't allocate cache for read-only 'butes */
1.278 + attr->attr_info.type = aType;
1.279 + attr->attr_info.length = aLength;
1.280 + attr->attr_info.readonly = aRdOnly;
1.281 + attr->attr_info.size = itemSize;
1.282 + if (aRdOnly)
1.283 + {
1.284 + for (copy=0;copy<NUM_ATTR_VALUE_COPIES;copy++)
1.285 + {
1.286 + attr->attr_value[copy].gen_ptr = aValue;
1.287 + }
1.288 + }
1.289 + else
1.290 + {
1.291 + for (copy=0;copy<NUM_ATTR_VALUE_COPIES;copy++)
1.292 + {
1.293 + if (copy==COMMITTED_ATTR_VALUE_INDEX)
1.294 + {
1.295 + attr->attr_value[COMMITTED_ATTR_VALUE_INDEX].gen_ptr = aValue;
1.296 + }
1.297 + else
1.298 + {
1.299 + cache = xalloc(arraySize,1);
1.300 + COND_FAIL_NR(aContext, NULL != cache, ATTR_ERROR_NO_MEMORY);
1.301 + attr->attr_value[copy].gen_ptr = cache;
1.302 + }
1.303 + }
1.304 + }
1.305 +
1.306 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.307 +
1.308 +}
1.309 +
1.310 +/*
1.311 + * \brief Intialize integer attribute
1.312 + *
1.313 + * \param aContext Attibute context
1.314 + * \param aName Attribute name
1.315 + * \param aValue Attribute initial value
1.316 + * \param aRdOnly Read-only flag
1.317 + *
1.318 + * \return ATTR_ERROR_INVALID_ARGUMENT
1.319 + * ATTR_ERROR_INVALID_ATTRIBUTE
1.320 + * ATTR_ERROR_INVALID_CONTEXT
1.321 + */
1.322 +OWF_API_CALL void
1.323 +OWF_Attribute_Initi(OWF_ATTRIBUTE_LIST* aContext,
1.324 + OWFint aName,
1.325 + OWF_INT_REF aValue,
1.326 + OWFboolean aRdOnly)
1.327 +{
1.328 + OWF_Attribute_Init(aContext, aName, AT_INTEGER, 1, aValue, aRdOnly);
1.329 +}
1.330 +
1.331 +/*
1.332 + * \brief Initialize float attribute
1.333 + *
1.334 + * \param aContext Attribute context
1.335 + * \param aName Attribute name
1.336 + * \param aValue Initial value for attribute
1.337 + * \param aRdOnly Read-only flag
1.338 + *
1.339 + * \return ATTR_ERROR_INVALID_ARGUMENT
1.340 + * ATTR_ERROR_INVALID_ATTRIBUTE
1.341 + * ATTR_ERROR_INVALID_CONTEXT
1.342 + */
1.343 +OWF_API_CALL void
1.344 +OWF_Attribute_Initf(OWF_ATTRIBUTE_LIST* aContext,
1.345 + OWFint aName,
1.346 + OWF_FLOAT_REF aValue,
1.347 + OWFboolean aRdOnly)
1.348 +{
1.349 + OWF_Attribute_Init(aContext, aName, AT_FLOAT, 1, aValue, aRdOnly);
1.350 +}
1.351 +
1.352 +/*
1.353 + * \brief Initialize boolean attribute
1.354 + *
1.355 + * \param aContext Attribute context
1.356 + * \param aName Attribute name
1.357 + * \param aValue Initial value for attribute
1.358 + * \param aRdOnly Read-only flag
1.359 + *
1.360 + * \return ATTR_ERROR_INVALID_ARGUMENT
1.361 + * ATTR_ERROR_INVALID_ATTRIBUTE
1.362 + * ATTR_ERROR_INVALID_CONTEXT
1.363 + */
1.364 +OWF_API_CALL void
1.365 +OWF_Attribute_Initb(OWF_ATTRIBUTE_LIST* aContext,
1.366 + OWFint aName,
1.367 + OWF_BOOL_REF aValue,
1.368 + OWFboolean aRdOnly)
1.369 +{
1.370 + OWF_Attribute_Init(aContext, aName, AT_BOOLEAN, 1, aValue, aRdOnly);
1.371 +}
1.372 +
1.373 +/*
1.374 + * \brief Initialize vector attribute
1.375 + *
1.376 + * \param aContext Attribute context
1.377 + * \param aName Attribute name
1.378 + * \param aLength Attribute (vector) length
1.379 + * \param aValues Initial value(s) for attribute
1.380 + * \param aRdOnly Read-only flag
1.381 + *
1.382 + * \return ATTR_ERROR_INVALID_ARGUMENT
1.383 + * ATTR_ERROR_INVALID_ATTRIBUTE
1.384 + * ATTR_ERROR_INVALID_CONTEXT
1.385 + * ATTR_ERROR_CANT_HANDLE
1.386 + */
1.387 +OWF_API_CALL void
1.388 +OWF_Attribute_Initiv(OWF_ATTRIBUTE_LIST* aContext,
1.389 + OWFint aName,
1.390 + OWFint aLength,
1.391 + OWF_INT_VECTOR_REF aValues,
1.392 + OWFboolean aRdOnly)
1.393 +{
1.394 + OWF_Attribute_Init(aContext, aName, AT_INTEGER, aLength, aValues, aRdOnly);
1.395 +}
1.396 +
1.397 +/*
1.398 + * \brief Initialize vector attribute
1.399 + *
1.400 + * \param aContext Attribute context
1.401 + * \param aName Attribute name
1.402 + * \param aLength Attribute (vector) length
1.403 + * \param aValues Initial value(s) for attributes
1.404 + * \param aRdOnly Read-only flag
1.405 + *
1.406 + * \return
1.407 + */
1.408 +OWF_API_CALL void
1.409 +OWF_Attribute_Initfv(OWF_ATTRIBUTE_LIST* aContext,
1.410 + OWFint aName,
1.411 + OWFint aLength,
1.412 + OWF_FLOAT_VECTOR_REF aValues,
1.413 + OWFboolean aRdOnly)
1.414 +{
1.415 + OWF_Attribute_Init(aContext, aName, AT_FLOAT, aLength, aValues, aRdOnly);
1.416 +}
1.417 +
1.418 +/*
1.419 +=============================================================================
1.420 +GETTER FUNCTIONS
1.421 +=============================================================================
1.422 +*/
1.423 +
1.424 +/*
1.425 + * \brief Get attribute integer value.
1.426 + *
1.427 + * \param aContext Attribute context
1.428 + * \param aName Attribute name
1.429 + *
1.430 + * \return Attribute integer value (floats are floor()ed). For vector
1.431 + * attributes the return value will be error ATTR_ERROR_INVALID_TYPE.
1.432 + * ATTR_ERROR_INVALID_ATTRIBUTE
1.433 + * ATTR_ERROR_INVALID_CONTEXT
1.434 + */
1.435 +OWF_API_CALL OWFint
1.436 +OWF_Attribute_GetValuei(OWF_ATTRIBUTE_LIST* aContext,
1.437 + OWFint aName)
1.438 +{
1.439 + OWFint index = 0;
1.440 + OWF_ATTRIBUTE* attr = 0;
1.441 + OWFint result = 0;
1.442 +
1.443 + COND_FAIL_NS(aContext, 0);
1.444 + COND_FAIL(aContext,
1.445 + aContext->attributes,
1.446 + ATTR_ERROR_INVALID_CONTEXT,
1.447 + 0);
1.448 + CHECK_BAD(aContext, aName, 0);
1.449 +
1.450 +
1.451 + index = aName - aContext->range_start;
1.452 + attr = &aContext->attributes[index];
1.453 +
1.454 + COND_FAIL(aContext,
1.455 + 1 == attr->attr_info.length,
1.456 + ATTR_ERROR_INVALID_TYPE,
1.457 + 0);
1.458 +
1.459 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.460 +
1.461 + switch (attr->attr_info.type) {
1.462 + case AT_FLOAT: {
1.463 + result = floor(attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0]);
1.464 + break;
1.465 + }
1.466 +
1.467 + case AT_INTEGER:
1.468 + case AT_BOOLEAN: {
1.469 + result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
1.470 + break;
1.471 + }
1.472 +
1.473 + default: {
1.474 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.475 + break;
1.476 + }
1.477 + }
1.478 + return result;
1.479 +}
1.480 +
1.481 +/*
1.482 + * \brief Return boolean attribute value
1.483 + *
1.484 + * \param aContext Attribute context
1.485 + * \param aName Attribute name
1.486 + *
1.487 + * \return Attribute value
1.488 + * ATTR_ERROR_INVALID_ATTRIBUTE
1.489 + * ATTR_ERROR_INVALID_TYPE
1.490 + */
1.491 +OWF_API_CALL OWFboolean
1.492 +OWF_Attribute_GetValueb(OWF_ATTRIBUTE_LIST* aContext,
1.493 + OWFint aName)
1.494 +{
1.495 + /* boolean is stored as int, must cast */
1.496 + return (OWFboolean) OWF_Attribute_GetValuei(aContext, aName);
1.497 +}
1.498 +
1.499 +/*
1.500 + * \brief Get attribute float value
1.501 + *
1.502 + * \param aContext
1.503 + * \param aName
1.504 + * \param aValue
1.505 + *
1.506 + * \return Attribute
1.507 + */
1.508 +OWF_API_CALL OWFfloat
1.509 +OWF_Attribute_GetValuef(OWF_ATTRIBUTE_LIST* aContext,
1.510 + OWFint aName)
1.511 +{
1.512 + OWFint index = 0;
1.513 + OWF_ATTRIBUTE* attr = NULL;
1.514 + OWFfloat result = 0.f;
1.515 +
1.516 + COND_FAIL_NS(aContext, 0);
1.517 + COND_FAIL(aContext,
1.518 + aContext->attributes,
1.519 + ATTR_ERROR_INVALID_CONTEXT,
1.520 + 0);
1.521 + CHECK_BAD(aContext, aName, 0);
1.522 +
1.523 +
1.524 + index = aName - aContext->range_start;
1.525 + attr = &aContext->attributes[index];
1.526 +
1.527 + COND_FAIL(aContext,
1.528 + 1 == attr->attr_info.length,
1.529 + ATTR_ERROR_INVALID_TYPE,
1.530 + 0);
1.531 +
1.532 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.533 + result = 0.f;
1.534 +
1.535 + switch (attr->attr_info.type) {
1.536 + case AT_FLOAT: {
1.537 + result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0];
1.538 + break;
1.539 + }
1.540 +
1.541 + case AT_INTEGER:
1.542 + case AT_BOOLEAN: {
1.543 + result = (OWFfloat) attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
1.544 + break;
1.545 + }
1.546 +
1.547 + default: {
1.548 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.549 + break;
1.550 + }
1.551 + }
1.552 + return result;
1.553 +}
1.554 +
1.555 +/*
1.556 + * \brief
1.557 + *
1.558 + * \param aContext
1.559 + * \param aName
1.560 + * \param aSize
1.561 + * \param aValue
1.562 + *
1.563 + * \return
1.564 + */
1.565 +OWF_API_CALL OWFint
1.566 +OWF_Attribute_GetValueiv(OWF_ATTRIBUTE_LIST* aContext,
1.567 + OWFint aName,
1.568 + OWFint aLength,
1.569 + OWFint* aValue)
1.570 +{
1.571 + OWFint index = 0;
1.572 + OWF_ATTRIBUTE* attr = NULL;
1.573 + OWFint count = 0;
1.574 +
1.575 + COND_FAIL_NS(aContext, 0);
1.576 + COND_FAIL(aContext,
1.577 + aContext->attributes,
1.578 + ATTR_ERROR_INVALID_CONTEXT,
1.579 + 0);
1.580 + CHECK_BAD(aContext, aName, 0);
1.581 +
1.582 +
1.583 + index = aName - aContext->range_start;
1.584 + attr = &aContext->attributes[index];
1.585 +
1.586 + COND_FAIL(aContext,
1.587 + attr->attr_info.length >= 1,
1.588 + ATTR_ERROR_INVALID_TYPE,
1.589 + 0);
1.590 +
1.591 + if (!aValue) {
1.592 + /* fetch size only */
1.593 + return attr->attr_info.length;
1.594 + }
1.595 +
1.596 + count = min(aLength, attr->attr_info.length);
1.597 +
1.598 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.599 +
1.600 + switch (attr->attr_info.type) {
1.601 + case AT_FLOAT: {
1.602 + OWFint i;
1.603 + OWFfloat* v = attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value;
1.604 + for (i = 0; i < count; i++) {
1.605 + aValue[i] = floor(v[i]);
1.606 + }
1.607 + break;
1.608 + }
1.609 +
1.610 + case AT_BOOLEAN:
1.611 + case AT_INTEGER: {
1.612 + memcpy(aValue,
1.613 + attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value,
1.614 + count * attr->attr_info.size);
1.615 + break;
1.616 + }
1.617 +
1.618 + default: {
1.619 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.620 + break;
1.621 + }
1.622 + }
1.623 + return count;
1.624 +}
1.625 +
1.626 +/*
1.627 + * \brief
1.628 + *
1.629 + * \param aContext
1.630 + * \param aName
1.631 + * \param aSize
1.632 + * \param aValue
1.633 + *
1.634 + * \return
1.635 + */
1.636 +OWF_API_CALL OWFint
1.637 +OWF_Attribute_GetValuefv(OWF_ATTRIBUTE_LIST* aContext,
1.638 + OWFint aName,
1.639 + OWFint aLength,
1.640 + OWFfloat* aValue)
1.641 +{
1.642 + OWFint index = 0;
1.643 + OWF_ATTRIBUTE* attr = NULL;
1.644 + OWFint count = 0;
1.645 +
1.646 + COND_FAIL_NS(aContext, 0);
1.647 + COND_FAIL(aContext,
1.648 + aContext->attributes,
1.649 + ATTR_ERROR_INVALID_CONTEXT,
1.650 + 0);
1.651 + CHECK_BAD(aContext, aName, 0);
1.652 +
1.653 +
1.654 + index = aName - aContext->range_start;
1.655 + attr = &aContext->attributes[index];
1.656 +
1.657 + COND_FAIL(aContext,
1.658 + attr->attr_info.length >= 1,
1.659 + ATTR_ERROR_INVALID_TYPE, 0);
1.660 +
1.661 + if (!aValue) {
1.662 + /* fetch size only */
1.663 + return attr->attr_info.length;
1.664 + }
1.665 +
1.666 + count = min(aLength, attr->attr_info.length);
1.667 +
1.668 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.669 +
1.670 + switch (attr->attr_info.type) {
1.671 + case AT_FLOAT: {
1.672 + memcpy(aValue,
1.673 + attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value,
1.674 + count * attr->attr_info.size);
1.675 + break;
1.676 + }
1.677 +
1.678 + case AT_BOOLEAN:
1.679 + case AT_INTEGER: {
1.680 + OWFint i;
1.681 + OWFint* v = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value;
1.682 + for (i = 0; i < count; i++) {
1.683 + aValue[i] = (OWFfloat) v[i];
1.684 + }
1.685 + break;
1.686 + }
1.687 +
1.688 + default: {
1.689 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.690 + break;
1.691 + }
1.692 + }
1.693 + return count;
1.694 +}
1.695 +
1.696 +/*
1.697 +=============================================================================
1.698 +SETTER FUNCTIONS
1.699 +=============================================================================
1.700 +*/
1.701 +
1.702 +/*
1.703 + * \brief
1.704 + *
1.705 + * \param aContext
1.706 + * \param aName
1.707 + * \param aValue
1.708 + *
1.709 + * \return
1.710 + */
1.711 +OWF_API_CALL void
1.712 +OWF_Attribute_SetValuei(OWF_ATTRIBUTE_LIST* aContext,
1.713 + OWFint aName,
1.714 + OWFint aValue)
1.715 +{
1.716 + OWFint index = 0;
1.717 + OWF_ATTRIBUTE* attr = NULL;
1.718 +
1.719 + COND_FAIL_NR_NS(aContext);
1.720 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.721 + CHECK_BAD_NR(aContext, aName);
1.722 +
1.723 +
1.724 + index = aName - aContext->range_start;
1.725 + attr = &aContext->attributes[index];
1.726 +
1.727 + COND_FAIL_NR(aContext,
1.728 + 1 == attr->attr_info.length,
1.729 + ATTR_ERROR_INVALID_TYPE);
1.730 + COND_FAIL_NR(aContext, !attr->attr_info.readonly, ATTR_ERROR_ACCESS_DENIED);
1.731 +
1.732 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.733 +
1.734 + attr->attr_info.dirty = 1;
1.735 +
1.736 + switch (attr->attr_info.type) {
1.737 + case AT_FLOAT: {
1.738 + attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0] = aValue;
1.739 + break;
1.740 + }
1.741 +
1.742 + case AT_INTEGER:
1.743 + case AT_BOOLEAN: {
1.744 + attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0] = aValue;
1.745 + break;
1.746 + }
1.747 +
1.748 + default: {
1.749 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.750 + break;
1.751 + }
1.752 + }
1.753 +}
1.754 +
1.755 +/*
1.756 + * \brief
1.757 + *
1.758 + * \param aContext
1.759 + * \param aName
1.760 + * \param aValue
1.761 + *
1.762 + * \return
1.763 + */
1.764 +OWF_API_CALL void
1.765 +OWF_Attribute_SetValuef(OWF_ATTRIBUTE_LIST* aContext,
1.766 + OWFint aName,
1.767 + OWFfloat aValue)
1.768 +{
1.769 + OWFint index = 0;
1.770 + OWF_ATTRIBUTE* attr = NULL;
1.771 +
1.772 + COND_FAIL_NR_NS(aContext);
1.773 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.774 + CHECK_BAD_NR(aContext, aName);
1.775 +
1.776 +
1.777 + index = aName - aContext->range_start;
1.778 + attr = &aContext->attributes[index];
1.779 +
1.780 + COND_FAIL_NR(aContext,
1.781 + 1 == attr->attr_info.length,
1.782 + ATTR_ERROR_INVALID_TYPE);
1.783 + COND_FAIL_NR(aContext,
1.784 + !attr->attr_info.readonly,
1.785 + ATTR_ERROR_ACCESS_DENIED);
1.786 +
1.787 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.788 +
1.789 + attr->attr_info.dirty = 1;
1.790 +
1.791 + switch (attr->attr_info.type) {
1.792 + case AT_FLOAT: {
1.793 + attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0] = aValue;
1.794 + break;
1.795 + }
1.796 +
1.797 + case AT_INTEGER:
1.798 + case AT_BOOLEAN: {
1.799 + attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0] = floor(aValue);
1.800 + break;
1.801 + }
1.802 +
1.803 + default: {
1.804 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.805 + break;
1.806 + }
1.807 + }
1.808 +}
1.809 +
1.810 +/*
1.811 + * \brief
1.812 + *
1.813 + * \param
1.814 + * \param
1.815 + * \param
1.816 + *
1.817 + * \return
1.818 + */
1.819 +OWF_API_CALL void
1.820 +OWF_Attribute_SetValueb(OWF_ATTRIBUTE_LIST* aContext,
1.821 + OWFint aName,
1.822 + OWFboolean aValue)
1.823 +{
1.824 + OWF_Attribute_SetValuei(aContext, aName, (OWFint) aValue);
1.825 +}
1.826 +
1.827 +/*
1.828 + * \brief
1.829 + *
1.830 + * \param
1.831 + * \param
1.832 + * \param
1.833 + *
1.834 + * \return
1.835 + */
1.836 +OWF_API_CALL void
1.837 +OWF_Attribute_SetValueiv(OWF_ATTRIBUTE_LIST* aContext,
1.838 + OWFint aName,
1.839 + OWFint aLength,
1.840 + const OWFint* aValue)
1.841 +{
1.842 + OWFint index = 0;
1.843 + OWF_ATTRIBUTE* attr = NULL;
1.844 + OWFint count = 0;
1.845 +
1.846 + COND_FAIL_NR_NS(aContext);
1.847 + COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
1.848 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.849 + CHECK_BAD_NR(aContext, aName);
1.850 +
1.851 + index = aName - aContext->range_start;
1.852 + attr = &aContext->attributes[index];
1.853 +/*
1.854 + COND_FAIL_NR(aContext,
1.855 + attr->attr_info.length >= 1,
1.856 + ATTR_ERROR_INVALID_TYPE);
1.857 +*/
1.858 + COND_FAIL_NR(aContext,
1.859 + aLength > 0 && aLength <= attr->attr_info.length,
1.860 + ATTR_ERROR_INVALID_ARGUMENT);
1.861 +
1.862 + COND_FAIL_NR(aContext,
1.863 + !attr->attr_info.readonly,
1.864 + ATTR_ERROR_ACCESS_DENIED);
1.865 +
1.866 + count = min(aLength, attr->attr_info.length);
1.867 +
1.868 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.869 +
1.870 + switch (attr->attr_info.type) {
1.871 + case AT_FLOAT: {
1.872 + OWFint i = 0;
1.873 + OWFfloat* v = attr->attr_value[1].float_value;
1.874 + for (i = 0; i < count; i++) {
1.875 + v[i] = floor(aValue[i]);
1.876 + }
1.877 + break;
1.878 + }
1.879 +
1.880 + case AT_BOOLEAN:
1.881 + case AT_INTEGER: {
1.882 + memcpy(attr->attr_value[1].int_value,
1.883 + aValue,
1.884 + count * attr->attr_info.size);
1.885 + break;
1.886 + }
1.887 +
1.888 + default: {
1.889 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.890 + break;
1.891 + }
1.892 + }
1.893 + aContext->attributes[index].attr_info.dirty = 1;
1.894 +}
1.895 +
1.896 +/*
1.897 + * \brief
1.898 + *
1.899 + * \param
1.900 + * \param
1.901 + * \param
1.902 + *
1.903 + * \return
1.904 + */
1.905 +OWF_API_CALL void
1.906 +OWF_Attribute_SetValuefv(OWF_ATTRIBUTE_LIST* aContext,
1.907 + OWFint aName,
1.908 + OWFint aLength,
1.909 + const OWFfloat* aValue)
1.910 +{
1.911 + OWFint index = 0;
1.912 + OWF_ATTRIBUTE* attr = NULL;
1.913 + OWFint count = 0;
1.914 +
1.915 + COND_FAIL_NR_NS(aContext);
1.916 + COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
1.917 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.918 + CHECK_BAD_NR(aContext, aName);
1.919 +
1.920 + index = aName - aContext->range_start;
1.921 + attr = &aContext->attributes[index];
1.922 +
1.923 +/*
1.924 + COND_FAIL_NR(aContext,
1.925 + attr->attr_info.length >= 1,
1.926 + ATTR_ERROR_INVALID_TYPE);
1.927 +*/
1.928 +
1.929 + COND_FAIL_NR(aContext,
1.930 + aLength > 0 && aLength <= attr->attr_info.length,
1.931 + ATTR_ERROR_INVALID_ARGUMENT);
1.932 +
1.933 + COND_FAIL_NR(aContext,
1.934 + !attr->attr_info.readonly,
1.935 + ATTR_ERROR_ACCESS_DENIED);
1.936 +
1.937 + count = min(aLength, attr->attr_info.length);
1.938 +
1.939 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.940 +
1.941 + switch (attr->attr_info.type) {
1.942 + case AT_FLOAT: {
1.943 + memcpy(attr->attr_value[1].float_value,
1.944 + aValue,
1.945 + count * attr->attr_info.size);
1.946 + break;
1.947 + }
1.948 +
1.949 + case AT_BOOLEAN:
1.950 + case AT_INTEGER: {
1.951 + OWFint i;
1.952 + OWFint* v = attr->attr_value[1].int_value;
1.953 + for (i = 0; i < count; i++) {
1.954 + v[i] = floor(aValue[i]);
1.955 + }
1.956 + break;
1.957 + }
1.958 +
1.959 + default: {
1.960 + SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
1.961 + break;
1.962 + }
1.963 + }
1.964 + aContext->attributes[index].attr_info.dirty = 1;
1.965 +}
1.966 +
1.967 +static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr,
1.968 + OWFint aDirtyFlag,
1.969 + OWFint aCopyTo,
1.970 + OWFint aCopyFrom )
1.971 + {
1.972 + OWF_ASSERT(aCopyTo >= 0);
1.973 + OWF_ASSERT(aCopyTo < NUM_ATTR_VALUE_COPIES);
1.974 + OWF_ASSERT(aCopyFrom >= 0);
1.975 + OWF_ASSERT(aCopyFrom < NUM_ATTR_VALUE_COPIES);
1.976 + /* if type is undefined, it means there're gaps in the attribute
1.977 + range (e.g. reservations for future use and such.) ignore them. */
1.978 + if (aAttr->attr_info.type != AT_UNDEFINED && aDirtyFlag)
1.979 + {
1.980 + /* poor-man's commit */
1.981 + memcpy(aAttr->attr_value[aCopyTo].gen_ptr,
1.982 + aAttr->attr_value[aCopyFrom].gen_ptr,
1.983 + aAttr->attr_info.size * aAttr->attr_info.length);
1.984 + return 0;
1.985 + }
1.986 + else
1.987 + {
1.988 + return aDirtyFlag;
1.989 + }
1.990 + }
1.991 +
1.992 +
1.993 +OWF_API_CALL void
1.994 +OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext,
1.995 + OWFint aStart,
1.996 + OWFint aEnd,
1.997 + OWFint aCopyTo )
1.998 +{
1.999 + OWFint index = 0;
1.1000 + /* Attribute commit works like the element list commit
1.1001 + * by forward-copying the "working" attributes to the snapshot
1.1002 + * during client invoked commit,
1.1003 + * then copying the snapshot to the commited scene during the docommit job.
1.1004 + * This requires the same wait-for-the-previous-commit-job strategy used in the element commit.
1.1005 + * Could in future use copy-back technique to avoid having to wait substantially,
1.1006 + * in which case the index of the working attribute set would switch after each invoked commit,
1.1007 + * instead of being a constant.
1.1008 + *
1.1009 + * The same number of copies would still need to take place
1.1010 + * but would not need exclusive access to the list.
1.1011 + */
1.1012 +
1.1013 + COND_FAIL_NR_NS(aContext);
1.1014 + COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT);
1.1015 + COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1.1016 + CHECK_BAD_NR(aContext, aStart);
1.1017 + CHECK_BAD_NR(aContext, aEnd);
1.1018 +
1.1019 + switch (aCopyTo)
1.1020 + {
1.1021 + case COMMITTED_ATTR_VALUE_INDEX: /* Used in composition thread to set displayed scene attributes */
1.1022 + for (index = aStart; index <= aEnd; index++)
1.1023 + {
1.1024 + OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1.1025 + attr->attr_info.dirtysnapshot=
1.1026 + OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot,
1.1027 + COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX);
1.1028 + }
1.1029 + break;
1.1030 + case SNAPSHOT_ATTR_VALUE_INDEX: /* Used in API threads to make a snapshot of the client attributes */
1.1031 + for (index = aStart; index <= aEnd; index++)
1.1032 + {
1.1033 + OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1.1034 + OWFuint oldDirty=attr->attr_info.dirty;
1.1035 + attr->attr_info.dirtysnapshot=oldDirty;
1.1036 + attr->attr_info.dirty=
1.1037 + OWF_Attribute_Commit(attr,oldDirty,
1.1038 + SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
1.1039 + }
1.1040 + break;
1.1041 + case WORKING_ATTR_VALUE_INDEX: /* Used in initialisation to copy displayed attributes to client copies */
1.1042 + for (index = aStart; index <= aEnd; index++)
1.1043 + {
1.1044 + OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1.1045 + OWF_Attribute_Commit(attr,!attr->attr_info.readonly,
1.1046 + WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX);
1.1047 + }
1.1048 + break;
1.1049 + case COMMIT_ATTR_DIRECT_FROM_WORKING: /* Used in WFD to commit new working values directly in 1 step. */
1.1050 + for (index = aStart; index <= aEnd; index++)
1.1051 + {
1.1052 + OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1.1053 + attr->attr_info.dirty=
1.1054 + OWF_Attribute_Commit(attr,attr->attr_info.dirty,
1.1055 + COMMITTED_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
1.1056 + }
1.1057 + break;
1.1058 + default:
1.1059 + COND_FAIL_NR(aContext, 0, ATTR_ERROR_INVALID_ARGUMENT);
1.1060 + }
1.1061 +
1.1062 + SET_ERROR(aContext, ATTR_ERROR_NONE);
1.1063 +}
1.1064 +
1.1065 +#ifdef __cplusplus
1.1066 +}
1.1067 +#endif