1f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck/*
2f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * Copyright (C) 2017 The Android Open Source Project
3f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck *
4f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * you may not use this file except in compliance with the License.
6f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * You may obtain a copy of the License at
7f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck *
8f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck *
10f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * Unless required by applicable law or agreed to in writing, software
11f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * See the License for the specific language governing permissions and
14f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * limitations under the License.
15f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck */
16f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
17f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#ifndef HWUI_THREADBASE_H
18f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#define HWUI_THREADBASE_H
19f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
20f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include "WorkQueue.h"
21f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include "utils/Macros.h"
22f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
23f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include <utils/Looper.h>
24f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include <utils/Thread.h>
25f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
26f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include <algorithm>
27f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
28f8441e65526cd1721f1ad77dad21b1a1e2743d76John Recknamespace android::uirenderer {
29f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
30f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckclass ThreadBase : protected Thread {
31f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    PREVENT_COPY_AND_ASSIGN(ThreadBase);
32f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
33f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckpublic:
34259b25a310bf3beb5d41233717aaf3dc02a46c36John Reck    ThreadBase()
35259b25a310bf3beb5d41233717aaf3dc02a46c36John Reck            : Thread(false)
36259b25a310bf3beb5d41233717aaf3dc02a46c36John Reck            , mLooper(new Looper(false))
37259b25a310bf3beb5d41233717aaf3dc02a46c36John Reck            , mQueue([this]() { mLooper->wake(); }, mLock) {}
38f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
39f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    WorkQueue& queue() { return mQueue; }
40f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
41f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    void requestExit() {
42f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        Thread::requestExit();
43f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        mLooper->wake();
44f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    }
45f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
461bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void start(const char* name = "ThreadBase") { Thread::run(name); }
47f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void join() { Thread::join(); }
49f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
50f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckprotected:
51f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    void waitForWork() {
52f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        nsecs_t nextWakeup;
53f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        {
54f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck            std::unique_lock lock{mLock};
55f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck            nextWakeup = mQueue.nextWakeup(lock);
56f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        }
57f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        int timeout = -1;
58f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        if (nextWakeup < std::numeric_limits<nsecs_t>::max()) {
59f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck            timeout = ns2ms(nextWakeup - WorkQueue::clock::now());
60f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck            if (timeout < 0) timeout = 0;
61f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        }
62f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        int result = mLooper->pollOnce(timeout);
631bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck        LOG_ALWAYS_FATAL_IF(result == Looper::POLL_ERROR, "RenderThread Looper POLL_ERROR!");
64f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    }
65f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
661bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void processQueue() { mQueue.process(); }
67f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
68f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    virtual bool threadLoop() override {
69f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        while (!exitPending()) {
70f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck            waitForWork();
71f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck            processQueue();
72f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        }
73f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck        return false;
74f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    }
75f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
76f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    sp<Looper> mLooper;
77f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
78f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckprivate:
79f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    WorkQueue mQueue;
80f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck    std::mutex mLock;
81f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck};
82f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
831bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}  // namespace android::uirenderer
84f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck
851bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#endif  // HWUI_THREADBASE_H
86