// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_RASTER_TASK_H_ #define CC_RASTER_TASK_H_ #include #include #include #include "base/memory/ref_counted.h" #include "cc/cc_export.h" namespace cc { class Task; // This class provides states to manage life cycle of a task and given below is // how it is used by TaskGraphWorkQueue to process life cycle of a task. // Task is in NEW state when it is created. When task is added to // |ready_to_run_tasks| then its state is changed to SCHEDULED. Task can be // canceled from NEW state (not yet scheduled to run) or from SCHEDULED state, // when new ScheduleTasks() is triggered and its state is changed to CANCELED. // When task is about to run it is added |running_tasks| and its state is // changed to RUNNING. Once task finishes running, its state is changed to // FINISHED. Both CANCELED and FINISHED tasks are added to |completed_tasks|. // ╔═════╗ // +------║ NEW ║------+ // | ╚═════╝ | // v v // ┌───────────┐ ╔══════════╗ // │ SCHEDULED │------> ║ CANCELED ║ // └───────────┘ ╚══════════╝ // | // v // ┌─────────┐ ╔══════════╗ // │ RUNNING │-------> ║ FINISHED ║ // └─────────┘ ╚══════════╝ class CC_EXPORT TaskState { public: bool IsNew() const; bool IsScheduled() const; bool IsRunning() const; bool IsFinished() const; bool IsCanceled() const; // Functions to change the state of task. These functions should be called // only from TaskGraphWorkQueue where the life cycle of a task is decided or // from tests. These functions are not thread-safe. Caller is responsible for // thread safety. void Reset(); // Sets state to NEW. void DidSchedule(); void DidStart(); void DidFinish(); void DidCancel(); std::string ToString() const; private: friend class Task; // Let only Task class create the TaskState. TaskState(); ~TaskState(); enum class Value : uint16_t { NEW, SCHEDULED, RUNNING, FINISHED, CANCELED }; Value value_; }; // A task which can be run by a TaskGraphRunner. To run a Task, it should be // inserted into a TaskGraph, which can then be scheduled on the // TaskGraphRunner. class CC_EXPORT Task : public base::RefCountedThreadSafe { public: typedef std::vector> Vector; TaskState& state() { return state_; } // Subclasses should implement this method. RunOnWorkerThread may be called // on any thread, and subclasses are responsible for locking and thread // safety. virtual void RunOnWorkerThread() = 0; protected: friend class base::RefCountedThreadSafe; Task(); virtual ~Task(); private: TaskState state_; }; // A task dependency graph describes the order in which to execute a set // of tasks. Dependencies are represented as edges. Each node is assigned // a category, a priority and a run count that matches the number of // dependencies. Priority range from 0 (most favorable scheduling) to UINT16_MAX // (least favorable). Categories range from 0 to UINT16_MAX. It is up to the // implementation and its consumer to determine the meaning (if any) of a // category. A TaskGraphRunner implementation may chose to prioritize certain // categories over others, regardless of the individual priorities of tasks. struct CC_EXPORT TaskGraph { struct CC_EXPORT Node { typedef std::vector Vector; Node(scoped_refptr task, uint16_t category, uint16_t priority, uint32_t dependencies); Node(Node&& other); ~Node(); Node& operator=(Node&& other) = default; scoped_refptr task; uint16_t category; uint16_t priority; uint32_t dependencies; private: DISALLOW_COPY_AND_ASSIGN(Node); }; struct Edge { typedef std::vector Vector; Edge(const Task* task, Task* dependent) : task(task), dependent(dependent) {} const Task* task; Task* dependent; }; TaskGraph(); TaskGraph(TaskGraph&& other); ~TaskGraph(); void Swap(TaskGraph* other); void Reset(); Node::Vector nodes; Edge::Vector edges; private: DISALLOW_COPY_AND_ASSIGN(TaskGraph); }; } // namespace cc #endif // CC_RASTER_TASK_H_