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