From 2234002b0710c8db73f82d397cb945cd541c6bbb Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Mon, 7 Apr 2014 12:04:41 -0700 Subject: Start pulling bits of FastMixer up to FastThread Change-Id: I4c6f7b8f88fcf107bb29ee6432feecd4ab6554d2 --- services/audioflinger/FastMixer.h | 134 +++++++++++--------------------------- 1 file changed, 38 insertions(+), 96 deletions(-) (limited to 'services/audioflinger/FastMixer.h') diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h index 7aeddef..981c1a7 100644 --- a/services/audioflinger/FastMixer.h +++ b/services/audioflinger/FastMixer.h @@ -18,122 +18,64 @@ #define ANDROID_AUDIO_FAST_MIXER_H #include +#if 1 // FIXME move to where used extern "C" { #include "../private/bionic_futex.h" } +#endif #include "FastThread.h" #include "StateQueue.h" #include "FastMixerState.h" +#include "FastMixerDumpState.h" namespace android { +class AudioMixer; + typedef StateQueue FastMixerStateQueue; class FastMixer : public FastThread { public: - FastMixer() : FastThread() { } - virtual ~FastMixer() { } + FastMixer(); + virtual ~FastMixer(); - FastMixerStateQueue* sq() { return &mSQ; } + FastMixerStateQueue* sq(); private: - virtual bool threadLoop(); FastMixerStateQueue mSQ; -}; // class FastMixer - -// Describes the underrun status for a single "pull" attempt -enum FastTrackUnderrunStatus { - UNDERRUN_FULL, // framesReady() is full frame count, no underrun - UNDERRUN_PARTIAL, // framesReady() is non-zero but < full frame count, partial underrun - UNDERRUN_EMPTY, // framesReady() is zero, total underrun -}; - -// Underrun counters are not reset to zero for new tracks or if track generation changes. -// This packed representation is used to keep the information atomic. -union FastTrackUnderruns { - FastTrackUnderruns() { mAtomic = 0; - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(FastTrackUnderruns) == sizeof(uint32_t)); } - FastTrackUnderruns(const FastTrackUnderruns& copyFrom) : mAtomic(copyFrom.mAtomic) { } - FastTrackUnderruns& operator=(const FastTrackUnderruns& rhs) - { if (this != &rhs) mAtomic = rhs.mAtomic; return *this; } - struct { -#define UNDERRUN_BITS 10 -#define UNDERRUN_MASK ((1 << UNDERRUN_BITS) - 1) - uint32_t mFull : UNDERRUN_BITS; // framesReady() is full frame count - uint32_t mPartial : UNDERRUN_BITS; // framesReady() is non-zero but < full frame count - uint32_t mEmpty : UNDERRUN_BITS; // framesReady() is zero - FastTrackUnderrunStatus mMostRecent : 2; // status of most recent framesReady() - } mBitFields; -private: - uint32_t mAtomic; -}; - -// Represents the dump state of a fast track -struct FastTrackDump { - FastTrackDump() : mFramesReady(0) { } - /*virtual*/ ~FastTrackDump() { } - FastTrackUnderruns mUnderruns; - size_t mFramesReady; // most recent value only; no long-term statistics kept -}; + // callouts + virtual const FastThreadState *poll(); + virtual void setLog(NBLog::Writer *logWriter); + virtual void onIdle(); + virtual void onExit(); + virtual bool isSubClassCommand(FastThreadState::Command command); + virtual void onStateChange(); + virtual void onWork(); + + // FIXME these former local variables need comments and to be renamed to have "m" prefix + static const FastMixerState initial; + FastMixerState preIdle; // copy of state before we went into idle + long slopNs; // accumulated time we've woken up too early (> 0) or too late (< 0) + int fastTrackNames[FastMixerState::kMaxFastTracks]; // handles used by mixer to identify tracks + int generations[FastMixerState::kMaxFastTracks]; // last observed mFastTracks[i].mGeneration + NBAIO_Sink *outputSink; + int outputSinkGen; + AudioMixer* mixer; + short *mixBuffer; + enum {UNDEFINED, MIXED, ZEROED} mixBufferState; + NBAIO_Format format; + unsigned sampleRate; + int fastTracksGen; + FastMixerDumpState dummyDumpState; + uint32_t totalNativeFramesWritten; // copied to dumpState->mFramesWritten + + // next 2 fields are valid only when timestampStatus == NO_ERROR + AudioTimestamp timestamp; + uint32_t nativeFramesWrittenButNotPresented; -// The FastMixerDumpState keeps a cache of FastMixer statistics that can be logged by dumpsys. -// Each individual native word-sized field is accessed atomically. But the -// overall structure is non-atomic, that is there may be an inconsistency between fields. -// No barriers or locks are used for either writing or reading. -// Only POD types are permitted, and the contents shouldn't be trusted (i.e. do range checks). -// It has a different lifetime than the FastMixer, and so it can't be a member of FastMixer. -struct FastMixerDumpState { - FastMixerDumpState( -#ifdef FAST_MIXER_STATISTICS - uint32_t samplingN = kSamplingNforLowRamDevice -#endif - ); - /*virtual*/ ~FastMixerDumpState(); - - void dump(int fd) const; // should only be called on a stable copy, not the original - - FastMixerState::Command mCommand; // current command - uint32_t mWriteSequence; // incremented before and after each write() - uint32_t mFramesWritten; // total number of frames written successfully - uint32_t mNumTracks; // total number of active fast tracks - uint32_t mWriteErrors; // total number of write() errors - uint32_t mUnderruns; // total number of underruns - uint32_t mOverruns; // total number of overruns - uint32_t mSampleRate; - size_t mFrameCount; - struct timespec mMeasuredWarmupTs; // measured warmup time - uint32_t mWarmupCycles; // number of loop cycles required to warmup - uint32_t mTrackMask; // mask of active tracks - FastTrackDump mTracks[FastMixerState::kMaxFastTracks]; - -#ifdef FAST_MIXER_STATISTICS - // Recently collected samples of per-cycle monotonic time, thread CPU time, and CPU frequency. - // kSamplingN is max size of sampling frame (statistics), and must be a power of 2 <= 0x8000. - // The sample arrays are virtually allocated based on this compile-time constant, - // but are only initialized and used based on the runtime parameter mSamplingN. - static const uint32_t kSamplingN = 0x8000; - // Compile-time constant for a "low RAM device", must be a power of 2 <= kSamplingN. - // This value was chosen such that each array uses 1 small page (4 Kbytes). - static const uint32_t kSamplingNforLowRamDevice = 0x400; - // Corresponding runtime maximum size of sample arrays, must be a power of 2 <= kSamplingN. - uint32_t mSamplingN; - // The bounds define the interval of valid samples, and are represented as follows: - // newest open (excluded) endpoint = lower 16 bits of bounds, modulo N - // oldest closed (included) endpoint = upper 16 bits of bounds, modulo N - // Number of valid samples is newest - oldest. - uint32_t mBounds; // bounds for mMonotonicNs, mThreadCpuNs, and mCpukHz - // The elements in the *Ns arrays are in units of nanoseconds <= 3999999999. - uint32_t mMonotonicNs[kSamplingN]; // delta monotonic (wall clock) time - uint32_t mLoadNs[kSamplingN]; // delta CPU load in time -#ifdef CPU_FREQUENCY_STATISTICS - uint32_t mCpukHz[kSamplingN]; // absolute CPU clock frequency in kHz, bits 0-3 are CPU# -#endif - // Increase sampling window after construction, must be a power of 2 <= kSamplingN - void increaseSamplingN(uint32_t samplingN); -#endif -}; +}; // class FastMixer } // namespace android -- cgit v1.1