| Index: cc/resources/gpu_tile_task_worker_pool.cc
|
| diff --git a/cc/resources/gpu_tile_task_worker_pool.cc b/cc/resources/gpu_tile_task_worker_pool.cc
|
| index 824945740b97b0bbd049f8790c85e599733a58c3..f07f610fd8d51b73b3ab4c4b996401f370a28388 100644
|
| --- a/cc/resources/gpu_tile_task_worker_pool.cc
|
| +++ b/cc/resources/gpu_tile_task_worker_pool.cc
|
| @@ -6,7 +6,9 @@
|
|
|
| #include <algorithm>
|
|
|
| +#include "base/threading/platform_thread.h"
|
| #include "base/trace_event/trace_event.h"
|
| +#include "cc/output/context_provider.h"
|
| #include "cc/resources/raster_buffer.h"
|
| #include "cc/resources/raster_source.h"
|
| #include "cc/resources/resource.h"
|
| @@ -16,34 +18,93 @@
|
| #include "third_party/skia/include/core/SkPictureRecorder.h"
|
| #include "third_party/skia/include/core/SkSurface.h"
|
| #include "third_party/skia/include/gpu/GrContext.h"
|
| +using gpu::gles2::GLES2Interface;
|
|
|
| namespace cc {
|
| namespace {
|
|
|
| class RasterBufferImpl : public RasterBuffer {
|
| public:
|
| - RasterBufferImpl() {}
|
| + RasterBufferImpl(ResourceProvider* resource_provider,
|
| + const Resource* resource,
|
| + bool use_distance_field_text)
|
| + : lock_(resource_provider, resource->id()),
|
| + resource_provider_(resource_provider),
|
| + resource_(resource),
|
| + sk_surface_(nullptr),
|
| + use_distance_field_text_(use_distance_field_text) {}
|
|
|
| // Overridden from RasterBuffer:
|
| void Playback(const RasterSource* raster_source,
|
| const gfx::Rect& rect,
|
| float scale) override {
|
| - // Don't do anything.
|
| + TRACE_EVENT0("cc", "RasterBufferImpl::Playback");
|
| +
|
| + // Play back raster_source into temp SkPicture.
|
| + SkPictureRecorder recorder;
|
| + gfx::Size size = resource_->size();
|
| + const int flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag;
|
| + skia::RefPtr<SkCanvas> canvas = skia::SharePtr(
|
| + recorder.beginRecording(size.width(), size.height(), NULL, flags));
|
| +
|
| + canvas->save();
|
| + raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
|
| + canvas->restore();
|
| +
|
| + skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
|
| +
|
| + // Bind ContextProvider to current thread.
|
| + resource_provider_->output_surface()
|
| + ->worker_context_provider()
|
| + ->RebindToCurrentThread();
|
| +
|
| + // Draw picture to Resource's texture.
|
| + {
|
| + ScopedGpuRaster gpu_raster(
|
| + resource_provider_->output_surface()->worker_context_provider());
|
| +
|
| + skia::RefPtr<SkSurface> sk_surface = skia::AdoptRef(
|
| + lock_.GetSkSurface(use_distance_field_text_, false, 0));
|
| +
|
| +#ifdef TODO_VMIURA_SINGLE_PICTURE_PLAYBACK
|
| + // This doesn't work if layer hoisting is enabled :(.
|
| + picture->playback(sk_surface->getCanvas(), nullptr);
|
| +#else
|
| + // This works...
|
| + SkMultiPictureDraw multi_picture_draw;
|
| + multi_picture_draw.add(sk_surface->getCanvas(), picture.get());
|
| + multi_picture_draw.draw(false);
|
| +#endif
|
| + sk_surface.clear();
|
| + }
|
| +
|
| + // Save Flush point after this tile, which the cc thread executes
|
| + // via SafeFlush().
|
| + resource_provider_->output_surface()
|
| + ->worker_context_provider()
|
| + ->ContextGL()
|
| + ->SetSafeFlushPoint();
|
| }
|
|
|
| private:
|
| + ResourceProvider::ScopedWriteLockGr lock_;
|
| + ResourceProvider* resource_provider_;
|
| + const Resource* resource_;
|
| + SkSurface* sk_surface_;
|
| + bool use_distance_field_text_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
|
| };
|
|
|
| } // namespace
|
| +
|
| // static
|
| scoped_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create(
|
| base::SequencedTaskRunner* task_runner,
|
| TaskGraphRunner* task_graph_runner,
|
| ResourceProvider* resource_provider) {
|
| - return make_scoped_ptr<TileTaskWorkerPool>(
|
| - new GpuTileTaskWorkerPool(
|
| - task_runner, task_graph_runner, resource_provider));
|
| + return make_scoped_ptr<TileTaskWorkerPool>(new GpuTileTaskWorkerPool(
|
| + task_runner, task_graph_runner, resource_provider));
|
| }
|
|
|
| // TODO(hendrikw): This class should be removed. See crbug.com/444938.
|
| @@ -53,8 +114,8 @@ GpuTileTaskWorkerPool::GpuTileTaskWorkerPool(
|
| ResourceProvider* resource_provider)
|
| : task_runner_(task_runner),
|
| task_graph_runner_(task_graph_runner),
|
| - namespace_token_(task_graph_runner_->GetNamespaceToken()),
|
| resource_provider_(resource_provider),
|
| + namespace_token_(task_graph_runner_->GetNamespaceToken()),
|
| task_set_finished_weak_ptr_factory_(this),
|
| weak_ptr_factory_(this) {
|
| }
|
| @@ -106,7 +167,8 @@ void GpuTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) {
|
| for (TileTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
|
| it != queue->items.end(); ++it) {
|
| const TileTaskQueue::Item& item = *it;
|
| - RasterTask* task = item.task;
|
| + RasterTask* task = item.task->AsRasterTask();
|
| + DCHECK(task);
|
| DCHECK(!task->HasCompleted());
|
|
|
| for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
|
| @@ -129,6 +191,13 @@ void GpuTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) {
|
| }
|
|
|
| ScheduleTasksOnOriginThread(this, &graph_);
|
| +
|
| + // Flush compositor context to sync resources to worker context.
|
| + resource_provider_->output_surface()
|
| + ->context_provider()
|
| + ->ContextGL()
|
| + ->ShallowFlushCHROMIUM();
|
| +
|
| task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
|
|
|
| std::copy(new_task_set_finished_tasks,
|
| @@ -141,6 +210,14 @@ void GpuTileTaskWorkerPool::CheckForCompletedTasks() {
|
|
|
| task_graph_runner_->CollectCompletedTasks(namespace_token_,
|
| &completed_tasks_);
|
| +
|
| + // Flush worker context so raster outputs are synced to the compositor
|
| + // context.
|
| + resource_provider_->output_surface()
|
| + ->worker_context_provider()
|
| + ->ContextGL()
|
| + ->SafeFlush();
|
| +
|
| CompleteTasks(completed_tasks_);
|
| completed_tasks_.clear();
|
| }
|
| @@ -164,7 +241,9 @@ void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) {
|
|
|
| scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster(
|
| const Resource* resource) {
|
| - return make_scoped_ptr<RasterBuffer>(new RasterBufferImpl());
|
| + bool use_distance_field_text = false;
|
| + return make_scoped_ptr<RasterBuffer>(new RasterBufferImpl(
|
| + resource_provider_, resource, use_distance_field_text));
|
| }
|
|
|
| void GpuTileTaskWorkerPool::ReleaseBufferForRaster(
|
|
|