1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /* 3DMacroscopic implementation */
18
19 #include "sles_allinclusive.h"
20
21
I3DMacroscopic_SetSize(SL3DMacroscopicItf self,SLmillimeter width,SLmillimeter height,SLmillimeter depth)22 static SLresult I3DMacroscopic_SetSize(SL3DMacroscopicItf self,
23 SLmillimeter width, SLmillimeter height, SLmillimeter depth)
24 {
25 SL_ENTER_INTERFACE
26
27 if (!((0 <= width) && (width <= SL_MILLIMETER_MAX) &&
28 (0 <= height) && (height <= SL_MILLIMETER_MAX) &&
29 (0 <= depth) && (depth <= SL_MILLIMETER_MAX))) {
30 result = SL_RESULT_PARAMETER_INVALID;
31 } else {
32 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
33 interface_lock_exclusive(thiz);
34 thiz->mSize.mWidth = width;
35 thiz->mSize.mHeight = height;
36 thiz->mSize.mDepth = depth;
37 interface_unlock_exclusive(thiz);
38 result = SL_RESULT_SUCCESS;
39 }
40
41 SL_LEAVE_INTERFACE
42 }
43
44
I3DMacroscopic_GetSize(SL3DMacroscopicItf self,SLmillimeter * pWidth,SLmillimeter * pHeight,SLmillimeter * pDepth)45 static SLresult I3DMacroscopic_GetSize(SL3DMacroscopicItf self,
46 SLmillimeter *pWidth, SLmillimeter *pHeight, SLmillimeter *pDepth)
47 {
48 SL_ENTER_INTERFACE
49
50 if (NULL == pWidth || NULL == pHeight || NULL == pDepth) {
51 result = SL_RESULT_PARAMETER_INVALID;
52 } else {
53 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
54 interface_lock_shared(thiz);
55 SLmillimeter width = thiz->mSize.mWidth;
56 SLmillimeter height = thiz->mSize.mHeight;
57 SLmillimeter depth = thiz->mSize.mDepth;
58 interface_unlock_shared(thiz);
59 *pWidth = width;
60 *pHeight = height;
61 *pDepth = depth;
62 result = SL_RESULT_SUCCESS;
63 }
64
65 SL_LEAVE_INTERFACE
66 }
67
68
I3DMacroscopic_SetOrientationAngles(SL3DMacroscopicItf self,SLmillidegree heading,SLmillidegree pitch,SLmillidegree roll)69 static SLresult I3DMacroscopic_SetOrientationAngles(SL3DMacroscopicItf self,
70 SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll)
71 {
72 SL_ENTER_INTERFACE
73
74 if (!((-360000 <= heading) && (heading <= 360000) &&
75 (-90000 <= pitch) && (pitch <= 90000) &&
76 (-360000 <= roll) && (roll <= 360000))) {
77 result = SL_RESULT_PARAMETER_INVALID;
78 } else {
79 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
80 interface_lock_exclusive(thiz);
81 thiz->mOrientationAngles.mHeading = heading;
82 thiz->mOrientationAngles.mPitch = pitch;
83 thiz->mOrientationAngles.mRoll = roll;
84 thiz->mOrientationActive = ANGLES_SET_VECTORS_UNKNOWN;
85 thiz->mRotatePending = SL_BOOLEAN_FALSE;
86 // ++thiz->mGeneration;
87 interface_unlock_exclusive(thiz);
88 result = SL_RESULT_SUCCESS;
89 }
90
91 SL_LEAVE_INTERFACE
92 }
93
94
I3DMacroscopic_SetOrientationVectors(SL3DMacroscopicItf self,const SLVec3D * pFront,const SLVec3D * pAbove)95 static SLresult I3DMacroscopic_SetOrientationVectors(SL3DMacroscopicItf self,
96 const SLVec3D *pFront, const SLVec3D *pAbove)
97 {
98 SL_ENTER_INTERFACE
99
100 if (NULL == pFront || NULL == pAbove) {
101 result = SL_RESULT_PARAMETER_INVALID;
102 } else {
103 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
104 SLVec3D front = *pFront;
105 SLVec3D above = *pAbove;
106 // NTH Check for vectors close to zero or close to parallel
107 interface_lock_exclusive(thiz);
108 thiz->mOrientationVectors.mFront = front;
109 thiz->mOrientationVectors.mAbove = above;
110 thiz->mOrientationVectors.mUp = above; // wrong
111 thiz->mOrientationActive = ANGLES_UNKNOWN_VECTORS_SET;
112 thiz->mRotatePending = SL_BOOLEAN_FALSE;
113 interface_unlock_exclusive(thiz);
114 result = SL_RESULT_SUCCESS;
115 }
116
117 SL_LEAVE_INTERFACE
118 }
119
120
I3DMacroscopic_Rotate(SL3DMacroscopicItf self,SLmillidegree theta,const SLVec3D * pAxis)121 static SLresult I3DMacroscopic_Rotate(SL3DMacroscopicItf self,
122 SLmillidegree theta, const SLVec3D *pAxis)
123 {
124 SL_ENTER_INTERFACE
125
126 if (!((-360000 <= theta) && (theta <= 360000)) || NULL == pAxis) {
127 result = SL_RESULT_PARAMETER_INVALID;
128 } else {
129 SLVec3D axis = *pAxis;
130 // NTH Check that axis is not (close to) zero vector, length does not matter
131 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
132 interface_lock_exclusive(thiz);
133 while (thiz->mRotatePending)
134 interface_cond_wait(thiz);
135 thiz->mTheta = theta;
136 thiz->mAxis = axis;
137 thiz->mRotatePending = SL_BOOLEAN_TRUE;
138 interface_unlock_exclusive(thiz);
139 result = SL_RESULT_SUCCESS;
140 }
141
142 SL_LEAVE_INTERFACE
143 }
144
145
I3DMacroscopic_GetOrientationVectors(SL3DMacroscopicItf self,SLVec3D * pFront,SLVec3D * pUp)146 static SLresult I3DMacroscopic_GetOrientationVectors(SL3DMacroscopicItf self,
147 SLVec3D *pFront, SLVec3D *pUp)
148 {
149 SL_ENTER_INTERFACE
150
151 if (NULL == pFront || NULL == pUp) {
152 result = SL_RESULT_PARAMETER_INVALID;
153 } else {
154 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
155 interface_lock_exclusive(thiz);
156 for (;;) {
157 enum AnglesVectorsActive orientationActive = thiz->mOrientationActive;
158 switch (orientationActive) {
159 case ANGLES_COMPUTED_VECTORS_SET: // not in 1.0.1
160 case ANGLES_REQUESTED_VECTORS_SET: // not in 1.0.1
161 case ANGLES_UNKNOWN_VECTORS_SET:
162 case ANGLES_SET_VECTORS_COMPUTED:
163 {
164 SLVec3D front = thiz->mOrientationVectors.mFront;
165 SLVec3D up = thiz->mOrientationVectors.mUp;
166 interface_unlock_exclusive(thiz);
167 *pFront = front;
168 *pUp = up;
169 }
170 break;
171 case ANGLES_SET_VECTORS_UNKNOWN:
172 thiz->mOrientationActive = ANGLES_SET_VECTORS_REQUESTED;
173 FALLTHROUGH_INTENDED;
174 case ANGLES_SET_VECTORS_REQUESTED:
175 // matched by cond_broadcast in case multiple requesters
176 #if 0
177 interface_cond_wait(thiz);
178 #else
179 thiz->mOrientationActive = ANGLES_SET_VECTORS_COMPUTED;
180 #endif
181 continue;
182 default:
183 interface_unlock_exclusive(thiz);
184 assert(SL_BOOLEAN_FALSE);
185 pFront->x = 0;
186 pFront->y = 0;
187 pFront->z = 0;
188 pUp->x = 0;
189 pUp->y = 0;
190 pUp->z = 0;
191 break;
192 }
193 break;
194 }
195 result = SL_RESULT_SUCCESS;
196 }
197
198 SL_LEAVE_INTERFACE
199 }
200
201
202 static const struct SL3DMacroscopicItf_ I3DMacroscopic_Itf = {
203 I3DMacroscopic_SetSize,
204 I3DMacroscopic_GetSize,
205 I3DMacroscopic_SetOrientationAngles,
206 I3DMacroscopic_SetOrientationVectors,
207 I3DMacroscopic_Rotate,
208 I3DMacroscopic_GetOrientationVectors
209 };
210
I3DMacroscopic_init(void * self)211 void I3DMacroscopic_init(void *self)
212 {
213 I3DMacroscopic *thiz = (I3DMacroscopic *) self;
214 thiz->mItf = &I3DMacroscopic_Itf;
215 thiz->mSize.mWidth = 0;
216 thiz->mSize.mHeight = 0;
217 thiz->mSize.mDepth = 0;
218 thiz->mOrientationAngles.mHeading = 0;
219 thiz->mOrientationAngles.mPitch = 0;
220 thiz->mOrientationAngles.mRoll = 0;
221 memset(&thiz->mOrientationVectors, 0x55, sizeof(thiz->mOrientationVectors));
222 thiz->mOrientationVectors.mFront.x = 0;
223 thiz->mOrientationVectors.mFront.y = 0;
224 thiz->mOrientationVectors.mFront.z = -1000;
225 thiz->mOrientationVectors.mUp.x = 0;
226 thiz->mOrientationVectors.mUp.y = 1000;
227 thiz->mOrientationVectors.mUp.z = 0;
228 thiz->mOrientationVectors.mAbove.x = 0;
229 thiz->mOrientationVectors.mAbove.y = 0;
230 thiz->mOrientationVectors.mAbove.z = 0;
231 thiz->mOrientationActive = ANGLES_SET_VECTORS_COMPUTED;
232 thiz->mTheta = 0x55555555;
233 thiz->mAxis.x = 0x55555555;
234 thiz->mAxis.y = 0x55555555;
235 thiz->mAxis.z = 0x55555555;
236 thiz->mRotatePending = SL_BOOLEAN_FALSE;
237 }
238