1cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/*
2cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Copyright (C) 2013 The Android Open Source Project
3cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
4cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * you may not use this file except in compliance with the License.
6cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * You may obtain a copy of the License at
7cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
8cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
10cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Unless required by applicable law or agreed to in writing, software
11cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * See the License for the specific language governing permissions and
14cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * limitations under the License.
15cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
16cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
17cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#ifndef RENDERTASK_H_
18cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#define RENDERTASK_H_
19cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
20cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <cutils/compiler.h>
214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <utils/Timers.h>
22cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
23cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace android {
244f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckclass Mutex;
254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckclass Condition;
26cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace uirenderer {
27cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace renderthread {
28cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#define METHOD_INVOKE_PAYLOAD_SIZE (8 * sizeof(void*))
304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck/*
324f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * Notes about memory management
334f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
344f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * RenderThread will only invoke RenderTask::run(). It is the responsibility
354f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * of the RenderTask to know if it needs to suicide at the end of run() or
364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * if some other lifecycle is being used. As such, it is not valid to reference
374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * anything on RenderTask after the first call to run().
384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * For example SignalingRenderTask
404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * is expected to be stack allocated by the calling thread, so it does not
414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * suicide in run() but instead relies on the caller to destroy it.
424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * MethodInvokeRenderTask however is currently allocated with new, so it will
444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * suicide at the end of run(). TODO: Replace this with a small pool to avoid
454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * malloc/free churn of small objects?
464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck */
474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckclass ANDROID_API RenderTask {
49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic:
50d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    ANDROID_API RenderTask() : mNext(nullptr), mRunAt(0) {}
514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    ANDROID_API virtual ~RenderTask() {}
52cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
53cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    ANDROID_API virtual void run() = 0;
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    RenderTask* mNext;
561bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    nsecs_t mRunAt;  // nano-seconds on the SYSTEM_TIME_MONOTONIC clock
574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck};
584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckclass SignalingRenderTask : public RenderTask {
604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckpublic:
614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    // Takes ownership of task, caller owns lock and signal
624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    SignalingRenderTask(RenderTask* task, Mutex* lock, Condition* signal)
63298a146754e35cbc650aa991ebff1a41eefdbe80Tom Cherry            : mTask(task), mLock(lock), mSignal(signal), mHasRun(false) {}
64d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    virtual void run() override;
65298a146754e35cbc650aa991ebff1a41eefdbe80Tom Cherry    bool hasRun() const { return mHasRun; }
664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckprivate:
684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* mTask;
694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    Mutex* mLock;
704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    Condition* mSignal;
71298a146754e35cbc650aa991ebff1a41eefdbe80Tom Cherry    bool mHasRun;
724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck};
734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Recktypedef void* (*RunnableMethod)(void* data);
754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckclass MethodInvokeRenderTask : public RenderTask {
774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckpublic:
781bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    explicit MethodInvokeRenderTask(RunnableMethod method) : mMethod(method), mReturnPtr(nullptr) {}
794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void* payload() { return mData; }
814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void setReturnPtr(void** retptr) { mReturnPtr = retptr; }
824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
83d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    virtual void run() override {
844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        void* retval = mMethod(mData);
854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (mReturnPtr) {
864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            *mReturnPtr = retval;
874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        // Commit suicide
894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        delete this;
904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
911bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck
924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckprivate:
934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RunnableMethod mMethod;
944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    char mData[METHOD_INVOKE_PAYLOAD_SIZE];
954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void** mReturnPtr;
96cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck};
97cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
98cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace renderthread */
99cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace uirenderer */
100cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace android */
101cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#endif /* RENDERTASK_H_ */
102