// Copyright 2013 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_RESOURCES_RASTER_WORKER_POOL_H_
#define CC_RESOURCES_RASTER_WORKER_POOL_H_
#include <vector>
#include "base/containers/hash_tables.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/resources/picture_pile_impl.h"
#include "cc/resources/raster_mode.h"
#include "cc/resources/resource.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/tile_priority.h"
#include "cc/resources/worker_pool.h"
#include "third_party/khronos/GLES2/gl2.h"
namespace skia {
class LazyPixelRef;
}
namespace cc {
namespace internal {
class CC_EXPORT RasterWorkerPoolTask
: public base::RefCounted<RasterWorkerPoolTask> {
public:
typedef std::vector<scoped_refptr<WorkerPoolTask> > TaskVector;
// Returns true if |buffer| was written to. False indicate that
// the content of |buffer| is undefined and the resource doesn't
// need to be initialized.
virtual bool RunOnWorkerThread(unsigned thread_index,
void* buffer,
gfx::Size size,
int stride) = 0;
virtual void CompleteOnOriginThread() = 0;
void DidRun(bool was_canceled);
bool HasFinishedRunning() const;
bool WasCanceled() const;
void WillComplete();
void DidComplete();
bool HasCompleted() const;
const Resource* resource() const { return resource_; }
const TaskVector& dependencies() const { return dependencies_; }
protected:
friend class base::RefCounted<RasterWorkerPoolTask>;
RasterWorkerPoolTask(const Resource* resource, TaskVector* dependencies);
virtual ~RasterWorkerPoolTask();
private:
bool did_run_;
bool did_complete_;
bool was_canceled_;
const Resource* resource_;
TaskVector dependencies_;
};
} // namespace internal
} // namespace cc
#if defined(COMPILER_GCC)
namespace BASE_HASH_NAMESPACE {
template <> struct hash<cc::internal::RasterWorkerPoolTask*> {
size_t operator()(cc::internal::RasterWorkerPoolTask* ptr) const {
return hash<size_t>()(reinterpret_cast<size_t>(ptr));
}
};
} // namespace BASE_HASH_NAMESPACE
#endif // COMPILER
namespace cc {
class CC_EXPORT RasterWorkerPoolClient {
public:
virtual bool ShouldForceTasksRequiredForActivationToComplete() const = 0;
virtual void DidFinishRunningTasks() = 0;
virtual void DidFinishRunningTasksRequiredForActivation() = 0;
protected:
virtual ~RasterWorkerPoolClient() {}
};
// A worker thread pool that runs raster tasks.
class CC_EXPORT RasterWorkerPool : public WorkerPool {
public:
class CC_EXPORT Task {
public:
typedef base::Callback<void(bool was_canceled)> Reply;
class CC_EXPORT Set {
public:
Set();
~Set();
void Insert(const Task& task);
private:
friend class RasterWorkerPool;
friend class RasterWorkerPoolTest;
typedef internal::RasterWorkerPoolTask::TaskVector TaskVector;
TaskVector tasks_;
};
Task();
~Task();
// Returns true if Task is null (doesn't refer to anything).
bool is_null() const { return !internal_.get(); }
// Returns the Task into an uninitialized state.
void Reset();
protected:
friend class RasterWorkerPool;
friend class RasterWorkerPoolTest;
explicit Task(internal::WorkerPoolTask* internal);
scoped_refptr<internal::WorkerPoolTask> internal_;
};
class CC_EXPORT RasterTask {
public:
typedef base::Callback<void(const PicturePileImpl::Analysis& analysis,
bool was_canceled)> Reply;
class CC_EXPORT Queue {
public:
Queue();
~Queue();
void Append(const RasterTask& task, bool required_for_activation);
private:
friend class RasterWorkerPool;
typedef std::vector<scoped_refptr<internal::RasterWorkerPoolTask> >
TaskVector;
TaskVector tasks_;
typedef base::hash_set<internal::RasterWorkerPoolTask*> TaskSet;
TaskSet tasks_required_for_activation_;
};
RasterTask();
~RasterTask();
// Returns true if Task is null (doesn't refer to anything).
bool is_null() const { return !internal_.get(); }
// Returns the Task into an uninitialized state.
void Reset();
protected:
friend class RasterWorkerPool;
friend class RasterWorkerPoolTest;
explicit RasterTask(internal::RasterWorkerPoolTask* internal);
scoped_refptr<internal::RasterWorkerPoolTask> internal_;
};
virtual ~RasterWorkerPool();
void SetClient(RasterWorkerPoolClient* client);
// Tells the worker pool to shutdown after canceling all previously
// scheduled tasks. Reply callbacks are still guaranteed to run.
virtual void Shutdown() OVERRIDE;
// Schedule running of raster tasks in |queue| and all dependencies.
// Previously scheduled tasks that are no longer needed to run
// raster tasks in |queue| will be canceled unless already running.
// Once scheduled, reply callbacks are guaranteed to run for all tasks
// even if they later get canceled by another call to ScheduleTasks().
virtual void ScheduleTasks(RasterTask::Queue* queue) = 0;
// Returns the target that needs to be used for raster task resources.
virtual GLenum GetResourceTarget() const = 0;
// Returns the format that needs to be used for raster task resources.
virtual ResourceFormat GetResourceFormat() const = 0;
// TODO(vmpstr): Figure out an elegant way to not pass this many parameters.
static RasterTask CreateRasterTask(
const Resource* resource,
PicturePileImpl* picture_pile,
gfx::Rect content_rect,
float contents_scale,
RasterMode raster_mode,
TileResolution tile_resolution,
int layer_id,
const void* tile_id,
int source_frame_number,
RenderingStatsInstrumentation* rendering_stats,
const RasterTask::Reply& reply,
Task::Set* dependencies);
static Task CreateImageDecodeTask(
skia::LazyPixelRef* pixel_ref,
int layer_id,
RenderingStatsInstrumentation* stats_instrumentation,
const Task::Reply& reply);
protected:
typedef std::vector<scoped_refptr<internal::WorkerPoolTask> > TaskVector;
typedef std::vector<scoped_refptr<internal::RasterWorkerPoolTask> >
RasterTaskVector;
typedef base::hash_set<internal::RasterWorkerPoolTask*> RasterTaskSet;
typedef internal::RasterWorkerPoolTask* TaskMapKey;
typedef base::hash_map<TaskMapKey,
scoped_refptr<internal::WorkerPoolTask> > TaskMap;
RasterWorkerPool(ResourceProvider* resource_provider, size_t num_threads);
virtual void OnRasterTasksFinished() = 0;
virtual void OnRasterTasksRequiredForActivationFinished() = 0;
void SetRasterTasks(RasterTask::Queue* queue);
bool IsRasterTaskRequiredForActivation(
internal::RasterWorkerPoolTask* task) const;
RasterWorkerPoolClient* client() const { return client_; }
ResourceProvider* resource_provider() const { return resource_provider_; }
const RasterTaskVector& raster_tasks() const { return raster_tasks_; }
const RasterTaskSet& raster_tasks_required_for_activation() const {
return raster_tasks_required_for_activation_;
}
void set_raster_finished_task(
scoped_refptr<internal::WorkerPoolTask> raster_finished_task) {
raster_finished_task_ = raster_finished_task;
}
void set_raster_required_for_activation_finished_task(
scoped_refptr<internal::WorkerPoolTask>
raster_required_for_activation_finished_task) {
raster_required_for_activation_finished_task_ =
raster_required_for_activation_finished_task;
}
scoped_refptr<internal::WorkerPoolTask> CreateRasterFinishedTask();
scoped_refptr<internal::WorkerPoolTask>
CreateRasterRequiredForActivationFinishedTask();
scoped_ptr<base::Value> ScheduledStateAsValue() const;
static internal::GraphNode* CreateGraphNodeForTask(
internal::WorkerPoolTask* task,
unsigned priority,
TaskGraph* graph);
static internal::GraphNode* CreateGraphNodeForRasterTask(
internal::WorkerPoolTask* raster_task,
const TaskVector& decode_tasks,
unsigned priority,
TaskGraph* graph);
private:
void OnRasterFinished(const internal::WorkerPoolTask* source);
void OnRasterRequiredForActivationFinished(
const internal::WorkerPoolTask* source);
RasterWorkerPoolClient* client_;
ResourceProvider* resource_provider_;
RasterTask::Queue::TaskVector raster_tasks_;
RasterTask::Queue::TaskSet raster_tasks_required_for_activation_;
scoped_refptr<internal::WorkerPoolTask> raster_finished_task_;
scoped_refptr<internal::WorkerPoolTask>
raster_required_for_activation_finished_task_;
base::WeakPtrFactory<RasterWorkerPool> weak_ptr_factory_;
};
} // namespace cc
#endif // CC_RESOURCES_RASTER_WORKER_POOL_H_