910e62b5创建于 1月15日历史提交
// Copyright 2016 The Chromium Authors
// 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 <stdint.h>

#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#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 kNew state when it is created. When task is added to
// |ready_to_run_tasks| then its state is changed to kScheduled. Task can be
// canceled from kNew state (not yet scheduled to run) or from kScheduled state,
// when new ScheduleTasks() is triggered and its state is changed to kCanceled.
// When task is about to run it is added |running_tasks| and its state is
// changed to kRunning. Once task finishes running, its state is changed to
// kFinished. Both kCanceled and kFinished tasks are added to |completed_tasks|.
//                ╔═════╗
//         +------║ kNew║------+
//         |      ╚═════╝      |
//         v                   v
//   ┌───────────┐        ╔══════════╗
//   │ kScheduled│------> ║ kCanceled║
//   └───────────┘        ╚══════════╝
//         |
//         v
//    ┌─────────┐         ╔══════════╗
//    │ kRunning│-------> ║ kFinished║
//    └─────────┘         ╚══════════╝
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 kNew.
  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 {
    kNew,
    kScheduled,
    kRunning,
    kFinished,
    kCanceled
  };

  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<Task> {
 public:
  typedef std::vector<scoped_refptr<Task>> Vector;

  TaskState& state() { return state_; }
  void set_frame_number(int64_t frame_number) { frame_number_ = frame_number; }
  int64_t frame_number() { return frame_number_; }

  // Unique trace flow id for the given task, used to connect the places where
  // the task was posted from and the task itself.
  uint64_t trace_task_id() { return trace_task_id_; }

  // 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>;

  Task();
  virtual ~Task();

 private:
  TaskState state_;
  int64_t frame_number_ = -1;
  uint64_t trace_task_id_;
};

// 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<Node> Vector;

    Node(scoped_refptr<Task> new_task,
         uint16_t category,
         uint16_t priority,
         uint32_t dependencies,
         bool has_external_dependency = false);
    Node(const Node&) = delete;
    Node(Node&& other);
    ~Node();

    Node& operator=(const Node&) = delete;
    Node& operator=(Node&& other) = default;

    scoped_refptr<Task> task;
    uint16_t category;
    uint16_t priority;
    uint32_t dependencies;
    bool has_external_dependency;
  };

  struct Edge {
    typedef std::vector<Edge> Vector;

    Edge(const Task* task, Task* dependent)
        : task(task), dependent(dependent) {}

    raw_ptr<const Task> task;
    raw_ptr<Task> dependent;
  };

  TaskGraph();
  TaskGraph(const TaskGraph&) = delete;
  TaskGraph(TaskGraph&& other);
  ~TaskGraph();

  TaskGraph& operator=(const TaskGraph&) = delete;
  TaskGraph& operator=(TaskGraph&&) = default;

  void Swap(TaskGraph* other);
  void Reset();

  Node::Vector nodes;
  Edge::Vector edges;
};

}  // namespace cc

#endif  // CC_RASTER_TASK_H_