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

Commit d2100593 authored by Glenn Kasten's avatar Glenn Kasten Committed by android-build-merger
Browse files

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

am: c1c545a2

* commit 'c1c545a2':
  Add AutoPark template class and use to control FastMixer
parents 8c9adfe1 c1c545a2
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;
}