14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/*
24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright (C) 2017 The Android Open Source Project
34344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
44344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Licensed under the Apache License, Version 2.0 (the "License");
54344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * you may not use this file except in compliance with the License.
64344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * You may obtain a copy of the License at
74344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
84344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *      http://www.apache.org/licenses/LICENSE-2.0
94344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Unless required by applicable law or agreed to in writing, software
114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * distributed under the License is distributed on an "AS IS" BASIS,
124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * See the License for the specific language governing permissions and
144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * limitations under the License.
154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
17d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar//#define LOG_NDEBUG 0
184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define LOG_TAG "SimpleC2Component"
19d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <log/log.h>
204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
210c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar#include <cutils/properties.h>
220c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar
234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <inttypes.h>
244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2551ea56a991d6371e35c8d0bb5001e721cc63f8eeLajos Molnar#include <C2Config.h>
26d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <C2Debug.h>
274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2PlatformSupport.h>
284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <SimpleC2Component.h>
294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mQueue.pop_front();
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return work;
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::WorkQueue::push_back(std::unique_ptr<C2Work> work) {
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mQueue.push_back({ std::move(work), NO_DRAIN });
404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool SimpleC2Component::WorkQueue::empty() const {
434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mQueue.empty();
444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::WorkQueue::clear() {
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mQueue.clear();
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimuint32_t SimpleC2Component::WorkQueue::drainMode() const {
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mQueue.front().drainMode;
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::WorkQueue::markDrain(uint32_t drainMode) {
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mQueue.push_back({ nullptr, drainMode });
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim////////////////////////////////////////////////////////////////////////////////
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6045c52538eab8ff337687d374f657cff5d6c51912Wonsik Kimnamespace {
6145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim
6245c52538eab8ff337687d374f657cff5d6c51912Wonsik Kimstruct DummyReadView : public C2ReadView {
6345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    DummyReadView() : C2ReadView(C2_NO_INIT) {}
6445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim};
6545c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim
6645c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim}  // namespace
6745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim
684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimSimpleC2Component::SimpleC2Component(
694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2ComponentInterface> &intf)
7045c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    : mDummyReadView(DummyReadView()),
7145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim      mIntf(intf) {
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::setListener_vb(
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2Component::Listener> &listener, c2_blocking_t mayBlock) {
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Mutexed<ExecState>::Locked state(mExecState);
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (state->mState == RUNNING) {
784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (listener) {
794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_BAD_STATE;
804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else if (!mayBlock) {
814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_BLOCKING;
824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    state->mListener = listener;
854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: wait for listener change to have taken place before returning
864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // (e.g. if there is an ongoing listener callback)
874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::queue_nb(std::list<std::unique_ptr<C2Work>> * const items) {
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (state->mState != RUNNING) {
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_BAD_STATE;
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        while (!items->empty()) {
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            queue->push_back(std::move(items->front()));
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            items->pop_front();
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->mCondition.broadcast();
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) {
1094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)items;
1104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OMITTED;
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::flush_sm(
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        flush_mode_t flushMode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)flushMode;
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (state->mState != RUNNING) {
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_BAD_STATE;
1204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
1234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
1244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->incGeneration();
1254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // TODO: queue->splicedBy(flushedWork, flushedWork->end());
1264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        while (!queue->empty()) {
1274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::unique_ptr<C2Work> work = queue->pop_front();
1284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (work) {
1294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                flushedWork->push_back(std::move(work));
1304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
1314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
1344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<PendingWork>::Locked pending(mPendingWork);
1354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        while (!pending->empty()) {
1364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            flushedWork->push_back(std::move(pending->begin()->second));
1374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            pending->erase(pending->begin());
1384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
1424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::drain_nb(drain_mode_t drainMode) {
1454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (drainMode == DRAIN_CHAIN) {
1464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_OMITTED;
1474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
1494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
1504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (state->mState != RUNNING) {
1514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_BAD_STATE;
1524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
1554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
1564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->markDrain(drainMode);
1574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->mCondition.broadcast();
1584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
1614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::start() {
1644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Mutexed<ExecState>::Locked state(mExecState);
1654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (state->mState == RUNNING) {
1664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_BAD_STATE;
1674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool needsInit = (state->mState == UNINITIALIZED);
1694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (needsInit) {
1704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        state.unlock();
1714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t err = onInit();
1724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (err != C2_OK) {
1734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return err;
1744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        state.lock();
1764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!state->mThread.joinable()) {
1784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mExitRequested = false;
1794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        {
1804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
1814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            monitor->mExited = false;
1824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        state->mThread = std::thread(
1844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                [](std::weak_ptr<SimpleC2Component> wp) {
1854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    while (true) {
1864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        std::shared_ptr<SimpleC2Component> thiz = wp.lock();
1874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        if (!thiz) {
1884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            return;
1894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        }
1904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        if (thiz->exitRequested()) {
1914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            ALOGV("stop processing");
1924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            thiz->signalExit();
1934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            return;
1944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        }
1954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        thiz->processQueue();
1964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
1974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                },
1984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                shared_from_this());
1994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    state->mState = RUNNING;
2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
2024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::signalExit() {
2054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
2064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    monitor->mExited = true;
2074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    monitor->mCondition.broadcast();
2084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::requestExitAndWait(std::function<void()> job) {
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (!state->mThread.joinable()) {
2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return;
2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mExitRequested = true;
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->mCondition.broadcast();
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: timeout?
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        while (!monitor->mExited) {
2264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            monitor.waitForCondition(monitor->mCondition);
2274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        job();
2294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Mutexed<ExecState>::Locked state(mExecState);
2314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (state->mThread.joinable()) {
2324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("joining the processing thread");
2334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        state->mThread.join();
2344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("joined the processing thread");
2354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::stop() {
2394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("stop");
2404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
2424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (state->mState != RUNNING) {
2434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_BAD_STATE;
2444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        state->mState = STOPPED;
2464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
2494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->clear();
2504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<PendingWork>::Locked pending(mPendingWork);
2534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        pending->clear();
2544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t err;
2564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    requestExitAndWait([this, &err]{ err = onStop(); });
2574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (err != C2_OK) {
2584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return err;
2594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
2614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::reset() {
2644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("reset");
2654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
2674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        state->mState = UNINITIALIZED;
2684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
2714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        queue->clear();
2724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
2744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<PendingWork>::Locked pending(mPendingWork);
2754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        pending->clear();
2764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    requestExitAndWait([this]{ onReset(); });
2784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
2794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t SimpleC2Component::release() {
2824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("release");
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    requestExitAndWait([this]{ onRelease(); });
2844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
2854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ComponentInterface> SimpleC2Component::intf() {
2884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mIntf;
2894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace {
2924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::list<std::unique_ptr<C2Work>> vec(std::unique_ptr<C2Work> &work) {
2944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::list<std::unique_ptr<C2Work>> ret;
2954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ret.push_back(std::move(work));
2964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ret;
2974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace
3004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::finish(
3024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork) {
3034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<C2Work> work;
3044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
3054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<PendingWork>::Locked pending(mPendingWork);
3064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (pending->count(frameIndex) == 0) {
3074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGW("unknown frame index: %" PRIu64, frameIndex);
3084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return;
3094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        work = std::move(pending->at(frameIndex));
3114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        pending->erase(frameIndex);
3124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (work) {
3144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        fillWork(work);
3154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
3168a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa        std::shared_ptr<C2Component::Listener> listener = state->mListener;
3178a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa        state.unlock();
3188a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa        listener->onWorkDone_nb(shared_from_this(), vec(work));
3194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("returning pending work");
3204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid SimpleC2Component::processQueue() {
3244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<C2Work> work;
3254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint64_t generation;
3264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    int32_t drainMode;
3274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool isFlushPending = false;
3284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
3294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
3304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        nsecs_t deadline = systemTime() + ms2ns(250);
3314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        while (queue->empty()) {
3324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (exitRequested()) {
3334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return;
3344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            nsecs_t now = systemTime();
3364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (now >= deadline) {
3374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return;
3384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            status_t err = queue.waitForConditionRelative(queue->mCondition, deadline - now);
3404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (err == TIMED_OUT) {
3414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return;
3424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        generation = queue->generation();
3464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        drainMode = queue->drainMode();
3474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        isFlushPending = queue->popPendingFlush();
3484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        work = queue->pop_front();
3494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (isFlushPending) {
3514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("processing pending flush");
3524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t err = onFlush_sm();
3534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (err != C2_OK) {
3544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("flush err: %d", err);
3554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: error
3564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mOutputBlockPool) {
3604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t err = [this] {
3614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: don't use query_vb
3624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2StreamFormatConfig::output outputFormat(0u);
36373fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa            std::vector<std::unique_ptr<C2Param>> params;
3644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            c2_status_t err = intf()->query_vb(
3654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    { &outputFormat },
36673fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    { C2PortBlockPoolsTuning::output::PARAM_TYPE },
3674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    C2_DONT_BLOCK,
36873fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    &params);
3692d378340ffd372c9f41ef15a5138695e1a1d24acWonsik Kim            if (err != C2_OK && err != C2_BAD_INDEX) {
3702d378340ffd372c9f41ef15a5138695e1a1d24acWonsik Kim                ALOGD("query err = %d", err);
3714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return err;
3724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3730c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar            C2BlockPool::local_id_t poolId =
37473fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                outputFormat.value == C2FormatVideo
37573fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                        ? C2BlockPool::BASIC_GRAPHIC
3760c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar                        : C2BlockPool::BASIC_LINEAR;
37773fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa            if (params.size()) {
37873fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                C2PortBlockPoolsTuning::output *outputPools =
37973fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    C2PortBlockPoolsTuning::output::From(params[0].get());
38073fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                if (outputPools && outputPools->flexCount() >= 1) {
38173fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    poolId = outputPools->m.values[0];
38273fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                }
3834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
38473fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa
38573fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa            err = GetCodec2BlockPool(poolId, shared_from_this(), &mOutputBlockPool);
38673fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa            ALOGD("Using output block pool with poolID %llu => got %llu - %d",
38773fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    (unsigned long long)poolId,
38873fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    (unsigned long long)(
38973fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                            mOutputBlockPool ? mOutputBlockPool->getLocalId() : 111000111),
39073fa1be9eba6a23fc5532d0d019036ce7c9f2a03Pawin Vongmasa                    err);
3910c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar            return err;
3924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }();
3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (err != C2_OK) {
3944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            Mutexed<ExecState>::Locked state(mExecState);
3958a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            std::shared_ptr<C2Component::Listener> listener = state->mListener;
3968a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            state.unlock();
3978a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            listener->onError_nb(shared_from_this(), err);
3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return;
3994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!work) {
4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t err = drain(drainMode, mOutputBlockPool);
4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (err != C2_OK) {
4054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            Mutexed<ExecState>::Locked state(mExecState);
4068a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            std::shared_ptr<C2Component::Listener> listener = state->mListener;
4078a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            state.unlock();
4088a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            listener->onError_nb(shared_from_this(), err);
4094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return;
4114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
41345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    process(work, mOutputBlockPool);
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("processed frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
4154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    {
4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
4174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (queue->generation() != generation) {
4184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("work form old generation: was %" PRIu64 " now %" PRIu64,
4194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    queue->generation(), generation);
4204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            work->result = C2_NOT_FOUND;
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            queue.unlock();
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            {
4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                Mutexed<ExecState>::Locked state(mExecState);
4248a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa                std::shared_ptr<C2Component::Listener> listener = state->mListener;
4258a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa                state.unlock();
4268a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa                listener->onWorkDone_nb(shared_from_this(), vec(work));
4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            queue.lock();
4294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return;
4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (work->workletsProcessed != 0u) {
4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mutexed<ExecState>::Locked state(mExecState);
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("returning this work");
4358a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa        std::shared_ptr<C2Component::Listener> listener = state->mListener;
4368a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa        state.unlock();
4378a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa        listener->onWorkDone_nb(shared_from_this(), vec(work));
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("queue pending work");
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_ptr<C2Work> unexpected;
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        {
4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            Mutexed<PendingWork>::Locked pending(mPendingWork);
4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (pending->count(frameIndex) != 0) {
4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                unexpected = std::move(pending->at(frameIndex));
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                pending->erase(frameIndex);
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (void)pending->insert({ frameIndex, std::move(work) });
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (unexpected) {
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("unexpected pending work");
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            unexpected->result = C2_CORRUPTED;
4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            Mutexed<ExecState>::Locked state(mExecState);
4548a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            std::shared_ptr<C2Component::Listener> listener = state->mListener;
4558a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            state.unlock();
4568a9da94f95a3d718a8eff2f2ae5db3bfff160af7Pawin Vongmasa            listener->onWorkDone_nb(shared_from_this(), vec(unexpected));
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2LinearBlock> &block) {
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return createLinearBuffer(block, block->offset(), block->size());
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size) {
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2Buffer::CreateLinearBuffer(block->share(offset, size, ::C2Fence()));
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2GraphicBlock> &block) {
473b48374b4d99a02fca0c9448fd979f4786fcdde2bLajos Molnar    return createGraphicBuffer(block, C2Rect(block->width(), block->height()));
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2GraphicBlock> &block, const C2Rect &crop) {
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2Buffer::CreateGraphicBuffer(block->share(crop, ::C2Fence()));
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim} // namespace android
482