Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7844f679 authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Eric Laurent
Browse files

AudioFlinger: Modify flush handling for offload path

Do not allow an offload track to directly control the offload thread
behavior. OffloadThread can check for any pending flush reporting
by its active tracks and decide to flush the HW or not.

Bug: 12530661
Change-Id: Ib33f023c942f6c091b618004136b153c38a6eef6
parent 0f02f265
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ protected:
    bool isReady() const;
    void setPaused() { mState = PAUSED; }
    void reset();
    bool isFlushPending() const { return mFlushHwPending; }
    void flushAck();

    bool isOutputTrack() const {
        return (mStreamType == AUDIO_STREAM_CNT);
@@ -155,6 +157,7 @@ private:
    bool                mIsInvalid; // non-resettable latch, set by invalidate()
    AudioTrackServerProxy*  mAudioTrackServerProxy;
    bool                mResumeToStopping; // track was paused in stopping state.
    bool                mFlushHwPending; // track requests for thread flush
};  // end of Track

class TimedTrack : public Track {
+16 −11
Original line number Diff line number Diff line
@@ -2727,12 +2727,6 @@ void AudioFlinger::MixerThread::threadLoop_standby()
    PlaybackThread::threadLoop_standby();
}

// Empty implementation for standard mixer
// Overridden for offloaded playback
void AudioFlinger::PlaybackThread::flushOutput_l()
{
}

bool AudioFlinger::PlaybackThread::waitingAsyncCallback_l()
{
    return false;
@@ -4003,6 +3997,17 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
        sp<Track> l = mLatestActiveTrack.promote();
        bool last = l.get() == track;

        if (track->isInvalid()) {
            ALOGW("An invalidated track shouldn't be in active list");
            tracksToRemove->add(track);
            continue;
        }

        if (track->mState == TrackBase::IDLE) {
            ALOGW("An idle track shouldn't be in active list");
            continue;
        }

        if (track->isPausing()) {
            track->setPaused();
            if (last) {
@@ -4021,6 +4026,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
                mBytesRemaining = 0;    // stop writing
            }
            tracksToRemove->add(track);
        } else if (track->isFlushPending()) {
            track->flushAck();
            if (last) {
                mFlushPending = true;
            }
        } else if (track->framesReady() && track->isReady() &&
                !track->isPaused() && !track->isTerminated() && !track->isStopping_2()) {
            ALOGVV("OffloadThread: track %d s=%08x [OK]", track->name(), cblk->mServer);
@@ -4161,11 +4171,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
    return mixerStatus;
}

void AudioFlinger::OffloadThread::flushOutput_l()
{
    mFlushPending = true;
}

// must be called with thread mutex locked
bool AudioFlinger::OffloadThread::waitingAsyncCallback_l()
{
+0 −2
Original line number Diff line number Diff line
@@ -631,7 +631,6 @@ public:
protected:
                // accessed by both binder threads and within threadLoop(), lock on mutex needed
                unsigned    mFastTrackAvailMask;    // bit i set if fast track [i] is available
    virtual     void        flushOutput_l();

private:
    // timestamp latch:
@@ -750,7 +749,6 @@ protected:
    // threadLoop snippets
    virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
    virtual     void        threadLoop_exit();
    virtual     void        flushOutput_l();

    virtual     bool        waitingAsyncCallback();
    virtual     bool        waitingAsyncCallback_l();
+12 −2
Original line number Diff line number Diff line
@@ -347,7 +347,8 @@ AudioFlinger::PlaybackThread::Track::Track(
    mCachedVolume(1.0),
    mIsInvalid(false),
    mAudioTrackServerProxy(NULL),
    mResumeToStopping(false)
    mResumeToStopping(false),
    mFlushHwPending(false)
{
    if (mCblk != NULL) {
        if (sharedBuffer == 0) {
@@ -731,6 +732,7 @@ void AudioFlinger::PlaybackThread::Track::flush()
                mRetryCount = PlaybackThread::kMaxTrackRetriesOffload;
            }

            mFlushHwPending = true;
            mResumeToStopping = false;
        } else {
            if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
@@ -751,11 +753,19 @@ void AudioFlinger::PlaybackThread::Track::flush()
        // Prevent flush being lost if the track is flushed and then resumed
        // before mixer thread can run. This is important when offloading
        // because the hardware buffer could hold a large amount of audio
        playbackThread->flushOutput_l();
        playbackThread->broadcast_l();
    }
}

// must be called with thread lock held
void AudioFlinger::PlaybackThread::Track::flushAck()
{
    if (!isOffloaded())
        return;

    mFlushHwPending = false;
}

void AudioFlinger::PlaybackThread::Track::reset()
{
    // Do not reset twice to avoid discarding data written just after a flush and before