1 /* Copyright (c) 2009-2010 The Khronos Group Inc. |
1 /* Copyright (c) 2009 The Khronos Group Inc. |
2 * Portions copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies) |
|
3 * |
2 * |
4 * 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 |
5 * copy of this software and/or associated documentation files (the |
4 * copy of this software and/or associated documentation files (the |
6 * "Materials"), to deal in the Materials without restriction, including |
5 * "Materials"), to deal in the Materials without restriction, including |
7 * without limitation the rights to use, copy, modify, merge, publish, |
6 * without limitation the rights to use, copy, modify, merge, publish, |
33 #include <string.h> |
32 #include <string.h> |
34 #include <math.h> |
33 #include <math.h> |
35 |
34 |
36 #include "owfattributes.h" |
35 #include "owfattributes.h" |
37 #include "owfmemory.h" |
36 #include "owfmemory.h" |
38 #include "owfdebug.h" |
|
39 |
37 |
40 #define OWF_ATTRIB_RANGE_START (0) |
38 #define OWF_ATTRIB_RANGE_START (0) |
41 #define OWF_ATTRIB_RANGE_UNINITIALIZED (-1) |
39 #define OWF_ATTRIB_RANGE_UNINITIALIZED (-1) |
42 |
40 |
43 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom); |
41 static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom); |
44 |
42 |
45 /* |
43 /* |
46 This attribute class is not used for WFC element attributes because elements are |
44 This attribute class is currently only used for context attributes. |
47 completely cloned in the committed scene. |
45 Why isn't it used for element attributes? |
48 [This class could be replaced with 3 copies of a much simpler writable attributes raw |
46 - Because elements are completely cloned in the committed scene. |
49 structure with simple data members, and the whole structure copied each commit.] |
47 [This class could be replaced with 3 copies of a much simpler writable attributes raw |
50 Normal attribute values have three pointers indexed via an array: |
48 structure with simple data members, and the whole structure copied each commit.] |
51 COMMITTED_ATTR_VALUE_INDEX: |
49 Normal attribute values have three pointers indexed via an array: |
52 Attribute values used by the scene |
50 COMMITTED_ATTR_VALUE_INDEX: |
53 - points to named variables directly used by the compositor |
51 Attribute values used by the scene |
54 WORKING_ATTR_VALUE_INDEX: |
52 - points to named variables directly used by the compositor |
55 Attribute values that may be set by the client, if they are not read-only. |
53 WORKING_ATTR_VALUE_INDEX: |
56 SNAPSHOT_ATTR_VALUE_INDEX |
54 Attribute values that may be set by the client, if they are not read-only. |
57 A copy of the client-set attribute values following a client call to wfcCommit |
55 SNAPSHOT_ATTR_VALUE_INDEX |
58 The copy is then protected against further modification by the client until |
56 A copy of the client-set attribute values following a client call to wfcCommit |
59 the committed scene is updated and displayed. |
57 The copy is then protected against further modification by the client until |
60 The Working and Snapshot writable attributes require additional cache storage, |
58 the committed scene is updated and displayed. |
61 which is managed by the lifetime of the attribute list. |
59 The Working and Snapshot writable attributes require additional cache storage, |
62 Read-only attributes point all three pointers at the named compositor variables. |
60 which is managed by the lifetime of the attribute list. |
63 Currently, there are relatively few writable attributes so it is reasonable |
61 Read-only attributes point all three pointers at the named compositor variables. |
64 to individually dynamically allocate each cache. It would be better to allocate |
62 Currently, there are relatively few writable attributes so it is reasonable |
65 a single block sized after the attributes have been registered. |
63 to individually dynamically allocate each cache. It would be better to allocate |
66 |
64 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. |
|
71 */ |
65 */ |
72 #define COND_FAIL_NR(ctx, condition, error) \ |
66 #define COND_FAIL_NR(ctx, condition, error) \ |
73 if (!(condition)) { \ |
67 if (!(condition)) { \ |
74 if (ctx) { \ |
68 if (ctx) { \ |
75 (ctx)->last_error = error; \ |
69 (ctx)->last_error = error; \ |
247 OWF_ATTRIBUTE* attr = NULL; |
227 OWF_ATTRIBUTE* attr = NULL; |
248 void* cache = NULL; |
228 void* cache = NULL; |
249 OWFint itemSize; |
229 OWFint itemSize; |
250 OWFint arraySize; |
230 OWFint arraySize; |
251 OWFint copy; |
231 OWFint copy; |
252 OWFint index; |
232 OWFint index = aName - aContext->range_start; |
253 |
233 |
254 COND_FAIL_NR_NS(aContext); |
234 COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT); |
255 CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE); |
235 CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE); |
256 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT); |
236 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT); |
257 COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE); |
237 COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE); |
258 COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT); |
238 COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT); |
259 |
|
260 index = aName - aContext->range_start; |
|
261 |
239 |
262 attr = &aContext->attributes[index]; |
240 attr = &aContext->attributes[index]; |
263 |
241 |
264 memset(attr, 0, sizeof(OWF_ATTRIBUTE)); |
242 memset(attr, 0, sizeof(OWF_ATTRIBUTE)); |
265 |
243 |
266 /* when allocin', size DOES matter */ |
244 /* when allocin', size DOES matter */ |
|
245 |
267 if (aType == AT_INTEGER || aType == AT_BOOLEAN) { |
246 if (aType == AT_INTEGER || aType == AT_BOOLEAN) { |
268 itemSize = sizeof(OWFint); |
247 itemSize = sizeof(OWFint); |
269 } else { |
248 } else { |
270 itemSize = sizeof(OWFfloat); |
249 itemSize = sizeof(OWFfloat); |
271 } |
250 } |
272 arraySize=itemSize*aLength; |
251 arraySize=itemSize*aLength; |
273 |
252 |
274 /* don't allocate cache for read-only 'butes */ |
253 /* don't allocate cache for read-only 'butes */ |
275 attr->attr_info.type = aType; |
254 attr->attr_info.type = aType; |
276 attr->attr_info.length = aLength; |
255 attr->attr_info.length = aLength; |
277 attr->attr_info.readonly = aRdOnly; |
256 attr->attr_info.readonly = aRdOnly; |
278 attr->attr_info.size = itemSize; |
257 attr->attr_info.size = itemSize; |
984 { |
959 { |
985 return aDirtyFlag; |
960 return aDirtyFlag; |
986 } |
961 } |
987 } |
962 } |
988 |
963 |
989 |
|
990 OWF_API_CALL void |
964 OWF_API_CALL void |
991 OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext, |
965 OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext, |
992 OWFint aStart, |
966 OWFint aStart, |
993 OWFint aEnd, |
967 OWFint aEnd, |
994 OWFint aCopyTo ) |
968 OWFint aCopyTo ) |
995 { |
969 { |
996 OWFint index = 0; |
970 OWFint index = 0; |
997 /* Attribute commit works like the element list commit |
971 /* Attribute commit works like the element list commit |
998 * by forward-copying the "working" attributes to the snapshot |
972 * by forward-copying the "working" attributes to the snapshot |
999 * during client invoked commit, |
973 * during client invoked commit, |
1000 * then copying the snapshot to the commited scene during the docommit job. |
974 * 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. |
975 * 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, |
976 * 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, |
977 * in which case the index of the working attribute set would switch after each invoked commit, |
1004 * instead of being a constant. |
978 * instead of being a constant. |
1005 * |
|
1006 * The same number of copies would still need to take place |
979 * The same number of copies would still need to take place |
1007 * but would not need exclusive access to the list. |
980 * but would not need exclusive access to the list. |
1008 */ |
981 */ |
1009 |
982 COND_FAIL_NR(aContext, aContext, ATTR_ERROR_INVALID_ARGUMENT); |
1010 COND_FAIL_NR_NS(aContext); |
|
1011 COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT); |
983 COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT); |
1012 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT); |
984 COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT); |
1013 CHECK_BAD_NR(aContext, aStart); |
985 CHECK_BAD_NR(aContext, aStart); |
1014 CHECK_BAD_NR(aContext, aEnd); |
986 CHECK_BAD_NR(aContext, aEnd); |
1015 |
987 |
|
988 |
1016 switch (aCopyTo) |
989 switch (aCopyTo) |
1017 { |
990 { |
1018 case COMMITTED_ATTR_VALUE_INDEX: /* Used in composition thread to set displayed scene attributes */ |
991 case COMMITTED_ATTR_VALUE_INDEX: //Used in composition thread to set displayed scene attributes |
1019 for (index = aStart; index <= aEnd; index++) |
992 for (index = aStart; index <= aEnd; index++) |
1020 { |
993 { |
1021 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start]; |
994 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start]; |
1022 attr->attr_info.dirtysnapshot= |
995 attr->attr_info.dirtysnapshot= |
1023 OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot, |
996 OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot, |
1024 COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX); |
997 COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX); |
1025 } |
998 } |
1026 break; |
999 break; |
1027 case SNAPSHOT_ATTR_VALUE_INDEX: /* Used in API threads to make a snapshot of the client attributes */ |
1000 case SNAPSHOT_ATTR_VALUE_INDEX: //Used in API threads to make a snapshot of the client attributes |
1028 for (index = aStart; index <= aEnd; index++) |
1001 for (index = aStart; index <= aEnd; index++) |
1029 { |
1002 { |
1030 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start]; |
1003 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start]; |
1031 OWFuint oldDirty=attr->attr_info.dirty; |
1004 OWFuint oldDirty=attr->attr_info.dirty; |
1032 attr->attr_info.dirtysnapshot=oldDirty; |
1005 attr->attr_info.dirtysnapshot=oldDirty; |
1033 attr->attr_info.dirty= |
1006 attr->attr_info.dirty= |
1034 OWF_Attribute_Commit(attr,oldDirty, |
1007 OWF_Attribute_Commit(attr,oldDirty, |
1035 SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX); |
1008 SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX); |
1036 } |
1009 } |
1037 break; |
1010 break; |
1038 case WORKING_ATTR_VALUE_INDEX: /* Used in initialisation to copy displayed attributes to client copies */ |
1011 case WORKING_ATTR_VALUE_INDEX: //Used in initialisation to copy displayed attributes to client copies |
1039 for (index = aStart; index <= aEnd; index++) |
1012 for (index = aStart; index <= aEnd; index++) |
1040 { |
1013 { |
1041 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start]; |
1014 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start]; |
1042 OWF_Attribute_Commit(attr,!attr->attr_info.readonly, |
1015 OWF_Attribute_Commit(attr,!attr->attr_info.readonly, |
1043 WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX); |
1016 WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX); |
1044 } |
1017 } |
1045 break; |
1018 break; |
1046 case COMMIT_ATTR_DIRECT_FROM_WORKING: /* Used in WFD to commit new working values directly in 1 step. */ |
1019 |
1047 for (index = aStart; index <= aEnd; index++) |
1020 } |
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 } |
|
1058 |
1021 |
1059 SET_ERROR(aContext, ATTR_ERROR_NONE); |
1022 SET_ERROR(aContext, ATTR_ERROR_NONE); |
1060 } |
1023 } |
1061 |
1024 |
1062 #ifdef __cplusplus |
1025 #ifdef __cplusplus |