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( |