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;
56a6260b83da52b80438074a9fd207327d9e6e6d03John 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)
634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            : mTask(task), mLock(lock), mSignal(signal) {}
64d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    virtual void run() override;
654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckprivate:
674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* mTask;
684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    Mutex* mLock;
694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    Condition* mSignal;
704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck};
714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Recktypedef void* (*RunnableMethod)(void* data);
734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckclass MethodInvokeRenderTask : public RenderTask {
754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckpublic:
764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    MethodInvokeRenderTask(RunnableMethod method)
77d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        : mMethod(method), mReturnPtr(nullptr) {}
784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void* payload() { return mData; }
804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void setReturnPtr(void** retptr) { mReturnPtr = retptr; }
814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
82d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    virtual void run() override {
834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        void* retval = mMethod(mData);
844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (mReturnPtr) {
854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            *mReturnPtr = retval;
864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        // Commit suicide
884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        delete this;
894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckprivate:
914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RunnableMethod mMethod;
924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    char mData[METHOD_INVOKE_PAYLOAD_SIZE];
934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void** mReturnPtr;
94cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck};
95cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
96cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace renderthread */
97cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace uirenderer */
98cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace android */
99cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#endif /* RENDERTASK_H_ */
100