1d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten/* 2d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * 4d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * you may not use this file except in compliance with the License. 6d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * You may obtain a copy of the License at 7d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * 8d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * 10d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * See the License for the specific language governing permissions and 14d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * limitations under the License. 15d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten */ 16d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 17d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten/* sync */ 18d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 19d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten#include "sles_allinclusive.h" 20d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 22928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Sync thread. 23928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * The sync thread runs periodically to synchronize audio state between 24928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * the application and platform-specific device driver; for best results 25928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * it should run about every graphics frame (e.g. 20 Hz to 50 Hz). 260b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten */ 27d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 28d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenvoid *sync_start(void *arg) 29d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten{ 30bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CEngine *thiz = (CEngine *) arg; 31d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten for (;;) { 32e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 33d48ff338b8338c1e3e54e0f9dcd03567a0aa9de4Glenn Kasten // FIXME should be driven by cond_signal rather than polling, 34d48ff338b8338c1e3e54e0f9dcd03567a0aa9de4Glenn Kasten // or at least make the poll interval longer or configurable 35e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten usleep(20000*5); 36e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 37bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten object_lock_exclusive(&thiz->mObject); 38bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mEngine.mShutdown) { 39bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEngine.mShutdownAck = SL_BOOLEAN_TRUE; 404597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten // broadcast not signal, because this condition is also used for other purposes 41bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten object_cond_broadcast(&thiz->mObject); 42bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten object_unlock_exclusive(&thiz->mObject); 43d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten break; 44e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 45bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->m3DCommit.mWaiting) { 46bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->m3DCommit.mWaiting = 0; 47bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ++thiz->m3DCommit.mGeneration; 48a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // There might be more than one thread blocked in Commit, so wake them all 49bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten object_cond_broadcast(&thiz->mObject); 50a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // here is where we would process the enqueued 3D commands 51a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 52bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten // unsigned instanceMask = thiz->mEngine.mInstanceMask; // for debugger 53bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten unsigned changedMask = thiz->mEngine.mChangedMask; 54bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEngine.mChangedMask = 0; 55bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten object_unlock_exclusive(&thiz->mObject); 56e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 57e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // now we know which objects exist, and which of those have changes 58e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 59b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten unsigned combinedMask = changedMask /* | instanceMask for debugger */; 60e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten while (combinedMask) { 61e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten unsigned i = ctz(combinedMask); 62d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(MAX_INSTANCE > i); 63e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten combinedMask &= ~(1 << i); 64bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject *instance = (IObject *) thiz->mEngine.mInstances[i]; 65d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // Could be NULL during construct or destroy 66928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == instance) { 67d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten continue; 68928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 69e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 70e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_lock_exclusive(instance); 714b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten unsigned attributesMask = instance->mAttributesMask; 72e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten instance->mAttributesMask = 0; 73e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 74d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten switch (IObjectToObjectID(instance)) { 75d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten case SL_OBJECTID_AUDIOPLAYER: 76e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // do something here 77e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_unlock_exclusive(instance); 784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef USE_SNDFILE 794b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (attributesMask & (ATTR_POSITION | ATTR_TRANSPORT)) { 804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten CAudioPlayer *audioPlayer = (CAudioPlayer *) instance; 814b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayerTransportUpdate(audioPlayer); 82e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif 84d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten break; 85e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 86d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten default: 87e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_unlock_exclusive(instance); 88d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten break; 89d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 90d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 91d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 92d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return NULL; 93d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} 94