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

Commit c1c545a2 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Add AutoPark template class and use to control FastMixer" into nyc-dev

parents 681d56a8 c05b8d7d
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.
 */

namespace android {

// T is FastMixer or FastCapture
template<typename T> class AutoPark {
public:

    // Park the specific FastThread, which can be nullptr, in hot idle if not currently idling
    AutoPark(const sp<T>& fastThread) : mFastThread(fastThread)
    {
        mPreviousCommand = FastThreadState::HOT_IDLE;
        if (fastThread != nullptr) {
            auto sq = mFastThread->sq();
            FastThreadState *state = sq->begin();
            if (!(state->mCommand & FastThreadState::IDLE)) {
                mPreviousCommand = state->mCommand;
                state->mCommand = FastThreadState::HOT_IDLE;
                sq->end();
                sq->push(sq->BLOCK_UNTIL_ACKED);
            } else {
                sq->end(false /*didModify*/);
            }
        }
    }

    // Remove the FastThread from hot idle if necessary
    ~AutoPark()
    {
        if (!(mPreviousCommand & FastThreadState::IDLE)) {
            ALOG_ASSERT(mFastThread != nullptr);
            auto sq = mFastThread->sq();
            FastThreadState *state = sq->begin();
            ALOG_ASSERT(state->mCommand == FastThreadState::HOT_IDLE);
            state->mCommand = mPreviousCommand;
            sq->end();
            sq->push(sq->BLOCK_UNTIL_PUSHED);
        }
    }

private:
    const sp<T>                 mFastThread;
    // if !&IDLE, holds the FastThread state to restore after new parameters processed
    FastThreadState::Command    mPreviousCommand;
};  // class AutoPark

}   // namespace
+6 −72
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@
#include <cpustats/ThreadCpuUsage.h>
#endif

#include "AutoPark.h"

// ----------------------------------------------------------------------------

// Note: the following macro is used for extremely verbose logging message.  In
@@ -3283,31 +3285,9 @@ status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
status_t AudioFlinger::MixerThread::createAudioPatch_l(const struct audio_patch *patch,
                                                          audio_patch_handle_t *handle)
{
    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
    if (mFastMixer != 0) {
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        if (!(state->mCommand & FastMixerState::IDLE)) {
            previousCommand = state->mCommand;
            state->mCommand = FastMixerState::HOT_IDLE;
            sq->end();
            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
        } else {
            sq->end(false /*didModify*/);
        }
    }
    status_t status = PlaybackThread::createAudioPatch_l(patch, handle);
    AutoPark<FastMixer> park(mFastMixer);

    if (!(previousCommand & FastMixerState::IDLE)) {
        ALOG_ASSERT(mFastMixer != 0);
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
        state->mCommand = previousCommand;
        sq->end();
        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
    }
    status_t status = PlaybackThread::createAudioPatch_l(patch, handle);

    return status;
}
@@ -3390,33 +3370,10 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat

status_t AudioFlinger::MixerThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
    if (mFastMixer != 0) {
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        if (!(state->mCommand & FastMixerState::IDLE)) {
            previousCommand = state->mCommand;
            state->mCommand = FastMixerState::HOT_IDLE;
            sq->end();
            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
        } else {
            sq->end(false /*didModify*/);
        }
    }
    AutoPark<FastMixer> park(mFastMixer);

    status_t status = PlaybackThread::releaseAudioPatch_l(handle);

    if (!(previousCommand & FastMixerState::IDLE)) {
        ALOG_ASSERT(mFastMixer != 0);
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
        state->mCommand = previousCommand;
        sq->end();
        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
    }

    return status;
}

@@ -4464,20 +4421,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa

    status = NO_ERROR;

    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
    if (mFastMixer != 0) {
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        if (!(state->mCommand & FastMixerState::IDLE)) {
            previousCommand = state->mCommand;
            state->mCommand = FastMixerState::HOT_IDLE;
            sq->end();
            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
        } else {
            sq->end(false /*didModify*/);
        }
    }
    AutoPark<FastMixer> park(mFastMixer);

    AudioParameter param = AudioParameter(keyValuePair);
    int value;
@@ -4572,16 +4516,6 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa
        }
    }

    if (!(previousCommand & FastMixerState::IDLE)) {
        ALOG_ASSERT(mFastMixer != 0);
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
        state->mCommand = previousCommand;
        sq->end();
        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
    }

    return reconfig || a2dpDeviceChanged;
}