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) 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: 78faecb78a6b11c780db47bc940ca7662899ab5d5eChih-Hung Hsieh explicit MethodInvokeRenderTask(RunnableMethod method) 79d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : mMethod(method), mReturnPtr(nullptr) {} 804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void* payload() { return mData; } 824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void setReturnPtr(void** retptr) { mReturnPtr = retptr; } 834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 84d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void run() override { 854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void* retval = mMethod(mData); 864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mReturnPtr) { 874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *mReturnPtr = retval; 884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // Commit suicide 904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck delete this; 914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John 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