Home | History | Annotate | Download | only in itf
      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 
     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 
     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 
     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 
     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 
    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 
    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                 // fall through
    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 
    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