os/graphics/graphicscomposition/openwfcompositionengine/common/src/owfattributes.c
First public contribution.
1 /* Copyright (c) 2009-2010 The Khronos Group Inc.
2 * Portions copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and/or associated documentation files (the
6 * "Materials"), to deal in the Materials without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Materials, and to
9 * permit persons to whom the Materials are furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Materials.
15 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
36 #include "owfattributes.h"
37 #include "owfmemory.h"
40 #define OWF_ATTRIB_RANGE_START (0)
41 #define OWF_ATTRIB_RANGE_UNINITIALIZED (-1)
43 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom);
46 This attribute class is not used for WFC element attributes because elements are
47 completely cloned in the committed scene.
48 [This class could be replaced with 3 copies of a much simpler writable attributes raw
49 structure with simple data members, and the whole structure copied each commit.]
50 Normal attribute values have three pointers indexed via an array:
51 COMMITTED_ATTR_VALUE_INDEX:
52 Attribute values used by the scene
53 - points to named variables directly used by the compositor
54 WORKING_ATTR_VALUE_INDEX:
55 Attribute values that may be set by the client, if they are not read-only.
56 SNAPSHOT_ATTR_VALUE_INDEX
57 A copy of the client-set attribute values following a client call to wfcCommit
58 The copy is then protected against further modification by the client until
59 the committed scene is updated and displayed.
60 The Working and Snapshot writable attributes require additional cache storage,
61 which is managed by the lifetime of the attribute list.
62 Read-only attributes point all three pointers at the named compositor variables.
63 Currently, there are relatively few writable attributes so it is reasonable
64 to individually dynamically allocate each cache. It would be better to allocate
65 a single block sized after the attributes have been registered.
67 Internal code is expected to read or write to member variables that are abstracted
68 by read-only attributes. However they must not write directly to member variables
69 masked by writable attributes after the initial "commit" to working. The code does
70 not currently use const instances to enforce this behavior.
72 #define COND_FAIL_NR(ctx, condition, error) \
75 (ctx)->last_error = error; \
80 #define COND_FAIL(ctx, condition, error, r) \
83 (ctx)->last_error = error; \
88 // NS here means No Set as we are not setting the last_error member of the context.
89 // These are used when we are testing the context itself so setting the last_error
90 // member is itself is an error
91 #define COND_FAIL_NR_NS(condition) \
96 #define COND_FAIL_NS(condition, r) \
101 #define CHECK_INDEX_NR(ctx, index, error) \
102 if (index < (ctx)->range_start || index > (ctx)->range_end) { \
103 (ctx)->last_error = error; \
107 #define CHECK_INDEX(ctx, index, error, r) \
108 if (index < (ctx)->range_start || index > (ctx)->range_end) { \
109 (ctx)->last_error = error; \
113 #define CHECK_BAD_NR(ctx, index) \
114 CHECK_INDEX_NR(ctx, index, ATTR_ERROR_INVALID_ATTRIBUTE); \
115 if ((ctx)->attributes[index-(ctx)->range_start].attr_info.type == AT_UNDEFINED) { \
116 (ctx)->last_error = ATTR_ERROR_INVALID_ATTRIBUTE; \
120 #define CHECK_BAD(ctx, index, r) \
121 CHECK_INDEX(ctx, index, ATTR_ERROR_INVALID_ATTRIBUTE, r); \
122 if ((ctx)->attributes[index-(ctx)->range_start].attr_info.type == AT_UNDEFINED) { \
123 (ctx)->last_error = ATTR_ERROR_INVALID_ATTRIBUTE; \
127 #define SET_ERROR(ctx, err) \
128 if ((ctx)->last_error == ATTR_ERROR_NONE) { \
129 (ctx)->last_error = err; \
134 =============================================================================
135 ATTRIBUTE CONTEXT MANAGEMENT FUNCTIONS
136 =============================================================================
140 * \brief Initializes attribute context
142 * \param aContext Attribute context to initialize
143 * \param aStart Attribute range start
144 * \param aEnd Attribute range end. Must be greater than range start.
146 * \return ATTR_ERROR_INVALID_ARGUMENT
147 * ATTR_ERROR_NO_MEMORY
150 OWF_AttributeList_Create(OWF_ATTRIBUTE_LIST* aContext,
154 OWF_ATTRIBUTE* temp = NULL;
156 COND_FAIL_NR_NS(aContext);
157 COND_FAIL_NR(aContext, aEnd >= 0, ATTR_ERROR_INVALID_ARGUMENT);
158 COND_FAIL_NR(aContext, aEnd >= aStart, ATTR_ERROR_INVALID_ARGUMENT);
160 aContext->range_start = OWF_ATTRIB_RANGE_START;
161 aContext->range_end = OWF_ATTRIB_RANGE_UNINITIALIZED;
163 temp = (OWF_ATTRIBUTE*) xalloc(aEnd - aStart + 1, sizeof(OWF_ATTRIBUTE));
164 COND_FAIL_NR(aContext, temp, ATTR_ERROR_NO_MEMORY);
166 memset(aContext, 0, sizeof(OWF_ATTRIBUTE_LIST));
168 aContext->range_start = aStart;
169 aContext->range_end = aEnd;
170 aContext->attributes = temp;
172 SET_ERROR(aContext, ATTR_ERROR_NONE);
177 * \brief Destroy attribute context and free any resources (memory
178 * blocks) allocated to it. All attributes are destroyed.
180 * \param aContext Attribute context to destroy
182 * \return ATTR_ERROR_INVALID_ARGUMENT
183 * ATTR_ERROR_INVALID_CONTEXT
186 OWF_AttributeList_Destroy(OWF_ATTRIBUTE_LIST* aContext)
192 COND_FAIL_NR_NS(aContext);
193 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
195 count = aContext->range_end - aContext->range_start;
196 for (at = 0; at <= count; at++) {
198 OWF_ATTRIBUTE* attr = &aContext->attributes[at];
199 if (!attr->attr_info.readonly)
201 for (cache=0;cache<NUM_ATTR_VALUE_COPIES;cache++)
203 if (cache!=COMMITTED_ATTR_VALUE_INDEX)
205 xfree(attr->attr_value[cache].gen_ptr);
211 xfree(aContext->attributes);
212 memset(aContext, 0, sizeof(OWF_ATTRIBUTE_LIST));
213 SET_ERROR(aContext, ATTR_ERROR_NONE);
221 OWF_API_CALL OWF_ATTRIBUTE_LIST_STATUS
222 OWF_AttributeList_GetError(OWF_ATTRIBUTE_LIST* aContext)
224 OWF_ATTRIBUTE_LIST_STATUS error;
227 return ATTR_ERROR_INVALID_ARGUMENT;
229 error = aContext->last_error;
230 aContext->last_error = ATTR_ERROR_NONE;
235 =============================================================================
236 INITIALIZATION FUNCTIONS
237 =============================================================================
240 static void OWF_Attribute_Init(OWF_ATTRIBUTE_LIST* aContext,
242 OWF_ATTRIBUTE_TYPE aType,
247 OWF_ATTRIBUTE* attr = NULL;
254 COND_FAIL_NR_NS(aContext);
255 CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE);
256 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
257 COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE);
258 COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT);
260 index = aName - aContext->range_start;
262 attr = &aContext->attributes[index];
264 memset(attr, 0, sizeof(OWF_ATTRIBUTE));
266 /* when allocin', size DOES matter */
267 if (aType == AT_INTEGER || aType == AT_BOOLEAN) {
268 itemSize = sizeof(OWFint);
270 itemSize = sizeof(OWFfloat);
272 arraySize=itemSize*aLength;
274 /* don't allocate cache for read-only 'butes */
275 attr->attr_info.type = aType;
276 attr->attr_info.length = aLength;
277 attr->attr_info.readonly = aRdOnly;
278 attr->attr_info.size = itemSize;
281 for (copy=0;copy<NUM_ATTR_VALUE_COPIES;copy++)
283 attr->attr_value[copy].gen_ptr = aValue;
288 for (copy=0;copy<NUM_ATTR_VALUE_COPIES;copy++)
290 if (copy==COMMITTED_ATTR_VALUE_INDEX)
292 attr->attr_value[COMMITTED_ATTR_VALUE_INDEX].gen_ptr = aValue;
296 cache = xalloc(arraySize,1);
297 COND_FAIL_NR(aContext, NULL != cache, ATTR_ERROR_NO_MEMORY);
298 attr->attr_value[copy].gen_ptr = cache;
303 SET_ERROR(aContext, ATTR_ERROR_NONE);
308 * \brief Intialize integer attribute
310 * \param aContext Attibute context
311 * \param aName Attribute name
312 * \param aValue Attribute initial value
313 * \param aRdOnly Read-only flag
315 * \return ATTR_ERROR_INVALID_ARGUMENT
316 * ATTR_ERROR_INVALID_ATTRIBUTE
317 * ATTR_ERROR_INVALID_CONTEXT
320 OWF_Attribute_Initi(OWF_ATTRIBUTE_LIST* aContext,
325 OWF_Attribute_Init(aContext, aName, AT_INTEGER, 1, aValue, aRdOnly);
329 * \brief Initialize float attribute
331 * \param aContext Attribute context
332 * \param aName Attribute name
333 * \param aValue Initial value for attribute
334 * \param aRdOnly Read-only flag
336 * \return ATTR_ERROR_INVALID_ARGUMENT
337 * ATTR_ERROR_INVALID_ATTRIBUTE
338 * ATTR_ERROR_INVALID_CONTEXT
341 OWF_Attribute_Initf(OWF_ATTRIBUTE_LIST* aContext,
343 OWF_FLOAT_REF aValue,
346 OWF_Attribute_Init(aContext, aName, AT_FLOAT, 1, aValue, aRdOnly);
350 * \brief Initialize boolean attribute
352 * \param aContext Attribute context
353 * \param aName Attribute name
354 * \param aValue Initial value for attribute
355 * \param aRdOnly Read-only flag
357 * \return ATTR_ERROR_INVALID_ARGUMENT
358 * ATTR_ERROR_INVALID_ATTRIBUTE
359 * ATTR_ERROR_INVALID_CONTEXT
362 OWF_Attribute_Initb(OWF_ATTRIBUTE_LIST* aContext,
367 OWF_Attribute_Init(aContext, aName, AT_BOOLEAN, 1, aValue, aRdOnly);
371 * \brief Initialize vector attribute
373 * \param aContext Attribute context
374 * \param aName Attribute name
375 * \param aLength Attribute (vector) length
376 * \param aValues Initial value(s) for attribute
377 * \param aRdOnly Read-only flag
379 * \return ATTR_ERROR_INVALID_ARGUMENT
380 * ATTR_ERROR_INVALID_ATTRIBUTE
381 * ATTR_ERROR_INVALID_CONTEXT
382 * ATTR_ERROR_CANT_HANDLE
385 OWF_Attribute_Initiv(OWF_ATTRIBUTE_LIST* aContext,
388 OWF_INT_VECTOR_REF aValues,
391 OWF_Attribute_Init(aContext, aName, AT_INTEGER, aLength, aValues, aRdOnly);
395 * \brief Initialize vector attribute
397 * \param aContext Attribute context
398 * \param aName Attribute name
399 * \param aLength Attribute (vector) length
400 * \param aValues Initial value(s) for attributes
401 * \param aRdOnly Read-only flag
406 OWF_Attribute_Initfv(OWF_ATTRIBUTE_LIST* aContext,
409 OWF_FLOAT_VECTOR_REF aValues,
412 OWF_Attribute_Init(aContext, aName, AT_FLOAT, aLength, aValues, aRdOnly);
416 =============================================================================
418 =============================================================================
422 * \brief Get attribute integer value.
424 * \param aContext Attribute context
425 * \param aName Attribute name
427 * \return Attribute integer value (floats are floor()ed). For vector
428 * attributes the return value will be error ATTR_ERROR_INVALID_TYPE.
429 * ATTR_ERROR_INVALID_ATTRIBUTE
430 * ATTR_ERROR_INVALID_CONTEXT
433 OWF_Attribute_GetValuei(OWF_ATTRIBUTE_LIST* aContext,
437 OWF_ATTRIBUTE* attr = 0;
440 COND_FAIL_NS(aContext, 0);
442 aContext->attributes,
443 ATTR_ERROR_INVALID_CONTEXT,
445 CHECK_BAD(aContext, aName, 0);
448 index = aName - aContext->range_start;
449 attr = &aContext->attributes[index];
452 1 == attr->attr_info.length,
453 ATTR_ERROR_INVALID_TYPE,
456 SET_ERROR(aContext, ATTR_ERROR_NONE);
458 switch (attr->attr_info.type) {
460 result = floor(attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0]);
466 result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
471 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
479 * \brief Return boolean attribute value
481 * \param aContext Attribute context
482 * \param aName Attribute name
484 * \return Attribute value
485 * ATTR_ERROR_INVALID_ATTRIBUTE
486 * ATTR_ERROR_INVALID_TYPE
488 OWF_API_CALL OWFboolean
489 OWF_Attribute_GetValueb(OWF_ATTRIBUTE_LIST* aContext,
492 /* boolean is stored as int, must cast */
493 return (OWFboolean) OWF_Attribute_GetValuei(aContext, aName);
497 * \brief Get attribute float value
505 OWF_API_CALL OWFfloat
506 OWF_Attribute_GetValuef(OWF_ATTRIBUTE_LIST* aContext,
510 OWF_ATTRIBUTE* attr = NULL;
511 OWFfloat result = 0.f;
513 COND_FAIL_NS(aContext, 0);
515 aContext->attributes,
516 ATTR_ERROR_INVALID_CONTEXT,
518 CHECK_BAD(aContext, aName, 0);
521 index = aName - aContext->range_start;
522 attr = &aContext->attributes[index];
525 1 == attr->attr_info.length,
526 ATTR_ERROR_INVALID_TYPE,
529 SET_ERROR(aContext, ATTR_ERROR_NONE);
532 switch (attr->attr_info.type) {
534 result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0];
540 result = (OWFfloat) attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
545 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
563 OWF_Attribute_GetValueiv(OWF_ATTRIBUTE_LIST* aContext,
569 OWF_ATTRIBUTE* attr = NULL;
572 COND_FAIL_NS(aContext, 0);
574 aContext->attributes,
575 ATTR_ERROR_INVALID_CONTEXT,
577 CHECK_BAD(aContext, aName, 0);
580 index = aName - aContext->range_start;
581 attr = &aContext->attributes[index];
584 attr->attr_info.length >= 1,
585 ATTR_ERROR_INVALID_TYPE,
589 /* fetch size only */
590 return attr->attr_info.length;
593 count = min(aLength, attr->attr_info.length);
595 SET_ERROR(aContext, ATTR_ERROR_NONE);
597 switch (attr->attr_info.type) {
600 OWFfloat* v = attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value;
601 for (i = 0; i < count; i++) {
602 aValue[i] = floor(v[i]);
610 attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value,
611 count * attr->attr_info.size);
616 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
634 OWF_Attribute_GetValuefv(OWF_ATTRIBUTE_LIST* aContext,
640 OWF_ATTRIBUTE* attr = NULL;
643 COND_FAIL_NS(aContext, 0);
645 aContext->attributes,
646 ATTR_ERROR_INVALID_CONTEXT,
648 CHECK_BAD(aContext, aName, 0);
651 index = aName - aContext->range_start;
652 attr = &aContext->attributes[index];
655 attr->attr_info.length >= 1,
656 ATTR_ERROR_INVALID_TYPE, 0);
659 /* fetch size only */
660 return attr->attr_info.length;
663 count = min(aLength, attr->attr_info.length);
665 SET_ERROR(aContext, ATTR_ERROR_NONE);
667 switch (attr->attr_info.type) {
670 attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value,
671 count * attr->attr_info.size);
678 OWFint* v = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value;
679 for (i = 0; i < count; i++) {
680 aValue[i] = (OWFfloat) v[i];
686 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
694 =============================================================================
696 =============================================================================
709 OWF_Attribute_SetValuei(OWF_ATTRIBUTE_LIST* aContext,
714 OWF_ATTRIBUTE* attr = NULL;
716 COND_FAIL_NR_NS(aContext);
717 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
718 CHECK_BAD_NR(aContext, aName);
721 index = aName - aContext->range_start;
722 attr = &aContext->attributes[index];
724 COND_FAIL_NR(aContext,
725 1 == attr->attr_info.length,
726 ATTR_ERROR_INVALID_TYPE);
727 COND_FAIL_NR(aContext, !attr->attr_info.readonly, ATTR_ERROR_ACCESS_DENIED);
729 SET_ERROR(aContext, ATTR_ERROR_NONE);
731 attr->attr_info.dirty = 1;
733 switch (attr->attr_info.type) {
735 attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0] = aValue;
741 attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0] = aValue;
746 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
762 OWF_Attribute_SetValuef(OWF_ATTRIBUTE_LIST* aContext,
767 OWF_ATTRIBUTE* attr = NULL;
769 COND_FAIL_NR_NS(aContext);
770 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
771 CHECK_BAD_NR(aContext, aName);
774 index = aName - aContext->range_start;
775 attr = &aContext->attributes[index];
777 COND_FAIL_NR(aContext,
778 1 == attr->attr_info.length,
779 ATTR_ERROR_INVALID_TYPE);
780 COND_FAIL_NR(aContext,
781 !attr->attr_info.readonly,
782 ATTR_ERROR_ACCESS_DENIED);
784 SET_ERROR(aContext, ATTR_ERROR_NONE);
786 attr->attr_info.dirty = 1;
788 switch (attr->attr_info.type) {
790 attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0] = aValue;
796 attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0] = floor(aValue);
801 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
817 OWF_Attribute_SetValueb(OWF_ATTRIBUTE_LIST* aContext,
821 OWF_Attribute_SetValuei(aContext, aName, (OWFint) aValue);
834 OWF_Attribute_SetValueiv(OWF_ATTRIBUTE_LIST* aContext,
837 const OWFint* aValue)
840 OWF_ATTRIBUTE* attr = NULL;
843 COND_FAIL_NR_NS(aContext);
844 COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
845 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
846 CHECK_BAD_NR(aContext, aName);
848 index = aName - aContext->range_start;
849 attr = &aContext->attributes[index];
851 COND_FAIL_NR(aContext,
852 attr->attr_info.length >= 1,
853 ATTR_ERROR_INVALID_TYPE);
855 COND_FAIL_NR(aContext,
856 aLength > 0 && aLength <= attr->attr_info.length,
857 ATTR_ERROR_INVALID_ARGUMENT);
859 COND_FAIL_NR(aContext,
860 !attr->attr_info.readonly,
861 ATTR_ERROR_ACCESS_DENIED);
863 count = min(aLength, attr->attr_info.length);
865 SET_ERROR(aContext, ATTR_ERROR_NONE);
867 switch (attr->attr_info.type) {
870 OWFfloat* v = attr->attr_value[1].float_value;
871 for (i = 0; i < count; i++) {
872 v[i] = floor(aValue[i]);
879 memcpy(attr->attr_value[1].int_value,
881 count * attr->attr_info.size);
886 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
890 aContext->attributes[index].attr_info.dirty = 1;
903 OWF_Attribute_SetValuefv(OWF_ATTRIBUTE_LIST* aContext,
906 const OWFfloat* aValue)
909 OWF_ATTRIBUTE* attr = NULL;
912 COND_FAIL_NR_NS(aContext);
913 COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
914 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
915 CHECK_BAD_NR(aContext, aName);
917 index = aName - aContext->range_start;
918 attr = &aContext->attributes[index];
921 COND_FAIL_NR(aContext,
922 attr->attr_info.length >= 1,
923 ATTR_ERROR_INVALID_TYPE);
926 COND_FAIL_NR(aContext,
927 aLength > 0 && aLength <= attr->attr_info.length,
928 ATTR_ERROR_INVALID_ARGUMENT);
930 COND_FAIL_NR(aContext,
931 !attr->attr_info.readonly,
932 ATTR_ERROR_ACCESS_DENIED);
934 count = min(aLength, attr->attr_info.length);
936 SET_ERROR(aContext, ATTR_ERROR_NONE);
938 switch (attr->attr_info.type) {
940 memcpy(attr->attr_value[1].float_value,
942 count * attr->attr_info.size);
949 OWFint* v = attr->attr_value[1].int_value;
950 for (i = 0; i < count; i++) {
951 v[i] = floor(aValue[i]);
957 SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
961 aContext->attributes[index].attr_info.dirty = 1;
964 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr,
969 OWF_ASSERT(aCopyTo >= 0);
970 OWF_ASSERT(aCopyTo < NUM_ATTR_VALUE_COPIES);
971 OWF_ASSERT(aCopyFrom >= 0);
972 OWF_ASSERT(aCopyFrom < NUM_ATTR_VALUE_COPIES);
973 /* if type is undefined, it means there're gaps in the attribute
974 range (e.g. reservations for future use and such.) ignore them. */
975 if (aAttr->attr_info.type != AT_UNDEFINED && aDirtyFlag)
977 /* poor-man's commit */
978 memcpy(aAttr->attr_value[aCopyTo].gen_ptr,
979 aAttr->attr_value[aCopyFrom].gen_ptr,
980 aAttr->attr_info.size * aAttr->attr_info.length);
991 OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext,
997 /* Attribute commit works like the element list commit
998 * by forward-copying the "working" attributes to the snapshot
999 * during client invoked commit,
1000 * then copying the snapshot to the commited scene during the docommit job.
1001 * This requires the same wait-for-the-previous-commit-job strategy used in the element commit.
1002 * Could in future use copy-back technique to avoid having to wait substantially,
1003 * in which case the index of the working attribute set would switch after each invoked commit,
1004 * instead of being a constant.
1006 * The same number of copies would still need to take place
1007 * but would not need exclusive access to the list.
1010 COND_FAIL_NR_NS(aContext);
1011 COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT);
1012 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
1013 CHECK_BAD_NR(aContext, aStart);
1014 CHECK_BAD_NR(aContext, aEnd);
1018 case COMMITTED_ATTR_VALUE_INDEX: /* Used in composition thread to set displayed scene attributes */
1019 for (index = aStart; index <= aEnd; index++)
1021 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1022 attr->attr_info.dirtysnapshot=
1023 OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot,
1024 COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX);
1027 case SNAPSHOT_ATTR_VALUE_INDEX: /* Used in API threads to make a snapshot of the client attributes */
1028 for (index = aStart; index <= aEnd; index++)
1030 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1031 OWFuint oldDirty=attr->attr_info.dirty;
1032 attr->attr_info.dirtysnapshot=oldDirty;
1033 attr->attr_info.dirty=
1034 OWF_Attribute_Commit(attr,oldDirty,
1035 SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
1038 case WORKING_ATTR_VALUE_INDEX: /* Used in initialisation to copy displayed attributes to client copies */
1039 for (index = aStart; index <= aEnd; index++)
1041 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1042 OWF_Attribute_Commit(attr,!attr->attr_info.readonly,
1043 WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX);
1046 case COMMIT_ATTR_DIRECT_FROM_WORKING: /* Used in WFD to commit new working values directly in 1 step. */
1047 for (index = aStart; index <= aEnd; index++)
1049 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
1050 attr->attr_info.dirty=
1051 OWF_Attribute_Commit(attr,attr->attr_info.dirty,
1052 COMMITTED_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
1056 COND_FAIL_NR(aContext, 0, ATTR_ERROR_INVALID_ARGUMENT);
1059 SET_ERROR(aContext, ATTR_ERROR_NONE);