summaryrefslogtreecommitdiffstats
path: root/libs/hwui/thread
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/thread')
-rw-r--r--libs/hwui/thread/Future.h2
-rw-r--r--libs/hwui/thread/Task.h63
-rw-r--r--libs/hwui/thread/TaskManager.cpp118
-rw-r--r--libs/hwui/thread/TaskManager.h100
-rw-r--r--libs/hwui/thread/TaskProcessor.h72
5 files changed, 354 insertions, 1 deletions
diff --git a/libs/hwui/thread/Future.h b/libs/hwui/thread/Future.h
index 340fec7..a3ff3bc 100644
--- a/libs/hwui/thread/Future.h
+++ b/libs/hwui/thread/Future.h
@@ -24,7 +24,7 @@
namespace android {
namespace uirenderer {
-template<class T>
+template<typename T>
class Future: public LightRefBase<Future<T> > {
public:
Future(Condition::WakeUpType type = Condition::WAKE_UP_ONE): mBarrier(type), mResult() { }
diff --git a/libs/hwui/thread/Task.h b/libs/hwui/thread/Task.h
new file mode 100644
index 0000000..9a211a2
--- /dev/null
+++ b/libs/hwui/thread/Task.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 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 ANDROID_HWUI_TASK_H
+#define ANDROID_HWUI_TASK_H
+
+#define ATRACE_TAG ATRACE_TAG_VIEW
+
+#include <utils/RefBase.h>
+#include <utils/Trace.h>
+
+#include "Future.h"
+
+namespace android {
+namespace uirenderer {
+
+class TaskBase: public RefBase {
+public:
+ TaskBase() { }
+ virtual ~TaskBase() { }
+};
+
+template<typename T>
+class Task: public TaskBase {
+public:
+ Task(): mFuture(new Future<T>()) { }
+ virtual ~Task() { }
+
+ T getResult() const {
+ ATRACE_NAME("waitForTask");
+ return mFuture->get();
+ }
+
+ void setResult(T result) {
+ mFuture->produce(result);
+ }
+
+protected:
+ const sp<Future<T> >& future() const {
+ return mFuture;
+ }
+
+private:
+ sp<Future<T> > mFuture;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_TASK_H
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
new file mode 100644
index 0000000..ce6c8c0
--- /dev/null
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <sys/sysinfo.h>
+
+#include "Task.h"
+#include "TaskProcessor.h"
+#include "TaskManager.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Manager
+///////////////////////////////////////////////////////////////////////////////
+
+TaskManager::TaskManager() {
+ // Get the number of available CPUs. This value does not change over time.
+ int cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
+
+ for (int i = 0; i < cpuCount / 2; i++) {
+ String8 name;
+ name.appendFormat("hwuiTask%d", i + 1);
+ mThreads.add(new WorkerThread(name));
+ }
+}
+
+TaskManager::~TaskManager() {
+ for (size_t i = 0; i < mThreads.size(); i++) {
+ mThreads[i]->exit();
+ }
+}
+
+bool TaskManager::canRunTasks() const {
+ return mThreads.size() > 0;
+}
+
+bool TaskManager::addTaskBase(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor) {
+ if (mThreads.size() > 0) {
+ TaskWrapper wrapper(task, processor);
+
+ size_t minQueueSize = INT_MAX;
+ sp<WorkerThread> thread;
+
+ for (size_t i = 0; i < mThreads.size(); i++) {
+ if (mThreads[i]->getTaskCount() < minQueueSize) {
+ thread = mThreads[i];
+ minQueueSize = mThreads[i]->getTaskCount();
+ }
+ }
+
+ return thread->addTask(wrapper);
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Thread
+///////////////////////////////////////////////////////////////////////////////
+
+bool TaskManager::WorkerThread::threadLoop() {
+ mSignal.wait();
+ Vector<TaskWrapper> tasks;
+ {
+ Mutex::Autolock l(mLock);
+ tasks = mTasks;
+ mTasks.clear();
+ }
+
+ for (size_t i = 0; i < tasks.size(); i++) {
+ const TaskWrapper& task = tasks.itemAt(i);
+ task.mProcessor->process(task.mTask);
+ }
+
+ return true;
+}
+
+bool TaskManager::WorkerThread::addTask(TaskWrapper task) {
+ if (!isRunning()) {
+ run(mName.string(), PRIORITY_DEFAULT);
+ }
+
+ Mutex::Autolock l(mLock);
+ ssize_t index = mTasks.add(task);
+ mSignal.signal();
+
+ return index >= 0;
+}
+
+size_t TaskManager::WorkerThread::getTaskCount() const {
+ Mutex::Autolock l(mLock);
+ return mTasks.size();
+}
+
+void TaskManager::WorkerThread::exit() {
+ {
+ Mutex::Autolock l(mLock);
+ mTasks.clear();
+ }
+ requestExit();
+ mSignal.signal();
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
new file mode 100644
index 0000000..bc86062
--- /dev/null
+++ b/libs/hwui/thread/TaskManager.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 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 ANDROID_HWUI_TASK_MANAGER_H
+#define ANDROID_HWUI_TASK_MANAGER_H
+
+#include <utils/Mutex.h>
+#include <utils/String8.h>
+#include <utils/Thread.h>
+#include <utils/Vector.h>
+
+#include "Signal.h"
+
+namespace android {
+namespace uirenderer {
+
+template <typename T>
+class Task;
+class TaskBase;
+
+template <typename T>
+class TaskProcessor;
+class TaskProcessorBase;
+
+class TaskManager {
+public:
+ TaskManager();
+ ~TaskManager();
+
+ /**
+ * Returns true if this task manager can run tasks,
+ * false otherwise. This method will typically return
+ * true on a single CPU core device.
+ */
+ bool canRunTasks() const;
+
+private:
+ template <typename T>
+ friend class TaskProcessor;
+
+ template<typename T>
+ bool addTask(const sp<Task<T> >& task, const sp<TaskProcessor<T> >& processor) {
+ return addTaskBase(sp<TaskBase>(task), sp<TaskProcessorBase>(processor));
+ }
+
+ bool addTaskBase(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor);
+
+ struct TaskWrapper {
+ TaskWrapper(): mTask(), mProcessor() { }
+
+ TaskWrapper(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor):
+ mTask(task), mProcessor(processor) {
+ }
+
+ sp<TaskBase> mTask;
+ sp<TaskProcessorBase> mProcessor;
+ };
+
+ class WorkerThread: public Thread {
+ public:
+ WorkerThread(const String8 name): mSignal(Condition::WAKE_UP_ONE), mName(name) { }
+
+ bool addTask(TaskWrapper task);
+ size_t getTaskCount() const;
+ void exit();
+
+ private:
+ virtual bool threadLoop();
+
+ // Lock for the list of tasks
+ mutable Mutex mLock;
+ Vector<TaskWrapper> mTasks;
+
+ // Signal used to wake up the thread when a new
+ // task is available in the list
+ mutable Signal mSignal;
+
+ const String8 mName;
+ };
+
+ Vector<sp<WorkerThread> > mThreads;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_TASK_MANAGER_H
diff --git a/libs/hwui/thread/TaskProcessor.h b/libs/hwui/thread/TaskProcessor.h
new file mode 100644
index 0000000..d1269f0
--- /dev/null
+++ b/libs/hwui/thread/TaskProcessor.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 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 ANDROID_HWUI_TASK_PROCESSOR_H
+#define ANDROID_HWUI_TASK_PROCESSOR_H
+
+#include <utils/RefBase.h>
+
+#include "Task.h"
+#include "TaskManager.h"
+
+namespace android {
+namespace uirenderer {
+
+class TaskProcessorBase: public RefBase {
+public:
+ TaskProcessorBase() { }
+ virtual ~TaskProcessorBase() { };
+
+private:
+ friend class TaskManager;
+
+ virtual void process(const sp<TaskBase>& task) = 0;
+};
+
+template<typename T>
+class TaskProcessor: public TaskProcessorBase {
+public:
+ TaskProcessor(TaskManager* manager): mManager(manager) { }
+ virtual ~TaskProcessor() { }
+
+ bool add(const sp<Task<T> >& task);
+
+ virtual void onProcess(const sp<Task<T> >& task) = 0;
+
+private:
+ virtual void process(const sp<TaskBase>& task) {
+ sp<Task<T> > realTask = static_cast<Task<T>* >(task.get());
+ // This is the right way to do it but sp<> doesn't play nice
+ // sp<Task<T> > realTask = static_cast<sp<Task<T> > >(task);
+ onProcess(realTask);
+ }
+
+ TaskManager* mManager;
+};
+
+template<typename T>
+bool TaskProcessor<T>::add(const sp<Task<T> >& task) {
+ if (mManager) {
+ sp<TaskProcessor<T> > self(this);
+ return mManager->addTask(task, self);
+ }
+ return false;
+}
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_TASK_PROCESSOR_H