graphicscomposition/openwfcompositionengine/common/src/owfattributes.c
changeset 36 01a6848ebfd7
parent 0 5d03bc08d59c
child 152 9f1c3fea0f87
equal deleted inserted replaced
0:5d03bc08d59c 36:01a6848ebfd7
     1 /* Copyright (c) 2009 The Khronos Group Inc.
     1 /* Copyright (c) 2009-2010 The Khronos Group Inc.
     2  *
     2  *
     3  * Permission is hereby granted, free of charge, to any person obtaining a
     3  * Permission is hereby granted, free of charge, to any person obtaining a
     4  * copy of this software and/or associated documentation files (the
     4  * copy of this software and/or associated documentation files (the
     5  * "Materials"), to deal in the Materials without restriction, including
     5  * "Materials"), to deal in the Materials without restriction, including
     6  * without limitation the rights to use, copy, modify, merge, publish,
     6  * without limitation the rights to use, copy, modify, merge, publish,
    32 #include <string.h>
    32 #include <string.h>
    33 #include <math.h>
    33 #include <math.h>
    34 
    34 
    35 #include "owfattributes.h"
    35 #include "owfattributes.h"
    36 #include "owfmemory.h"
    36 #include "owfmemory.h"
       
    37 #include "owfdebug.h"
    37 
    38 
    38 #define OWF_ATTRIB_RANGE_START            (0)
    39 #define OWF_ATTRIB_RANGE_START            (0)
    39 #define OWF_ATTRIB_RANGE_UNINITIALIZED    (-1)
    40 #define OWF_ATTRIB_RANGE_UNINITIALIZED    (-1)
    40 
    41 
    41 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom);
    42 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom);
    42 
    43  
    43 /*
    44   /*
    44  This attribute class is currently only used for context attributes.
    45   This attribute class is not used for WFC element attributes because elements are 
    45  Why isn't it used for element attributes? 
    46   completely cloned in the committed scene.
    46      - Because elements are completely cloned in the committed scene.
    47   [This class could be replaced with 3 copies of a much simpler writable attributes raw 
    47  [This class could be replaced with 3 copies of a much simpler writable attributes raw 
    48   structure with simple data members, and the whole structure copied each commit.] 
    48  structure with simple data members, and the whole structure copied each commit.] 
    49   Normal attribute values have three pointers indexed via an array:
    49  Normal attribute values have three pointers indexed via an array:
    50      COMMITTED_ATTR_VALUE_INDEX:
    50     COMMITTED_ATTR_VALUE_INDEX:
    51          Attribute values used by the scene 
    51         Attribute values used by the scene 
    52              - points to named variables directly used by the compositor
    52             - points to named variables directly used by the compositor
    53      WORKING_ATTR_VALUE_INDEX:
    53     WORKING_ATTR_VALUE_INDEX:
    54          Attribute values that may be set by the client, if they are not read-only.
    54         Attribute values that may be set by the client, if they are not read-only.
    55      SNAPSHOT_ATTR_VALUE_INDEX
    55     SNAPSHOT_ATTR_VALUE_INDEX
    56          A copy of the client-set attribute values following a client call to wfcCommit
    56         A copy of the client-set attribute values following a client call to wfcCommit
    57          The copy is then protected against further modification by the client until 
    57         The copy is then protected against further modification by the client until 
    58          the committed scene is updated and displayed.
    58         the committed scene is updated and displayed.
    59   The Working and Snapshot writable attributes require additional cache storage, 
    59  The Working and Snapshot writable attributes require additional cache storage, 
    60   which is managed by the lifetime of the attribute list.
    60  which is managed by the lifetime of the attribute list.
    61   Read-only attributes point all three pointers at the named compositor variables.
    61  Read-only attributes point all three pointers at the named compositor variables.
    62   Currently, there are relatively few writable attributes so it is reasonable 
    62  Currently, there are relatively few writable attributes so it is reasonable 
    63   to individually dynamically allocate each cache. It would be better to allocate 
    63  to individually dynamically allocate each cache. It would be better to allocate 
    64   a single block sized after the attributes have been registered.  
    64  a single block sized after the attributes have been registered.  
    65   
       
    66   Internal code is expected to read or write to member variables that are abstracted 
       
    67   by read-only attributes. However they must not write directly to member variables 
       
    68   masked by writable attributes after the initial "commit" to working. The code does 
       
    69   not currently use const instances to enforce this behavior.
    65  */
    70  */
    66 #define COND_FAIL_NR(ctx, condition, error) \
    71 #define COND_FAIL_NR(ctx, condition, error) \
    67     if (!(condition)) { \
    72     if (!(condition)) { \
    68         if (ctx) { \
    73         if (ctx) { \
    69             (ctx)->last_error = error; \
    74             (ctx)->last_error = error; \
    76         if (ctx) { \
    81         if (ctx) { \
    77             (ctx)->last_error = error; \
    82             (ctx)->last_error = error; \
    78         } \
    83         } \
    79         return r; \
    84         return r; \
    80     }
    85     }
       
    86 	
       
    87 // NS here means No Set as we are not setting the last_error member of the context.
       
    88 // These are used when we are testing the context itself so setting the last_error
       
    89 // member is itself is an error
       
    90 #define COND_FAIL_NR_NS(condition) \
       
    91     if (!(condition)) { \
       
    92         return; \
       
    93     }
       
    94 
       
    95 #define COND_FAIL_NS(condition, r) \
       
    96     if (!(condition)) { \
       
    97         return r; \
       
    98     }
    81 
    99 
    82 #define CHECK_INDEX_NR(ctx, index, error) \
   100 #define CHECK_INDEX_NR(ctx, index, error) \
    83     if (index < (ctx)->range_start || index > (ctx)->range_end) { \
   101     if (index < (ctx)->range_start || index > (ctx)->range_end) { \
    84         (ctx)->last_error = error; \
   102         (ctx)->last_error = error; \
    85         return; \
   103         return; \
   132                          OWFint aStart,
   150                          OWFint aStart,
   133                          OWFint aEnd)
   151                          OWFint aEnd)
   134 {
   152 {
   135     OWF_ATTRIBUTE*          temp = NULL;
   153     OWF_ATTRIBUTE*          temp = NULL;
   136 
   154 
   137     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   155     COND_FAIL_NR_NS(aContext);
   138     COND_FAIL_NR(aContext, aEnd >= 0, ATTR_ERROR_INVALID_ARGUMENT);
   156     COND_FAIL_NR(aContext, aEnd >= 0, ATTR_ERROR_INVALID_ARGUMENT);
   139     COND_FAIL_NR(aContext, aEnd >= aStart, ATTR_ERROR_INVALID_ARGUMENT);
   157     COND_FAIL_NR(aContext, aEnd >= aStart, ATTR_ERROR_INVALID_ARGUMENT);
   140 
   158 
   141     aContext->range_start = OWF_ATTRIB_RANGE_START;
   159     aContext->range_start = OWF_ATTRIB_RANGE_START;
   142     aContext->range_end = OWF_ATTRIB_RANGE_UNINITIALIZED;
   160     aContext->range_end = OWF_ATTRIB_RANGE_UNINITIALIZED;
   168 {
   186 {
   169     OWFint                 count = 0;
   187     OWFint                 count = 0;
   170     OWFint                 at = 0;
   188     OWFint                 at = 0;
   171     OWFint                 cache = 0;
   189     OWFint                 cache = 0;
   172 
   190 
   173     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   191     COND_FAIL_NR_NS(aContext);
   174     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   192     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   175 
   193 
   176     count = aContext->range_end - aContext->range_start;
   194     count = aContext->range_end - aContext->range_start;
   177     for (at = 0; at <= count; at++) {
   195     for (at = 0; at <= count; at++) {
       
   196 
   178         OWF_ATTRIBUTE* attr = &aContext->attributes[at];
   197         OWF_ATTRIBUTE* attr = &aContext->attributes[at];
   179         if (!attr->attr_info.readonly)
   198         if (!attr->attr_info.readonly)
   180             {
   199             {
   181             for (cache=0;cache<NUM_ATTR_VALUE_COPIES;cache++)
   200             for (cache=0;cache<NUM_ATTR_VALUE_COPIES;cache++)
   182                 {
   201                 {
   227     OWF_ATTRIBUTE*          attr = NULL;
   246     OWF_ATTRIBUTE*          attr = NULL;
   228     void*                   cache = NULL;
   247     void*                   cache = NULL;
   229     OWFint                  itemSize;
   248     OWFint                  itemSize;
   230     OWFint                  arraySize;
   249     OWFint                  arraySize;
   231     OWFint                  copy;
   250     OWFint                  copy;
   232     OWFint                  index = aName - aContext->range_start;
   251     OWFint                  index;
   233 
   252 	
   234     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   253 	COND_FAIL_NR_NS(aContext);
   235     CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE);
   254 	CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE);
   236     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   255     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   237     COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE);
   256     COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE);
   238     COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT);
   257     COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT);
       
   258 	
       
   259 	index = aName - aContext->range_start;
   239 
   260 
   240     attr = &aContext->attributes[index];
   261     attr = &aContext->attributes[index];
   241     
   262     
   242     memset(attr, 0, sizeof(OWF_ATTRIBUTE));
   263     memset(attr, 0, sizeof(OWF_ATTRIBUTE));
   243     
   264 
   244     /* when allocin', size DOES matter */
   265     /* when allocin', size DOES matter */
   245     
       
   246     if (aType == AT_INTEGER || aType == AT_BOOLEAN) {
   266     if (aType == AT_INTEGER || aType == AT_BOOLEAN) {
   247         itemSize = sizeof(OWFint);
   267         itemSize = sizeof(OWFint);
   248     } else {
   268     } else {
   249         itemSize = sizeof(OWFfloat);
   269         itemSize = sizeof(OWFfloat);
   250     }
   270     }
   251     arraySize=itemSize*aLength;
   271     arraySize=itemSize*aLength;
   252     
   272 
   253     /* don't allocate cache for read-only 'butes */
   273     /* don't allocate cache for read-only 'butes */
   254     attr->attr_info.type        = aType;
   274     attr->attr_info.type        = aType;
   255     attr->attr_info.length      = aLength;
   275     attr->attr_info.length      = aLength;
   256     attr->attr_info.readonly    = aRdOnly;
   276     attr->attr_info.readonly    = aRdOnly;
   257     attr->attr_info.size        = itemSize;
   277     attr->attr_info.size        = itemSize;
   275                 cache = xalloc(arraySize,1);
   295                 cache = xalloc(arraySize,1);
   276                 COND_FAIL_NR(aContext, NULL != cache, ATTR_ERROR_NO_MEMORY);
   296                 COND_FAIL_NR(aContext, NULL != cache, ATTR_ERROR_NO_MEMORY);
   277                 attr->attr_value[copy].gen_ptr = cache;
   297                 attr->attr_value[copy].gen_ptr = cache;
   278                 }
   298                 }
   279              }
   299              }
   280         OWF_Attribute_Commit(attr,1,
       
   281                 WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX);
       
   282        }
   300        }
   283 
       
   284 
       
   285 
       
   286     
       
   287 
   301 
   288     SET_ERROR(aContext, ATTR_ERROR_NONE);
   302     SET_ERROR(aContext, ATTR_ERROR_NONE);
   289 
   303 
   290 }
   304 }
   291 
   305 
   420 {
   434 {
   421     OWFint                  index = 0;
   435     OWFint                  index = 0;
   422     OWF_ATTRIBUTE*          attr = 0;
   436     OWF_ATTRIBUTE*          attr = 0;
   423     OWFint                  result = 0;
   437     OWFint                  result = 0;
   424 
   438 
   425     COND_FAIL(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT, 0);
   439     COND_FAIL_NS(aContext, 0); 
       
   440 	COND_FAIL(aContext,
       
   441               aContext->attributes,
       
   442               ATTR_ERROR_INVALID_CONTEXT,
       
   443               0);
   426     CHECK_BAD(aContext, aName, 0);
   444     CHECK_BAD(aContext, aName, 0);
       
   445 
       
   446 
       
   447     index = aName - aContext->range_start;
       
   448     attr = &aContext->attributes[index];
       
   449 
       
   450     COND_FAIL(aContext,
       
   451               1 == attr->attr_info.length,
       
   452               ATTR_ERROR_INVALID_TYPE,
       
   453               0);
       
   454 
       
   455     SET_ERROR(aContext, ATTR_ERROR_NONE);
       
   456 
       
   457     switch (attr->attr_info.type) {
       
   458         case AT_FLOAT: {
       
   459             result = floor(attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0]);
       
   460             break;
       
   461         }
       
   462 
       
   463         case AT_INTEGER:
       
   464         case AT_BOOLEAN: {
       
   465             result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
       
   466             break;
       
   467         }
       
   468 
       
   469         default: {
       
   470             SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
       
   471             break;
       
   472         }
       
   473     }
       
   474     return result;
       
   475 }
       
   476 
       
   477 /*
       
   478  * \brief Return boolean attribute value
       
   479  *
       
   480  * \param aContext Attribute context
       
   481  * \param aName Attribute name
       
   482  *
       
   483  * \return Attribute value
       
   484  * ATTR_ERROR_INVALID_ATTRIBUTE
       
   485  * ATTR_ERROR_INVALID_TYPE
       
   486  */
       
   487 OWF_API_CALL OWFboolean
       
   488 OWF_Attribute_GetValueb(OWF_ATTRIBUTE_LIST* aContext,
       
   489                         OWFint aName)
       
   490 {
       
   491     /* boolean is stored as int, must cast */
       
   492     return (OWFboolean) OWF_Attribute_GetValuei(aContext, aName);
       
   493 }
       
   494 
       
   495 /*
       
   496  * \brief Get attribute float value
       
   497  *
       
   498  * \param aContext
       
   499  * \param aName
       
   500  * \param aValue
       
   501  *
       
   502  * \return Attribute
       
   503  */
       
   504 OWF_API_CALL OWFfloat
       
   505 OWF_Attribute_GetValuef(OWF_ATTRIBUTE_LIST* aContext,
       
   506                         OWFint aName)
       
   507 {
       
   508     OWFint                 index = 0;
       
   509     OWF_ATTRIBUTE*          attr = NULL;
       
   510     OWFfloat                result = 0.f;
       
   511 
       
   512     COND_FAIL_NS(aContext, 0);
   427     COND_FAIL(aContext,
   513     COND_FAIL(aContext,
   428               aContext->attributes,
   514               aContext->attributes,
   429               ATTR_ERROR_INVALID_CONTEXT,
   515               ATTR_ERROR_INVALID_CONTEXT,
   430               0);
   516               0);
   431 
       
   432     index = aName - aContext->range_start;
       
   433     attr = &aContext->attributes[index];
       
   434 
       
   435     COND_FAIL(aContext,
       
   436               1 == attr->attr_info.length,
       
   437               ATTR_ERROR_INVALID_TYPE,
       
   438               0);
       
   439 
       
   440     SET_ERROR(aContext, ATTR_ERROR_NONE);
       
   441 
       
   442     switch (attr->attr_info.type) {
       
   443         case AT_FLOAT: {
       
   444             result = floor(attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0]);
       
   445             break;
       
   446         }
       
   447 
       
   448         case AT_INTEGER:
       
   449         case AT_BOOLEAN: {
       
   450             result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
       
   451             break;
       
   452         }
       
   453 
       
   454         default: {
       
   455             SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
       
   456             break;
       
   457         }
       
   458     }
       
   459     return result;
       
   460 }
       
   461 
       
   462 /*
       
   463  * \brief Return boolean attribute value
       
   464  *
       
   465  * \param aContext Attribute context
       
   466  * \param aName Attribute name
       
   467  *
       
   468  * \return Attribute value
       
   469  * ATTR_ERROR_INVALID_ATTRIBUTE
       
   470  * ATTR_ERROR_INVALID_TYPE
       
   471  */
       
   472 OWF_API_CALL OWFboolean
       
   473 OWF_Attribute_GetValueb(OWF_ATTRIBUTE_LIST* aContext,
       
   474                         OWFint aName)
       
   475 {
       
   476     /* boolean is stored as int, must cast */
       
   477     return (OWFboolean) OWF_Attribute_GetValuei(aContext, aName);
       
   478 }
       
   479 
       
   480 /*
       
   481  * \brief Get attribute float value
       
   482  *
       
   483  * \param aContext
       
   484  * \param aName
       
   485  * \param aValue
       
   486  *
       
   487  * \return Attribute
       
   488  */
       
   489 OWF_API_CALL OWFfloat
       
   490 OWF_Attribute_GetValuef(OWF_ATTRIBUTE_LIST* aContext,
       
   491                         OWFint aName)
       
   492 {
       
   493     OWFint                 index = 0;
       
   494     OWF_ATTRIBUTE*          attr = NULL;
       
   495     OWFfloat                result = 0.f;
       
   496 
       
   497     COND_FAIL(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT, 0);
       
   498     CHECK_BAD(aContext, aName, 0);
   517     CHECK_BAD(aContext, aName, 0);
   499     COND_FAIL(aContext,
   518 
   500               aContext->attributes,
       
   501               ATTR_ERROR_INVALID_CONTEXT,
       
   502               0);
       
   503 
   519 
   504     index = aName - aContext->range_start;
   520     index = aName - aContext->range_start;
   505     attr = &aContext->attributes[index];
   521     attr = &aContext->attributes[index];
   506 
   522 
   507     COND_FAIL(aContext,
   523     COND_FAIL(aContext,
   550 {
   566 {
   551     OWFint                 index = 0;
   567     OWFint                 index = 0;
   552     OWF_ATTRIBUTE*          attr = NULL;
   568     OWF_ATTRIBUTE*          attr = NULL;
   553     OWFint                 count = 0;
   569     OWFint                 count = 0;
   554 
   570 
   555     COND_FAIL(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT, 0);
   571     COND_FAIL_NS(aContext, 0);
   556     CHECK_BAD(aContext, aName, 0);
       
   557     COND_FAIL(aContext,
   572     COND_FAIL(aContext,
   558               aContext->attributes,
   573               aContext->attributes,
   559               ATTR_ERROR_INVALID_CONTEXT,
   574               ATTR_ERROR_INVALID_CONTEXT,
   560               0);
   575               0);
       
   576     CHECK_BAD(aContext, aName, 0);
       
   577 
   561 
   578 
   562     index = aName - aContext->range_start;
   579     index = aName - aContext->range_start;
   563     attr = &aContext->attributes[index];
   580     attr = &aContext->attributes[index];
   564 
   581 
   565     COND_FAIL(aContext,
   582     COND_FAIL(aContext,
   620 {
   637 {
   621     OWFint                 index = 0;
   638     OWFint                 index = 0;
   622     OWF_ATTRIBUTE*          attr = NULL;
   639     OWF_ATTRIBUTE*          attr = NULL;
   623     OWFint                 count = 0;
   640     OWFint                 count = 0;
   624 
   641 
   625     COND_FAIL(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT, 0);
   642     COND_FAIL_NS(aContext, 0);
   626     CHECK_BAD(aContext, aName, 0);
       
   627     COND_FAIL(aContext,
   643     COND_FAIL(aContext,
   628               aContext->attributes,
   644               aContext->attributes,
   629               ATTR_ERROR_INVALID_CONTEXT,
   645               ATTR_ERROR_INVALID_CONTEXT,
   630               0);
   646               0);
       
   647     CHECK_BAD(aContext, aName, 0);
       
   648 
   631 
   649 
   632     index = aName - aContext->range_start;
   650     index = aName - aContext->range_start;
   633     attr = &aContext->attributes[index];
   651     attr = &aContext->attributes[index];
   634 
   652 
   635     COND_FAIL(aContext,
   653     COND_FAIL(aContext,
   692                         OWFint aValue)
   710                         OWFint aValue)
   693 {
   711 {
   694     OWFint                 index = 0;
   712     OWFint                 index = 0;
   695     OWF_ATTRIBUTE*          attr = NULL;
   713     OWF_ATTRIBUTE*          attr = NULL;
   696 
   714 
   697     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   715     COND_FAIL_NR_NS(aContext);
       
   716     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   698     CHECK_BAD_NR(aContext, aName);
   717     CHECK_BAD_NR(aContext, aName);
   699     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   718 
   700 
   719 
   701     index = aName - aContext->range_start;
   720     index = aName - aContext->range_start;
   702     attr = &aContext->attributes[index];
   721     attr = &aContext->attributes[index];
   703 
   722 
   704     COND_FAIL_NR(aContext,
   723     COND_FAIL_NR(aContext,
   744                         OWFfloat aValue)
   763                         OWFfloat aValue)
   745 {
   764 {
   746     OWFint                 index = 0;
   765     OWFint                 index = 0;
   747     OWF_ATTRIBUTE*          attr = NULL;
   766     OWF_ATTRIBUTE*          attr = NULL;
   748 
   767 
   749     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   768     COND_FAIL_NR_NS(aContext);
       
   769     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   750     CHECK_BAD_NR(aContext, aName);
   770     CHECK_BAD_NR(aContext, aName);
   751     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   771 
   752 
   772 
   753     index = aName - aContext->range_start;
   773     index = aName - aContext->range_start;
   754     attr = &aContext->attributes[index];
   774     attr = &aContext->attributes[index];
   755 
   775 
   756     COND_FAIL_NR(aContext,
   776     COND_FAIL_NR(aContext,
   817 {
   837 {
   818     OWFint                 index = 0;
   838     OWFint                 index = 0;
   819     OWF_ATTRIBUTE*          attr = NULL;
   839     OWF_ATTRIBUTE*          attr = NULL;
   820     OWFint                 count = 0;
   840     OWFint                 count = 0;
   821 
   841 
   822     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   842     COND_FAIL_NR_NS(aContext);
   823     COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
   843     COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
   824     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   844     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   825     CHECK_BAD_NR(aContext, aName);
   845     CHECK_BAD_NR(aContext, aName);
   826 
   846 
   827     index = aName - aContext->range_start;
   847     index = aName - aContext->range_start;
   886 {
   906 {
   887     OWFint                 index = 0;
   907     OWFint                 index = 0;
   888     OWF_ATTRIBUTE*          attr = NULL;
   908     OWF_ATTRIBUTE*          attr = NULL;
   889     OWFint                 count = 0;
   909     OWFint                 count = 0;
   890 
   910 
   891     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
   911     COND_FAIL_NR_NS(aContext);
   892     COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
   912     COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
   893     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   913     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   894     CHECK_BAD_NR(aContext, aName);
   914     CHECK_BAD_NR(aContext, aName);
   895 
   915 
   896     index = aName - aContext->range_start;
   916     index = aName - aContext->range_start;
   943 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, 
   963 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, 
   944                             OWFint aDirtyFlag, 
   964                             OWFint aDirtyFlag, 
   945                             OWFint aCopyTo,
   965                             OWFint aCopyTo,
   946                             OWFint aCopyFrom )
   966                             OWFint aCopyFrom )
   947     {
   967     {
       
   968 	OWF_ASSERT(aCopyTo >= 0);
       
   969 	OWF_ASSERT(aCopyTo < NUM_ATTR_VALUE_COPIES);
       
   970 	OWF_ASSERT(aCopyFrom >= 0);
       
   971 	OWF_ASSERT(aCopyFrom < NUM_ATTR_VALUE_COPIES);
   948     /* if type is undefined, it means there're gaps in the attribute
   972     /* if type is undefined, it means there're gaps in the attribute
   949        range (e.g. reservations for future use and such.) ignore them. */
   973        range (e.g. reservations for future use and such.) ignore them. */
   950     if (aAttr->attr_info.type != AT_UNDEFINED && aDirtyFlag) 
   974     if (aAttr->attr_info.type != AT_UNDEFINED && aDirtyFlag) 
   951         {
   975         {
   952         /* poor-man's commit */
   976         /* poor-man's commit */
   959         {
   983         {
   960         return aDirtyFlag;
   984         return aDirtyFlag;
   961         }
   985         }
   962     }
   986     }
   963 
   987 
       
   988 
   964 OWF_API_CALL void
   989 OWF_API_CALL void
   965 OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext,
   990 OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext,
   966                      OWFint aStart,
   991                      OWFint aStart,
   967                      OWFint aEnd,
   992                      OWFint aEnd,
   968                      OWFint aCopyTo )
   993 		     OWFint aCopyTo )
   969 {
   994 {
   970     OWFint                 index = 0;
   995     OWFint                 index = 0;
   971     /* Attribute commit works like the element list commit
   996     /* Attribute commit works like the element list commit
   972      * by forward-copying the "working" attributes to the snapshot  
   997      * by forward-copying the "working" attributes to the snapshot  
   973      * during client invoked commit,
   998      * during client invoked commit,
   974      * then copying the snapshot to the commited scene during the docommit job.
   999      * then copying the snapshot to the commited scene during the docommit job.
   975      * This requires the same wait-for-the-previous-commit-job strategy used in the element commit.
  1000      * This requires the same wait-for-the-previous-commit-job strategy used in the element commit.
   976      * Could in future use copy-back technique to avoid having to wait substantially, 
  1001      * Could in future use copy-back technique to avoid having to wait substantially, 
   977      * in which case the index of the working attribute set would switch after each invoked commit,
  1002      * in which case the index of the working attribute set would switch after each invoked commit,
   978      * instead of being a constant.
  1003      * instead of being a constant.
       
  1004      *
   979      * The same number of copies would still need to take place  
  1005      * The same number of copies would still need to take place  
   980      * but would not need exclusive access to the list.
  1006      * but would not need exclusive access to the list.
   981      */
  1007      */
   982     COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT);
  1008 
       
  1009     COND_FAIL_NR_NS(aContext);
   983     COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT);
  1010     COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT);
   984     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
  1011     COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
   985     CHECK_BAD_NR(aContext, aStart);
  1012     CHECK_BAD_NR(aContext, aStart);
   986     CHECK_BAD_NR(aContext, aEnd);
  1013     CHECK_BAD_NR(aContext, aEnd);
   987 
  1014 
   988 
       
   989     switch (aCopyTo)
  1015     switch (aCopyTo)
   990         {
  1016         {
   991         case COMMITTED_ATTR_VALUE_INDEX: //Used in composition thread to set displayed scene attributes 
  1017         case COMMITTED_ATTR_VALUE_INDEX: /* Used in composition thread to set displayed scene attributes */
   992             for (index = aStart; index <= aEnd; index++) 
  1018             for (index = aStart; index <= aEnd; index++) 
   993                 {
  1019                 {
   994                 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
  1020                 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
   995                 attr->attr_info.dirtysnapshot=
  1021                 attr->attr_info.dirtysnapshot=
   996                     OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot,
  1022                     OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot,
   997                             COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX);
  1023                             COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX);
   998                 }
  1024                 }
   999             break;
  1025             break;
  1000         case SNAPSHOT_ATTR_VALUE_INDEX: //Used in API threads to make a snapshot of the client attributes
  1026         case SNAPSHOT_ATTR_VALUE_INDEX: /* Used in API threads to make a snapshot of the client attributes */
  1001              for (index = aStart; index <= aEnd; index++) 
  1027              for (index = aStart; index <= aEnd; index++) 
  1002                  {
  1028                  {
  1003                  OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
  1029                  OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
  1004                  OWFuint oldDirty=attr->attr_info.dirty;
  1030                  OWFuint oldDirty=attr->attr_info.dirty;
  1005                  attr->attr_info.dirtysnapshot=oldDirty;
  1031                  attr->attr_info.dirtysnapshot=oldDirty;
  1006                  attr->attr_info.dirty=
  1032                  attr->attr_info.dirty=
  1007                      OWF_Attribute_Commit(attr,oldDirty,
  1033                      OWF_Attribute_Commit(attr,oldDirty,
  1008                              SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
  1034                              SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
  1009                  }
  1035                  }
  1010              break;
  1036              break;
  1011         case WORKING_ATTR_VALUE_INDEX:   //Used in initialisation to copy displayed attributes to client copies
  1037         case WORKING_ATTR_VALUE_INDEX:   /* Used in initialisation to copy displayed attributes to client copies */
  1012              for (index = aStart; index <= aEnd; index++) 
  1038              for (index = aStart; index <= aEnd; index++) 
  1013                  {
  1039                  {
  1014                  OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
  1040                  OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
  1015                  OWF_Attribute_Commit(attr,!attr->attr_info.readonly,
  1041                  OWF_Attribute_Commit(attr,!attr->attr_info.readonly,
  1016                          WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX);
  1042                          WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX);
  1017                  }
  1043                  }
  1018              break;
  1044              break;
  1019             
  1045 	case COMMIT_ATTR_DIRECT_FROM_WORKING: /* Used in WFD to commit new working values directly in 1 step. */
  1020         }
  1046             for (index = aStart; index <= aEnd; index++) 
       
  1047                 {
       
  1048                 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
       
  1049                 attr->attr_info.dirty=
       
  1050                     OWF_Attribute_Commit(attr,attr->attr_info.dirty,
       
  1051                             COMMITTED_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
       
  1052                 }
       
  1053             break;
       
  1054 	default:
       
  1055 			COND_FAIL_NR(aContext, 0, ATTR_ERROR_INVALID_ARGUMENT);
       
  1056           }
  1021     
  1057     
  1022     SET_ERROR(aContext, ATTR_ERROR_NONE);
  1058     SET_ERROR(aContext, ATTR_ERROR_NONE);
  1023 }
  1059 }
  1024 
  1060 
  1025 #ifdef __cplusplus
  1061 #ifdef __cplusplus