/*
 * Copyright (C) 2017 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.
 */

#ifndef HWUI_THREADBASE_H
#define HWUI_THREADBASE_H

#include "WorkQueue.h"
#include "utils/Macros.h"

#include <utils/Looper.h>
#include <utils/Thread.h>

#include <algorithm>

namespace android::uirenderer {

class ThreadBase : public Thread {
    PREVENT_COPY_AND_ASSIGN(ThreadBase);

public:
    ThreadBase()
            : Thread(false)
            , mLooper(new Looper(false))
            , mQueue([this]() { mLooper->wake(); }, mLock) {}

    WorkQueue& queue() { return mQueue; }

    void requestExit() {
        Thread::requestExit();
        mLooper->wake();
    }

    void start(const char* name = "ThreadBase") { Thread::run(name); }

    void join() { Thread::join(); }

    bool isRunning() const { return Thread::isRunning(); }

protected:
    void waitForWork() {
        nsecs_t nextWakeup;
        {
            std::unique_lock lock{mLock};
            nextWakeup = mQueue.nextWakeup(lock);
        }
        int timeout = -1;
        if (nextWakeup < std::numeric_limits<nsecs_t>::max()) {
            timeout = ns2ms(nextWakeup - WorkQueue::clock::now());
            if (timeout < 0) timeout = 0;
        }
        int result = mLooper->pollOnce(timeout);
        LOG_ALWAYS_FATAL_IF(result == Looper::POLL_ERROR, "RenderThread Looper POLL_ERROR!");
    }

    void processQueue() { mQueue.process(); }

    virtual bool threadLoop() override {
        Looper::setForThread(mLooper);
        while (!exitPending()) {
            waitForWork();
            processQueue();
        }
        Looper::setForThread(nullptr);
        return false;
    }

    sp<Looper> mLooper;

private:
    WorkQueue mQueue;
    std::mutex mLock;
};

}  // namespace android::uirenderer

#endif  // HWUI_THREADBASE_H
