/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* sync */ #include "sles_allinclusive.h" /** \brief Sync thread. * The sync thread runs periodically to synchronize audio state between * the application and platform-specific device driver; for best results * it should run about every graphics frame (e.g. 20 Hz to 50 Hz). */ void *sync_start(void *arg) { CEngine *this = (CEngine *) arg; for (;;) { // FIXME should be driven by cond_signal rather than polling, // or at least make the poll interval longer or configurable usleep(20000*5); object_lock_exclusive(&this->mObject); if (this->mEngine.mShutdown) { this->mEngine.mShutdownAck = SL_BOOLEAN_TRUE; // broadcast not signal, because this condition is also used for other purposes object_cond_broadcast(&this->mObject); object_unlock_exclusive(&this->mObject); break; } if (this->m3DCommit.mWaiting) { this->m3DCommit.mWaiting = 0; ++this->m3DCommit.mGeneration; // There might be more than one thread blocked in Commit, so wake them all object_cond_broadcast(&this->mObject); // here is where we would process the enqueued 3D commands } unsigned instanceMask = this->mEngine.mInstanceMask; unsigned changedMask = this->mEngine.mChangedMask; this->mEngine.mChangedMask = 0; object_unlock_exclusive(&this->mObject); // now we know which objects exist, and which of those have changes unsigned combinedMask = changedMask /* | instanceMask for debugger */; while (combinedMask) { unsigned i = ctz(combinedMask); assert(MAX_INSTANCE > i); combinedMask &= ~(1 << i); IObject *instance = (IObject *) this->mEngine.mInstances[i]; // Could be NULL during construct or destroy if (NULL == instance) { continue; } object_lock_exclusive(instance); unsigned attributesMask = instance->mAttributesMask; instance->mAttributesMask = 0; switch (IObjectToObjectID(instance)) { case SL_OBJECTID_AUDIOPLAYER: // do something here object_unlock_exclusive(instance); #ifdef USE_SNDFILE if (attributesMask & (ATTR_POSITION | ATTR_TRANSPORT)) { CAudioPlayer *audioPlayer = (CAudioPlayer *) instance; audioPlayerTransportUpdate(audioPlayer); } #endif break; default: object_unlock_exclusive(instance); break; } } } return NULL; }