diff options
author | Ben Murdoch <benm@google.com> | 2014-04-16 11:17:03 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2014-04-16 11:17:03 +0100 |
commit | a02191e04bc25c4935f804f2c080ae28663d096d (patch) | |
tree | 3cf38961650b5734763e473336009287244306ac /cc | |
parent | 8bad47e0f7d0c250a0443923cceb52f4a4abcd40 (diff) | |
download | chromium_org-a02191e04bc25c4935f804f2c080ae28663d096d.tar.gz |
Merge from Chromium at DEPS revision 263965
This commit was generated by merge_to_master.py.
Change-Id: Ia1121eddd985123f160afde6372525c3d25975bf
Diffstat (limited to 'cc')
105 files changed, 2838 insertions, 2055 deletions
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc index 05e6155bd5..ea4b6e1c51 100644 --- a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc +++ b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc @@ -21,6 +21,7 @@ class ScrollbarAnimationControllerLinearFadeTest : public testing::Test { protected: virtual void SetUp() { const int kThumbThickness = 10; + const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; const bool kIsOverlayScrollbar = true; // Allow opacity animations. @@ -31,6 +32,7 @@ class ScrollbarAnimationControllerLinearFadeTest : public testing::Test { 2, HORIZONTAL, kThumbThickness, + kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); clip_layer_ = LayerImpl::Create(host_impl_.active_tree(), 3); diff --git a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc index 383ce22b88..ff036a6a29 100644 --- a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc +++ b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc @@ -29,6 +29,7 @@ class ScrollbarAnimationControllerThinningTest : public testing::Test { const int kId = 2; const int kThumbThickness = 10; + const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; const bool kIsOverlayScrollbar = true; scrollbar_layer_ = @@ -36,6 +37,7 @@ class ScrollbarAnimationControllerThinningTest : public testing::Test { kId, HORIZONTAL, kThumbThickness, + kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); @@ -366,8 +366,10 @@ 'resources/raster_mode.h', 'resources/raster_worker_pool.cc', 'resources/raster_worker_pool.h', - 'resources/raster_worker_pool_delegate.cc', - 'resources/raster_worker_pool_delegate.h', + 'resources/rasterizer.cc', + 'resources/rasterizer.h', + 'resources/rasterizer_delegate.cc', + 'resources/rasterizer_delegate.h', 'resources/release_callback.h', 'resources/resource.cc', 'resources/resource.h', diff --git a/cc/cc.target.darwin-arm.mk b/cc/cc.target.darwin-arm.mk index 9d3504cd36..01669bc58e 100644 --- a/cc/cc.target.darwin-arm.mk +++ b/cc/cc.target.darwin-arm.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -289,8 +290,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -414,8 +417,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.darwin-mips.mk b/cc/cc.target.darwin-mips.mk index 29ac41b2ff..4a9a8496a4 100644 --- a/cc/cc.target.darwin-mips.mk +++ b/cc/cc.target.darwin-mips.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -288,8 +289,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -412,8 +415,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.darwin-x86.mk b/cc/cc.target.darwin-x86.mk index 78c868e94f..d36c6c492f 100644 --- a/cc/cc.target.darwin-x86.mk +++ b/cc/cc.target.darwin-x86.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -290,8 +291,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -415,8 +418,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.darwin-x86_64.mk b/cc/cc.target.darwin-x86_64.mk index 890f697a1d..3a05f9f423 100644 --- a/cc/cc.target.darwin-x86_64.mk +++ b/cc/cc.target.darwin-x86_64.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -290,8 +291,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -415,8 +418,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.linux-arm.mk b/cc/cc.target.linux-arm.mk index 9d3504cd36..01669bc58e 100644 --- a/cc/cc.target.linux-arm.mk +++ b/cc/cc.target.linux-arm.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -289,8 +290,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -414,8 +417,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.linux-mips.mk b/cc/cc.target.linux-mips.mk index 29ac41b2ff..4a9a8496a4 100644 --- a/cc/cc.target.linux-mips.mk +++ b/cc/cc.target.linux-mips.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -288,8 +289,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -412,8 +415,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.linux-x86.mk b/cc/cc.target.linux-x86.mk index 78c868e94f..d36c6c492f 100644 --- a/cc/cc.target.linux-x86.mk +++ b/cc/cc.target.linux-x86.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -290,8 +291,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -415,8 +418,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/cc.target.linux-x86_64.mk b/cc/cc.target.linux-x86_64.mk index 890f697a1d..3a05f9f423 100644 --- a/cc/cc.target.linux-x86_64.mk +++ b/cc/cc.target.linux-x86_64.mk @@ -180,7 +180,8 @@ LOCAL_SRC_FILES := \ cc/resources/priority_calculator.cc \ cc/resources/raster_mode.cc \ cc/resources/raster_worker_pool.cc \ - cc/resources/raster_worker_pool_delegate.cc \ + cc/resources/rasterizer.cc \ + cc/resources/rasterizer_delegate.cc \ cc/resources/resource.cc \ cc/resources/resource_format.cc \ cc/resources/resource_pool.cc \ @@ -290,8 +291,10 @@ MY_DEFS_Debug := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ @@ -415,8 +418,10 @@ MY_DEFS_Release := \ '-DGR_GL_IGNORE_ES3_MSAA=0' \ '-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \ '-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \ - '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \ + '-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \ + '-DSK_SUPPORT_LEGACY_N32_NAME' \ + '-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \ '-DSK_BUILD_FOR_ANDROID' \ '-DSK_USE_POSIX_THREADS' \ '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc index b764535ac2..48d7c34f11 100644 --- a/cc/debug/rasterize_and_record_benchmark_impl.cc +++ b/cc/debug/rasterize_and_record_benchmark_impl.cc @@ -28,7 +28,7 @@ base::TimeTicks Now() { : base::TimeTicks::HighResNow(); } -class BenchmarkRasterTask : public internal::Task { +class BenchmarkRasterTask : public Task { public: BenchmarkRasterTask(PicturePileImpl* picture_pile, const gfx::Rect& content_rect, @@ -41,7 +41,7 @@ class BenchmarkRasterTask : public internal::Task { is_solid_color_(false), best_time_(base::TimeDelta::Max()) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { PicturePileImpl* picture_pile = picture_pile_->GetCloneForDrawingOnThread( RasterWorkerPool::GetPictureCloneIndexForCurrentThread()); @@ -142,8 +142,7 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) { return; } - internal::TaskGraphRunner* task_graph_runner = - RasterWorkerPool::GetTaskGraphRunner(); + TaskGraphRunner* task_graph_runner = RasterWorkerPool::GetTaskGraphRunner(); DCHECK(task_graph_runner); if (!task_namespace_.IsValid()) @@ -169,17 +168,17 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) { contents_scale, rasterize_repeat_count_)); - internal::TaskGraph graph; + TaskGraph graph; - graph.nodes.push_back(internal::TaskGraph::Node( - benchmark_raster_task, - RasterWorkerPool::kBenchmarkRasterTaskPriority, - 0u)); + graph.nodes.push_back( + TaskGraph::Node(benchmark_raster_task, + RasterWorkerPool::kBenchmarkRasterTaskPriority, + 0u)); task_graph_runner->ScheduleTasks(task_namespace_, &graph); task_graph_runner->WaitForTasksToFinishRunning(task_namespace_); - internal::Task::Vector completed_tasks; + Task::Vector completed_tasks; task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks); DCHECK_EQ(1u, completed_tasks.size()); DCHECK_EQ(completed_tasks[0], benchmark_raster_task); diff --git a/cc/debug/rasterize_and_record_benchmark_impl.h b/cc/debug/rasterize_and_record_benchmark_impl.h index 985df7ba17..cceef05169 100644 --- a/cc/debug/rasterize_and_record_benchmark_impl.h +++ b/cc/debug/rasterize_and_record_benchmark_impl.h @@ -49,7 +49,7 @@ class RasterizeAndRecordBenchmarkImpl : public MicroBenchmarkImpl { RasterizeResults rasterize_results_; int rasterize_repeat_count_; - internal::NamespaceToken task_namespace_; + NamespaceToken task_namespace_; }; } // namespace cc diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 2ef8a2fdf1..4bfb27c99b 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc @@ -43,7 +43,7 @@ static inline SkPaint CreatePaint() { swizzle_matrix.fMat[3 + 5 * 3] = 1; skia::RefPtr<SkColorMatrixFilter> filter = - skia::AdoptRef(new SkColorMatrixFilter(swizzle_matrix)); + skia::AdoptRef(SkColorMatrixFilter::Create(swizzle_matrix)); paint.setColorFilter(filter.get()); #endif return paint; diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index dee9a78bc9..e47f4b88d1 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc @@ -20,7 +20,7 @@ PictureLayer::PictureLayer(ContentLayerClient* client) pile_(make_scoped_refptr(new PicturePile())), instrumentation_object_tracker_(id()), is_mask_(false), - has_gpu_rasterization_hint_(false), + has_gpu_rasterization_hint_(TRIBOOL_UNKNOWN), update_source_frame_number_(-1) {} PictureLayer::~PictureLayer() { @@ -50,7 +50,7 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { } layer_impl->SetIsMask(is_mask_); - layer_impl->SetHasGpuRasterizationHint(has_gpu_rasterization_hint_); + layer_impl->SetUseGpuRasterization(ShouldUseGpuRasterization()); // Unlike other properties, invalidation must always be set on layer_impl. // See PictureLayerImpl::PushPropertiesTo for more details. @@ -138,11 +138,37 @@ void PictureLayer::SetIsMask(bool is_mask) { } void PictureLayer::SetHasGpuRasterizationHint(bool has_hint) { - DCHECK(IsPropertyChangeAllowed()); - if (has_gpu_rasterization_hint_ == has_hint) - return; - has_gpu_rasterization_hint_ = has_hint; - SetNeedsCommit(); + switch (has_gpu_rasterization_hint_) { + case TRIBOOL_UNKNOWN: // Fall-through. + case TRIBOOL_TRUE: + has_gpu_rasterization_hint_ = has_hint ? TRIBOOL_TRUE : TRIBOOL_FALSE; + break; + case TRIBOOL_FALSE: + // GPU rasterization cannot be enabled once disabled. + // This is done to prevent frequent invalidations and visual flashing. + break; + default: + NOTREACHED(); + } + // No need to set needs commit or push-properties. + // If only the hint changes and the layer is still valid, there is no need + // to invalidate the rasterization for the whole layer. If there is an + // invalidation (current or future) we will re-raster everything so that it + // is consistent across the layer. +} + +bool PictureLayer::ShouldUseGpuRasterization() const { + switch (layer_tree_host()->settings().rasterization_site) { + case LayerTreeSettings::CpuRasterization: + return false; + case LayerTreeSettings::HybridRasterization: + return has_gpu_rasterization_hint_ == TRIBOOL_TRUE && + pile_->is_suitable_for_gpu_rasterization(); + case LayerTreeSettings::GpuRasterization: + return true; + } + NOTREACHED(); + return false; } bool PictureLayer::SupportsLCDText() const { diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index 78bb8f4464..28f4f906c0 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h @@ -41,6 +41,9 @@ class CC_EXPORT PictureLayer : public Layer { ContentLayerClient* client() { return client_; } void SetHasGpuRasterizationHint(bool has_hint); + bool ShouldUseGpuRasterization() const; + + PicturePile* GetPicturePileForTesting() const { return pile_.get(); } protected: explicit PictureLayer(ContentLayerClient* client); @@ -57,7 +60,9 @@ class CC_EXPORT PictureLayer : public Layer { Region pile_invalidation_; gfx::Rect last_updated_visible_content_rect_; bool is_mask_; - bool has_gpu_rasterization_hint_; + + enum TriBool { TRIBOOL_UNKNOWN, TRIBOOL_FALSE, TRIBOOL_TRUE }; + TriBool has_gpu_rasterization_hint_; int update_source_frame_number_; diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 57becf4396..558ef91a27 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -54,8 +54,8 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) is_using_lcd_text_(tree_impl->settings().can_use_lcd_text), needs_post_commit_initialization_(true), should_update_tile_priorities_(false), - has_gpu_rasterization_hint_(false), should_use_low_res_tiling_(tree_impl->settings().create_low_res_tiling), + use_gpu_rasterization_(false), layer_needs_to_register_itself_(true) {} PictureLayerImpl::~PictureLayerImpl() { @@ -96,7 +96,7 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { layer_impl->SetIsMask(is_mask_); layer_impl->pile_ = pile_; - layer_impl->SetHasGpuRasterizationHint(has_gpu_rasterization_hint_); + layer_impl->use_gpu_rasterization_ = use_gpu_rasterization_; // Tilings would be expensive to push, so we swap. layer_impl->tilings_.swap(tilings_); @@ -490,24 +490,12 @@ skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() { return pile_->GetFlattenedPicture(); } -void PictureLayerImpl::SetHasGpuRasterizationHint(bool has_hint) { - bool old_should_use_gpu_rasterization = ShouldUseGpuRasterization(); - has_gpu_rasterization_hint_ = has_hint; - if (ShouldUseGpuRasterization() != old_should_use_gpu_rasterization) - RemoveAllTilings(); -} +void PictureLayerImpl::SetUseGpuRasterization(bool use_gpu) { + if (use_gpu_rasterization_ == use_gpu) + return; -bool PictureLayerImpl::ShouldUseGpuRasterization() const { - switch (layer_tree_impl()->settings().rasterization_site) { - case LayerTreeSettings::CpuRasterization: - return false; - case LayerTreeSettings::HybridRasterization: - return has_gpu_rasterization_hint_; - case LayerTreeSettings::GpuRasterization: - return true; - } - NOTREACHED(); - return false; + use_gpu_rasterization_ = use_gpu; + RemoveAllTilings(); } scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, @@ -1309,8 +1297,10 @@ PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator( bool prioritize_low_res) : layer_(layer), current_stage_(0) { DCHECK(layer_); - if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) + if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) { + current_stage_ = arraysize(stages_); return; + } WhichTree tree = layer_->layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; @@ -1405,7 +1395,8 @@ PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() layer_(NULL) {} PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( - PictureLayerImpl* layer) + PictureLayerImpl* layer, + TreePriority tree_priority) : iterator_index_(0), iteration_stage_(TilePriority::EVENTUALLY), required_for_activation_(false), @@ -1413,9 +1404,6 @@ PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) return; - WhichTree tree = - layer_->layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; - size_t high_res_tiling_index = layer_->tilings_->num_tilings(); size_t low_res_tiling_index = layer_->tilings_->num_tilings(); for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { @@ -1431,7 +1419,7 @@ PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( // Higher resolution non-ideal goes first. for (size_t i = 0; i < high_res_tiling_index; ++i) { iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( - layer_->tilings_->tiling_at(i), tree)); + layer_->tilings_->tiling_at(i), tree_priority)); } // Lower resolution non-ideal goes next. @@ -1443,19 +1431,19 @@ PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( continue; iterators_.push_back( - PictureLayerTiling::TilingEvictionTileIterator(tiling, tree)); + PictureLayerTiling::TilingEvictionTileIterator(tiling, tree_priority)); } // Now, put the low res tiling if we have one. if (low_res_tiling_index < layer_->tilings_->num_tilings()) { iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( - layer_->tilings_->tiling_at(low_res_tiling_index), tree)); + layer_->tilings_->tiling_at(low_res_tiling_index), tree_priority)); } // Finally, put the high res tiling if we have one. if (high_res_tiling_index < layer_->tilings_->num_tilings()) { iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( - layer_->tilings_->tiling_at(high_res_tiling_index), tree)); + layer_->tilings_->tiling_at(high_res_tiling_index), tree_priority)); } DCHECK_GT(iterators_.size(), 0u); diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index b9a04eaf3b..dcaee1257f 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -58,7 +58,8 @@ class CC_EXPORT PictureLayerImpl class CC_EXPORT LayerEvictionTileIterator { public: LayerEvictionTileIterator(); - explicit LayerEvictionTileIterator(PictureLayerImpl* layer); + LayerEvictionTileIterator(PictureLayerImpl* layer, + TreePriority tree_priority); ~LayerEvictionTileIterator(); Tile* operator*(); @@ -129,8 +130,8 @@ class CC_EXPORT PictureLayerImpl virtual void RunMicroBenchmark(MicroBenchmarkImpl* benchmark) OVERRIDE; - void SetHasGpuRasterizationHint(bool has_hint); - bool ShouldUseGpuRasterization() const; + void SetUseGpuRasterization(bool use_gpu); + bool ShouldUseGpuRasterization() const { return use_gpu_rasterization_; } // Functions used by tile manager. void DidUnregisterLayer(); @@ -208,8 +209,8 @@ class CC_EXPORT PictureLayerImpl // A sanity state check to make sure UpdateTilePriorities only gets called // after a CalculateContentsScale/ManageTilings. bool should_update_tile_priorities_; - bool has_gpu_rasterization_hint_; bool should_use_low_res_tiling_; + bool use_gpu_rasterization_; bool layer_needs_to_register_itself_; diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 6cdd577e40..15ade9b1b6 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -18,8 +18,6 @@ #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_picture_pile_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/gpu_rasterization_settings.h" -#include "cc/test/hybrid_rasterization_settings.h" #include "cc/test/impl_side_painting_settings.h" #include "cc/test/mock_quad_culler.h" #include "cc/test/test_shared_bitmap_manager.h" @@ -1634,7 +1632,7 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterReleaseResource) { EXPECT_EQ(HIGH_RESOLUTION, high_res->resolution()); } -TEST_F(PictureLayerImplTest, TilingWithoutGpuRasterization) { +TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) { gfx::Size default_tile_size(host_impl_.settings().default_tile_size); gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); @@ -1654,6 +1652,20 @@ TEST_F(PictureLayerImplTest, TilingWithoutGpuRasterization) { &result_bounds); // Should have a low-res and a high-res tiling. ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings()); + + pending_layer_->SetUseGpuRasterization(true); + EXPECT_TRUE(pending_layer_->ShouldUseGpuRasterization()); + EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + pending_layer_->CalculateContentsScale(1.f, + 1.f, + 1.f, + 1.f, + false, + &result_scale_x, + &result_scale_y, + &result_bounds); + // Should only have the high-res tiling. + ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) { @@ -1768,54 +1780,9 @@ TEST_F(DeferredInitPictureLayerImplTest, host_impl_.active_tree()->UpdateDrawProperties(); } -class HybridRasterizationPictureLayerImplTest : public PictureLayerImplTest { - public: - HybridRasterizationPictureLayerImplTest() - : PictureLayerImplTest(HybridRasterizationSettings()) {} -}; - -TEST_F(HybridRasterizationPictureLayerImplTest, Tiling) { - gfx::Size default_tile_size(host_impl_.settings().default_tile_size); - gfx::Size layer_bounds(default_tile_size.width() * 4, - default_tile_size.height() * 4); - float result_scale_x, result_scale_y; - gfx::Size result_bounds; - - SetupDefaultTrees(layer_bounds); - EXPECT_FALSE(pending_layer_->ShouldUseGpuRasterization()); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - pending_layer_->CalculateContentsScale(1.f, - 1.f, - 1.f, - 1.f, - false, - &result_scale_x, - &result_scale_y, - &result_bounds); - // Should have a low-res and a high-res tiling. - ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings()); - - pending_layer_->SetHasGpuRasterizationHint(true); - EXPECT_TRUE(pending_layer_->ShouldUseGpuRasterization()); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - pending_layer_->CalculateContentsScale(1.f, - 1.f, - 1.f, - 1.f, - false, - &result_scale_x, - &result_scale_y, - &result_bounds); - // Should only have the high-res tiling. - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); -} - -TEST_F(HybridRasterizationPictureLayerImplTest, - HighResTilingDuringAnimationForCpuRasterization) { +TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForCpuRasterization) { gfx::Size tile_size(host_impl_.settings().default_tile_size); SetupDefaultTrees(tile_size); - pending_layer_->SetHasGpuRasterizationHint(false); - active_layer_->SetHasGpuRasterizationHint(false); float contents_scale = 1.f; float device_scale = 1.3f; @@ -1901,12 +1868,11 @@ TEST_F(HybridRasterizationPictureLayerImplTest, EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f); } -TEST_F(HybridRasterizationPictureLayerImplTest, - HighResTilingDuringAnimationForGpuRasterization) { +TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForGpuRasterization) { gfx::Size tile_size(host_impl_.settings().default_tile_size); SetupDefaultTrees(tile_size); - pending_layer_->SetHasGpuRasterizationHint(true); - active_layer_->SetHasGpuRasterizationHint(true); + pending_layer_->SetUseGpuRasterization(true); + active_layer_->SetUseGpuRasterization(true); float contents_scale = 1.f; float device_scale = 1.f; @@ -1956,50 +1922,6 @@ TEST_F(HybridRasterizationPictureLayerImplTest, EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f); } -class GpuRasterizationPictureLayerImplTest : public PictureLayerImplTest { - public: - GpuRasterizationPictureLayerImplTest() - : PictureLayerImplTest(GpuRasterizationSettings()) {} -}; - -TEST_F(GpuRasterizationPictureLayerImplTest, Tiling) { - gfx::Size default_tile_size(host_impl_.settings().default_tile_size); - gfx::Size layer_bounds(default_tile_size.width() * 4, - default_tile_size.height() * 4); - float result_scale_x, result_scale_y; - gfx::Size result_bounds; - - SetupDefaultTrees(layer_bounds); - pending_layer_->SetHasGpuRasterizationHint(true); - EXPECT_TRUE(pending_layer_->ShouldUseGpuRasterization()); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - pending_layer_->CalculateContentsScale(1.f, - 1.f, - 1.f, - 1.f, - false, - &result_scale_x, - &result_scale_y, - &result_bounds); - // Should only have the high-res tiling. - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); - - pending_layer_->SetHasGpuRasterizationHint(false); - EXPECT_TRUE(pending_layer_->ShouldUseGpuRasterization()); - // Should still have the high-res tiling. - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); - pending_layer_->CalculateContentsScale(1.f, - 1.f, - 1.f, - 1.f, - false, - &result_scale_x, - &result_scale_y, - &result_bounds); - // Should still only have the high-res tiling. - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); -} - TEST_F(PictureLayerImplTest, LayerRasterTileIterator) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); @@ -2013,6 +1935,14 @@ TEST_F(PictureLayerImplTest, LayerRasterTileIterator) { float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + // Empty iterator + PictureLayerImpl::LayerRasterTileIterator it; + EXPECT_FALSE(it); + + // No tilings. + it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, false); + EXPECT_FALSE(it); + pending_layer_->AddTiling(low_res_factor); pending_layer_->AddTiling(0.3f); pending_layer_->AddTiling(0.7f); @@ -2022,9 +1952,6 @@ TEST_F(PictureLayerImplTest, LayerRasterTileIterator) { host_impl_.SetViewportSize(gfx::Size(500, 500)); host_impl_.pending_tree()->UpdateDrawProperties(); - PictureLayerImpl::LayerRasterTileIterator it; - EXPECT_FALSE(it); - std::set<Tile*> unique_tiles; bool reached_prepaint = false; size_t non_ideal_tile_count = 0u; @@ -2146,7 +2073,8 @@ TEST_F(PictureLayerImplTest, LayerEvictionTileIterator) { EXPECT_FALSE(it); // Tiles don't have resources yet. - it = PictureLayerImpl::LayerEvictionTileIterator(pending_layer_); + it = PictureLayerImpl::LayerEvictionTileIterator( + pending_layer_, SAME_PRIORITY_FOR_BOTH_TREES); EXPECT_FALSE(it); host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); @@ -2157,7 +2085,9 @@ TEST_F(PictureLayerImplTest, LayerEvictionTileIterator) { bool reached_visible = false; bool reached_required = false; Tile* last_tile = NULL; - for (it = PictureLayerImpl::LayerEvictionTileIterator(pending_layer_); it; + for (it = PictureLayerImpl::LayerEvictionTileIterator( + pending_layer_, SAME_PRIORITY_FOR_BOTH_TREES); + it; ++it) { Tile* tile = *it; if (!last_tile) diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 3ff1de5cd8..5df3449188 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc @@ -10,6 +10,8 @@ #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_proxy.h" +#include "cc/test/gpu_rasterization_settings.h" +#include "cc/test/hybrid_rasterization_settings.h" #include "cc/test/impl_side_painting_settings.h" #include "cc/trees/occlusion_tracker.h" #include "cc/trees/single_thread_proxy.h" @@ -67,5 +69,86 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { } } +TEST(PictureLayerTest, ForcedCpuRaster) { + MockContentLayerClient client; + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); + + scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + host->SetRootLayer(layer); + + // The default value is false. + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); + + // Gpu rasterization cannot be enabled even with raster hint. + layer->SetHasGpuRasterizationHint(true); + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); +} + +TEST(PictureLayerTest, ForcedGpuRaster) { + MockContentLayerClient client; + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); + + scoped_ptr<FakeLayerTreeHost> host = + FakeLayerTreeHost::Create(GpuRasterizationSettings()); + host->SetRootLayer(layer); + + // The default value is true. + EXPECT_TRUE(layer->ShouldUseGpuRasterization()); + + // Gpu rasterization cannot be disabled even with raster hint. + layer->SetHasGpuRasterizationHint(false); + EXPECT_TRUE(layer->ShouldUseGpuRasterization()); + + // Gpu rasterization cannot be disabled even with skia veto. + PicturePile* pile = layer->GetPicturePileForTesting(); + EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); + pile->SetUnsuitableForGpuRasterizationForTesting(); + EXPECT_TRUE(layer->ShouldUseGpuRasterization()); +} + +TEST(PictureLayerTest, HybridRaster) { + MockContentLayerClient client; + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); + + scoped_ptr<FakeLayerTreeHost> host = + FakeLayerTreeHost::Create(HybridRasterizationSettings()); + host->SetRootLayer(layer); + + // The default value is false. + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); + + // Gpu rasterization can be enabled first time. + layer->SetHasGpuRasterizationHint(true); + EXPECT_TRUE(layer->ShouldUseGpuRasterization()); + + // Gpu rasterization can always be disabled. + layer->SetHasGpuRasterizationHint(false); + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); + + // Gpu rasterization cannot be enabled once disabled. + layer->SetHasGpuRasterizationHint(true); + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); +} + +TEST(PictureLayerTest, VetoGpuRaster) { + MockContentLayerClient client; + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); + + scoped_ptr<FakeLayerTreeHost> host = + FakeLayerTreeHost::Create(HybridRasterizationSettings()); + host->SetRootLayer(layer); + + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); + + layer->SetHasGpuRasterizationHint(true); + EXPECT_TRUE(layer->ShouldUseGpuRasterization()); + + // Veto gpu rasterization. + PicturePile* pile = layer->GetPicturePileForTesting(); + EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); + pile->SetUnsuitableForGpuRasterizationForTesting(); + EXPECT_FALSE(layer->ShouldUseGpuRasterization()); +} + } // namespace } // namespace cc diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index a92229a08b..22a266470d 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc @@ -33,20 +33,22 @@ namespace cc { namespace { -LayerImpl* LayerImplForScrollAreaAndScrollbar( - FakeLayerTreeHost* host, - scoped_ptr<Scrollbar> scrollbar, - bool reverse_order, - bool use_solid_color_scrollbar, - int thumb_thickness) { +LayerImpl* LayerImplForScrollAreaAndScrollbar(FakeLayerTreeHost* host, + scoped_ptr<Scrollbar> scrollbar, + bool reverse_order, + bool use_solid_color_scrollbar, + int thumb_thickness, + int track_start) { scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> child2; if (use_solid_color_scrollbar) { const bool kIsLeftSideVerticalScrollbar = false; - child2 = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), thumb_thickness, - kIsLeftSideVerticalScrollbar, child1->id()); + child2 = SolidColorScrollbarLayer::Create(scrollbar->Orientation(), + thumb_thickness, + track_start, + kIsLeftSideVerticalScrollbar, + child1->id()); } else { child2 = PaintedScrollbarLayer::Create(scrollbar.Pass(), child1->id()); } @@ -60,7 +62,7 @@ TEST(ScrollbarLayerTest, ResolveScrollLayerPointer) { scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - host.get(), scrollbar.Pass(), false, false, 0); + host.get(), scrollbar.Pass(), false, false, 0, 0); LayerImpl* cc_child1 = layer_impl_tree_root->children()[0]; PaintedScrollbarLayerImpl* cc_child2 = @@ -75,7 +77,7 @@ TEST(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) { scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - host.get(), scrollbar.Pass(), true, false, 0); + host.get(), scrollbar.Pass(), true, false, 0, 0); PaintedScrollbarLayerImpl* cc_child1 = static_cast<PaintedScrollbarLayerImpl*>( @@ -92,7 +94,7 @@ TEST(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { // Create and attach a non-overlay scrollbar. scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - host.get(), scrollbar.Pass(), false, false, 0); + host.get(), scrollbar.Pass(), false, false, 0, 0); PaintedScrollbarLayerImpl* scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( layer_impl_tree_root->children()[1]); @@ -108,7 +110,7 @@ TEST(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { scrollbar.reset(new FakeScrollbar(false, false, true)); layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - host.get(), scrollbar.Pass(), false, false, 0); + host.get(), scrollbar.Pass(), false, false, 0, 0); scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( layer_impl_tree_root->children()[1]); @@ -271,6 +273,7 @@ TEST(ScrollbarLayerTest, ThumbRect) { TEST(ScrollbarLayerTest, SolidColorDrawQuads) { const int kThumbThickness = 3; + const int kTrackStart = 0; const int kTrackLength = 100; LayerTreeSettings layer_tree_settings; @@ -279,7 +282,7 @@ TEST(ScrollbarLayerTest, SolidColorDrawQuads) { scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - host.get(), scrollbar.Pass(), false, true, kThumbThickness); + host.get(), scrollbar.Pass(), false, true, kThumbThickness, kTrackStart); ScrollbarLayerImplBase* scrollbar_layer_impl = static_cast<SolidColorScrollbarLayerImpl*>( layer_impl_tree_root->children()[1]); @@ -333,6 +336,7 @@ TEST(ScrollbarLayerTest, SolidColorDrawQuads) { TEST(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { const int kThumbThickness = 3; + const int kTrackStart = 0; const int kTrackLength = 10; LayerTreeSettings layer_tree_settings; @@ -350,6 +354,7 @@ TEST(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { const bool kIsLeftSideVerticalScrollbar = false; child2 = SolidColorScrollbarLayer::Create(scrollbar->Orientation(), kThumbThickness, + kTrackStart, kIsLeftSideVerticalScrollbar, child1->id()); child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id()); @@ -394,6 +399,7 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { layer_tree_settings, &proxy_, &shared_bitmap_manager_)); const int kThumbThickness = 3; + const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; const bool kIsOverlayScrollbar = false; @@ -402,6 +408,7 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { 1, HORIZONTAL, kThumbThickness, + kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); vertical_scrollbar_layer_ = @@ -409,6 +416,7 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { 2, VERTICAL, kThumbThickness, + kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); } @@ -624,10 +632,12 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { scoped_refptr<Layer> scrollbar_layer; if (use_solid_color_scrollbar) { const int kThumbThickness = 3; + const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; scrollbar_layer = SolidColorScrollbarLayer::Create(scrollbar->Orientation(), kThumbThickness, + kTrackStart, kIsLeftSideVerticalScrollbar, layer_tree_root->id()); } else { diff --git a/cc/layers/solid_color_scrollbar_layer.cc b/cc/layers/solid_color_scrollbar_layer.cc index 4a8e722498..8749398aa6 100644 --- a/cc/layers/solid_color_scrollbar_layer.cc +++ b/cc/layers/solid_color_scrollbar_layer.cc @@ -17,6 +17,7 @@ scoped_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl( id(), orientation(), thumb_thickness_, + track_start_, is_left_side_vertical_scrollbar_, kIsOverlayScrollbar) .PassAs<LayerImpl>(); @@ -25,24 +26,28 @@ scoped_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl( scoped_refptr<SolidColorScrollbarLayer> SolidColorScrollbarLayer::Create( ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, int scroll_layer_id) { - return make_scoped_refptr(new SolidColorScrollbarLayer( - orientation, - thumb_thickness, - is_left_side_vertical_scrollbar, - scroll_layer_id)); + return make_scoped_refptr( + new SolidColorScrollbarLayer(orientation, + thumb_thickness, + track_start, + is_left_side_vertical_scrollbar, + scroll_layer_id)); } SolidColorScrollbarLayer::SolidColorScrollbarLayer( ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, int scroll_layer_id) : scroll_layer_id_(Layer::INVALID_ID), clip_layer_id_(scroll_layer_id), orientation_(orientation), thumb_thickness_(thumb_thickness), + track_start_(track_start), is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) {} SolidColorScrollbarLayer::~SolidColorScrollbarLayer() {} diff --git a/cc/layers/solid_color_scrollbar_layer.h b/cc/layers/solid_color_scrollbar_layer.h index 67d4ae7b36..654a6a6ae7 100644 --- a/cc/layers/solid_color_scrollbar_layer.h +++ b/cc/layers/solid_color_scrollbar_layer.h @@ -20,6 +20,7 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, static scoped_refptr<SolidColorScrollbarLayer> Create( ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, int scroll_layer_id); @@ -42,6 +43,7 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, protected: SolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, int scroll_layer_id); virtual ~SolidColorScrollbarLayer(); @@ -51,6 +53,7 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, int clip_layer_id_; ScrollbarOrientation orientation_; int thumb_thickness_; + int track_start_; bool is_left_side_vertical_scrollbar_; DISALLOW_COPY_AND_ASSIGN(SolidColorScrollbarLayer); diff --git a/cc/layers/solid_color_scrollbar_layer_impl.cc b/cc/layers/solid_color_scrollbar_layer_impl.cc index 211108ad49..f579ea6b26 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl.cc +++ b/cc/layers/solid_color_scrollbar_layer_impl.cc @@ -15,6 +15,7 @@ scoped_ptr<SolidColorScrollbarLayerImpl> SolidColorScrollbarLayerImpl::Create( int id, ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, bool is_overlay) { return make_scoped_ptr( @@ -22,6 +23,7 @@ scoped_ptr<SolidColorScrollbarLayerImpl> SolidColorScrollbarLayerImpl::Create( id, orientation, thumb_thickness, + track_start, is_left_side_vertical_scrollbar, is_overlay)); } @@ -34,6 +36,7 @@ scoped_ptr<LayerImpl> SolidColorScrollbarLayerImpl::CreateLayerImpl( id(), orientation(), thumb_thickness_, + track_start_, is_left_side_vertical_scrollbar(), is_overlay_scrollbar()) .PassAs<LayerImpl>(); @@ -44,6 +47,7 @@ SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl( int id, ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, bool is_overlay) : ScrollbarLayerImplBase(tree_impl, @@ -52,6 +56,7 @@ SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl( is_left_side_vertical_scrollbar, is_overlay), thumb_thickness_(thumb_thickness), + track_start_(track_start), color_(tree_impl->settings().solid_color_scrollbar_color) {} void SolidColorScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { @@ -76,14 +81,12 @@ int SolidColorScrollbarLayerImpl::ThumbLength() const { float SolidColorScrollbarLayerImpl::TrackLength() const { if (orientation() == HORIZONTAL) - return bounds().width(); + return bounds().width() - TrackStart() * 2; else - return bounds().height() + vertical_adjust(); + return bounds().height() + vertical_adjust() - TrackStart() * 2; } -int SolidColorScrollbarLayerImpl::TrackStart() const { - return 0; -} +int SolidColorScrollbarLayerImpl::TrackStart() const { return track_start_; } bool SolidColorScrollbarLayerImpl::IsThumbResizable() const { return true; diff --git a/cc/layers/solid_color_scrollbar_layer_impl.h b/cc/layers/solid_color_scrollbar_layer_impl.h index 205496a6e7..4cea04b4ab 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl.h +++ b/cc/layers/solid_color_scrollbar_layer_impl.h @@ -17,6 +17,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { int id, ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, bool is_overlay); virtual ~SolidColorScrollbarLayerImpl(); @@ -35,6 +36,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { int id, ScrollbarOrientation orientation, int thumb_thickness, + int track_start, bool is_left_side_vertical_scrollbar, bool is_overlay); @@ -47,6 +49,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { private: int thumb_thickness_; + int track_start_; SkColor color_; }; diff --git a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc index 0317015e96..ba82be5357 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc +++ b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc @@ -18,6 +18,7 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) { ScrollbarOrientation orientation = VERTICAL; int thumb_thickness = layer_size.width(); + int track_start = 0; bool is_left_side_vertical_scrollbar = false; bool is_overlay = false; @@ -25,6 +26,7 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) { impl.AddChildToRoot<SolidColorScrollbarLayerImpl>( orientation, thumb_thickness, + track_start, is_left_side_vertical_scrollbar, is_overlay); scrollbar_layer_impl->SetAnchorPoint(gfx::PointF()); diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index 43a0412f5e..8960c55bbe 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc @@ -421,10 +421,8 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame, return BindFramebufferToTexture(frame, texture, render_pass->output_rect); } -void DirectRenderer::RunOnDemandRasterTask( - internal::Task* on_demand_raster_task) { - internal::TaskGraphRunner* task_graph_runner = - RasterWorkerPool::GetTaskGraphRunner(); +void DirectRenderer::RunOnDemandRasterTask(Task* on_demand_raster_task) { + TaskGraphRunner* task_graph_runner = RasterWorkerPool::GetTaskGraphRunner(); DCHECK(task_graph_runner); // Make sure we have a unique task namespace token. @@ -432,18 +430,18 @@ void DirectRenderer::RunOnDemandRasterTask( on_demand_task_namespace_ = task_graph_runner->GetNamespaceToken(); // Construct a task graph that contains this single raster task. - internal::TaskGraph graph; + TaskGraph graph; graph.nodes.push_back( - internal::TaskGraph::Node(on_demand_raster_task, - RasterWorkerPool::kOnDemandRasterTaskPriority, - 0u)); + TaskGraph::Node(on_demand_raster_task, + RasterWorkerPool::kOnDemandRasterTaskPriority, + 0u)); // Schedule task and wait for task graph runner to finish running it. task_graph_runner->ScheduleTasks(on_demand_task_namespace_, &graph); task_graph_runner->WaitForTasksToFinishRunning(on_demand_task_namespace_); // Collect task now that it has finished running. - internal::Task::Vector completed_tasks; + Task::Vector completed_tasks; task_graph_runner->CollectCompletedTasks(on_demand_task_namespace_, &completed_tasks); DCHECK_EQ(1u, completed_tasks.size()); diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h index a1eacade39..3fbae4a13a 100644 --- a/cc/output/direct_renderer.h +++ b/cc/output/direct_renderer.h @@ -97,7 +97,7 @@ class CC_EXPORT DirectRenderer : public Renderer { void DrawRenderPass(DrawingFrame* frame, const RenderPass* render_pass); bool UseRenderPass(DrawingFrame* frame, const RenderPass* render_pass); - void RunOnDemandRasterTask(internal::Task* on_demand_raster_task); + void RunOnDemandRasterTask(Task* on_demand_raster_task); virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) = 0; virtual bool BindFramebufferToTexture(DrawingFrame* frame, @@ -140,7 +140,7 @@ class CC_EXPORT DirectRenderer : public Renderer { private: gfx::Vector2d enlarge_pass_texture_amount_; - internal::NamespaceToken on_demand_task_namespace_; + NamespaceToken on_demand_task_namespace_; DISALLOW_COPY_AND_ASSIGN(DirectRenderer); }; diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index e05a20d282..51c83dd047 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -79,7 +79,7 @@ class SimpleSwapFence : public ResourceProvider::Fence { bool has_passed_; }; -class OnDemandRasterTaskImpl : public internal::Task { +class OnDemandRasterTaskImpl : public Task { public: OnDemandRasterTaskImpl(PicturePileImpl* picture_pile, SkBitmap* bitmap, @@ -93,7 +93,7 @@ class OnDemandRasterTaskImpl : public internal::Task { DCHECK(bitmap_); } - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { TRACE_EVENT0("cc", "OnDemandRasterTaskImpl::RunOnWorkerThread"); SkCanvas canvas(*bitmap_); @@ -1764,7 +1764,7 @@ void GLRenderer::DrawPictureQuad(const DrawingFrame* frame, } // Create and run on-demand raster task for tile. - scoped_refptr<internal::Task> on_demand_raster_task( + scoped_refptr<Task> on_demand_raster_task( new OnDemandRasterTaskImpl(quad->picture_pile, &on_demand_tile_raster_bitmap_, quad->content_rect, diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 9c52bcb368..3aaa1a1768 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -48,10 +48,10 @@ OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) device_scale_factor_(-1), max_frames_pending_(0), pending_swap_buffers_(0), - needs_begin_impl_frame_(false), - client_ready_for_begin_impl_frame_(true), + needs_begin_frame_(false), + client_ready_for_begin_frame_(true), client_(NULL), - check_for_retroactive_begin_impl_frame_pending_(false), + check_for_retroactive_begin_frame_pending_(false), external_stencil_test_enabled_(false), weak_ptr_factory_(this), gpu_latency_history_(kGpuLatencyHistorySize) {} @@ -61,10 +61,10 @@ OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) device_scale_factor_(-1), max_frames_pending_(0), pending_swap_buffers_(0), - needs_begin_impl_frame_(false), - client_ready_for_begin_impl_frame_(true), + needs_begin_frame_(false), + client_ready_for_begin_frame_(true), client_(NULL), - check_for_retroactive_begin_impl_frame_pending_(false), + check_for_retroactive_begin_frame_pending_(false), external_stencil_test_enabled_(false), weak_ptr_factory_(this), gpu_latency_history_(kGpuLatencyHistorySize) {} @@ -76,15 +76,15 @@ OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider, device_scale_factor_(-1), max_frames_pending_(0), pending_swap_buffers_(0), - needs_begin_impl_frame_(false), - client_ready_for_begin_impl_frame_(true), + needs_begin_frame_(false), + client_ready_for_begin_frame_(true), client_(NULL), - check_for_retroactive_begin_impl_frame_pending_(false), + check_for_retroactive_begin_frame_pending_(false), external_stencil_test_enabled_(false), weak_ptr_factory_(this), gpu_latency_history_(kGpuLatencyHistorySize) {} -void OutputSurface::InitializeBeginImplFrameEmulation( +void OutputSurface::InitializeBeginFrameEmulation( base::SingleThreadTaskRunner* task_runner, bool throttle_frame_production, base::TimeDelta interval) { @@ -133,9 +133,9 @@ void OutputSurface::FrameRateControllerTick(bool throttled, const BeginFrameArgs& args) { DCHECK(frame_rate_controller_); if (throttled) - skipped_begin_impl_frame_args_ = args; + skipped_begin_frame_args_ = args; else - BeginImplFrame(args); + BeginFrame(args); } // Forwarded to OutputSurfaceClient @@ -144,64 +144,65 @@ void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { client_->SetNeedsRedrawRect(damage_rect); } -void OutputSurface::SetNeedsBeginImplFrame(bool enable) { - TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable); - needs_begin_impl_frame_ = enable; - client_ready_for_begin_impl_frame_ = true; +void OutputSurface::SetNeedsBeginFrame(bool enable) { + TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable); + needs_begin_frame_ = enable; + client_ready_for_begin_frame_ = true; if (frame_rate_controller_) { BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable); if (skipped.IsValid()) - skipped_begin_impl_frame_args_ = skipped; + skipped_begin_frame_args_ = skipped; } - if (needs_begin_impl_frame_) - PostCheckForRetroactiveBeginImplFrame(); + if (needs_begin_frame_) + PostCheckForRetroactiveBeginFrame(); } -void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) { - TRACE_EVENT2("cc", "OutputSurface::BeginImplFrame", - "client_ready_for_begin_impl_frame_", - client_ready_for_begin_impl_frame_, - "pending_swap_buffers_", pending_swap_buffers_); - if (!needs_begin_impl_frame_ || !client_ready_for_begin_impl_frame_ || +void OutputSurface::BeginFrame(const BeginFrameArgs& args) { + TRACE_EVENT2("cc", + "OutputSurface::BeginFrame", + "client_ready_for_begin_frame_", + client_ready_for_begin_frame_, + "pending_swap_buffers_", + pending_swap_buffers_); + if (!needs_begin_frame_ || !client_ready_for_begin_frame_ || (pending_swap_buffers_ >= max_frames_pending_ && max_frames_pending_ > 0)) { - skipped_begin_impl_frame_args_ = args; + skipped_begin_frame_args_ = args; } else { - client_ready_for_begin_impl_frame_ = false; - client_->BeginImplFrame(args); - // args might be an alias for skipped_begin_impl_frame_args_. - // Do not reset it before calling BeginImplFrame! - skipped_begin_impl_frame_args_ = BeginFrameArgs(); + client_ready_for_begin_frame_ = false; + client_->BeginFrame(args); + // args might be an alias for skipped_begin_frame_args_. + // Do not reset it before calling BeginFrame! + skipped_begin_frame_args_ = BeginFrameArgs(); } } -base::TimeTicks OutputSurface::RetroactiveBeginImplFrameDeadline() { +base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() { // TODO(brianderson): Remove the alternative deadline once we have better // deadline estimations. base::TimeTicks alternative_deadline = - skipped_begin_impl_frame_args_.frame_time + + skipped_begin_frame_args_.frame_time + BeginFrameArgs::DefaultRetroactiveBeginFramePeriod(); - return std::max(skipped_begin_impl_frame_args_.deadline, - alternative_deadline); + return std::max(skipped_begin_frame_args_.deadline, alternative_deadline); } -void OutputSurface::PostCheckForRetroactiveBeginImplFrame() { - if (!skipped_begin_impl_frame_args_.IsValid() || - check_for_retroactive_begin_impl_frame_pending_) +void OutputSurface::PostCheckForRetroactiveBeginFrame() { + if (!skipped_begin_frame_args_.IsValid() || + check_for_retroactive_begin_frame_pending_) return; base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame, - weak_ptr_factory_.GetWeakPtr())); - check_for_retroactive_begin_impl_frame_pending_ = true; + FROM_HERE, + base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame, + weak_ptr_factory_.GetWeakPtr())); + check_for_retroactive_begin_frame_pending_ = true; } -void OutputSurface::CheckForRetroactiveBeginImplFrame() { - TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame"); - check_for_retroactive_begin_impl_frame_pending_ = false; - if (gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline()) - BeginImplFrame(skipped_begin_impl_frame_args_); +void OutputSurface::CheckForRetroactiveBeginFrame() { + TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame"); + check_for_retroactive_begin_frame_pending_ = false; + if (gfx::FrameTime::Now() < RetroactiveBeginFrameDeadline()) + BeginFrame(skipped_begin_frame_args_); } void OutputSurface::DidSwapBuffers() { @@ -211,7 +212,7 @@ void OutputSurface::DidSwapBuffers() { client_->DidSwapBuffers(); if (frame_rate_controller_) frame_rate_controller_->DidSwapBuffers(); - PostCheckForRetroactiveBeginImplFrame(); + PostCheckForRetroactiveBeginFrame(); } void OutputSurface::OnSwapBuffersComplete() { @@ -221,7 +222,7 @@ void OutputSurface::OnSwapBuffersComplete() { client_->OnSwapBuffersComplete(); if (frame_rate_controller_) frame_rate_controller_->DidSwapBuffersComplete(); - PostCheckForRetroactiveBeginImplFrame(); + PostCheckForRetroactiveBeginFrame(); } void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { @@ -230,9 +231,9 @@ void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { void OutputSurface::DidLoseOutputSurface() { TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); - client_ready_for_begin_impl_frame_ = true; + client_ready_for_begin_frame_ = true; pending_swap_buffers_ = 0; - skipped_begin_impl_frame_args_ = BeginFrameArgs(); + skipped_begin_frame_args_ = BeginFrameArgs(); if (frame_rate_controller_) frame_rate_controller_->SetActive(false); pending_gpu_latency_query_ids_.clear(); diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index 5bec9d1153..a5d4d7bc77 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -69,7 +69,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { int max_frames_pending; bool deferred_gl_initialization; bool draw_and_swap_full_viewport_every_frame; - // This doesn't handle the <webview> case, but once BeginImplFrame is + // This doesn't handle the <webview> case, but once BeginFrame is // supported natively, we shouldn't need adjust_deadline_for_parent. bool adjust_deadline_for_parent; // Whether this output surface renders to the default OpenGL zero @@ -105,10 +105,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { // thread. virtual bool BindToClient(OutputSurfaceClient* client); - void InitializeBeginImplFrameEmulation( - base::SingleThreadTaskRunner* task_runner, - bool throttle_frame_production, - base::TimeDelta interval); + void InitializeBeginFrameEmulation(base::SingleThreadTaskRunner* task_runner, + bool throttle_frame_production, + base::TimeDelta interval); void SetMaxFramesPending(int max_frames_pending); @@ -129,10 +128,10 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { // processing should be stopped, or lowered in priority. virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {} - // Requests a BeginImplFrame notification from the output surface. The + // Requests a BeginFrame notification from the output surface. The // notification will be delivered by calling - // OutputSurfaceClient::BeginImplFrame until the callback is disabled. - virtual void SetNeedsBeginImplFrame(bool enable); + // OutputSurfaceClient::BeginFrame until the callback is disabled. + virtual void SetNeedsBeginFrame(bool enable); bool HasClient() { return !!client_; } @@ -165,7 +164,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { float device_scale_factor_; // The FrameRateController is deprecated. - // Platforms should move to native BeginImplFrames instead. + // Platforms should move to native BeginFrames instead. void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval); virtual void FrameRateControllerTick(bool throttled, @@ -173,17 +172,17 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { scoped_ptr<FrameRateController> frame_rate_controller_; int max_frames_pending_; int pending_swap_buffers_; - bool needs_begin_impl_frame_; - bool client_ready_for_begin_impl_frame_; + bool needs_begin_frame_; + bool client_ready_for_begin_frame_; - // This stores a BeginImplFrame that we couldn't process immediately, + // This stores a BeginFrame that we couldn't process immediately, // but might process retroactively in the near future. - BeginFrameArgs skipped_begin_impl_frame_args_; + BeginFrameArgs skipped_begin_frame_args_; // Forwarded to OutputSurfaceClient but threaded through OutputSurface // first so OutputSurface has a chance to update the FrameRateController void SetNeedsRedrawRect(const gfx::Rect& damage_rect); - void BeginImplFrame(const BeginFrameArgs& args); + void BeginFrame(const BeginFrameArgs& args); void DidSwapBuffers(); void OnSwapBuffersComplete(); void ReclaimResources(const CompositorFrameAck* ack); @@ -195,9 +194,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { bool valid_for_tile_management); // virtual for testing. - virtual base::TimeTicks RetroactiveBeginImplFrameDeadline(); - virtual void PostCheckForRetroactiveBeginImplFrame(); - void CheckForRetroactiveBeginImplFrame(); + virtual base::TimeTicks RetroactiveBeginFrameDeadline(); + virtual void PostCheckForRetroactiveBeginFrame(); + void CheckForRetroactiveBeginFrame(); private: OutputSurfaceClient* client_; @@ -207,9 +206,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { void SetMemoryPolicy(const ManagedMemoryPolicy& policy); void UpdateAndMeasureGpuLatency(); - // check_for_retroactive_begin_impl_frame_pending_ is used to avoid posting - // redundant checks for a retroactive BeginImplFrame. - bool check_for_retroactive_begin_impl_frame_pending_; + // check_for_retroactive_begin_frame_pending_ is used to avoid posting + // redundant checks for a retroactive BeginFrame. + bool check_for_retroactive_begin_frame_pending_; bool external_stencil_test_enabled_; diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index 7e509a8269..08d9b62488 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h @@ -31,7 +31,7 @@ class CC_EXPORT OutputSurfaceClient { scoped_refptr<ContextProvider> offscreen_context_provider) = 0; virtual void ReleaseGL() = 0; virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0; - virtual void BeginImplFrame(const BeginFrameArgs& args) = 0; + virtual void BeginFrame(const BeginFrameArgs& args) = 0; virtual void DidSwapBuffers() = 0; virtual void OnSwapBuffersComplete() = 0; virtual void ReclaimResources(const CompositorFrameAck* ack) = 0; diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index b0220fbcc5..d40feb167d 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -24,18 +24,18 @@ class TestOutputSurface : public OutputSurface { public: explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider) : OutputSurface(context_provider), - retroactive_begin_impl_frame_deadline_enabled_(false), + retroactive_begin_frame_deadline_enabled_(false), override_retroactive_period_(false) {} explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) : OutputSurface(software_device.Pass()), - retroactive_begin_impl_frame_deadline_enabled_(false), + retroactive_begin_frame_deadline_enabled_(false), override_retroactive_period_(false) {} TestOutputSurface(scoped_refptr<ContextProvider> context_provider, scoped_ptr<SoftwareOutputDevice> software_device) : OutputSurface(context_provider, software_device.Pass()), - retroactive_begin_impl_frame_deadline_enabled_(false), + retroactive_begin_frame_deadline_enabled_(false), override_retroactive_period_(false) {} bool InitializeNewContext3d( @@ -51,8 +51,8 @@ class TestOutputSurface : public OutputSurface { CommitVSyncParameters(timebase, interval); } - void BeginImplFrameForTesting() { - OutputSurface::BeginImplFrame(BeginFrameArgs::CreateExpiredForTesting()); + void BeginFrameForTesting() { + OutputSurface::BeginFrame(BeginFrameArgs::CreateExpiredForTesting()); } void DidSwapBuffersForTesting() { @@ -67,34 +67,33 @@ class TestOutputSurface : public OutputSurface { OnSwapBuffersComplete(); } - void EnableRetroactiveBeginImplFrameDeadline( - bool enable, - bool override_retroactive_period, - base::TimeDelta period_override) { - retroactive_begin_impl_frame_deadline_enabled_ = enable; + void EnableRetroactiveBeginFrameDeadline(bool enable, + bool override_retroactive_period, + base::TimeDelta period_override) { + retroactive_begin_frame_deadline_enabled_ = enable; override_retroactive_period_ = override_retroactive_period; retroactive_period_override_ = period_override; } protected: - virtual void PostCheckForRetroactiveBeginImplFrame() OVERRIDE { + virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE { // For testing purposes, we check immediately rather than posting a task. - CheckForRetroactiveBeginImplFrame(); + CheckForRetroactiveBeginFrame(); } - virtual base::TimeTicks RetroactiveBeginImplFrameDeadline() OVERRIDE { - if (retroactive_begin_impl_frame_deadline_enabled_) { + virtual base::TimeTicks RetroactiveBeginFrameDeadline() OVERRIDE { + if (retroactive_begin_frame_deadline_enabled_) { if (override_retroactive_period_) { - return skipped_begin_impl_frame_args_.frame_time + + return skipped_begin_frame_args_.frame_time + retroactive_period_override_; } else { - return OutputSurface::RetroactiveBeginImplFrameDeadline(); + return OutputSurface::RetroactiveBeginFrameDeadline(); } } return base::TimeTicks(); } - bool retroactive_begin_impl_frame_deadline_enabled_; + bool retroactive_begin_frame_deadline_enabled_; bool override_retroactive_period_; base::TimeDelta retroactive_period_override_; }; @@ -221,7 +220,7 @@ TEST_F(OutputSurfaceTestInitializeNewContext3d, ClientDeferredInitializeFails) { InitializeNewContextExpectFail(); } -TEST(OutputSurfaceTest, BeginImplFrameEmulation) { +TEST(OutputSurfaceTest, BeginFrameEmulation) { TestOutputSurface output_surface(TestContextProvider::Create()); EXPECT_FALSE(output_surface.HasClient()); @@ -230,86 +229,84 @@ TEST(OutputSurfaceTest, BeginImplFrameEmulation) { EXPECT_TRUE(output_surface.HasClient()); EXPECT_FALSE(client.deferred_initialize_called()); - // Initialize BeginImplFrame emulation + // Initialize BeginFrame emulation scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; bool throttle_frame_production = true; const base::TimeDelta display_refresh_interval = BeginFrameArgs::DefaultInterval(); - output_surface.InitializeBeginImplFrameEmulation( - task_runner.get(), - throttle_frame_production, - display_refresh_interval); + output_surface.InitializeBeginFrameEmulation( + task_runner.get(), throttle_frame_production, display_refresh_interval); output_surface.SetMaxFramesPending(2); - output_surface.EnableRetroactiveBeginImplFrameDeadline( + output_surface.EnableRetroactiveBeginFrameDeadline( false, false, base::TimeDelta()); - // We should start off with 0 BeginImplFrames - EXPECT_EQ(client.begin_impl_frame_count(), 0); + // We should start off with 0 BeginFrames + EXPECT_EQ(client.begin_frame_count(), 0); EXPECT_EQ(output_surface.pending_swap_buffers(), 0); - // We should not have a pending task until a BeginImplFrame has been + // We should not have a pending task until a BeginFrame has been // requested. EXPECT_FALSE(task_runner->HasPendingTask()); - output_surface.SetNeedsBeginImplFrame(true); + output_surface.SetNeedsBeginFrame(true); EXPECT_TRUE(task_runner->HasPendingTask()); - // BeginImplFrame should be called on the first tick. + // BeginFrame should be called on the first tick. task_runner->RunPendingTasks(); - EXPECT_EQ(client.begin_impl_frame_count(), 1); + EXPECT_EQ(client.begin_frame_count(), 1); EXPECT_EQ(output_surface.pending_swap_buffers(), 0); - // BeginImplFrame should not be called when there is a pending BeginImplFrame. + // BeginFrame should not be called when there is a pending BeginFrame. task_runner->RunPendingTasks(); - EXPECT_EQ(client.begin_impl_frame_count(), 1); + EXPECT_EQ(client.begin_frame_count(), 1); EXPECT_EQ(output_surface.pending_swap_buffers(), 0); - // SetNeedsBeginImplFrame should clear the pending BeginImplFrame after + // SetNeedsBeginFrame should clear the pending BeginFrame after // a SwapBuffers. output_surface.DidSwapBuffersForTesting(); - output_surface.SetNeedsBeginImplFrame(true); - EXPECT_EQ(client.begin_impl_frame_count(), 1); + output_surface.SetNeedsBeginFrame(true); + EXPECT_EQ(client.begin_frame_count(), 1); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); task_runner->RunPendingTasks(); - EXPECT_EQ(client.begin_impl_frame_count(), 2); + EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); - // BeginImplFrame should be throttled by pending swap buffers. + // BeginFrame should be throttled by pending swap buffers. output_surface.DidSwapBuffersForTesting(); - output_surface.SetNeedsBeginImplFrame(true); - EXPECT_EQ(client.begin_impl_frame_count(), 2); + output_surface.SetNeedsBeginFrame(true); + EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); task_runner->RunPendingTasks(); - EXPECT_EQ(client.begin_impl_frame_count(), 2); + EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); - // SwapAck should decrement pending swap buffers and unblock BeginImplFrame + // SwapAck should decrement pending swap buffers and unblock BeginFrame // again. output_surface.OnSwapBuffersCompleteForTesting(); - EXPECT_EQ(client.begin_impl_frame_count(), 2); + EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); task_runner->RunPendingTasks(); - EXPECT_EQ(client.begin_impl_frame_count(), 3); + EXPECT_EQ(client.begin_frame_count(), 3); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); - // Calling SetNeedsBeginImplFrame again indicates a swap did not occur but - // the client still wants another BeginImplFrame. - output_surface.SetNeedsBeginImplFrame(true); + // Calling SetNeedsBeginFrame again indicates a swap did not occur but + // the client still wants another BeginFrame. + output_surface.SetNeedsBeginFrame(true); task_runner->RunPendingTasks(); - EXPECT_EQ(client.begin_impl_frame_count(), 4); + EXPECT_EQ(client.begin_frame_count(), 4); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); - // Disabling SetNeedsBeginImplFrame should prevent further BeginImplFrames. - output_surface.SetNeedsBeginImplFrame(false); + // Disabling SetNeedsBeginFrame should prevent further BeginFrames. + output_surface.SetNeedsBeginFrame(false); task_runner->RunPendingTasks(); EXPECT_FALSE(task_runner->HasPendingTask()); - EXPECT_EQ(client.begin_impl_frame_count(), 4); + EXPECT_EQ(client.begin_frame_count(), 4); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); } -TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginImplFrames) { +TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) { TestOutputSurface output_surface(TestContextProvider::Create()); EXPECT_FALSE(output_surface.HasClient()); @@ -319,48 +316,47 @@ TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginImplFrames) { EXPECT_FALSE(client.deferred_initialize_called()); output_surface.SetMaxFramesPending(2); - output_surface.EnableRetroactiveBeginImplFrameDeadline( + output_surface.EnableRetroactiveBeginFrameDeadline( true, false, base::TimeDelta()); - // Optimistically injected BeginImplFrames should be throttled if - // SetNeedsBeginImplFrame is false... - output_surface.SetNeedsBeginImplFrame(false); - output_surface.BeginImplFrameForTesting(); - EXPECT_EQ(client.begin_impl_frame_count(), 0); - // ...and retroactively triggered by a SetNeedsBeginImplFrame. - output_surface.SetNeedsBeginImplFrame(true); - EXPECT_EQ(client.begin_impl_frame_count(), 1); - - // Optimistically injected BeginImplFrames should be throttled by pending - // BeginImplFrames... - output_surface.BeginImplFrameForTesting(); - EXPECT_EQ(client.begin_impl_frame_count(), 1); - // ...and retroactively triggered by a SetNeedsBeginImplFrame. - output_surface.SetNeedsBeginImplFrame(true); - EXPECT_EQ(client.begin_impl_frame_count(), 2); + // Optimistically injected BeginFrames should be throttled if + // SetNeedsBeginFrame is false... + output_surface.SetNeedsBeginFrame(false); + output_surface.BeginFrameForTesting(); + EXPECT_EQ(client.begin_frame_count(), 0); + // ...and retroactively triggered by a SetNeedsBeginFrame. + output_surface.SetNeedsBeginFrame(true); + EXPECT_EQ(client.begin_frame_count(), 1); + + // Optimistically injected BeginFrames should be throttled by pending + // BeginFrames... + output_surface.BeginFrameForTesting(); + EXPECT_EQ(client.begin_frame_count(), 1); + // ...and retroactively triggered by a SetNeedsBeginFrame. + output_surface.SetNeedsBeginFrame(true); + EXPECT_EQ(client.begin_frame_count(), 2); // ...or retroactively triggered by a Swap. - output_surface.BeginImplFrameForTesting(); - EXPECT_EQ(client.begin_impl_frame_count(), 2); + output_surface.BeginFrameForTesting(); + EXPECT_EQ(client.begin_frame_count(), 2); output_surface.DidSwapBuffersForTesting(); - output_surface.SetNeedsBeginImplFrame(true); - EXPECT_EQ(client.begin_impl_frame_count(), 3); + output_surface.SetNeedsBeginFrame(true); + EXPECT_EQ(client.begin_frame_count(), 3); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); - // Optimistically injected BeginImplFrames should be by throttled by pending + // Optimistically injected BeginFrames should be by throttled by pending // swap buffers... output_surface.DidSwapBuffersForTesting(); - output_surface.SetNeedsBeginImplFrame(true); - EXPECT_EQ(client.begin_impl_frame_count(), 3); + output_surface.SetNeedsBeginFrame(true); + EXPECT_EQ(client.begin_frame_count(), 3); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); - output_surface.BeginImplFrameForTesting(); - EXPECT_EQ(client.begin_impl_frame_count(), 3); + output_surface.BeginFrameForTesting(); + EXPECT_EQ(client.begin_frame_count(), 3); // ...and retroactively triggered by OnSwapBuffersComplete output_surface.OnSwapBuffersCompleteForTesting(); - EXPECT_EQ(client.begin_impl_frame_count(), 4); + EXPECT_EQ(client.begin_frame_count(), 4); } -TEST(OutputSurfaceTest, - RetroactiveBeginImplFrameDoesNotDoubleTickWhenEmulating) { +TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); @@ -374,16 +370,14 @@ TEST(OutputSurfaceTest, base::TimeDelta big_interval = base::TimeDelta::FromSeconds(10); - // Initialize BeginImplFrame emulation + // Initialize BeginFrame emulation scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; bool throttle_frame_production = true; const base::TimeDelta display_refresh_interval = big_interval; - output_surface.InitializeBeginImplFrameEmulation( - task_runner.get(), - throttle_frame_production, - display_refresh_interval); + output_surface.InitializeBeginFrameEmulation( + task_runner.get(), throttle_frame_production, display_refresh_interval); // We need to subtract an epsilon from Now() because some platforms have // a slow clock. @@ -391,31 +385,30 @@ TEST(OutputSurfaceTest, gfx::FrameTime::Now() - base::TimeDelta::FromSeconds(1), big_interval); output_surface.SetMaxFramesPending(2); - output_surface.EnableRetroactiveBeginImplFrameDeadline( - true, true, big_interval); + output_surface.EnableRetroactiveBeginFrameDeadline(true, true, big_interval); - // We should start off with 0 BeginImplFrames - EXPECT_EQ(client.begin_impl_frame_count(), 0); + // We should start off with 0 BeginFrames + EXPECT_EQ(client.begin_frame_count(), 0); EXPECT_EQ(output_surface.pending_swap_buffers(), 0); - // The first SetNeedsBeginImplFrame(true) should start a retroactive - // BeginImplFrame. + // The first SetNeedsBeginFrame(true) should start a retroactive + // BeginFrame. EXPECT_FALSE(task_runner->HasPendingTask()); - output_surface.SetNeedsBeginImplFrame(true); + output_surface.SetNeedsBeginFrame(true); EXPECT_TRUE(task_runner->HasPendingTask()); EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2); - EXPECT_EQ(client.begin_impl_frame_count(), 1); + EXPECT_EQ(client.begin_frame_count(), 1); - output_surface.SetNeedsBeginImplFrame(false); + output_surface.SetNeedsBeginFrame(false); EXPECT_TRUE(task_runner->HasPendingTask()); - EXPECT_EQ(client.begin_impl_frame_count(), 1); + EXPECT_EQ(client.begin_frame_count(), 1); - // The second SetNeedBeginImplFrame(true) should not retroactively start a - // BeginImplFrame if the timestamp would be the same as the previous - // BeginImplFrame. - output_surface.SetNeedsBeginImplFrame(true); + // The second SetNeedBeginFrame(true) should not retroactively start a + // BeginFrame if the timestamp would be the same as the previous + // BeginFrame. + output_surface.SetNeedsBeginFrame(true); EXPECT_TRUE(task_runner->HasPendingTask()); - EXPECT_EQ(client.begin_impl_frame_count(), 1); + EXPECT_EQ(client.begin_frame_count(), 1); } TEST(OutputSurfaceTest, MemoryAllocation) { diff --git a/cc/output/render_surface_filters.cc b/cc/output/render_surface_filters.cc index bc13b5eae7..ca97e13360 100644 --- a/cc/output/render_surface_filters.cc +++ b/cc/output/render_surface_filters.cc @@ -151,7 +151,7 @@ skia::RefPtr<SkImageFilter> CreateMatrixImageFilter( const SkScalar matrix[20], const skia::RefPtr<SkImageFilter>& input) { skia::RefPtr<SkColorFilter> color_filter = - skia::AdoptRef(new SkColorMatrixFilter(matrix)); + skia::AdoptRef(SkColorMatrixFilter::Create(matrix)); return skia::AdoptRef( SkColorFilterImageFilter::Create(color_filter.get(), input.get())); } @@ -199,11 +199,11 @@ skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( image_filter = CreateMatrixImageFilter(matrix, image_filter); break; case FilterOperation::BLUR: - image_filter = skia::AdoptRef(new SkBlurImageFilter( + image_filter = skia::AdoptRef(SkBlurImageFilter::Create( op.amount(), op.amount(), image_filter.get())); break; case FilterOperation::DROP_SHADOW: - image_filter = skia::AdoptRef(new SkDropShadowImageFilter( + image_filter = skia::AdoptRef(SkDropShadowImageFilter::Create( SkIntToScalar(op.drop_shadow_offset().x()), SkIntToScalar(op.drop_shadow_offset().y()), SkIntToScalar(op.amount()), @@ -214,8 +214,8 @@ skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( image_filter = CreateMatrixImageFilter(op.matrix(), image_filter); break; case FilterOperation::ZOOM: { - skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( - new SkMagnifierImageFilter( + skia::RefPtr<SkImageFilter> zoom_filter = + skia::AdoptRef(SkMagnifierImageFilter::Create( SkRect::MakeXYWH( (size.width() - (size.width() / op.amount())) / 2.f, (size.height() - (size.height() / op.amount())) / 2.f, @@ -226,7 +226,7 @@ skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( // TODO(ajuma): When there's a 1-input version of // SkMagnifierImageFilter, use that to handle the input filter // instead of using an SkComposeImageFilter. - image_filter = skia::AdoptRef(new SkComposeImageFilter( + image_filter = skia::AdoptRef(SkComposeImageFilter::Create( zoom_filter.get(), image_filter.get())); } else { image_filter = zoom_filter; @@ -253,7 +253,7 @@ skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( !op.image_filter()->getInput(0)) { image_filter = CreateMatrixImageFilter(matrix, image_filter); } else if (image_filter) { - image_filter = skia::AdoptRef(new SkComposeImageFilter( + image_filter = skia::AdoptRef(SkComposeImageFilter::Create( op.image_filter().get(), image_filter.get())); } else { image_filter = op.image_filter(); diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 86f447e035..fb24e44308 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -37,7 +37,7 @@ namespace cc { namespace { -class OnDemandRasterTaskImpl : public internal::Task { +class OnDemandRasterTaskImpl : public Task { public: OnDemandRasterTaskImpl(PicturePileImpl* picture_pile, SkCanvas* canvas, @@ -51,7 +51,7 @@ class OnDemandRasterTaskImpl : public internal::Task { DCHECK(canvas_); } - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { TRACE_EVENT0("cc", "OnDemandRasterTaskImpl::RunOnWorkerThread"); @@ -391,7 +391,7 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, "SoftwareRenderer::DrawPictureQuad"); // Create and run on-demand raster task for tile. - scoped_refptr<internal::Task> on_demand_raster_task( + scoped_refptr<Task> on_demand_raster_task( new OnDemandRasterTaskImpl(quad->picture_pile, current_canvas_, quad->content_rect, diff --git a/cc/resources/bitmap_content_layer_updater.cc b/cc/resources/bitmap_content_layer_updater.cc index a5b9f122e3..fff62cf0ac 100644 --- a/cc/resources/bitmap_content_layer_updater.cc +++ b/cc/resources/bitmap_content_layer_updater.cc @@ -64,12 +64,13 @@ void BitmapContentLayerUpdater::PrepareToUpdate( devtools_instrumentation::ScopedLayerTask paint_setup( devtools_instrumentation::kPaintSetup, layer_id_); canvas_size_ = content_rect.size(); - bitmap_backing_.allocN32Pixels( + bool alloc = bitmap_backing_.allocN32Pixels( canvas_size_.width(), canvas_size_.height(), layer_is_opaque_); + // TODO(danak): Remove when skia does the check for us: crbug.com/360384 + CHECK(alloc); canvas_ = skia::AdoptRef(new SkCanvas(bitmap_backing_)); - SkISize size = canvas_->getBaseLayerSize(); - CHECK_EQ(content_rect.width(), size.width()); - CHECK_EQ(content_rect.height(), size.height()); + DCHECK_EQ(content_rect.width(), canvas_->getBaseLayerSize().width()); + DCHECK_EQ(content_rect.height(), canvas_->getBaseLayerSize().height()); } base::TimeTicks start_time = diff --git a/cc/resources/content_layer_updater.cc b/cc/resources/content_layer_updater.cc index 6de0d73849..249a6e92cd 100644 --- a/cc/resources/content_layer_updater.cc +++ b/cc/resources/content_layer_updater.cc @@ -47,9 +47,8 @@ void ContentLayerUpdater::PaintContents(SkCanvas* canvas, SkFloatToScalar(-content_rect.y())); // The |canvas| backing should be sized to hold the |content_rect|. - SkISize size = canvas->getBaseLayerSize(); - CHECK_EQ(content_rect.width(), size.width()); - CHECK_EQ(content_rect.height(), size.height()); + DCHECK_EQ(content_rect.width(), canvas->getBaseLayerSize().width()); + DCHECK_EQ(content_rect.height(), canvas->getBaseLayerSize().height()); gfx::Rect layer_rect = content_rect; if (contents_width_scale != 1.f || contents_height_scale != 1.f) { diff --git a/cc/resources/direct_raster_worker_pool.cc b/cc/resources/direct_raster_worker_pool.cc index abe73daa3d..bf7d7a272e 100644 --- a/cc/resources/direct_raster_worker_pool.cc +++ b/cc/resources/direct_raster_worker_pool.cc @@ -14,11 +14,11 @@ namespace cc { // static -scoped_ptr<DirectRasterWorkerPool> DirectRasterWorkerPool::Create( +scoped_ptr<RasterWorkerPool> DirectRasterWorkerPool::Create( base::SequencedTaskRunner* task_runner, ResourceProvider* resource_provider, ContextProvider* context_provider) { - return make_scoped_ptr(new DirectRasterWorkerPool( + return make_scoped_ptr<RasterWorkerPool>(new DirectRasterWorkerPool( task_runner, resource_provider, context_provider)); } @@ -39,7 +39,9 @@ DirectRasterWorkerPool::~DirectRasterWorkerPool() { DCHECK_EQ(0u, completed_tasks_.size()); } -void DirectRasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { +Rasterizer* DirectRasterWorkerPool::AsRasterizer() { return this; } + +void DirectRasterWorkerPool::SetClient(RasterizerClient* client) { client_ = client; } @@ -58,7 +60,7 @@ void DirectRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { // Cancel existing OnRasterFinished callbacks. raster_finished_weak_ptr_factory_.InvalidateWeakPtrs(); - scoped_refptr<internal::WorkerPoolTask> + scoped_refptr<RasterizerTask> new_raster_required_for_activation_finished_task( CreateRasterRequiredForActivationFinishedTask( queue->required_for_activation_count, @@ -66,7 +68,7 @@ void DirectRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { base::Bind(&DirectRasterWorkerPool:: OnRasterRequiredForActivationFinished, raster_finished_weak_ptr_factory_.GetWeakPtr()))); - scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task( + scoped_refptr<RasterizerTask> new_raster_finished_task( CreateRasterFinishedTask( task_runner_.get(), base::Bind(&DirectRasterWorkerPool::OnRasterFinished, @@ -81,7 +83,7 @@ void DirectRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { raster_tasks_.items.begin(); it != raster_tasks_.items.end(); ++it) { - internal::RasterWorkerPoolTask* task = it->task; + RasterTask* task = it->task; if (std::find_if(queue->items.begin(), queue->items.end(), @@ -100,38 +102,25 @@ void DirectRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { new_raster_required_for_activation_finished_task; } -unsigned DirectRasterWorkerPool::GetResourceTarget() const { - return GL_TEXTURE_2D; -} - -ResourceFormat DirectRasterWorkerPool::GetResourceFormat() const { - return resource_provider_->best_texture_format(); -} - void DirectRasterWorkerPool::CheckForCompletedTasks() { TRACE_EVENT0("cc", "DirectRasterWorkerPool::CheckForCompletedTasks"); - for (internal::WorkerPoolTask::Vector::const_iterator it = - completed_tasks_.begin(); + for (RasterizerTask::Vector::const_iterator it = completed_tasks_.begin(); it != completed_tasks_.end(); ++it) { - internal::WorkerPoolTask* task = it->get(); + RasterizerTask* task = it->get(); task->RunReplyOnOriginThread(); } completed_tasks_.clear(); } -SkCanvas* DirectRasterWorkerPool::AcquireCanvasForRaster( - internal::WorkerPoolTask* task, - const Resource* resource) { - return resource_provider_->MapDirectRasterBuffer(resource->id()); +SkCanvas* DirectRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) { + return resource_provider_->MapDirectRasterBuffer(task->resource()->id()); } -void DirectRasterWorkerPool::ReleaseCanvasForRaster( - internal::WorkerPoolTask* task, - const Resource* resource) { - resource_provider_->UnmapDirectRasterBuffer(resource->id()); +void DirectRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) { + resource_provider_->UnmapDirectRasterBuffer(task->resource()->id()); } void DirectRasterWorkerPool::OnRasterFinished() { @@ -186,15 +175,15 @@ void DirectRasterWorkerPool::RunTasksOnOriginThread() { raster_tasks_.items.begin(); it != raster_tasks_.items.end(); ++it) { - internal::RasterWorkerPoolTask* task = it->task; + RasterTask* task = it->task; DCHECK(!task->HasCompleted()); // First need to run all dependencies. - for (internal::WorkerPoolTask::Vector::const_iterator it = + for (ImageDecodeTask::Vector::const_iterator it = task->dependencies().begin(); it != task->dependencies().end(); ++it) { - internal::WorkerPoolTask* dependency = it->get(); + ImageDecodeTask* dependency = it->get(); if (dependency->HasCompleted()) continue; @@ -217,8 +206,7 @@ void DirectRasterWorkerPool::RunTasksOnOriginThread() { RunTaskOnOriginThread(raster_finished_task_.get()); } -void DirectRasterWorkerPool::RunTaskOnOriginThread( - internal::WorkerPoolTask* task) { +void DirectRasterWorkerPool::RunTaskOnOriginThread(RasterizerTask* task) { task->WillSchedule(); task->ScheduleOnOriginThread(this); task->DidSchedule(); diff --git a/cc/resources/direct_raster_worker_pool.h b/cc/resources/direct_raster_worker_pool.h index 74013b681d..f2c927b585 100644 --- a/cc/resources/direct_raster_worker_pool.h +++ b/cc/resources/direct_raster_worker_pool.h @@ -7,49 +7,49 @@ #include "base/memory/weak_ptr.h" #include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer.h" namespace cc { class ContextProvider; class ResourceProvider; class CC_EXPORT DirectRasterWorkerPool : public RasterWorkerPool, - public internal::WorkerPoolTaskClient { + public Rasterizer, + public RasterizerTaskClient { public: virtual ~DirectRasterWorkerPool(); - static scoped_ptr<DirectRasterWorkerPool> Create( + static scoped_ptr<RasterWorkerPool> Create( base::SequencedTaskRunner* task_runner, ResourceProvider* resource_provider, ContextProvider* context_provider); // Overridden from RasterWorkerPool: - virtual void SetClient(RasterWorkerPoolClient* client) OVERRIDE; + virtual Rasterizer* AsRasterizer() OVERRIDE; + + // Overridden from Rasterizer: + virtual void SetClient(RasterizerClient* client) OVERRIDE; virtual void Shutdown() OVERRIDE {} virtual void ScheduleTasks(RasterTaskQueue* queue) OVERRIDE; - virtual unsigned GetResourceTarget() const OVERRIDE; - virtual ResourceFormat GetResourceFormat() const OVERRIDE; virtual void CheckForCompletedTasks() OVERRIDE; - // Overridden from internal::WorkerPoolTaskClient: - virtual SkCanvas* AcquireCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE; - virtual void ReleaseCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE; + // Overridden from RasterizerTaskClient: + virtual SkCanvas* AcquireCanvasForRaster(RasterTask* task) OVERRIDE; + virtual void ReleaseCanvasForRaster(RasterTask* task) OVERRIDE; - protected: + private: DirectRasterWorkerPool(base::SequencedTaskRunner* task_runner, ResourceProvider* resource_provider, ContextProvider* context_provider); - private: void OnRasterFinished(); void OnRasterRequiredForActivationFinished(); void ScheduleRunTasksOnOriginThread(); void RunTasksOnOriginThread(); - void RunTaskOnOriginThread(internal::WorkerPoolTask* task); + void RunTaskOnOriginThread(RasterizerTask* task); scoped_refptr<base::SequencedTaskRunner> task_runner_; - RasterWorkerPoolClient* client_; + RasterizerClient* client_; ResourceProvider* resource_provider_; ContextProvider* context_provider_; @@ -63,11 +63,10 @@ class CC_EXPORT DirectRasterWorkerPool : public RasterWorkerPool, base::WeakPtrFactory<DirectRasterWorkerPool> raster_finished_weak_ptr_factory_; - scoped_refptr<internal::WorkerPoolTask> raster_finished_task_; - scoped_refptr<internal::WorkerPoolTask> - raster_required_for_activation_finished_task_; + scoped_refptr<RasterizerTask> raster_finished_task_; + scoped_refptr<RasterizerTask> raster_required_for_activation_finished_task_; - internal::WorkerPoolTask::Vector completed_tasks_; + RasterizerTask::Vector completed_tasks_; base::WeakPtrFactory<DirectRasterWorkerPool> weak_ptr_factory_; diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc index 6adf02b361..007c1ed83f 100644 --- a/cc/resources/image_raster_worker_pool.cc +++ b/cc/resources/image_raster_worker_pool.cc @@ -11,38 +11,38 @@ namespace cc { // static -scoped_ptr<ImageRasterWorkerPool> ImageRasterWorkerPool::Create( +scoped_ptr<RasterWorkerPool> ImageRasterWorkerPool::Create( base::SequencedTaskRunner* task_runner, - ResourceProvider* resource_provider, - unsigned texture_target) { - return make_scoped_ptr(new ImageRasterWorkerPool( - task_runner, GetTaskGraphRunner(), resource_provider, texture_target)); + TaskGraphRunner* task_graph_runner, + ResourceProvider* resource_provider) { + return make_scoped_ptr<RasterWorkerPool>(new ImageRasterWorkerPool( + task_runner, task_graph_runner, resource_provider)); } ImageRasterWorkerPool::ImageRasterWorkerPool( base::SequencedTaskRunner* task_runner, - internal::TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider, - unsigned texture_target) + TaskGraphRunner* task_graph_runner, + ResourceProvider* resource_provider) : task_runner_(task_runner), task_graph_runner_(task_graph_runner), namespace_token_(task_graph_runner->GetNamespaceToken()), resource_provider_(resource_provider), - texture_target_(texture_target), raster_tasks_pending_(false), raster_tasks_required_for_activation_pending_(false), raster_finished_weak_ptr_factory_(this) {} ImageRasterWorkerPool::~ImageRasterWorkerPool() {} -void ImageRasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { +Rasterizer* ImageRasterWorkerPool::AsRasterizer() { return this; } + +void ImageRasterWorkerPool::SetClient(RasterizerClient* client) { client_ = client; } void ImageRasterWorkerPool::Shutdown() { TRACE_EVENT0("cc", "ImageRasterWorkerPool::Shutdown"); - internal::TaskGraph empty; + TaskGraph empty; task_graph_runner_->ScheduleTasks(namespace_token_, &empty); task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); } @@ -69,7 +69,7 @@ void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { // Cancel existing OnRasterFinished callbacks. raster_finished_weak_ptr_factory_.InvalidateWeakPtrs(); - scoped_refptr<internal::WorkerPoolTask> + scoped_refptr<RasterizerTask> new_raster_required_for_activation_finished_task( CreateRasterRequiredForActivationFinishedTask( queue->required_for_activation_count, @@ -77,7 +77,7 @@ void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { base::Bind( &ImageRasterWorkerPool::OnRasterRequiredForActivationFinished, raster_finished_weak_ptr_factory_.GetWeakPtr()))); - scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task( + scoped_refptr<RasterizerTask> new_raster_finished_task( CreateRasterFinishedTask( task_runner_.get(), base::Bind(&ImageRasterWorkerPool::OnRasterFinished, @@ -87,18 +87,18 @@ void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { it != queue->items.end(); ++it) { const RasterTaskQueue::Item& item = *it; - internal::RasterWorkerPoolTask* task = item.task; + RasterTask* task = item.task; DCHECK(!task->HasCompleted()); if (item.required_for_activation) { - graph_.edges.push_back(internal::TaskGraph::Edge( + graph_.edges.push_back(TaskGraph::Edge( task, new_raster_required_for_activation_finished_task.get())); } InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); graph_.edges.push_back( - internal::TaskGraph::Edge(task, new_raster_finished_task.get())); + TaskGraph::Edge(task, new_raster_finished_task.get())); } InsertNodeForTask(&graph_, @@ -126,24 +126,15 @@ void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { TracedValue::FromValue(StateAsValue().release())); } -unsigned ImageRasterWorkerPool::GetResourceTarget() const { - return texture_target_; -} - -ResourceFormat ImageRasterWorkerPool::GetResourceFormat() const { - return resource_provider_->best_texture_format(); -} - void ImageRasterWorkerPool::CheckForCompletedTasks() { TRACE_EVENT0("cc", "ImageRasterWorkerPool::CheckForCompletedTasks"); task_graph_runner_->CollectCompletedTasks(namespace_token_, &completed_tasks_); - for (internal::Task::Vector::const_iterator it = completed_tasks_.begin(); + for (Task::Vector::const_iterator it = completed_tasks_.begin(); it != completed_tasks_.end(); ++it) { - internal::WorkerPoolTask* task = - static_cast<internal::WorkerPoolTask*>(it->get()); + RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); task->WillComplete(); task->CompleteOnOriginThread(this); @@ -154,16 +145,17 @@ void ImageRasterWorkerPool::CheckForCompletedTasks() { completed_tasks_.clear(); } -SkCanvas* ImageRasterWorkerPool::AcquireCanvasForRaster( - internal::WorkerPoolTask* task, - const Resource* resource) { - return resource_provider_->MapImageRasterBuffer(resource->id()); +SkCanvas* ImageRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) { + return resource_provider_->MapImageRasterBuffer(task->resource()->id()); } -void ImageRasterWorkerPool::ReleaseCanvasForRaster( - internal::WorkerPoolTask* task, - const Resource* resource) { - resource_provider_->UnmapImageRasterBuffer(resource->id()); +void ImageRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) { + resource_provider_->UnmapImageRasterBuffer(task->resource()->id()); + + // Map/UnmapImageRasterBuffer provides direct access to the memory used by the + // GPU. Read lock fences are required to ensure that we're not trying to map a + // resource that is currently in-use by the GPU. + resource_provider_->EnableReadLockFences(task->resource()->id(), true); } void ImageRasterWorkerPool::OnRasterFinished() { diff --git a/cc/resources/image_raster_worker_pool.h b/cc/resources/image_raster_worker_pool.h index 7720d4bb72..2e11a220f4 100644 --- a/cc/resources/image_raster_worker_pool.h +++ b/cc/resources/image_raster_worker_pool.h @@ -8,39 +8,39 @@ #include "base/memory/weak_ptr.h" #include "base/values.h" #include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer.h" namespace cc { class ResourceProvider; class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool, - public internal::WorkerPoolTaskClient { + public Rasterizer, + public RasterizerTaskClient { public: virtual ~ImageRasterWorkerPool(); - static scoped_ptr<ImageRasterWorkerPool> Create( + static scoped_ptr<RasterWorkerPool> Create( base::SequencedTaskRunner* task_runner, - ResourceProvider* resource_provider, - unsigned texture_target); + TaskGraphRunner* task_graph_runner, + ResourceProvider* resource_provider); // Overridden from RasterWorkerPool: - virtual void SetClient(RasterWorkerPoolClient* client) OVERRIDE; + virtual Rasterizer* AsRasterizer() OVERRIDE; + + // Overridden from Rasterizer: + virtual void SetClient(RasterizerClient* client) OVERRIDE; virtual void Shutdown() OVERRIDE; virtual void ScheduleTasks(RasterTaskQueue* queue) OVERRIDE; - virtual unsigned GetResourceTarget() const OVERRIDE; - virtual ResourceFormat GetResourceFormat() const OVERRIDE; virtual void CheckForCompletedTasks() OVERRIDE; - // Overridden from internal::WorkerPoolTaskClient: - virtual SkCanvas* AcquireCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE; - virtual void ReleaseCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE; + // Overridden from RasterizerTaskClient: + virtual SkCanvas* AcquireCanvasForRaster(RasterTask* task) OVERRIDE; + virtual void ReleaseCanvasForRaster(RasterTask* task) OVERRIDE; protected: ImageRasterWorkerPool(base::SequencedTaskRunner* task_runner, - internal::TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider, - unsigned texture_target); + TaskGraphRunner* task_graph_runner, + ResourceProvider* resource_provider); private: void OnRasterFinished(); @@ -48,25 +48,23 @@ class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool, scoped_ptr<base::Value> StateAsValue() const; scoped_refptr<base::SequencedTaskRunner> task_runner_; - internal::TaskGraphRunner* task_graph_runner_; - const internal::NamespaceToken namespace_token_; - RasterWorkerPoolClient* client_; + TaskGraphRunner* task_graph_runner_; + const NamespaceToken namespace_token_; + RasterizerClient* client_; ResourceProvider* resource_provider_; - const unsigned texture_target_; bool raster_tasks_pending_; bool raster_tasks_required_for_activation_pending_; base::WeakPtrFactory<ImageRasterWorkerPool> raster_finished_weak_ptr_factory_; - scoped_refptr<internal::WorkerPoolTask> raster_finished_task_; - scoped_refptr<internal::WorkerPoolTask> - raster_required_for_activation_finished_task_; + scoped_refptr<RasterizerTask> raster_finished_task_; + scoped_refptr<RasterizerTask> raster_required_for_activation_finished_task_; // Task graph used when scheduling tasks and vector used to gather // completed tasks. - internal::TaskGraph graph_; - internal::Task::Vector completed_tasks_; + TaskGraph graph_; + Task::Vector completed_tasks_; DISALLOW_COPY_AND_ASSIGN(ImageRasterWorkerPool); }; diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h index 3423737348..b3d80bb3aa 100644 --- a/cc/resources/managed_tile_state.h +++ b/cc/resources/managed_tile_state.h @@ -8,7 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "cc/resources/platform_color.h" #include "cc/resources/raster_mode.h" -#include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer.h" #include "cc/resources/resource_pool.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_resource.h" @@ -102,7 +102,7 @@ class CC_EXPORT ManagedTileState { SkColor solid_color_; bool has_text_; scoped_ptr<ScopedResource> resource_; - scoped_refptr<internal::RasterWorkerPoolTask> raster_task_; + scoped_refptr<RasterTask> raster_task_; }; ManagedTileState(); diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc index 8080d22cb4..93b59aea74 100644 --- a/cc/resources/picture.cc +++ b/cc/resources/picture.cc @@ -197,6 +197,19 @@ Picture* Picture::GetCloneForDrawingOnThread(unsigned thread_index) { return thread_index == clones_.size() ? this : clones_[thread_index].get(); } +bool Picture::IsSuitableForGpuRasterization() const { + DCHECK(picture_); + + // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. + // Ideally this GrContext should be the same as that for rasterizing this + // picture. But we are on the main thread while the rasterization context + // may be on the compositor or raster thread. + // SkPicture::suitableForGpuRasterization is not implemented yet. + // Pass a NULL context for now and discuss with skia folks if the context + // is really needed. + return picture_->suitableForGpuRasterization(NULL); +} + void Picture::CloneForDrawing(int num_threads) { TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); diff --git a/cc/resources/picture.h b/cc/resources/picture.h index aef6b95f9c..d32b8435af 100644 --- a/cc/resources/picture.h +++ b/cc/resources/picture.h @@ -70,6 +70,8 @@ class CC_EXPORT Picture // Has Record() been called yet? bool HasRecording() const { return picture_.get() != NULL; } + bool IsSuitableForGpuRasterization() const; + // Apply this scale and raster the negated region into the canvas. See comment // in PicturePileImpl::RasterCommon for explanation on negated content region. int Raster(SkCanvas* canvas, diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 955c097e42..26e27da748 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -22,12 +22,15 @@ namespace { class TileEvictionOrder { public: - explicit TileEvictionOrder(WhichTree tree) : tree_(tree) {} + explicit TileEvictionOrder(TreePriority tree_priority) + : tree_priority_(tree_priority) {} ~TileEvictionOrder() {} bool operator()(const Tile* a, const Tile* b) { - const TilePriority& a_priority = a->priority(tree_); - const TilePriority& b_priority = b->priority(tree_); + const TilePriority& a_priority = + a->priority_for_tree_priority(tree_priority_); + const TilePriority& b_priority = + b->priority_for_tree_priority(tree_priority_); if (a_priority.priority_bin == b_priority.priority_bin && a->required_for_activation() != b->required_for_activation()) { @@ -37,7 +40,7 @@ class TileEvictionOrder { } private: - WhichTree tree_; + TreePriority tree_priority_; }; } // namespace @@ -59,7 +62,8 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale, client_(client), tiling_data_(gfx::Size(), gfx::Size(), true), last_impl_frame_time_in_seconds_(0.0), - eviction_tiles_cache_valid_(false) { + eviction_tiles_cache_valid_(false), + eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { gfx::Size content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); gfx::Size tile_size = client_->CalculateTileSize(content_bounds); @@ -768,8 +772,10 @@ gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( return result; } -void PictureLayerTiling::UpdateEvictionCacheIfNeeded(WhichTree tree) { - if (eviction_tiles_cache_valid_) +void PictureLayerTiling::UpdateEvictionCacheIfNeeded( + TreePriority tree_priority) { + if (eviction_tiles_cache_valid_ && + eviction_cache_tree_priority_ == tree_priority) return; eviction_tiles_cache_.clear(); @@ -782,8 +788,9 @@ void PictureLayerTiling::UpdateEvictionCacheIfNeeded(WhichTree tree) { std::sort(eviction_tiles_cache_.begin(), eviction_tiles_cache_.end(), - TileEvictionOrder(tree)); + TileEvictionOrder(tree_priority)); eviction_tiles_cache_valid_ = true; + eviction_cache_tree_priority_ = tree_priority; } PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() @@ -886,8 +893,8 @@ PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( PictureLayerTiling* tiling, - WhichTree tree) - : is_valid_(false), tiling_(tiling), tree_(tree) {} + TreePriority tree_priority) + : is_valid_(false), tiling_(tiling), tree_priority_(tree_priority) {} PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() {} @@ -922,7 +929,7 @@ void PictureLayerTiling::TilingEvictionTileIterator::Initialize() { if (!tiling_) return; - tiling_->UpdateEvictionCacheIfNeeded(tree_); + tiling_->UpdateEvictionCacheIfNeeded(tree_priority_); tile_iterator_ = tiling_->eviction_tiles_cache_.begin(); is_valid_ = true; if (tile_iterator_ != tiling_->eviction_tiles_cache_.end() && diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index fe6fb7d3ee..bd442de656 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -92,7 +92,8 @@ class CC_EXPORT PictureLayerTiling { class CC_EXPORT TilingEvictionTileIterator { public: TilingEvictionTileIterator(); - TilingEvictionTileIterator(PictureLayerTiling* tiling, WhichTree tree); + TilingEvictionTileIterator(PictureLayerTiling* tiling, + TreePriority tree_priority); ~TilingEvictionTileIterator(); operator bool(); @@ -100,7 +101,9 @@ class CC_EXPORT PictureLayerTiling { TilingEvictionTileIterator& operator++(); TilePriority::PriorityBin get_type() { DCHECK(*this); - return (*tile_iterator_)->priority(tree_).priority_bin; + const TilePriority& priority = + (*tile_iterator_)->priority_for_tree_priority(tree_priority_); + return priority.priority_bin; } private: @@ -109,7 +112,7 @@ class CC_EXPORT PictureLayerTiling { bool is_valid_; PictureLayerTiling* tiling_; - WhichTree tree_; + TreePriority tree_priority_; std::vector<Tile*>::iterator tile_iterator_; }; @@ -276,7 +279,7 @@ class CC_EXPORT PictureLayerTiling { const gfx::Rect& visible_rect_in_content_space) const; - void UpdateEvictionCacheIfNeeded(WhichTree tree); + void UpdateEvictionCacheIfNeeded(TreePriority tree_priority); void DoInvalidate(const Region& layer_region, bool recreate_tiles); // Given properties. @@ -300,6 +303,7 @@ class CC_EXPORT PictureLayerTiling { std::vector<Tile*> eviction_tiles_cache_; bool eviction_tiles_cache_valid_; + TreePriority eviction_cache_tree_priority_; private: DISALLOW_ASSIGN(PictureLayerTiling); diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index 46e6dcc361..16b68c1e70 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -949,7 +949,8 @@ TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) { std::vector<Tile*> all_tiles = tiling->AllTilesForTesting(); - PictureLayerTiling::TilingEvictionTileIterator it(tiling.get(), ACTIVE_TREE); + PictureLayerTiling::TilingEvictionTileIterator it(tiling.get(), + SMOOTHNESS_TAKES_PRIORITY); // Tiles don't have resources to evict. EXPECT_FALSE(it); @@ -961,8 +962,8 @@ TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) { std::set<Tile*> all_tiles_set(all_tiles.begin(), all_tiles.end()); - it = - PictureLayerTiling::TilingEvictionTileIterator(tiling.get(), ACTIVE_TREE); + it = PictureLayerTiling::TilingEvictionTileIterator( + tiling.get(), SMOOTHNESS_TAKES_PRIORITY); EXPECT_TRUE(it); std::set<Tile*> eviction_tiles; diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc index 0e2e363102..8a15ea604e 100644 --- a/cc/resources/picture_pile.cc +++ b/cc/resources/picture_pile.cc @@ -141,8 +141,7 @@ float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, namespace cc { -PicturePile::PicturePile() { -} +PicturePile::PicturePile() : is_suitable_for_gpu_rasterization_(true) {} PicturePile::~PicturePile() { } @@ -245,6 +244,14 @@ bool PicturePile::Update(ContentLayerClient* painter, gather_pixel_refs, num_raster_threads, Picture::RECORD_NORMALLY); + // Note the '&&' with previous is-suitable state. + // This means that once a picture-pile becomes unsuitable for gpu + // rasterization due to some content, it will continue to be unsuitable + // even if that content is replaced by gpu-friendly content. + // This is an optimization to avoid iterating though all pictures in + // the pile after each invalidation. + is_suitable_for_gpu_rasterization_ &= + picture->IsSuitableForGpuRasterization(); base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); best_duration = std::min(duration, best_duration); diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h index 804a67979e..dbc3966b88 100644 --- a/cc/resources/picture_pile.h +++ b/cc/resources/picture_pile.h @@ -37,12 +37,21 @@ class CC_EXPORT PicturePile : public PicturePileBase { show_debug_picture_borders_ = show; } + bool is_suitable_for_gpu_rasterization() const { + return is_suitable_for_gpu_rasterization_; + } + void SetUnsuitableForGpuRasterizationForTesting() { + is_suitable_for_gpu_rasterization_ = false; + } + protected: virtual ~PicturePile(); private: friend class PicturePileImpl; + bool is_suitable_for_gpu_rasterization_; + DISALLOW_COPY_AND_ASSIGN(PicturePile); }; diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc index 9f72d04d75..4c8ca7b622 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.cc +++ b/cc/resources/pixel_buffer_raster_worker_pool.cc @@ -18,26 +18,27 @@ const int kCheckForCompletedRasterTasksDelayMs = 6; const size_t kMaxScheduledRasterTasks = 48; -typedef base::StackVector<internal::WorkerPoolTask*, kMaxScheduledRasterTasks> - WorkerPoolTaskVector; +typedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks> + RasterTaskVector; } // namespace // static -scoped_ptr<PixelBufferRasterWorkerPool> PixelBufferRasterWorkerPool::Create( +scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create( base::SequencedTaskRunner* task_runner, + TaskGraphRunner* task_graph_runner, ResourceProvider* resource_provider, size_t max_transfer_buffer_usage_bytes) { - return make_scoped_ptr( + return make_scoped_ptr<RasterWorkerPool>( new PixelBufferRasterWorkerPool(task_runner, - GetTaskGraphRunner(), + task_graph_runner, resource_provider, max_transfer_buffer_usage_bytes)); } PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( base::SequencedTaskRunner* task_runner, - internal::TaskGraphRunner* task_graph_runner, + TaskGraphRunner* task_graph_runner, ResourceProvider* resource_provider, size_t max_transfer_buffer_usage_bytes) : task_runner_(task_runner), @@ -68,7 +69,9 @@ PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { DCHECK_EQ(0u, raster_tasks_required_for_activation_count_); } -void PixelBufferRasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { +Rasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; } + +void PixelBufferRasterWorkerPool::SetClient(RasterizerClient* client) { client_ = client; } @@ -77,11 +80,11 @@ void PixelBufferRasterWorkerPool::Shutdown() { shutdown_ = true; - internal::TaskGraph empty; + TaskGraph empty; task_graph_runner_->ScheduleTasks(namespace_token_, &empty); task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); - CheckForCompletedWorkerPoolTasks(); + CheckForCompletedRasterizerTasks(); CheckForCompletedUploads(); check_for_completed_raster_tasks_pending_ = false; @@ -122,7 +125,7 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { it != queue->items.end(); ++it) { const RasterTaskQueue::Item& item = *it; - internal::WorkerPoolTask* task = item.task; + RasterTask* task = item.task; // Remove any old items that are associated with this task. The result is // that the old queue is left with all items not present in this queue, @@ -166,7 +169,7 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { it != raster_tasks_.items.end(); ++it) { const RasterTaskQueue::Item& item = *it; - internal::WorkerPoolTask* task = item.task; + RasterTask* task = item.task; RasterTaskState::Vector::iterator state_it = std::find_if(raster_task_states_.begin(), @@ -198,7 +201,7 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { // Check for completed tasks when ScheduleTasks() is called as // priorities might have changed and this maximizes the number // of top priority tasks that are scheduled. - CheckForCompletedWorkerPoolTasks(); + CheckForCompletedRasterizerTasks(); CheckForCompletedUploads(); FlushUploads(); @@ -219,35 +222,26 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { TracedValue::FromValue(StateAsValue().release())); } -unsigned PixelBufferRasterWorkerPool::GetResourceTarget() const { - return GL_TEXTURE_2D; -} - -ResourceFormat PixelBufferRasterWorkerPool::GetResourceFormat() const { - return resource_provider_->memory_efficient_texture_format(); -} - void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); - CheckForCompletedWorkerPoolTasks(); + CheckForCompletedRasterizerTasks(); CheckForCompletedUploads(); FlushUploads(); - for (internal::WorkerPoolTask::Vector::const_iterator it = + for (RasterizerTask::Vector::const_iterator it = completed_image_decode_tasks_.begin(); it != completed_image_decode_tasks_.end(); ++it) { - internal::WorkerPoolTask* task = it->get(); + RasterizerTask* task = it->get(); task->RunReplyOnOriginThread(); } completed_image_decode_tasks_.clear(); - for (internal::WorkerPoolTask::Vector::const_iterator it = - completed_raster_tasks_.begin(); + for (RasterTask::Vector::const_iterator it = completed_raster_tasks_.begin(); it != completed_raster_tasks_.end(); ++it) { - internal::WorkerPoolTask* task = it->get(); + RasterTask* task = it->get(); RasterTaskState::Vector::iterator state_it = std::find_if(raster_task_states_.begin(), raster_task_states_.end(), @@ -264,29 +258,21 @@ void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { } SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster( - internal::WorkerPoolTask* task, - const Resource* resource) { - RasterTaskState::Vector::iterator it = - std::find_if(raster_task_states_.begin(), - raster_task_states_.end(), - RasterTaskState::TaskComparator(task)); - DCHECK(it != raster_task_states_.end()); - DCHECK(!it->resource); - it->resource = resource; - resource_provider_->AcquirePixelRasterBuffer(resource->id()); - return resource_provider_->MapPixelRasterBuffer(resource->id()); + RasterTask* task) { + DCHECK(std::find_if(raster_task_states_.begin(), + raster_task_states_.end(), + RasterTaskState::TaskComparator(task)) != + raster_task_states_.end()); + resource_provider_->AcquirePixelRasterBuffer(task->resource()->id()); + return resource_provider_->MapPixelRasterBuffer(task->resource()->id()); } -void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster( - internal::WorkerPoolTask* task, - const Resource* resource) { - RasterTaskState::Vector::iterator it = - std::find_if(raster_task_states_.begin(), - raster_task_states_.end(), - RasterTaskState::TaskComparator(task)); - DCHECK(it != raster_task_states_.end()); - DCHECK(it->resource == resource); - resource_provider_->ReleasePixelRasterBuffer(resource->id()); +void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) { + DCHECK(std::find_if(raster_task_states_.begin(), + raster_task_states_.end(), + RasterTaskState::TaskComparator(task)) != + raster_task_states_.end()); + resource_provider_->ReleasePixelRasterBuffer(task->resource()->id()); } void PixelBufferRasterWorkerPool::OnRasterFinished() { @@ -332,21 +318,22 @@ void PixelBufferRasterWorkerPool::FlushUploads() { } void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { - internal::WorkerPoolTask::Vector tasks_with_completed_uploads; + RasterTask::Vector tasks_with_completed_uploads; // First check if any have completed. while (!raster_tasks_with_pending_upload_.empty()) { - internal::WorkerPoolTask* task = - raster_tasks_with_pending_upload_.front().get(); - RasterTaskState::Vector::const_iterator it = - std::find_if(raster_task_states_.begin(), - raster_task_states_.end(), - RasterTaskState::TaskComparator(task)); - DCHECK(it != raster_task_states_.end()); - DCHECK_EQ(RasterTaskState::UPLOADING, it->type); + RasterTask* task = raster_tasks_with_pending_upload_.front().get(); + DCHECK(std::find_if(raster_task_states_.begin(), + raster_task_states_.end(), + RasterTaskState::TaskComparator(task)) != + raster_task_states_.end()); + DCHECK_EQ(RasterTaskState::UPLOADING, + std::find_if(raster_task_states_.begin(), + raster_task_states_.end(), + RasterTaskState::TaskComparator(task))->type); // Uploads complete in the order they are issued. - if (!resource_provider_->DidSetPixelsComplete(it->resource->id())) + if (!resource_provider_->DidSetPixelsComplete(task->resource()->id())) break; tasks_with_completed_uploads.push_back(task); @@ -358,19 +345,20 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { shutdown_ || client_->ShouldForceTasksRequiredForActivationToComplete(); if (should_force_some_uploads_to_complete) { - internal::WorkerPoolTask::Vector tasks_with_uploads_to_force; - TaskDeque::iterator it = raster_tasks_with_pending_upload_.begin(); + RasterTask::Vector tasks_with_uploads_to_force; + RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin(); while (it != raster_tasks_with_pending_upload_.end()) { - internal::WorkerPoolTask* task = it->get(); + RasterTask* task = it->get(); RasterTaskState::Vector::const_iterator state_it = std::find_if(raster_task_states_.begin(), raster_task_states_.end(), RasterTaskState::TaskComparator(task)); DCHECK(state_it != raster_task_states_.end()); + const RasterTaskState& state = *state_it; // Force all uploads required for activation to complete. // During shutdown, force all pending uploads to complete. - if (shutdown_ || state_it->required_for_activation) { + if (shutdown_ || state.required_for_activation) { tasks_with_uploads_to_force.push_back(task); tasks_with_completed_uploads.push_back(task); it = raster_tasks_with_pending_upload_.erase(it); @@ -382,30 +370,24 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { // Force uploads in reverse order. Since forcing can cause a wait on // all previous uploads, we would rather wait only once downstream. - for (internal::WorkerPoolTask::Vector::reverse_iterator it = + for (RasterTask::Vector::reverse_iterator it = tasks_with_uploads_to_force.rbegin(); it != tasks_with_uploads_to_force.rend(); ++it) { - internal::WorkerPoolTask* task = it->get(); - RasterTaskState::Vector::const_iterator state_it = - std::find_if(raster_task_states_.begin(), - raster_task_states_.end(), - RasterTaskState::TaskComparator(task)); - DCHECK(state_it != raster_task_states_.end()); - DCHECK(state_it->resource); + RasterTask* task = it->get(); - resource_provider_->ForceSetPixelsToComplete(state_it->resource->id()); + resource_provider_->ForceSetPixelsToComplete(task->resource()->id()); has_performed_uploads_since_last_flush_ = true; } } // Release shared memory and move tasks with completed uploads // to |completed_raster_tasks_|. - for (internal::WorkerPoolTask::Vector::const_iterator it = + for (RasterTask::Vector::const_iterator it = tasks_with_completed_uploads.begin(); it != tasks_with_completed_uploads.end(); ++it) { - internal::WorkerPoolTask* task = it->get(); + RasterTask* task = it->get(); RasterTaskState::Vector::iterator state_it = std::find_if(raster_task_states_.begin(), raster_task_states_.end(), @@ -413,12 +395,17 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { DCHECK(state_it != raster_task_states_.end()); RasterTaskState& state = *state_it; - bytes_pending_upload_ -= state.resource->bytes(); + bytes_pending_upload_ -= task->resource()->bytes(); task->WillComplete(); task->CompleteOnOriginThread(this); task->DidComplete(); + // Async set pixels commands are not necessarily processed in-sequence with + // drawing commands. Read lock fences are required to ensure that async + // commands don't access the resource while used for drawing. + resource_provider_->EnableReadLockFences(task->resource()->id(), true); + DCHECK(std::find(completed_raster_tasks_.begin(), completed_raster_tasks_.end(), task) == completed_raster_tasks_.end()); @@ -479,7 +466,7 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { DCHECK(should_notify_client_if_no_tasks_are_pending_); check_for_completed_raster_tasks_time_ = base::TimeTicks(); - CheckForCompletedWorkerPoolTasks(); + CheckForCompletedRasterizerTasks(); CheckForCompletedUploads(); FlushUploads(); @@ -531,8 +518,8 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); - WorkerPoolTaskVector tasks; - WorkerPoolTaskVector tasks_required_for_activation; + RasterTaskVector tasks; + RasterTaskVector tasks_required_for_activation; unsigned priority = kRasterTaskPriorityBase; @@ -547,7 +534,7 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { it != raster_tasks_.items.end(); ++it) { const RasterTaskQueue::Item& item = *it; - internal::RasterWorkerPoolTask* task = item.task; + RasterTask* task = item.task; // |raster_task_states_| contains the state of all tasks that we have not // yet run reply callbacks for. @@ -611,7 +598,7 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { // Cancel existing OnRasterFinished callbacks. raster_finished_weak_ptr_factory_.InvalidateWeakPtrs(); - scoped_refptr<internal::WorkerPoolTask> + scoped_refptr<RasterizerTask> new_raster_required_for_activation_finished_task; size_t scheduled_raster_task_required_for_activation_count = @@ -635,16 +622,16 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { new_raster_required_for_activation_finished_task.get(), kRasterRequiredForActivationFinishedTaskPriority, scheduled_raster_task_required_for_activation_count); - for (WorkerPoolTaskVector::ContainerType::const_iterator it = + for (RasterTaskVector::ContainerType::const_iterator it = tasks_required_for_activation.container().begin(); it != tasks_required_for_activation.container().end(); ++it) { - graph_.edges.push_back(internal::TaskGraph::Edge( + graph_.edges.push_back(TaskGraph::Edge( *it, new_raster_required_for_activation_finished_task.get())); } } - scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task; + scoped_refptr<RasterizerTask> new_raster_finished_task; size_t scheduled_raster_task_count = tasks.container().size(); DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount()); @@ -661,12 +648,12 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { new_raster_finished_task.get(), kRasterFinishedTaskPriority, scheduled_raster_task_count); - for (WorkerPoolTaskVector::ContainerType::const_iterator it = + for (RasterTaskVector::ContainerType::const_iterator it = tasks.container().begin(); it != tasks.container().end(); ++it) { graph_.edges.push_back( - internal::TaskGraph::Edge(*it, new_raster_finished_task.get())); + TaskGraph::Edge(*it, new_raster_finished_task.get())); } } @@ -706,23 +693,19 @@ const char* PixelBufferRasterWorkerPool::StateName() const { return "finishing"; } -void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() { +void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() { TRACE_EVENT0("cc", - "PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks"); + "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks"); task_graph_runner_->CollectCompletedTasks(namespace_token_, &completed_tasks_); - for (internal::Task::Vector::const_iterator it = completed_tasks_.begin(); + for (Task::Vector::const_iterator it = completed_tasks_.begin(); it != completed_tasks_.end(); ++it) { - internal::WorkerPoolTask* task = - static_cast<internal::WorkerPoolTask*>(it->get()); + RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); - RasterTaskState::Vector::iterator state_it = - std::find_if(raster_task_states_.begin(), - raster_task_states_.end(), - RasterTaskState::TaskComparator(task)); - if (state_it == raster_task_states_.end()) { + RasterTask* raster_task = task->AsRasterTask(); + if (!raster_task) { task->WillComplete(); task->CompleteOnOriginThread(this); task->DidComplete(); @@ -731,41 +714,45 @@ void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() { continue; } + RasterTaskState::Vector::iterator state_it = + std::find_if(raster_task_states_.begin(), + raster_task_states_.end(), + RasterTaskState::TaskComparator(raster_task)); + DCHECK(state_it != raster_task_states_.end()); + RasterTaskState& state = *state_it; DCHECK_EQ(RasterTaskState::SCHEDULED, state.type); - DCHECK(state.resource); // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster(). - bool content_has_changed = - resource_provider_->UnmapPixelRasterBuffer(state.resource->id()); + bool content_has_changed = resource_provider_->UnmapPixelRasterBuffer( + raster_task->resource()->id()); // |content_has_changed| can be false as result of task being canceled or // task implementation deciding not to modify bitmap (ie. analysis of raster // commands detected content as a solid color). if (!content_has_changed) { - task->WillComplete(); - task->CompleteOnOriginThread(this); - task->DidComplete(); + raster_task->WillComplete(); + raster_task->CompleteOnOriginThread(this); + raster_task->DidComplete(); - if (!task->HasFinishedRunning()) { + if (!raster_task->HasFinishedRunning()) { // When priorites change, a raster task can be canceled as a result of // no longer being of high enough priority to fit in our throttled // raster task budget. The task has not yet completed in this case. RasterTaskQueue::Item::Vector::const_iterator item_it = std::find_if(raster_tasks_.items.begin(), raster_tasks_.items.end(), - RasterTaskQueue::Item::TaskComparator(task)); + RasterTaskQueue::Item::TaskComparator(raster_task)); if (item_it != raster_tasks_.items.end()) { state.type = RasterTaskState::UNSCHEDULED; - state.resource = NULL; continue; } } DCHECK(std::find(completed_raster_tasks_.begin(), completed_raster_tasks_.end(), - task) == completed_raster_tasks_.end()); - completed_raster_tasks_.push_back(task); + raster_task) == completed_raster_tasks_.end()); + completed_raster_tasks_.push_back(raster_task); state.type = RasterTaskState::COMPLETED; DCHECK_LE(static_cast<size_t>(state.required_for_activation), raster_tasks_required_for_activation_count_); @@ -774,13 +761,13 @@ void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() { continue; } - DCHECK(task->HasFinishedRunning()); + DCHECK(raster_task->HasFinishedRunning()); - resource_provider_->BeginSetPixels(state.resource->id()); + resource_provider_->BeginSetPixels(raster_task->resource()->id()); has_performed_uploads_since_last_flush_ = true; - bytes_pending_upload_ += state.resource->bytes(); - raster_tasks_with_pending_upload_.push_back(task); + bytes_pending_upload_ += raster_task->resource()->bytes(); + raster_tasks_with_pending_upload_.push_back(raster_task); state.type = RasterTaskState::UPLOADING; } completed_tasks_.clear(); diff --git a/cc/resources/pixel_buffer_raster_worker_pool.h b/cc/resources/pixel_buffer_raster_worker_pool.h index eb8fe514b9..4f1c43525e 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.h +++ b/cc/resources/pixel_buffer_raster_worker_pool.h @@ -11,72 +11,68 @@ #include "base/memory/weak_ptr.h" #include "base/values.h" #include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer.h" namespace cc { class ResourceProvider; -class CC_EXPORT PixelBufferRasterWorkerPool - : public RasterWorkerPool, - public internal::WorkerPoolTaskClient { +class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool, + public Rasterizer, + public RasterizerTaskClient { public: virtual ~PixelBufferRasterWorkerPool(); - static scoped_ptr<PixelBufferRasterWorkerPool> Create( + static scoped_ptr<RasterWorkerPool> Create( base::SequencedTaskRunner* task_runner, + TaskGraphRunner* task_graph_runner, ResourceProvider* resource_provider, size_t max_transfer_buffer_usage_bytes); // Overridden from RasterWorkerPool: - virtual void SetClient(RasterWorkerPoolClient* client) OVERRIDE; + virtual Rasterizer* AsRasterizer() OVERRIDE; + + // Overridden from Rasterizer: + virtual void SetClient(RasterizerClient* client) OVERRIDE; virtual void Shutdown() OVERRIDE; virtual void ScheduleTasks(RasterTaskQueue* queue) OVERRIDE; - virtual unsigned GetResourceTarget() const OVERRIDE; - virtual ResourceFormat GetResourceFormat() const OVERRIDE; virtual void CheckForCompletedTasks() OVERRIDE; - // Overridden from internal::WorkerPoolTaskClient: - virtual SkCanvas* AcquireCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE; - virtual void ReleaseCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE; - - protected: - PixelBufferRasterWorkerPool(base::SequencedTaskRunner* task_runner, - internal::TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider, - size_t max_transfer_buffer_usage_bytes); + // Overridden from RasterizerTaskClient: + virtual SkCanvas* AcquireCanvasForRaster(RasterTask* task) OVERRIDE; + virtual void ReleaseCanvasForRaster(RasterTask* task) OVERRIDE; private: struct RasterTaskState { class TaskComparator { public: - explicit TaskComparator(const internal::WorkerPoolTask* task) - : task_(task) {} + explicit TaskComparator(const RasterTask* task) : task_(task) {} bool operator()(const RasterTaskState& state) const { return state.task == task_; } private: - const internal::WorkerPoolTask* task_; + const RasterTask* task_; }; typedef std::vector<RasterTaskState> Vector; - RasterTaskState(internal::WorkerPoolTask* task, - bool required_for_activation) + RasterTaskState(RasterTask* task, bool required_for_activation) : type(UNSCHEDULED), task(task), - resource(NULL), required_for_activation(required_for_activation) {} enum { UNSCHEDULED, SCHEDULED, UPLOADING, COMPLETED } type; - internal::WorkerPoolTask* task; - const Resource* resource; + RasterTask* task; bool required_for_activation; }; - typedef std::deque<scoped_refptr<internal::WorkerPoolTask> > TaskDeque; + typedef std::deque<scoped_refptr<RasterTask> > RasterTaskDeque; + + PixelBufferRasterWorkerPool(base::SequencedTaskRunner* task_runner, + TaskGraphRunner* task_graph_runner, + ResourceProvider* resource_provider, + size_t max_transfer_buffer_usage_bytes); void OnRasterFinished(); void OnRasterRequiredForActivationFinished(); @@ -89,25 +85,25 @@ class CC_EXPORT PixelBufferRasterWorkerPool unsigned PendingRasterTaskCount() const; bool HasPendingTasks() const; bool HasPendingTasksRequiredForActivation() const; - void CheckForCompletedWorkerPoolTasks(); + void CheckForCompletedRasterizerTasks(); const char* StateName() const; scoped_ptr<base::Value> StateAsValue() const; scoped_ptr<base::Value> ThrottleStateAsValue() const; scoped_refptr<base::SequencedTaskRunner> task_runner_; - internal::TaskGraphRunner* task_graph_runner_; - const internal::NamespaceToken namespace_token_; - RasterWorkerPoolClient* client_; + TaskGraphRunner* task_graph_runner_; + const NamespaceToken namespace_token_; + RasterizerClient* client_; ResourceProvider* resource_provider_; bool shutdown_; RasterTaskQueue raster_tasks_; RasterTaskState::Vector raster_task_states_; - TaskDeque raster_tasks_with_pending_upload_; - internal::WorkerPoolTask::Vector completed_raster_tasks_; - internal::WorkerPoolTask::Vector completed_image_decode_tasks_; + RasterTaskDeque raster_tasks_with_pending_upload_; + RasterTask::Vector completed_raster_tasks_; + RasterizerTask::Vector completed_image_decode_tasks_; size_t scheduled_raster_task_count_; size_t raster_tasks_required_for_activation_count_; @@ -125,14 +121,13 @@ class CC_EXPORT PixelBufferRasterWorkerPool base::WeakPtrFactory<PixelBufferRasterWorkerPool> raster_finished_weak_ptr_factory_; - scoped_refptr<internal::WorkerPoolTask> raster_finished_task_; - scoped_refptr<internal::WorkerPoolTask> - raster_required_for_activation_finished_task_; + scoped_refptr<RasterizerTask> raster_finished_task_; + scoped_refptr<RasterizerTask> raster_required_for_activation_finished_task_; // Task graph used when scheduling tasks and vector used to gather // completed tasks. - internal::TaskGraph graph_; - internal::Task::Vector completed_tasks_; + TaskGraph graph_; + Task::Vector completed_tasks_; base::WeakPtrFactory<PixelBufferRasterWorkerPool> weak_ptr_factory_; diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc index 58e8102b30..ebe144ed4b 100644 --- a/cc/resources/prioritized_tile_set_unittest.cc +++ b/cc/resources/prioritized_tile_set_unittest.cc @@ -59,8 +59,10 @@ class PrioritizedTileSetTest : public testing::Test { ResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1) .Pass(); + resource_pool_ = ResourcePool::Create( + resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); tile_manager_.reset( - new FakeTileManager(&tile_manager_client_, resource_provider_.get())); + new FakeTileManager(&tile_manager_client_, resource_pool_.get())); picture_pile_ = FakePicturePileImpl::CreateInfiniteFilledPile(); } @@ -81,6 +83,7 @@ class PrioritizedTileSetTest : public testing::Test { scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; + scoped_ptr<ResourcePool> resource_pool_; FakeTileManagerClient tile_manager_client_; scoped_ptr<FakeTileManager> tile_manager_; scoped_refptr<FakePicturePileImpl> picture_pile_; diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc index 0db46fcd50..e7b3f139d1 100644 --- a/cc/resources/raster_worker_pool.cc +++ b/cc/resources/raster_worker_pool.cc @@ -28,7 +28,7 @@ struct RasterRequiredForActivationSyntheticDelayInitializer { static base::LazyInstance<RasterRequiredForActivationSyntheticDelayInitializer> g_raster_required_for_activation_delay = LAZY_INSTANCE_INITIALIZER; -class RasterTaskGraphRunner : public internal::TaskGraphRunner, +class RasterTaskGraphRunner : public TaskGraphRunner, public base::DelegateSimpleThread::Delegate { public: RasterTaskGraphRunner() { @@ -70,7 +70,7 @@ class RasterTaskGraphRunner : public internal::TaskGraphRunner, DCHECK_GT(RasterWorkerPool::GetNumRasterThreads(), picture_clone_index); current_tls_.Set(new ThreadLocalState(picture_clone_index)); - internal::TaskGraphRunner::Run(); + TaskGraphRunner::Run(); } ScopedPtrDeque<base::DelegateSimpleThread> workers_; @@ -85,33 +85,31 @@ const int kDefaultNumRasterThreads = 1; int g_num_raster_threads = 0; -class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { +class RasterFinishedTaskImpl : public RasterizerTask { public: - explicit RasterFinishedWorkerPoolTaskImpl( + explicit RasterFinishedTaskImpl( base::SequencedTaskRunner* task_runner, const base::Closure& on_raster_finished_callback) : task_runner_(task_runner), on_raster_finished_callback_(on_raster_finished_callback) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { - TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread"); + TRACE_EVENT0("cc", "RasterFinishedTaskImpl::RunOnWorkerThread"); RasterFinished(); } - // Overridden from internal::WorkerPoolTask: - virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE {} + // Overridden from RasterizerTask: + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {} virtual void RunOnOriginThread() OVERRIDE { - TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnOriginThread"); + TRACE_EVENT0("cc", "RasterFinishedTaskImpl::RunOnOriginThread"); RasterFinished(); } - virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE {} + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {} virtual void RunReplyOnOriginThread() OVERRIDE {} protected: - virtual ~RasterFinishedWorkerPoolTaskImpl() {} + virtual ~RasterFinishedTaskImpl() {} void RasterFinished() { task_runner_->PostTask(FROM_HERE, on_raster_finished_callback_); @@ -121,18 +119,17 @@ class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { scoped_refptr<base::SequencedTaskRunner> task_runner_; const base::Closure on_raster_finished_callback_; - DISALLOW_COPY_AND_ASSIGN(RasterFinishedWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(RasterFinishedTaskImpl); }; -class RasterRequiredForActivationFinishedWorkerPoolTaskImpl - : public RasterFinishedWorkerPoolTaskImpl { +class RasterRequiredForActivationFinishedTaskImpl + : public RasterFinishedTaskImpl { public: - RasterRequiredForActivationFinishedWorkerPoolTaskImpl( + RasterRequiredForActivationFinishedTaskImpl( base::SequencedTaskRunner* task_runner, const base::Closure& on_raster_finished_callback, size_t tasks_required_for_activation_count) - : RasterFinishedWorkerPoolTaskImpl(task_runner, - on_raster_finished_callback), + : RasterFinishedTaskImpl(task_runner, on_raster_finished_callback), tasks_required_for_activation_count_( tasks_required_for_activation_count) { if (tasks_required_for_activation_count_) { @@ -141,24 +138,22 @@ class RasterRequiredForActivationFinishedWorkerPoolTaskImpl } } - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { - TRACE_EVENT0("cc", - "RasterRequiredForActivationFinishedWorkerPoolTaskImpl::" - "RunOnWorkerThread"); + TRACE_EVENT0( + "cc", "RasterRequiredForActivationFinishedTaskImpl::RunOnWorkerThread"); RunRasterFinished(); } - // Overridden from internal::WorkerPoolTask: + // Overridden from RasterizerTask: virtual void RunOnOriginThread() OVERRIDE { - TRACE_EVENT0("cc", - "RasterRequiredForActivationFinishedWorkerPoolTaskImpl::" - "RunOnOriginThread"); + TRACE_EVENT0( + "cc", "RasterRequiredForActivationFinishedTaskImpl::RunOnOriginThread"); RunRasterFinished(); } private: - virtual ~RasterRequiredForActivationFinishedWorkerPoolTaskImpl() {} + virtual ~RasterRequiredForActivationFinishedTaskImpl() {} void RunRasterFinished() { if (tasks_required_for_activation_count_) { @@ -171,73 +166,11 @@ class RasterRequiredForActivationFinishedWorkerPoolTaskImpl base::TimeTicks activation_delay_end_time_; const size_t tasks_required_for_activation_count_; - DISALLOW_COPY_AND_ASSIGN( - RasterRequiredForActivationFinishedWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(RasterRequiredForActivationFinishedTaskImpl); }; } // namespace -namespace internal { - -WorkerPoolTask::WorkerPoolTask() : did_schedule_(false), did_complete_(false) {} - -WorkerPoolTask::~WorkerPoolTask() { - DCHECK(!did_schedule_); - DCHECK(!did_run_ || did_complete_); -} - -void WorkerPoolTask::WillSchedule() { DCHECK(!did_schedule_); } - -void WorkerPoolTask::DidSchedule() { - did_schedule_ = true; - did_complete_ = false; -} - -bool WorkerPoolTask::HasBeenScheduled() const { return did_schedule_; } - -void WorkerPoolTask::WillComplete() { DCHECK(!did_complete_); } - -void WorkerPoolTask::DidComplete() { - DCHECK(did_schedule_); - DCHECK(!did_complete_); - did_schedule_ = false; - did_complete_ = true; -} - -bool WorkerPoolTask::HasCompleted() const { return did_complete_; } - -RasterWorkerPoolTask::RasterWorkerPoolTask( - const Resource* resource, - internal::WorkerPoolTask::Vector* dependencies) - : resource_(resource) { - dependencies_.swap(*dependencies); -} - -RasterWorkerPoolTask::~RasterWorkerPoolTask() {} - -} // namespace internal - -RasterTaskQueue::Item::Item(internal::RasterWorkerPoolTask* task, - bool required_for_activation) - : task(task), required_for_activation(required_for_activation) {} - -RasterTaskQueue::Item::~Item() {} - -RasterTaskQueue::RasterTaskQueue() : required_for_activation_count(0u) {} - -RasterTaskQueue::~RasterTaskQueue() {} - -void RasterTaskQueue::Swap(RasterTaskQueue* other) { - items.swap(other->items); - std::swap(required_for_activation_count, - other->required_for_activation_count); -} - -void RasterTaskQueue::Reset() { - required_for_activation_count = 0u; - items.clear(); -} - // This allows an external rasterize on-demand system to run raster tasks // with highest priority using the same task graph runner instance. unsigned RasterWorkerPool::kOnDemandRasterTaskPriority = 0u; @@ -251,6 +184,10 @@ unsigned RasterWorkerPool::kRasterRequiredForActivationFinishedTaskPriority = 1u; unsigned RasterWorkerPool::kRasterTaskPriorityBase = 3u; +RasterWorkerPool::RasterWorkerPool() {} + +RasterWorkerPool::~RasterWorkerPool() {} + // static void RasterWorkerPool::SetNumRasterThreads(int num_threads) { DCHECK_LT(0, num_threads); @@ -268,7 +205,7 @@ int RasterWorkerPool::GetNumRasterThreads() { } // static -internal::TaskGraphRunner* RasterWorkerPool::GetTaskGraphRunner() { +TaskGraphRunner* RasterWorkerPool::GetTaskGraphRunner() { return g_task_graph_runner.Pointer(); } @@ -278,39 +215,35 @@ size_t RasterWorkerPool::GetPictureCloneIndexForCurrentThread() { } // static -scoped_refptr<internal::WorkerPoolTask> -RasterWorkerPool::CreateRasterFinishedTask( +scoped_refptr<RasterizerTask> RasterWorkerPool::CreateRasterFinishedTask( base::SequencedTaskRunner* task_runner, const base::Closure& on_raster_finished_callback) { - return make_scoped_refptr(new RasterFinishedWorkerPoolTaskImpl( - task_runner, on_raster_finished_callback)); + return make_scoped_refptr( + new RasterFinishedTaskImpl(task_runner, on_raster_finished_callback)); } // static -scoped_refptr<internal::WorkerPoolTask> +scoped_refptr<RasterizerTask> RasterWorkerPool::CreateRasterRequiredForActivationFinishedTask( size_t tasks_required_for_activation_count, base::SequencedTaskRunner* task_runner, const base::Closure& on_raster_finished_callback) { - return make_scoped_refptr( - new RasterRequiredForActivationFinishedWorkerPoolTaskImpl( - task_runner, - on_raster_finished_callback, - tasks_required_for_activation_count)); + return make_scoped_refptr(new RasterRequiredForActivationFinishedTaskImpl( + task_runner, + on_raster_finished_callback, + tasks_required_for_activation_count)); } // static -void RasterWorkerPool::ScheduleTasksOnOriginThread( - internal::WorkerPoolTaskClient* client, - internal::TaskGraph* graph) { - TRACE_EVENT0("cc", "RasterWorkerPool::ScheduleTasksOnOriginThread"); +void RasterWorkerPool::ScheduleTasksOnOriginThread(RasterizerTaskClient* client, + TaskGraph* graph) { + TRACE_EVENT0("cc", "Rasterizer::ScheduleTasksOnOriginThread"); - for (internal::TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); + for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); it != graph->nodes.end(); ++it) { - internal::TaskGraph::Node& node = *it; - internal::WorkerPoolTask* task = - static_cast<internal::WorkerPoolTask*>(node.task); + TaskGraph::Node& node = *it; + RasterizerTask* task = static_cast<RasterizerTask*>(node.task); if (!task->HasBeenScheduled()) { task->WillSchedule(); @@ -321,32 +254,30 @@ void RasterWorkerPool::ScheduleTasksOnOriginThread( } // static -void RasterWorkerPool::InsertNodeForTask(internal::TaskGraph* graph, - internal::WorkerPoolTask* task, +void RasterWorkerPool::InsertNodeForTask(TaskGraph* graph, + RasterizerTask* task, unsigned priority, size_t dependencies) { DCHECK(std::find_if(graph->nodes.begin(), graph->nodes.end(), - internal::TaskGraph::Node::TaskComparator(task)) == + TaskGraph::Node::TaskComparator(task)) == graph->nodes.end()); - graph->nodes.push_back( - internal::TaskGraph::Node(task, priority, dependencies)); + graph->nodes.push_back(TaskGraph::Node(task, priority, dependencies)); } // static void RasterWorkerPool::InsertNodesForRasterTask( - internal::TaskGraph* graph, - internal::WorkerPoolTask* raster_task, - const internal::WorkerPoolTask::Vector& decode_tasks, + TaskGraph* graph, + RasterTask* raster_task, + const ImageDecodeTask::Vector& decode_tasks, unsigned priority) { size_t dependencies = 0u; // Insert image decode tasks. - for (internal::WorkerPoolTask::Vector::const_iterator it = - decode_tasks.begin(); + for (ImageDecodeTask::Vector::const_iterator it = decode_tasks.begin(); it != decode_tasks.end(); ++it) { - internal::WorkerPoolTask* decode_task = it->get(); + ImageDecodeTask* decode_task = it->get(); // Skip if already decoded. if (decode_task->HasCompleted()) @@ -355,14 +286,14 @@ void RasterWorkerPool::InsertNodesForRasterTask( dependencies++; // Add decode task if it doesn't already exists in graph. - internal::TaskGraph::Node::Vector::iterator decode_it = + TaskGraph::Node::Vector::iterator decode_it = std::find_if(graph->nodes.begin(), graph->nodes.end(), - internal::TaskGraph::Node::TaskComparator(decode_task)); + TaskGraph::Node::TaskComparator(decode_task)); if (decode_it == graph->nodes.end()) InsertNodeForTask(graph, decode_task, priority, 0u); - graph->edges.push_back(internal::TaskGraph::Edge(decode_task, raster_task)); + graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task)); } InsertNodeForTask(graph, raster_task, priority, dependencies); diff --git a/cc/resources/raster_worker_pool.h b/cc/resources/raster_worker_pool.h index 059c77e284..2c543a0d0c 100644 --- a/cc/resources/raster_worker_pool.h +++ b/cc/resources/raster_worker_pool.h @@ -5,130 +5,14 @@ #ifndef CC_RESOURCES_RASTER_WORKER_POOL_H_ #define CC_RESOURCES_RASTER_WORKER_POOL_H_ -#include <vector> - -#include "base/callback.h" -#include "cc/resources/resource_format.h" -#include "cc/resources/task_graph_runner.h" - -class SkCanvas; +#include "cc/resources/rasterizer.h" namespace base { class SequencedTaskRunner; } namespace cc { -class Resource; - -namespace internal { -class WorkerPoolTask; - -class CC_EXPORT WorkerPoolTaskClient { - public: - virtual SkCanvas* AcquireCanvasForRaster(WorkerPoolTask* task, - const Resource* resource) = 0; - virtual void ReleaseCanvasForRaster(WorkerPoolTask* task, - const Resource* resource) = 0; - - protected: - virtual ~WorkerPoolTaskClient() {} -}; - -class CC_EXPORT WorkerPoolTask : public Task { - public: - typedef std::vector<scoped_refptr<WorkerPoolTask> > Vector; - - virtual void ScheduleOnOriginThread(WorkerPoolTaskClient* client) = 0; - virtual void RunOnOriginThread() = 0; - virtual void CompleteOnOriginThread(WorkerPoolTaskClient* client) = 0; - virtual void RunReplyOnOriginThread() = 0; - - void WillSchedule(); - void DidSchedule(); - bool HasBeenScheduled() const; - - void WillComplete(); - void DidComplete(); - bool HasCompleted() const; - - protected: - WorkerPoolTask(); - virtual ~WorkerPoolTask(); - - bool did_schedule_; - bool did_complete_; -}; - -class CC_EXPORT RasterWorkerPoolTask : public WorkerPoolTask { - public: - const Resource* resource() const { return resource_; } - const internal::WorkerPoolTask::Vector& dependencies() const { - return dependencies_; - } - - protected: - RasterWorkerPoolTask(const Resource* resource, - internal::WorkerPoolTask::Vector* dependencies); - virtual ~RasterWorkerPoolTask(); - - private: - const Resource* resource_; - WorkerPoolTask::Vector dependencies_; -}; - -} // namespace internal - -class CC_EXPORT RasterWorkerPoolClient { - public: - virtual bool ShouldForceTasksRequiredForActivationToComplete() const = 0; - virtual void DidFinishRunningTasks() = 0; - virtual void DidFinishRunningTasksRequiredForActivation() = 0; - protected: - virtual ~RasterWorkerPoolClient() {} -}; - -struct CC_EXPORT RasterTaskQueue { - struct CC_EXPORT Item { - class TaskComparator { - public: - explicit TaskComparator(const internal::WorkerPoolTask* task) - : task_(task) {} - - bool operator()(const Item& item) const { return item.task == task_; } - - private: - const internal::WorkerPoolTask* task_; - }; - - typedef std::vector<Item> Vector; - - Item(internal::RasterWorkerPoolTask* task, bool required_for_activation); - ~Item(); - - static bool IsRequiredForActivation(const Item& item) { - return item.required_for_activation; - } - - internal::RasterWorkerPoolTask* task; - bool required_for_activation; - }; - - RasterTaskQueue(); - ~RasterTaskQueue(); - - void Swap(RasterTaskQueue* other); - void Reset(); - - Item::Vector items; - size_t required_for_activation_count; -}; - -// This interface can be used to schedule and run raster tasks. The client will -// be notified asynchronously when the set of tasks marked as "required for -// activation" have finished running and when all scheduled tasks have finished -// running. The client can call CheckForCompletedTasks() at any time to dispatch -// pending completion callbacks for all tasks that have finished running. class CC_EXPORT RasterWorkerPool { public: static unsigned kOnDemandRasterTaskPriority; @@ -137,6 +21,9 @@ class CC_EXPORT RasterWorkerPool { static unsigned kRasterRequiredForActivationFinishedTaskPriority; static unsigned kRasterTaskPriorityBase; + RasterWorkerPool(); + virtual ~RasterWorkerPool(); + // Set the number of threads to use for the global TaskGraphRunner instance. // This can only be called once and must be called prior to // GetNumRasterThreads(). @@ -146,76 +33,49 @@ class CC_EXPORT RasterWorkerPool { static int GetNumRasterThreads(); // Returns a pointer to the global TaskGraphRunner instance. - static internal::TaskGraphRunner* GetTaskGraphRunner(); + static TaskGraphRunner* GetTaskGraphRunner(); // Returns a unique clone index for the current thread. Guaranteed to be a // value between 0 and GetNumRasterThreads() - 1. static size_t GetPictureCloneIndexForCurrentThread(); - // Utility function that can be used by implementations to create a "raster - // finished" task that posts |callback| to |task_runner| when run. - static scoped_refptr<internal::WorkerPoolTask> CreateRasterFinishedTask( + // Utility function that can be used to create a "raster finished" task that + // posts |callback| to |task_runner| when run. + static scoped_refptr<RasterizerTask> CreateRasterFinishedTask( base::SequencedTaskRunner* task_runner, const base::Closure& callback); - // Utility function that can be used by implementations to create a "raster - // required for activation finished" task that posts |callback| to - // |task_runner| when run. - static scoped_refptr<internal::WorkerPoolTask> + // Utility function that can be used to create a "raster required for + // activation finished" task that posts |callback| to |task_runner| when run. + static scoped_refptr<RasterizerTask> CreateRasterRequiredForActivationFinishedTask( size_t tasks_required_for_activation_count, base::SequencedTaskRunner* task_runner, const base::Closure& callback); - // Utility function that can be used by implementations to call - // ::ScheduleOnOriginThread() for each task in |graph|. - static void ScheduleTasksOnOriginThread( - internal::WorkerPoolTaskClient* client, - internal::TaskGraph* graph); - - // Utility function that can be used by implementations to build a task graph. - // Inserts a node that represents |task| in |graph|. See TaskGraph definition - // for valid |priority| values. - static void InsertNodeForTask(internal::TaskGraph* graph, - internal::WorkerPoolTask* task, + // Utility function that can be used to call ::ScheduleOnOriginThread() for + // each task in |graph|. + static void ScheduleTasksOnOriginThread(RasterizerTaskClient* client, + TaskGraph* graph); + + // Utility function that can be used to build a task graph. Inserts a node + // that represents |task| in |graph|. See TaskGraph definition for valid + // |priority| values. + static void InsertNodeForTask(TaskGraph* graph, + RasterizerTask* task, unsigned priority, size_t dependencies); - // Utility function that can be used by implementations to build a task graph. - // Inserts nodes that represent |task| and all its image decode dependencies - // in |graph|. + // Utility function that can be used to build a task graph. Inserts nodes that + // represent |task| and all its image decode dependencies in |graph|. static void InsertNodesForRasterTask( - internal::TaskGraph* graph, - internal::WorkerPoolTask* task, - const internal::WorkerPoolTask::Vector& decode_tasks, + TaskGraph* graph, + RasterTask* task, + const ImageDecodeTask::Vector& decode_tasks, unsigned priority); - // Set the client instance to be notified when finished running tasks. - virtual void SetClient(RasterWorkerPoolClient* client) = 0; - - // Tells the worker pool to shutdown after canceling all previously scheduled - // tasks. Reply callbacks are still guaranteed to run when - // CheckForCompletedTasks() is called. - virtual void Shutdown() = 0; - - // Schedule running of raster tasks in |queue| and all dependencies. - // Previously scheduled tasks that are not 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(RasterTaskQueue* queue) = 0; - - // Check for completed tasks and dispatch reply callbacks. - virtual void CheckForCompletedTasks() = 0; - - // Returns the target that needs to be used for raster task resources. - virtual unsigned GetResourceTarget() const = 0; - - // Returns the format that needs to be used for raster task resources. - virtual ResourceFormat GetResourceFormat() const = 0; - - protected: - virtual ~RasterWorkerPool() {} + // Type-checking downcast routine. + virtual Rasterizer* AsRasterizer() = 0; }; } // namespace cc diff --git a/cc/resources/raster_worker_pool_delegate.cc b/cc/resources/raster_worker_pool_delegate.cc deleted file mode 100644 index 9d4b8b5e96..0000000000 --- a/cc/resources/raster_worker_pool_delegate.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2014 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. - -#include "cc/resources/raster_worker_pool_delegate.h" - -namespace cc { - -RasterWorkerPoolDelegate::RasterWorkerPoolDelegate( - RasterWorkerPoolClient* client, - RasterWorkerPool** raster_worker_pools, - size_t num_raster_worker_pools) - : client_(client), - raster_worker_pools_(raster_worker_pools, - raster_worker_pools + num_raster_worker_pools), - did_finish_running_tasks_pending_count_(0u), - did_finish_running_tasks_required_for_activation_pending_count_(0u) { - DCHECK(client_); - for (RasterWorkerPoolVector::iterator it = raster_worker_pools_.begin(); - it != raster_worker_pools_.end(); - ++it) - (*it)->SetClient(this); -} - -RasterWorkerPoolDelegate::~RasterWorkerPoolDelegate() {} - -// static -scoped_ptr<RasterWorkerPoolDelegate> RasterWorkerPoolDelegate::Create( - RasterWorkerPoolClient* client, - RasterWorkerPool** raster_worker_pools, - size_t num_raster_worker_pools) { - return make_scoped_ptr(new RasterWorkerPoolDelegate( - client, raster_worker_pools, num_raster_worker_pools)); -} - -void RasterWorkerPoolDelegate::Shutdown() { - for (RasterWorkerPoolVector::iterator it = raster_worker_pools_.begin(); - it != raster_worker_pools_.end(); - ++it) - (*it)->Shutdown(); -} - -void RasterWorkerPoolDelegate::ScheduleTasks(RasterTaskQueue* raster_queue) { - for (size_t i = 0; i < raster_worker_pools_.size(); ++i) - raster_worker_pools_[i]->ScheduleTasks(&raster_queue[i]); - - did_finish_running_tasks_pending_count_ = raster_worker_pools_.size(); - did_finish_running_tasks_required_for_activation_pending_count_ = - raster_worker_pools_.size(); -} - -void RasterWorkerPoolDelegate::CheckForCompletedTasks() { - for (RasterWorkerPoolVector::iterator it = raster_worker_pools_.begin(); - it != raster_worker_pools_.end(); - ++it) - (*it)->CheckForCompletedTasks(); -} - -bool RasterWorkerPoolDelegate::ShouldForceTasksRequiredForActivationToComplete() - const { - return client_->ShouldForceTasksRequiredForActivationToComplete(); -} - -void RasterWorkerPoolDelegate::DidFinishRunningTasks() { - DCHECK_LT(0u, did_finish_running_tasks_pending_count_); - if (--did_finish_running_tasks_pending_count_) - return; - client_->DidFinishRunningTasks(); -} - -void RasterWorkerPoolDelegate::DidFinishRunningTasksRequiredForActivation() { - DCHECK_LT(0u, - did_finish_running_tasks_required_for_activation_pending_count_); - if (--did_finish_running_tasks_required_for_activation_pending_count_) - return; - client_->DidFinishRunningTasksRequiredForActivation(); -} - -} // namespace cc diff --git a/cc/resources/raster_worker_pool_delegate.h b/cc/resources/raster_worker_pool_delegate.h deleted file mode 100644 index 0a3be78949..0000000000 --- a/cc/resources/raster_worker_pool_delegate.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 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_DELEGATE_H_ -#define CC_RESOURCES_RASTER_WORKER_POOL_DELEGATE_H_ - -#include <vector> - -#include "cc/resources/raster_worker_pool.h" - -namespace cc { - -class RasterWorkerPoolDelegate : public RasterWorkerPoolClient { - public: - virtual ~RasterWorkerPoolDelegate(); - - static scoped_ptr<RasterWorkerPoolDelegate> Create( - RasterWorkerPoolClient* client, - RasterWorkerPool** raster_worker_pools, - size_t num_raster_worker_pools); - - void SetClient(RasterWorkerPoolClient* client); - void Shutdown(); - void ScheduleTasks(RasterTaskQueue* raster_queue); - void CheckForCompletedTasks(); - - // Overriden from RasterWorkerPoolClient: - virtual bool ShouldForceTasksRequiredForActivationToComplete() const OVERRIDE; - virtual void DidFinishRunningTasks() OVERRIDE; - virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE; - - private: - RasterWorkerPoolDelegate(RasterWorkerPoolClient* client, - RasterWorkerPool** raster_worker_pools, - size_t num_raster_worker_pools); - - RasterWorkerPoolClient* client_; - typedef std::vector<RasterWorkerPool*> RasterWorkerPoolVector; - RasterWorkerPoolVector raster_worker_pools_; - size_t did_finish_running_tasks_pending_count_; - size_t did_finish_running_tasks_required_for_activation_pending_count_; -}; - -} // namespace cc - -#endif // CC_RESOURCES_RASTER_WORKER_POOL_DELEGATE_H_ diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc index de4cac4987..f99c29396e 100644 --- a/cc/resources/raster_worker_pool_perftest.cc +++ b/cc/resources/raster_worker_pool_perftest.cc @@ -9,6 +9,7 @@ #include "cc/resources/direct_raster_worker_pool.h" #include "cc/resources/image_raster_worker_pool.h" #include "cc/resources/pixel_buffer_raster_worker_pool.h" +#include "cc/resources/rasterizer.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_resource.h" #include "cc/test/fake_output_surface.h" @@ -80,19 +81,17 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class PerfWorkerPoolTaskImpl : public internal::WorkerPoolTask { +class PerfImageDecodeTaskImpl : public ImageDecodeTask { public: - PerfWorkerPoolTaskImpl() {} + PerfImageDecodeTaskImpl() {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE {} - // Overridden from internal::WorkerPoolTask: - virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE {} + // Overridden from RasterizerTask: + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {} virtual void RunOnOriginThread() OVERRIDE {} - virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE {} + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {} virtual void RunReplyOnOriginThread() OVERRIDE { Reset(); } void Reset() { @@ -101,31 +100,28 @@ class PerfWorkerPoolTaskImpl : public internal::WorkerPoolTask { } protected: - virtual ~PerfWorkerPoolTaskImpl() {} + virtual ~PerfImageDecodeTaskImpl() {} private: - DISALLOW_COPY_AND_ASSIGN(PerfWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl); }; -class PerfRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { +class PerfRasterTaskImpl : public RasterTask { public: - PerfRasterWorkerPoolTaskImpl(scoped_ptr<ScopedResource> resource, - internal::WorkerPoolTask::Vector* dependencies) - : internal::RasterWorkerPoolTask(resource.get(), dependencies), - resource_(resource.Pass()) {} + PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource, + ImageDecodeTask::Vector* dependencies) + : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE {} - // Overridden from internal::WorkerPoolTask: - virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE { - client->AcquireCanvasForRaster(this, resource()); + // Overridden from RasterizerTask: + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE { + client->AcquireCanvasForRaster(this); } virtual void RunOnOriginThread() OVERRIDE {} - virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE { - client->ReleaseCanvasForRaster(this, resource()); + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE { + client->ReleaseCanvasForRaster(this); } virtual void RunReplyOnOriginThread() OVERRIDE { Reset(); } @@ -135,52 +131,21 @@ class PerfRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { } protected: - virtual ~PerfRasterWorkerPoolTaskImpl() {} + virtual ~PerfRasterTaskImpl() {} private: scoped_ptr<ScopedResource> resource_; - DISALLOW_COPY_AND_ASSIGN(PerfRasterWorkerPoolTaskImpl); -}; - -class PerfPixelBufferRasterWorkerPoolImpl : public PixelBufferRasterWorkerPool { - public: - PerfPixelBufferRasterWorkerPoolImpl( - internal::TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider) - : PixelBufferRasterWorkerPool(base::MessageLoopProxy::current().get(), - task_graph_runner, - resource_provider, - std::numeric_limits<size_t>::max()) {} -}; - -class PerfImageRasterWorkerPoolImpl : public ImageRasterWorkerPool { - public: - PerfImageRasterWorkerPoolImpl(internal::TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider) - : ImageRasterWorkerPool(base::MessageLoopProxy::current().get(), - task_graph_runner, - resource_provider, - GL_TEXTURE_2D) {} -}; - -class PerfDirectRasterWorkerPoolImpl : public DirectRasterWorkerPool { - public: - PerfDirectRasterWorkerPoolImpl(ResourceProvider* resource_provider, - ContextProvider* context_provider) - : DirectRasterWorkerPool(base::MessageLoopProxy::current().get(), - resource_provider, - context_provider) {} + DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl); }; class RasterWorkerPoolPerfTestBase { public: - typedef std::vector<scoped_refptr<internal::RasterWorkerPoolTask> > - RasterTaskVector; + typedef std::vector<scoped_refptr<RasterTask> > RasterTaskVector; RasterWorkerPoolPerfTestBase() : context_provider_(make_scoped_refptr(new PerfContextProvider)), - task_graph_runner_(new internal::TaskGraphRunner), + task_graph_runner_(new TaskGraphRunner), timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) { @@ -192,26 +157,17 @@ class RasterWorkerPoolPerfTestBase { ResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1) .Pass(); - pixel_buffer_raster_worker_pool_.reset( - new PerfPixelBufferRasterWorkerPoolImpl(task_graph_runner_.get(), - resource_provider_.get())); - image_raster_worker_pool_.reset(new PerfImageRasterWorkerPoolImpl( - task_graph_runner_.get(), resource_provider_.get())); - direct_raster_worker_pool_.reset(new PerfDirectRasterWorkerPoolImpl( - resource_provider_.get(), context_provider_)); } - void CreateImageDecodeTasks( - unsigned num_image_decode_tasks, - internal::WorkerPoolTask::Vector* image_decode_tasks) { + void CreateImageDecodeTasks(unsigned num_image_decode_tasks, + ImageDecodeTask::Vector* image_decode_tasks) { for (unsigned i = 0; i < num_image_decode_tasks; ++i) - image_decode_tasks->push_back(new PerfWorkerPoolTaskImpl); + image_decode_tasks->push_back(new PerfImageDecodeTaskImpl); } - void CreateRasterTasks( - unsigned num_raster_tasks, - const internal::WorkerPoolTask::Vector& image_decode_tasks, - RasterTaskVector* raster_tasks) { + void CreateRasterTasks(unsigned num_raster_tasks, + const ImageDecodeTask::Vector& image_decode_tasks, + RasterTaskVector* raster_tasks) { const gfx::Size size(1, 1); for (unsigned i = 0; i < num_raster_tasks; ++i) { @@ -219,9 +175,9 @@ class RasterWorkerPoolPerfTestBase { ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888); - internal::WorkerPoolTask::Vector dependencies = image_decode_tasks; + ImageDecodeTask::Vector dependencies = image_decode_tasks; raster_tasks->push_back( - new PerfRasterWorkerPoolTaskImpl(resource.Pass(), &dependencies)); + new PerfRasterTaskImpl(resource.Pass(), &dependencies)); } } @@ -241,48 +197,55 @@ class RasterWorkerPoolPerfTestBase { scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<internal::TaskGraphRunner> task_graph_runner_; - scoped_ptr<PixelBufferRasterWorkerPool> pixel_buffer_raster_worker_pool_; - scoped_ptr<ImageRasterWorkerPool> image_raster_worker_pool_; - scoped_ptr<DirectRasterWorkerPool> direct_raster_worker_pool_; + scoped_ptr<TaskGraphRunner> task_graph_runner_; LapTimer timer_; }; class RasterWorkerPoolPerfTest : public RasterWorkerPoolPerfTestBase, public testing::TestWithParam<RasterWorkerPoolType>, - public RasterWorkerPoolClient { + public RasterizerClient { public: - RasterWorkerPoolPerfTest() : raster_worker_pool_(NULL) { + RasterWorkerPoolPerfTest() { switch (GetParam()) { case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER: - raster_worker_pool_ = pixel_buffer_raster_worker_pool_.get(); + raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( + base::MessageLoopProxy::current().get(), + task_graph_runner_.get(), + resource_provider_.get(), + std::numeric_limits<size_t>::max()); break; case RASTER_WORKER_POOL_TYPE_IMAGE: - raster_worker_pool_ = image_raster_worker_pool_.get(); + raster_worker_pool_ = ImageRasterWorkerPool::Create( + base::MessageLoopProxy::current().get(), + task_graph_runner_.get(), + resource_provider_.get()); break; case RASTER_WORKER_POOL_TYPE_DIRECT: - raster_worker_pool_ = direct_raster_worker_pool_.get(); + raster_worker_pool_ = DirectRasterWorkerPool::Create( + base::MessageLoopProxy::current().get(), + resource_provider_.get(), + context_provider_.get()); break; } DCHECK(raster_worker_pool_); - raster_worker_pool_->SetClient(this); + raster_worker_pool_->AsRasterizer()->SetClient(this); } // Overridden from testing::Test: virtual void TearDown() OVERRIDE { - raster_worker_pool_->Shutdown(); - raster_worker_pool_->CheckForCompletedTasks(); + raster_worker_pool_->AsRasterizer()->Shutdown(); + raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks(); } - // Overriden from RasterWorkerPoolClient: - virtual bool ShouldForceTasksRequiredForActivationToComplete() - const OVERRIDE { + // Overriden from RasterizerClient: + virtual bool ShouldForceTasksRequiredForActivationToComplete() const + OVERRIDE { return false; } virtual void DidFinishRunningTasks() OVERRIDE { - raster_worker_pool_->CheckForCompletedTasks(); + raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks(); base::MessageLoop::current()->Quit(); } virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE {} @@ -295,7 +258,7 @@ class RasterWorkerPoolPerfTest void RunScheduleTasksTest(const std::string& test_name, unsigned num_raster_tasks, unsigned num_image_decode_tasks) { - internal::WorkerPoolTask::Vector image_decode_tasks; + ImageDecodeTask::Vector image_decode_tasks; RasterTaskVector raster_tasks; CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks); CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks); @@ -307,13 +270,13 @@ class RasterWorkerPoolPerfTest do { queue.Reset(); BuildRasterTaskQueue(&queue, raster_tasks); - raster_worker_pool_->ScheduleTasks(&queue); - raster_worker_pool_->CheckForCompletedTasks(); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue); + raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks(); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); RasterTaskQueue empty; - raster_worker_pool_->ScheduleTasks(&empty); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); perf_test::PrintResult("schedule_tasks", @@ -328,7 +291,7 @@ class RasterWorkerPoolPerfTest unsigned num_raster_tasks, unsigned num_image_decode_tasks) { const size_t kNumVersions = 2; - internal::WorkerPoolTask::Vector image_decode_tasks[kNumVersions]; + ImageDecodeTask::Vector image_decode_tasks[kNumVersions]; RasterTaskVector raster_tasks[kNumVersions]; for (size_t i = 0; i < kNumVersions; ++i) { CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]); @@ -344,14 +307,14 @@ class RasterWorkerPoolPerfTest do { queue.Reset(); BuildRasterTaskQueue(&queue, raster_tasks[count % kNumVersions]); - raster_worker_pool_->ScheduleTasks(&queue); - raster_worker_pool_->CheckForCompletedTasks(); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue); + raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks(); ++count; timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); RasterTaskQueue empty; - raster_worker_pool_->ScheduleTasks(&empty); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); perf_test::PrintResult("schedule_alternate_tasks", @@ -365,7 +328,7 @@ class RasterWorkerPoolPerfTest void RunScheduleAndExecuteTasksTest(const std::string& test_name, unsigned num_raster_tasks, unsigned num_image_decode_tasks) { - internal::WorkerPoolTask::Vector image_decode_tasks; + ImageDecodeTask::Vector image_decode_tasks; RasterTaskVector raster_tasks; CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks); CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks); @@ -377,13 +340,13 @@ class RasterWorkerPoolPerfTest do { queue.Reset(); BuildRasterTaskQueue(&queue, raster_tasks); - raster_worker_pool_->ScheduleTasks(&queue); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue); RunMessageLoopUntilAllTasksHaveCompleted(); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); RasterTaskQueue empty; - raster_worker_pool_->ScheduleTasks(&empty); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); perf_test::PrintResult("schedule_and_execute_tasks", @@ -408,7 +371,7 @@ class RasterWorkerPoolPerfTest return std::string(); } - RasterWorkerPool* raster_worker_pool_; + scoped_ptr<RasterWorkerPool> raster_worker_pool_; }; TEST_P(RasterWorkerPoolPerfTest, ScheduleTasks) { @@ -450,7 +413,7 @@ class RasterWorkerPoolCommonPerfTest : public RasterWorkerPoolPerfTestBase, void RunBuildRasterTaskQueueTest(const std::string& test_name, unsigned num_raster_tasks, unsigned num_image_decode_tasks) { - internal::WorkerPoolTask::Vector image_decode_tasks; + ImageDecodeTask::Vector image_decode_tasks; RasterTaskVector raster_tasks; CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks); CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks); diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc index a7e18fff80..aff7461896 100644 --- a/cc/resources/raster_worker_pool_unittest.cc +++ b/cc/resources/raster_worker_pool_unittest.cc @@ -13,6 +13,7 @@ #include "cc/resources/picture_pile.h" #include "cc/resources/picture_pile_impl.h" #include "cc/resources/pixel_buffer_raster_worker_pool.h" +#include "cc/resources/rasterizer.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_resource.h" #include "cc/test/fake_output_surface.h" @@ -36,35 +37,33 @@ enum RasterWorkerPoolType { RASTER_WORKER_POOL_TYPE_DIRECT }; -class TestRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { +class TestRasterTaskImpl : public RasterTask { public: typedef base::Callback<void(const PicturePileImpl::Analysis& analysis, bool was_canceled, RasterThread raster_thread)> Reply; - TestRasterWorkerPoolTaskImpl(const Resource* resource, - const Reply& reply, - internal::WorkerPoolTask::Vector* dependencies) - : internal::RasterWorkerPoolTask(resource, dependencies), + TestRasterTaskImpl(const Resource* resource, + const Reply& reply, + ImageDecodeTask::Vector* dependencies) + : RasterTask(resource, dependencies), reply_(reply), raster_thread_(RASTER_THREAD_NONE) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { raster_thread_ = RASTER_THREAD_WORKER; } - // Overridden from internal::WorkerPoolTask: - virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE { - client->AcquireCanvasForRaster(this, resource()); + // Overridden from RasterizerTask: + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE { + client->AcquireCanvasForRaster(this); } virtual void RunOnOriginThread() OVERRIDE { raster_thread_ = RASTER_THREAD_ORIGIN; } - virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE { - client->ReleaseCanvasForRaster(this, resource()); + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE { + client->ReleaseCanvasForRaster(this); } virtual void RunReplyOnOriginThread() OVERRIDE { reply_.Run( @@ -72,47 +71,44 @@ class TestRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { } protected: - virtual ~TestRasterWorkerPoolTaskImpl() {} + virtual ~TestRasterTaskImpl() {} private: const Reply reply_; RasterThread raster_thread_; - DISALLOW_COPY_AND_ASSIGN(TestRasterWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(TestRasterTaskImpl); }; -class BlockingTestRasterWorkerPoolTaskImpl - : public TestRasterWorkerPoolTaskImpl { +class BlockingTestRasterTaskImpl : public TestRasterTaskImpl { public: - BlockingTestRasterWorkerPoolTaskImpl( - const Resource* resource, - const Reply& reply, - base::Lock* lock, - internal::WorkerPoolTask::Vector* dependencies) - : TestRasterWorkerPoolTaskImpl(resource, reply, dependencies), - lock_(lock) {} - - // Overridden from internal::Task: + BlockingTestRasterTaskImpl(const Resource* resource, + const Reply& reply, + base::Lock* lock, + ImageDecodeTask::Vector* dependencies) + : TestRasterTaskImpl(resource, reply, dependencies), lock_(lock) {} + + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { base::AutoLock lock(*lock_); - TestRasterWorkerPoolTaskImpl::RunOnWorkerThread(); + TestRasterTaskImpl::RunOnWorkerThread(); } - // Overridden from internal::WorkerPoolTask: + // Overridden from RasterizerTask: virtual void RunReplyOnOriginThread() OVERRIDE {} protected: - virtual ~BlockingTestRasterWorkerPoolTaskImpl() {} + virtual ~BlockingTestRasterTaskImpl() {} private: base::Lock* lock_; - DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl); }; class RasterWorkerPoolTest : public testing::TestWithParam<RasterWorkerPoolType>, - public RasterWorkerPoolClient { + public RasterizerClient { public: struct RasterTaskResult { unsigned id; @@ -120,8 +116,7 @@ class RasterWorkerPoolTest RasterThread raster_thread; }; - typedef std::vector<scoped_refptr<internal::RasterWorkerPoolTask> > - RasterTaskVector; + typedef std::vector<scoped_refptr<RasterTask> > RasterTaskVector; RasterWorkerPoolTest() : context_provider_(TestContextProvider::Create()), @@ -135,49 +130,47 @@ class RasterWorkerPoolTest ResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1) .Pass(); - pixel_buffer_raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( - base::MessageLoopProxy::current().get(), - resource_provider_.get(), - std::numeric_limits<size_t>::max()); - image_raster_worker_pool_ = - ImageRasterWorkerPool::Create(base::MessageLoopProxy::current().get(), - resource_provider_.get(), - GL_TEXTURE_2D); - direct_raster_worker_pool_ = - DirectRasterWorkerPool::Create(base::MessageLoopProxy::current().get(), - resource_provider_.get(), - context_provider_.get()); switch (GetParam()) { case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER: - raster_worker_pool_ = pixel_buffer_raster_worker_pool_.get(); + raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( + base::MessageLoopProxy::current().get(), + RasterWorkerPool::GetTaskGraphRunner(), + resource_provider_.get(), + std::numeric_limits<size_t>::max()); break; case RASTER_WORKER_POOL_TYPE_IMAGE: - raster_worker_pool_ = image_raster_worker_pool_.get(); + raster_worker_pool_ = ImageRasterWorkerPool::Create( + base::MessageLoopProxy::current().get(), + RasterWorkerPool::GetTaskGraphRunner(), + resource_provider_.get()); break; case RASTER_WORKER_POOL_TYPE_DIRECT: - raster_worker_pool_ = direct_raster_worker_pool_.get(); + raster_worker_pool_ = DirectRasterWorkerPool::Create( + base::MessageLoopProxy::current().get(), + resource_provider_.get(), + context_provider_.get()); break; } DCHECK(raster_worker_pool_); - raster_worker_pool_->SetClient(this); + raster_worker_pool_->AsRasterizer()->SetClient(this); } virtual ~RasterWorkerPoolTest() { resource_provider_.reset(); } // Overridden from testing::Test: virtual void TearDown() OVERRIDE { - raster_worker_pool_->Shutdown(); - raster_worker_pool_->CheckForCompletedTasks(); + raster_worker_pool_->AsRasterizer()->Shutdown(); + raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks(); } // Overriden from RasterWorkerPoolClient: - virtual bool ShouldForceTasksRequiredForActivationToComplete() - const OVERRIDE { + virtual bool ShouldForceTasksRequiredForActivationToComplete() const + OVERRIDE { return false; } virtual void DidFinishRunningTasks() OVERRIDE { - raster_worker_pool_->CheckForCompletedTasks(); + raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks(); base::MessageLoop::current()->Quit(); } virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE {} @@ -207,7 +200,7 @@ class RasterWorkerPoolTest ++it) queue.items.push_back(RasterTaskQueue::Item(*it, false)); - raster_worker_pool_->ScheduleTasks(&queue); + raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue); } void AppendTask(unsigned id) { @@ -218,8 +211,8 @@ class RasterWorkerPoolTest resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888); const Resource* const_resource = resource.get(); - internal::WorkerPoolTask::Vector empty; - tasks_.push_back(new TestRasterWorkerPoolTaskImpl( + ImageDecodeTask::Vector empty; + tasks_.push_back(new TestRasterTaskImpl( const_resource, base::Bind(&RasterWorkerPoolTest::OnTaskCompleted, base::Unretained(this), @@ -236,8 +229,8 @@ class RasterWorkerPoolTest resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888); const Resource* const_resource = resource.get(); - internal::WorkerPoolTask::Vector empty; - tasks_.push_back(new BlockingTestRasterWorkerPoolTaskImpl( + ImageDecodeTask::Vector empty; + tasks_.push_back(new BlockingTestRasterTaskImpl( const_resource, base::Bind(&RasterWorkerPoolTest::OnTaskCompleted, base::Unretained(this), @@ -275,10 +268,7 @@ class RasterWorkerPoolTest scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<PixelBufferRasterWorkerPool> pixel_buffer_raster_worker_pool_; - scoped_ptr<ImageRasterWorkerPool> image_raster_worker_pool_; - scoped_ptr<DirectRasterWorkerPool> direct_raster_worker_pool_; - RasterWorkerPool* raster_worker_pool_; + scoped_ptr<RasterWorkerPool> raster_worker_pool_; base::CancelableClosure timeout_; int timeout_seconds_; bool timed_out_; diff --git a/cc/resources/rasterizer.cc b/cc/resources/rasterizer.cc new file mode 100644 index 0000000000..563690d709 --- /dev/null +++ b/cc/resources/rasterizer.cc @@ -0,0 +1,78 @@ +// Copyright 2014 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. + +#include "cc/resources/rasterizer.h" + +#include <algorithm> + +namespace cc { + +RasterizerTask::RasterizerTask() : did_schedule_(false), did_complete_(false) {} + +RasterizerTask::~RasterizerTask() { + DCHECK(!did_schedule_); + DCHECK(!did_run_ || did_complete_); +} + +ImageDecodeTask* RasterizerTask::AsImageDecodeTask() { return NULL; } + +RasterTask* RasterizerTask::AsRasterTask() { return NULL; } + +void RasterizerTask::WillSchedule() { DCHECK(!did_schedule_); } + +void RasterizerTask::DidSchedule() { + did_schedule_ = true; + did_complete_ = false; +} + +bool RasterizerTask::HasBeenScheduled() const { return did_schedule_; } + +void RasterizerTask::WillComplete() { DCHECK(!did_complete_); } + +void RasterizerTask::DidComplete() { + DCHECK(did_schedule_); + DCHECK(!did_complete_); + did_schedule_ = false; + did_complete_ = true; +} + +bool RasterizerTask::HasCompleted() const { return did_complete_; } + +ImageDecodeTask::ImageDecodeTask() {} + +ImageDecodeTask::~ImageDecodeTask() {} + +ImageDecodeTask* ImageDecodeTask::AsImageDecodeTask() { return this; } + +RasterTask::RasterTask(const Resource* resource, + ImageDecodeTask::Vector* dependencies) + : resource_(resource) { + dependencies_.swap(*dependencies); +} + +RasterTask::~RasterTask() {} + +RasterTask* RasterTask::AsRasterTask() { return this; } + +RasterTaskQueue::Item::Item(RasterTask* task, bool required_for_activation) + : task(task), required_for_activation(required_for_activation) {} + +RasterTaskQueue::Item::~Item() {} + +RasterTaskQueue::RasterTaskQueue() : required_for_activation_count(0u) {} + +RasterTaskQueue::~RasterTaskQueue() {} + +void RasterTaskQueue::Swap(RasterTaskQueue* other) { + items.swap(other->items); + std::swap(required_for_activation_count, + other->required_for_activation_count); +} + +void RasterTaskQueue::Reset() { + required_for_activation_count = 0u; + items.clear(); +} + +} // namespace cc diff --git a/cc/resources/rasterizer.h b/cc/resources/rasterizer.h new file mode 100644 index 0000000000..5467d9055e --- /dev/null +++ b/cc/resources/rasterizer.h @@ -0,0 +1,166 @@ +// Copyright 2014 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_RASTERIZER_H_ +#define CC_RESOURCES_RASTERIZER_H_ + +#include <vector> + +#include "base/callback.h" +#include "cc/resources/resource_format.h" +#include "cc/resources/task_graph_runner.h" + +class SkCanvas; + +namespace cc { +class ImageDecodeTask; +class RasterTask; +class Resource; + +class CC_EXPORT RasterizerTaskClient { + public: + virtual SkCanvas* AcquireCanvasForRaster(RasterTask* task) = 0; + virtual void ReleaseCanvasForRaster(RasterTask* task) = 0; + + protected: + virtual ~RasterizerTaskClient() {} +}; + +class CC_EXPORT RasterizerTask : public Task { + public: + typedef std::vector<scoped_refptr<RasterizerTask> > Vector; + + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) = 0; + virtual void RunOnOriginThread() = 0; + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) = 0; + virtual void RunReplyOnOriginThread() = 0; + + // Type-checking downcast routines. + virtual ImageDecodeTask* AsImageDecodeTask(); + virtual RasterTask* AsRasterTask(); + + void WillSchedule(); + void DidSchedule(); + bool HasBeenScheduled() const; + + void WillComplete(); + void DidComplete(); + bool HasCompleted() const; + + protected: + RasterizerTask(); + virtual ~RasterizerTask(); + + bool did_schedule_; + bool did_complete_; +}; + +class CC_EXPORT ImageDecodeTask : public RasterizerTask { + public: + typedef std::vector<scoped_refptr<ImageDecodeTask> > Vector; + + // Overridden from RasterizerTask: + virtual ImageDecodeTask* AsImageDecodeTask() OVERRIDE; + + protected: + ImageDecodeTask(); + virtual ~ImageDecodeTask(); +}; + +class CC_EXPORT RasterTask : public RasterizerTask { + public: + typedef std::vector<scoped_refptr<RasterTask> > Vector; + + // Overridden from RasterizerTask: + virtual RasterTask* AsRasterTask() OVERRIDE; + + const Resource* resource() const { return resource_; } + const ImageDecodeTask::Vector& dependencies() const { return dependencies_; } + + protected: + RasterTask(const Resource* resource, ImageDecodeTask::Vector* dependencies); + virtual ~RasterTask(); + + private: + const Resource* resource_; + ImageDecodeTask::Vector dependencies_; +}; + +class CC_EXPORT RasterizerClient { + public: + virtual bool ShouldForceTasksRequiredForActivationToComplete() const = 0; + virtual void DidFinishRunningTasks() = 0; + virtual void DidFinishRunningTasksRequiredForActivation() = 0; + + protected: + virtual ~RasterizerClient() {} +}; + +struct CC_EXPORT RasterTaskQueue { + struct CC_EXPORT Item { + class TaskComparator { + public: + explicit TaskComparator(const RasterTask* task) : task_(task) {} + + bool operator()(const Item& item) const { return item.task == task_; } + + private: + const RasterTask* task_; + }; + + typedef std::vector<Item> Vector; + + Item(RasterTask* task, bool required_for_activation); + ~Item(); + + static bool IsRequiredForActivation(const Item& item) { + return item.required_for_activation; + } + + RasterTask* task; + bool required_for_activation; + }; + + RasterTaskQueue(); + ~RasterTaskQueue(); + + void Swap(RasterTaskQueue* other); + void Reset(); + + Item::Vector items; + size_t required_for_activation_count; +}; + +// This interface can be used to schedule and run raster tasks. The client will +// be notified asynchronously when the set of tasks marked as "required for +// activation" have finished running and when all scheduled tasks have finished +// running. The client can call CheckForCompletedTasks() at any time to dispatch +// pending completion callbacks for all tasks that have finished running. +class CC_EXPORT Rasterizer { + public: + // Set the client instance to be notified when finished running tasks. + virtual void SetClient(RasterizerClient* client) = 0; + + // Tells the worker pool to shutdown after canceling all previously scheduled + // tasks. Reply callbacks are still guaranteed to run when + // CheckForCompletedTasks() is called. + virtual void Shutdown() = 0; + + // Schedule running of raster tasks in |queue| and all dependencies. + // Previously scheduled tasks that are not 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(RasterTaskQueue* queue) = 0; + + // Check for completed tasks and dispatch reply callbacks. + virtual void CheckForCompletedTasks() = 0; + + protected: + virtual ~Rasterizer() {} +}; + +} // namespace cc + +#endif // CC_RESOURCES_RASTERIZER_H_ diff --git a/cc/resources/rasterizer_delegate.cc b/cc/resources/rasterizer_delegate.cc new file mode 100644 index 0000000000..dcceb1f215 --- /dev/null +++ b/cc/resources/rasterizer_delegate.cc @@ -0,0 +1,89 @@ +// Copyright 2014 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. + +#include "cc/resources/rasterizer_delegate.h" + +#include "base/debug/trace_event.h" + +namespace cc { + +RasterizerDelegate::RasterizerDelegate(RasterizerClient* client, + Rasterizer** rasterizers, + size_t num_rasterizers) + : client_(client), + rasterizers_(rasterizers, rasterizers + num_rasterizers), + did_finish_running_tasks_pending_count_(0u), + did_finish_running_tasks_required_for_activation_pending_count_(0u) { + DCHECK(client_); + for (RasterizerVector::iterator it = rasterizers_.begin(); + it != rasterizers_.end(); + ++it) + (*it)->SetClient(this); +} + +RasterizerDelegate::~RasterizerDelegate() {} + +// static +scoped_ptr<RasterizerDelegate> RasterizerDelegate::Create( + RasterizerClient* client, + Rasterizer** rasterizers, + size_t num_rasterizers) { + return make_scoped_ptr( + new RasterizerDelegate(client, rasterizers, num_rasterizers)); +} + +void RasterizerDelegate::Shutdown() { + for (RasterizerVector::iterator it = rasterizers_.begin(); + it != rasterizers_.end(); + ++it) + (*it)->Shutdown(); +} + +void RasterizerDelegate::ScheduleTasks(RasterTaskQueue* queue) { + for (size_t i = 0; i < rasterizers_.size(); ++i) + rasterizers_[i]->ScheduleTasks(&queue[i]); + + did_finish_running_tasks_pending_count_ = rasterizers_.size(); + did_finish_running_tasks_required_for_activation_pending_count_ = + rasterizers_.size(); +} + +void RasterizerDelegate::CheckForCompletedTasks() { + for (RasterizerVector::iterator it = rasterizers_.begin(); + it != rasterizers_.end(); + ++it) + (*it)->CheckForCompletedTasks(); +} + +bool RasterizerDelegate::ShouldForceTasksRequiredForActivationToComplete() + const { + return client_->ShouldForceTasksRequiredForActivationToComplete(); +} + +void RasterizerDelegate::DidFinishRunningTasks() { + TRACE_EVENT1("cc", + "RasterizerDelegate::DidFinishRunningTasks", + "pending_count", + did_finish_running_tasks_pending_count_); + + DCHECK_LT(0u, did_finish_running_tasks_pending_count_); + if (--did_finish_running_tasks_pending_count_) + return; + client_->DidFinishRunningTasks(); +} + +void RasterizerDelegate::DidFinishRunningTasksRequiredForActivation() { + TRACE_EVENT1("cc", + "RasterizerDelegate::DidFinishRunningTasksRequiredForActivation", + "pending_count", + did_finish_running_tasks_required_for_activation_pending_count_); + + DCHECK_LT(0u, + did_finish_running_tasks_required_for_activation_pending_count_); + if (--did_finish_running_tasks_required_for_activation_pending_count_) + return; + client_->DidFinishRunningTasksRequiredForActivation(); +} + +} // namespace cc diff --git a/cc/resources/rasterizer_delegate.h b/cc/resources/rasterizer_delegate.h new file mode 100644 index 0000000000..f92096371e --- /dev/null +++ b/cc/resources/rasterizer_delegate.h @@ -0,0 +1,46 @@ +// Copyright 2014 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_RASTERIZER_DELEGATE_H_ +#define CC_RESOURCES_RASTERIZER_DELEGATE_H_ + +#include <vector> + +#include "cc/resources/rasterizer.h" + +namespace cc { + +class RasterizerDelegate : public RasterizerClient { + public: + virtual ~RasterizerDelegate(); + + static scoped_ptr<RasterizerDelegate> Create(RasterizerClient* client, + Rasterizer** rasterizers, + size_t num_rasterizers); + + void SetClient(RasterizerClient* client); + void Shutdown(); + void ScheduleTasks(RasterTaskQueue* queue); + void CheckForCompletedTasks(); + + // Overriden from RasterizerClient: + virtual bool ShouldForceTasksRequiredForActivationToComplete() const OVERRIDE; + virtual void DidFinishRunningTasks() OVERRIDE; + virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE; + + private: + RasterizerDelegate(RasterizerClient* client, + Rasterizer** rasterizers, + size_t num_rasterizers); + + RasterizerClient* client_; + typedef std::vector<Rasterizer*> RasterizerVector; + RasterizerVector rasterizers_; + size_t did_finish_running_tasks_pending_count_; + size_t did_finish_running_tasks_required_for_activation_pending_count_; +}; + +} // namespace cc + +#endif // CC_RESOURCES_RASTERIZER_DELEGATE_H_ diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index 7170a397c7..31b9b27201 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc @@ -51,16 +51,10 @@ scoped_ptr<ScopedResource> ResourcePool::AcquireResource( return make_scoped_ptr(resource); } - // Create new resource. scoped_ptr<ScopedResource> resource = ScopedResource::Create(resource_provider_); resource->AllocateManaged(size, target_, format_); - // Extend all read locks on all resources until the resource is - // finished being used, such that we know when resources are - // truly safe to recycle. - resource_provider_->EnableReadLockFences(resource->id(), true); - memory_usage_bytes_ += resource->bytes(); ++resource_count_; return resource.Pass(); diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h index e321d08bb2..5f481e986a 100644 --- a/cc/resources/resource_pool.h +++ b/cc/resources/resource_pool.h @@ -40,10 +40,13 @@ class CC_EXPORT ResourcePool { size_t acquired_memory_usage_bytes() const { return memory_usage_bytes_ - unused_memory_usage_bytes_; } + size_t total_resource_count() const { return resource_count_; } size_t acquired_resource_count() const { return resource_count_ - unused_resources_.size(); } + ResourceFormat resource_format() const { return format_; } + protected: ResourcePool(ResourceProvider* resource_provider, GLenum target, diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 39d663ae56..f208341bb8 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -198,6 +198,30 @@ class BufferIdAllocator : public IdAllocator { DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator); }; +// Generic fence implementation for query objects. Fence has passed when query +// result is available. +class QueryFence : public ResourceProvider::Fence { + public: + QueryFence(gpu::gles2::GLES2Interface* gl, unsigned query_id) + : gl_(gl), query_id_(query_id) {} + + // Overridden from ResourceProvider::Fence: + virtual bool HasPassed() OVERRIDE { + unsigned available = 1; + gl_->GetQueryObjectuivEXT( + query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available); + return !!available; + } + + private: + virtual ~QueryFence() {} + + gpu::gles2::GLES2Interface* gl_; + unsigned query_id_; + + DISALLOW_COPY_AND_ASSIGN(QueryFence); +}; + } // namespace ResourceProvider::Resource::Resource() @@ -205,8 +229,8 @@ ResourceProvider::Resource::Resource() gl_id(0), gl_pixel_buffer_id(0), gl_upload_query_id(0), + gl_read_lock_query_id(0), pixels(NULL), - pixel_buffer(NULL), lock_for_read_count(0), imported_count(0), exported_count(0), @@ -250,8 +274,8 @@ ResourceProvider::Resource::Resource(GLuint texture_id, gl_id(texture_id), gl_pixel_buffer_id(0), gl_upload_query_id(0), + gl_read_lock_query_id(0), pixels(NULL), - pixel_buffer(NULL), lock_for_read_count(0), imported_count(0), exported_count(0), @@ -293,8 +317,8 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, gl_id(0), gl_pixel_buffer_id(0), gl_upload_query_id(0), + gl_read_lock_query_id(0), pixels(pixels), - pixel_buffer(NULL), lock_for_read_count(0), imported_count(0), exported_count(0), @@ -337,8 +361,8 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id, gl_id(0), gl_pixel_buffer_id(0), gl_upload_query_id(0), + gl_read_lock_query_id(0), pixels(NULL), - pixel_buffer(NULL), lock_for_read_count(0), imported_count(0), exported_count(0), @@ -833,13 +857,18 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, DCHECK(gl); GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id)); } - if (resource->gl_upload_query_id) { DCHECK(resource->origin == Resource::Internal); GLES2Interface* gl = ContextGL(); DCHECK(gl); GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id)); } + if (resource->gl_read_lock_query_id) { + DCHECK(resource->origin == Resource::Internal); + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id)); + } if (resource->gl_pixel_buffer_id) { DCHECK(resource->origin == Resource::Internal); GLES2Interface* gl = ContextGL(); @@ -887,10 +916,6 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, DCHECK(resource->origin == Resource::Internal); delete[] resource->pixels; } - if (resource->pixel_buffer) { - DCHECK(resource->origin == Resource::Internal); - delete[] resource->pixel_buffer; - } // We should never delete the texture for a resource created by // CreateResourceFromExternalTexture(). DCHECK(!resource->gl_id || resource->origin == Resource::External); @@ -1758,10 +1783,10 @@ SkCanvas* ResourceProvider::MapImageRasterBuffer(ResourceId id) { return resource->image_raster_buffer->LockForWrite(); } -void ResourceProvider::UnmapImageRasterBuffer(ResourceId id) { +bool ResourceProvider::UnmapImageRasterBuffer(ResourceId id) { Resource* resource = GetResource(id); - resource->image_raster_buffer->UnlockForWrite(); resource->dirty_image = true; + return resource->image_raster_buffer->UnlockForWrite(); } void ResourceProvider::AcquirePixelRasterBuffer(ResourceId id) { @@ -1797,27 +1822,20 @@ void ResourceProvider::AcquirePixelBuffer(Resource* resource) { DCHECK(!resource->image_id); DCHECK_NE(ETC1, resource->format); - if (resource->type == GLTexture) { - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - if (!resource->gl_pixel_buffer_id) - resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId(); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, - resource->gl_pixel_buffer_id); - unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8; - gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, - resource->size.height() * - RoundUp(bytes_per_pixel * resource->size.width(), 4u), - NULL, - GL_DYNAMIC_DRAW); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); - } else { - DCHECK_EQ(Bitmap, resource->type); - if (resource->pixel_buffer) - return; - size_t bytes = SharedBitmap::CheckedSizeInBytes(resource->size); - resource->pixel_buffer = new uint8_t[bytes]; - } + DCHECK_EQ(GLTexture, resource->type); + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + if (!resource->gl_pixel_buffer_id) + resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId(); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->gl_pixel_buffer_id); + unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8; + gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->size.height() * + RoundUp(bytes_per_pixel * resource->size.width(), 4u), + NULL, + GL_DYNAMIC_DRAW); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); } void ResourceProvider::ReleasePixelBuffer(Resource* resource) { @@ -1840,23 +1858,16 @@ void ResourceProvider::ReleasePixelBuffer(Resource* resource) { resource->locked_for_write = false; } - if (resource->type == GLTexture) { - if (!resource->gl_pixel_buffer_id) - return; - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, - resource->gl_pixel_buffer_id); - gl->BufferData( - GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); - } else { - DCHECK_EQ(Bitmap, resource->type); - if (!resource->pixel_buffer) - return; - delete[] resource->pixel_buffer; - resource->pixel_buffer = NULL; - } + DCHECK_EQ(GLTexture, resource->type); + if (!resource->gl_pixel_buffer_id) + return; + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->gl_pixel_buffer_id); + gl->BufferData( + GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); } uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource, @@ -1869,21 +1880,18 @@ uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource, DCHECK(!resource->image_id); *stride = 0; - if (resource->type == GLTexture) { - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - DCHECK(resource->gl_pixel_buffer_id); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, - resource->gl_pixel_buffer_id); - uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM( - GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY)); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); - // Buffer is required to be 4-byte aligned. - CHECK(!(reinterpret_cast<intptr_t>(image) & 3)); - return image; - } - DCHECK_EQ(Bitmap, resource->type); - return resource->pixel_buffer; + DCHECK_EQ(GLTexture, resource->type); + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + DCHECK(resource->gl_pixel_buffer_id); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->gl_pixel_buffer_id); + uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM( + GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY)); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); + // Buffer is required to be 4-byte aligned. + CHECK(!(reinterpret_cast<intptr_t>(image) & 3)); + return image; } void ResourceProvider::UnmapPixelBuffer(const Resource* resource) { @@ -1894,15 +1902,14 @@ void ResourceProvider::UnmapPixelBuffer(const Resource* resource) { DCHECK_EQ(resource->exported_count, 0); DCHECK(!resource->image_id); - if (resource->type == GLTexture) { - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - DCHECK(resource->gl_pixel_buffer_id); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, - resource->gl_pixel_buffer_id); - gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); - } + DCHECK_EQ(GLTexture, resource->type); + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + DCHECK(resource->gl_pixel_buffer_id); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->gl_pixel_buffer_id); + gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); } GLenum ResourceProvider::BindForSampling( @@ -1949,53 +1956,42 @@ void ResourceProvider::BeginSetPixels(ResourceId id) { resource->allocated = true; LockForWrite(id); - if (resource->type == GLTexture) { - DCHECK(resource->gl_id); - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - DCHECK(resource->gl_pixel_buffer_id); - DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D)); - gl->BindTexture(GL_TEXTURE_2D, resource->gl_id); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, - resource->gl_pixel_buffer_id); - if (!resource->gl_upload_query_id) - gl->GenQueriesEXT(1, &resource->gl_upload_query_id); - gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, - resource->gl_upload_query_id); - if (allocate) { - gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D, - 0, /* level */ - GLInternalFormat(resource->format), - resource->size.width(), - resource->size.height(), - 0, /* border */ - GLDataFormat(resource->format), - GLDataType(resource->format), - NULL); - } else { - gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, - 0, /* level */ - 0, /* x */ - 0, /* y */ - resource->size.width(), - resource->size.height(), - GLDataFormat(resource->format), - GLDataType(resource->format), - NULL); - } - gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM); - gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); + DCHECK_EQ(GLTexture, resource->type); + DCHECK(resource->gl_id); + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + DCHECK(resource->gl_pixel_buffer_id); + DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D)); + gl->BindTexture(GL_TEXTURE_2D, resource->gl_id); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->gl_pixel_buffer_id); + if (!resource->gl_upload_query_id) + gl->GenQueriesEXT(1, &resource->gl_upload_query_id); + gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, + resource->gl_upload_query_id); + if (allocate) { + gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D, + 0, /* level */ + GLInternalFormat(resource->format), + resource->size.width(), + resource->size.height(), + 0, /* border */ + GLDataFormat(resource->format), + GLDataType(resource->format), + NULL); } else { - DCHECK_EQ(Bitmap, resource->type); - DCHECK(!resource->mailbox.IsValid()); - DCHECK(resource->pixel_buffer); - DCHECK_EQ(RGBA_8888, resource->format); - - size_t bytes = SharedBitmap::CheckedSizeInBytes(resource->size); - memcpy(resource->pixels, resource->pixel_buffer, bytes); - delete[] resource->pixel_buffer; - resource->pixel_buffer = NULL; + gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, + 0, /* level */ + 0, /* x */ + 0, /* y */ + resource->size.width(), + resource->size.height(), + GLDataFormat(resource->format), + GLDataType(resource->format), + NULL); } + gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM); + gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); resource->pending_set_pixels = true; resource->set_pixels_completion_forced = false; @@ -2219,6 +2215,65 @@ void ResourceProvider::UnmapImage(const Resource* resource) { } } +void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) { + TRACE_EVENT0("cc", "ResourceProvider::CopyResource"); + + Resource* source_resource = GetResource(source_id); + DCHECK(!source_resource->lock_for_read_count); + DCHECK(source_resource->origin == Resource::Internal); + DCHECK_EQ(source_resource->exported_count, 0); + DCHECK(source_resource->allocated); + LazyCreate(source_resource); + + Resource* dest_resource = GetResource(dest_id); + DCHECK(!dest_resource->locked_for_write); + DCHECK(!dest_resource->lock_for_read_count); + DCHECK(dest_resource->origin == Resource::Internal); + DCHECK_EQ(dest_resource->exported_count, 0); + LazyCreate(dest_resource); + + DCHECK_EQ(source_resource->type, dest_resource->type); + DCHECK_EQ(source_resource->format, dest_resource->format); + DCHECK(source_resource->size == dest_resource->size); + + if (source_resource->type == GLTexture) { + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + if (source_resource->image_id && source_resource->dirty_image) { + gl->BindTexture(source_resource->target, source_resource->gl_id); + BindImageForSampling(source_resource); + } + if (!source_resource->gl_read_lock_query_id) + gl->GenQueriesEXT(1, &source_resource->gl_read_lock_query_id); + // Note: Use of COMMANDS_ISSUED target assumes that it's safe to access the + // source resource once the command has been processed on the service side. + // TODO(reveman): Implement COMMANDS_COMPLETED query that can be used to + // accurately determine when it's safe to access the source resource again. + gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, + source_resource->gl_read_lock_query_id); + DCHECK(!dest_resource->image_id); + dest_resource->allocated = true; + gl->CopyTextureCHROMIUM(dest_resource->target, + source_resource->gl_id, + dest_resource->gl_id, + 0, + GLInternalFormat(dest_resource->format), + GLDataType(dest_resource->format)); + // End query and create a read lock fence that will prevent access to + // source resource until CopyTextureCHROMIUM command has completed. + gl->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); + source_resource->read_lock_fence = make_scoped_refptr( + new QueryFence(gl, source_resource->gl_read_lock_query_id)); + } else { + DCHECK_EQ(Bitmap, source_resource->type); + DCHECK_EQ(RGBA_8888, source_resource->format); + LazyAllocate(dest_resource); + + size_t bytes = SharedBitmap::CheckedSizeInBytes(source_resource->size); + memcpy(dest_resource->pixels, source_resource->pixels, bytes); + } +} + GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) { GLint active_unit = 0; gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index c7c0f5f487..9853cb4608 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -324,13 +324,14 @@ class CC_EXPORT ResourceProvider { SkCanvas* MapDirectRasterBuffer(ResourceId id); void UnmapDirectRasterBuffer(ResourceId id); - // Returns a canvas backed by an image buffer. + // Returns a canvas backed by an image buffer. UnmapImageRasterBuffer + // returns true if canvas was written to while mapped. // Rasterizing to the canvas writes the content into the image buffer, // which is internally bound to the underlying resource when read. // Call Unmap before the resource can be read or used for compositing. // It is used by ImageRasterWorkerPool. SkCanvas* MapImageRasterBuffer(ResourceId id); - void UnmapImageRasterBuffer(ResourceId id); + bool UnmapImageRasterBuffer(ResourceId id); // Returns a canvas backed by pixel buffer. UnmapPixelRasterBuffer // returns true if canvas was written to while mapped. @@ -370,6 +371,9 @@ class CC_EXPORT ResourceProvider { // Indicates if we can currently lock this resource for write. bool CanLockForWrite(ResourceId id); + // Copy pixels from source to destination. + void CopyResource(ResourceId source_id, ResourceId dest_id); + static GLint GetActiveTextureUnit(gpu::gles2::GLES2Interface* gl); private: @@ -409,10 +413,11 @@ class CC_EXPORT ResourceProvider { unsigned gl_pixel_buffer_id; // Query used to determine when asynchronous set pixels complete. unsigned gl_upload_query_id; + // Query used to determine when read lock fence has passed. + unsigned gl_read_lock_query_id; TextureMailbox mailbox; ReleaseCallback release_callback; uint8_t* pixels; - uint8_t* pixel_buffer; int lock_for_read_count; int imported_count; int exported_count; diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 537154af56..f3e2e3014c 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -2812,50 +2812,6 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) { Mock::VerifyAndClearExpectations(context); } -TEST_P(ResourceProviderTest, PixelBuffer_Bitmap) { - if (GetParam() != ResourceProvider::Bitmap) - return; - FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( - FakeOutputSurface::CreateSoftware(make_scoped_ptr( - new SoftwareOutputDevice))); - CHECK(output_surface->BindToClient(&output_surface_client)); - - gfx::Size size(1, 1); - ResourceFormat format = RGBA_8888; - ResourceProvider::ResourceId id = 0; - const uint32_t kBadBeef = 0xbadbeef; - - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1)); - - id = resource_provider->CreateResource( - size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - resource_provider->AcquirePixelRasterBuffer(id); - - SkBitmap bitmap; - bitmap.allocN32Pixels(size.width(), size.height()); - *(bitmap.getAddr32(0, 0)) = kBadBeef; - SkCanvas* canvas = resource_provider->MapPixelRasterBuffer(id); - canvas->writePixels(bitmap, 0, 0); - resource_provider->UnmapPixelRasterBuffer(id); - - resource_provider->BeginSetPixels(id); - EXPECT_TRUE(resource_provider->DidSetPixelsComplete(id)); - - resource_provider->ReleasePixelRasterBuffer(id); - - { - ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), id); - const SkBitmap* sk_bitmap = lock.sk_bitmap(); - EXPECT_EQ(sk_bitmap->width(), size.width()); - EXPECT_EQ(sk_bitmap->height(), size.height()); - EXPECT_EQ(*sk_bitmap->getAddr32(0, 0), kBadBeef); - } - - resource_provider->DeleteResource(id); -} - TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) { // Only for GL textures. if (GetParam() != ResourceProvider::GLTexture) @@ -3071,6 +3027,136 @@ TEST_P(ResourceProviderTest, Image_Bitmap) { resource_provider->DeleteResource(id); } +TEST_P(ResourceProviderTest, CopyResource_GLTexture) { + if (GetParam() != ResourceProvider::GLTexture) + return; + scoped_ptr<AllocationTrackingContext3D> context_owned( + new StrictMock<AllocationTrackingContext3D>); + AllocationTrackingContext3D* context = context_owned.get(); + + FakeOutputSurfaceClient output_surface_client; + scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( + context_owned.PassAs<TestWebGraphicsContext3D>())); + ASSERT_TRUE(output_surface->BindToClient(&output_surface_client)); + + const int kWidth = 2; + const int kHeight = 2; + gfx::Size size(kWidth, kHeight); + ResourceFormat format = RGBA_8888; + ResourceProvider::ResourceId source_id = 0; + ResourceProvider::ResourceId dest_id = 0; + const unsigned kSourceTextureId = 123u; + const unsigned kDestTextureId = 321u; + const unsigned kImageId = 234u; + + scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1)); + + source_id = resource_provider->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + + const int kStride = 4; + void* dummy_mapped_buffer_address = NULL; + EXPECT_CALL(*context, createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES)) + .WillOnce(Return(kImageId)) + .RetiresOnSaturation(); + EXPECT_CALL( + *context, + getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _)) + .WillOnce(SetArgPointee<2>(kStride)) + .RetiresOnSaturation(); + EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE)) + .WillOnce(Return(dummy_mapped_buffer_address)) + .RetiresOnSaturation(); + resource_provider->MapImageRasterBuffer(source_id); + Mock::VerifyAndClearExpectations(context); + + EXPECT_CALL(*context, unmapImageCHROMIUM(kImageId)) + .Times(1) + .RetiresOnSaturation(); + resource_provider->UnmapImageRasterBuffer(source_id); + Mock::VerifyAndClearExpectations(context); + + dest_id = resource_provider->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + + EXPECT_CALL(*context, NextTextureId()) + .WillOnce(Return(kDestTextureId)) + .RetiresOnSaturation(); + EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kDestTextureId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*context, NextTextureId()) + .WillOnce(Return(kSourceTextureId)) + .RetiresOnSaturation(); + EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId)) + .Times(2) + .RetiresOnSaturation(); + EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId)) + .Times(1) + .RetiresOnSaturation(); + resource_provider->CopyResource(source_id, dest_id); + Mock::VerifyAndClearExpectations(context); + + EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*context, RetireTextureId(kSourceTextureId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*context, RetireTextureId(kDestTextureId)) + .Times(1) + .RetiresOnSaturation(); + resource_provider->DeleteResource(source_id); + resource_provider->DeleteResource(dest_id); +} + +TEST_P(ResourceProviderTest, CopyResource_Bitmap) { + if (GetParam() != ResourceProvider::Bitmap) + return; + FakeOutputSurfaceClient output_surface_client; + scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateSoftware( + make_scoped_ptr(new SoftwareOutputDevice))); + CHECK(output_surface->BindToClient(&output_surface_client)); + + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + ResourceProvider::ResourceId source_id = 0; + ResourceProvider::ResourceId dest_id = 0; + const uint32_t kBadBeef = 0xbadbeef; + + scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1)); + + source_id = resource_provider->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + + SkBitmap bitmap; + bitmap.allocN32Pixels(size.width(), size.height()); + *(bitmap.getAddr32(0, 0)) = kBadBeef; + SkCanvas* canvas = resource_provider->MapImageRasterBuffer(source_id); + ASSERT_TRUE(!!canvas); + canvas->writePixels(bitmap, 0, 0); + resource_provider->UnmapImageRasterBuffer(source_id); + + dest_id = resource_provider->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + + resource_provider->CopyResource(source_id, dest_id); + + { + ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), + dest_id); + const SkBitmap* sk_bitmap = lock.sk_bitmap(); + EXPECT_EQ(sk_bitmap->width(), size.width()); + EXPECT_EQ(sk_bitmap->height(), size.height()); + EXPECT_EQ(*sk_bitmap->getAddr32(0, 0), kBadBeef); + } + + resource_provider->DeleteResource(source_id); + resource_provider->DeleteResource(dest_id); +} + void InitializeGLAndCheck(ContextSharedData* shared_data, ResourceProvider* resource_provider, FakeOutputSurface* output_surface) { diff --git a/cc/resources/skpicture_content_layer_updater.cc b/cc/resources/skpicture_content_layer_updater.cc index 1445803414..b100778275 100644 --- a/cc/resources/skpicture_content_layer_updater.cc +++ b/cc/resources/skpicture_content_layer_updater.cc @@ -29,9 +29,8 @@ void SkPictureContentLayerUpdater::PrepareToUpdate( gfx::Rect* resulting_opaque_rect) { SkCanvas* canvas = picture_.beginRecording(content_rect.width(), content_rect.height()); - SkISize size = canvas->getBaseLayerSize(); - CHECK_EQ(content_rect.width(), size.width()); - CHECK_EQ(content_rect.height(), size.height()); + DCHECK_EQ(content_rect.width(), canvas->getBaseLayerSize().width()); + DCHECK_EQ(content_rect.height(), canvas->getBaseLayerSize().height()); base::TimeTicks start_time = rendering_stats_instrumentation_->StartRecording(); PaintContents(canvas, diff --git a/cc/resources/task_graph_runner.cc b/cc/resources/task_graph_runner.cc index 21a02f93f4..18cc012095 100644 --- a/cc/resources/task_graph_runner.cc +++ b/cc/resources/task_graph_runner.cc @@ -11,7 +11,6 @@ #include "base/threading/thread_restrictions.h" namespace cc { -namespace internal { namespace { // Helper class for iterating over all dependents of a task. @@ -466,5 +465,4 @@ void TaskGraphRunner::RunTaskWithLockAcquired() { has_namespaces_with_finished_running_tasks_cv_.Signal(); } -} // namespace internal } // namespace cc diff --git a/cc/resources/task_graph_runner.h b/cc/resources/task_graph_runner.h index f1b4c74478..9dc17f5830 100644 --- a/cc/resources/task_graph_runner.h +++ b/cc/resources/task_graph_runner.h @@ -14,7 +14,6 @@ #include "cc/base/cc_export.h" namespace cc { -namespace internal { class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> { public: @@ -227,7 +226,6 @@ class CC_EXPORT TaskGraphRunner { DISALLOW_COPY_AND_ASSIGN(TaskGraphRunner); }; -} // namespace internal } // namespace cc #endif // CC_RESOURCES_TASK_GRAPH_RUNNER_H_ diff --git a/cc/resources/task_graph_runner_perftest.cc b/cc/resources/task_graph_runner_perftest.cc index 8039b6c71b..2dff0638b5 100644 --- a/cc/resources/task_graph_runner_perftest.cc +++ b/cc/resources/task_graph_runner_perftest.cc @@ -20,13 +20,13 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class PerfTaskImpl : public internal::Task { +class PerfTaskImpl : public Task { public: typedef std::vector<scoped_refptr<PerfTaskImpl> > Vector; PerfTaskImpl() {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE {} void Reset() { did_run_ = false; } @@ -46,7 +46,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Overridden from testing::Test: virtual void SetUp() OVERRIDE { - task_graph_runner_ = make_scoped_ptr(new internal::TaskGraphRunner); + task_graph_runner_ = make_scoped_ptr(new TaskGraphRunner); namespace_token_ = task_graph_runner_->GetNamespaceToken(); } virtual void TearDown() OVERRIDE { task_graph_runner_.reset(); } @@ -69,7 +69,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { CreateTasks(num_leaf_tasks, &leaf_tasks); // Avoid unnecessary heap allocations by reusing the same graph. - internal::TaskGraph graph; + TaskGraph graph; timer_.Reset(); do { @@ -99,8 +99,8 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Avoid unnecessary heap allocations by reusing the same graph and // completed tasks vector. - internal::TaskGraph graph; - internal::Task::Vector completed_tasks; + TaskGraph graph; + Task::Vector completed_tasks; timer_.Reset(); do { @@ -113,7 +113,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - internal::TaskGraph empty; + TaskGraph empty; task_graph_runner_->ScheduleTasks(namespace_token_, &empty); CollectCompletedTasks(&completed_tasks); @@ -141,8 +141,8 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Avoid unnecessary heap allocations by reusing the same graph and // completed tasks vector. - internal::TaskGraph graph; - internal::Task::Vector completed_tasks; + TaskGraph graph; + Task::Vector completed_tasks; size_t count = 0; timer_.Reset(); @@ -159,7 +159,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - internal::TaskGraph empty; + TaskGraph empty; task_graph_runner_->ScheduleTasks(namespace_token_, &empty); CollectCompletedTasks(&completed_tasks); @@ -184,8 +184,8 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Avoid unnecessary heap allocations by reusing the same graph and // completed tasks vector. - internal::TaskGraph graph; - internal::Task::Vector completed_tasks; + TaskGraph graph; + Task::Vector completed_tasks; timer_.Reset(); do { @@ -230,55 +230,51 @@ class TaskGraphRunnerPerfTest : public testing::Test { void BuildTaskGraph(const PerfTaskImpl::Vector& top_level_tasks, const PerfTaskImpl::Vector& tasks, const PerfTaskImpl::Vector& leaf_tasks, - internal::TaskGraph* graph) { + TaskGraph* graph) { DCHECK(graph->nodes.empty()); DCHECK(graph->edges.empty()); for (PerfTaskImpl::Vector::const_iterator it = leaf_tasks.begin(); it != leaf_tasks.end(); ++it) { - graph->nodes.push_back(internal::TaskGraph::Node(it->get(), 0u, 0u)); + graph->nodes.push_back(TaskGraph::Node(it->get(), 0u, 0u)); } for (PerfTaskImpl::Vector::const_iterator it = tasks.begin(); it != tasks.end(); ++it) { - graph->nodes.push_back( - internal::TaskGraph::Node(it->get(), 0u, leaf_tasks.size())); + graph->nodes.push_back(TaskGraph::Node(it->get(), 0u, leaf_tasks.size())); for (PerfTaskImpl::Vector::const_iterator leaf_it = leaf_tasks.begin(); leaf_it != leaf_tasks.end(); ++leaf_it) { - graph->edges.push_back( - internal::TaskGraph::Edge(leaf_it->get(), it->get())); + graph->edges.push_back(TaskGraph::Edge(leaf_it->get(), it->get())); } for (PerfTaskImpl::Vector::const_iterator top_level_it = top_level_tasks.begin(); top_level_it != top_level_tasks.end(); ++top_level_it) { - graph->edges.push_back( - internal::TaskGraph::Edge(it->get(), top_level_it->get())); + graph->edges.push_back(TaskGraph::Edge(it->get(), top_level_it->get())); } } for (PerfTaskImpl::Vector::const_iterator it = top_level_tasks.begin(); it != top_level_tasks.end(); ++it) { - graph->nodes.push_back( - internal::TaskGraph::Node(it->get(), 0u, tasks.size())); + graph->nodes.push_back(TaskGraph::Node(it->get(), 0u, tasks.size())); } } - size_t CollectCompletedTasks(internal::Task::Vector* completed_tasks) { + size_t CollectCompletedTasks(Task::Vector* completed_tasks) { DCHECK(completed_tasks->empty()); task_graph_runner_->CollectCompletedTasks(namespace_token_, completed_tasks); return completed_tasks->size(); } - scoped_ptr<internal::TaskGraphRunner> task_graph_runner_; - internal::NamespaceToken namespace_token_; + scoped_ptr<TaskGraphRunner> task_graph_runner_; + NamespaceToken namespace_token_; LapTimer timer_; }; diff --git a/cc/resources/task_graph_runner_unittest.cc b/cc/resources/task_graph_runner_unittest.cc index b1faa4266d..1a6256c583 100644 --- a/cc/resources/task_graph_runner_unittest.cc +++ b/cc/resources/task_graph_runner_unittest.cc @@ -19,12 +19,12 @@ const int kNamespaceCount = 3; class TaskGraphRunnerTestBase { public: - struct Task { - Task(int namespace_index, - unsigned id, - unsigned dependent_id, - unsigned dependent_count, - unsigned priority) + struct TaskInfo { + TaskInfo(int namespace_index, + unsigned id, + unsigned dependent_id, + unsigned dependent_count, + unsigned priority) : namespace_index(namespace_index), id(id), dependent_id(dependent_id), @@ -38,8 +38,7 @@ class TaskGraphRunnerTestBase { unsigned priority; }; - TaskGraphRunnerTestBase() - : task_graph_runner_(new internal::TaskGraphRunner) {} + TaskGraphRunnerTestBase() : task_graph_runner_(new TaskGraphRunner) {} void ResetIds(int namespace_index) { run_task_ids_[namespace_index].clear(); @@ -50,10 +49,10 @@ class TaskGraphRunnerTestBase { task_graph_runner_->WaitForTasksToFinishRunning( namespace_token_[namespace_index]); - internal::Task::Vector completed_tasks; + Task::Vector completed_tasks; task_graph_runner_->CollectCompletedTasks(namespace_token_[namespace_index], &completed_tasks); - for (internal::Task::Vector::const_iterator it = completed_tasks.begin(); + for (Task::Vector::const_iterator it = completed_tasks.begin(); it != completed_tasks.end(); ++it) { FakeTaskImpl* task = static_cast<FakeTaskImpl*>(it->get()); @@ -78,26 +77,26 @@ class TaskGraphRunnerTestBase { return on_task_completed_ids_[namespace_index]; } - void ScheduleTasks(int namespace_index, const std::vector<Task>& tasks) { - internal::Task::Vector new_tasks; - internal::Task::Vector new_dependents; - internal::TaskGraph new_graph; + void ScheduleTasks(int namespace_index, const std::vector<TaskInfo>& tasks) { + Task::Vector new_tasks; + Task::Vector new_dependents; + TaskGraph new_graph; - for (std::vector<Task>::const_iterator it = tasks.begin(); + for (std::vector<TaskInfo>::const_iterator it = tasks.begin(); it != tasks.end(); ++it) { scoped_refptr<FakeTaskImpl> new_task( new FakeTaskImpl(this, it->namespace_index, it->id)); new_graph.nodes.push_back( - internal::TaskGraph::Node(new_task.get(), it->priority, 0u)); + TaskGraph::Node(new_task.get(), it->priority, 0u)); for (unsigned i = 0; i < it->dependent_count; ++i) { scoped_refptr<FakeDependentTaskImpl> new_dependent_task( new FakeDependentTaskImpl( this, it->namespace_index, it->dependent_id)); - new_graph.nodes.push_back(internal::TaskGraph::Node( - new_dependent_task.get(), it->priority, 1u)); - new_graph.edges.push_back(internal::TaskGraph::Edge( - new_task.get(), new_dependent_task.get())); + new_graph.nodes.push_back( + TaskGraph::Node(new_dependent_task.get(), it->priority, 1u)); + new_graph.edges.push_back( + TaskGraph::Edge(new_task.get(), new_dependent_task.get())); new_dependents.push_back(new_dependent_task.get()); } @@ -113,12 +112,12 @@ class TaskGraphRunnerTestBase { } protected: - class FakeTaskImpl : public internal::Task { + class FakeTaskImpl : public Task { public: FakeTaskImpl(TaskGraphRunnerTestBase* test, int namespace_index, int id) : test_(test), namespace_index_(namespace_index), id_(id) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { test_->RunTaskOnWorkerThread(namespace_index_, id_); } @@ -154,10 +153,10 @@ class TaskGraphRunnerTestBase { DISALLOW_COPY_AND_ASSIGN(FakeDependentTaskImpl); }; - scoped_ptr<internal::TaskGraphRunner> task_graph_runner_; - internal::NamespaceToken namespace_token_[kNamespaceCount]; - internal::Task::Vector tasks_[kNamespaceCount]; - internal::Task::Vector dependents_[kNamespaceCount]; + scoped_ptr<TaskGraphRunner> task_graph_runner_; + NamespaceToken namespace_token_[kNamespaceCount]; + Task::Vector tasks_[kNamespaceCount]; + Task::Vector dependents_[kNamespaceCount]; std::vector<unsigned> run_task_ids_[kNamespaceCount]; base::Lock run_task_ids_lock_; std::vector<unsigned> on_task_completed_ids_[kNamespaceCount]; @@ -200,7 +199,7 @@ TEST_P(TaskGraphRunnerTest, Basic) { EXPECT_EQ(0u, run_task_ids(i).size()); EXPECT_EQ(0u, on_task_completed_ids(i).size()); - ScheduleTasks(i, std::vector<Task>(1, Task(i, 0u, 0u, 0u, 0u))); + ScheduleTasks(i, std::vector<TaskInfo>(1, TaskInfo(i, 0u, 0u, 0u, 0u))); } for (int i = 0; i < kNamespaceCount; ++i) { @@ -211,7 +210,7 @@ TEST_P(TaskGraphRunnerTest, Basic) { } for (int i = 0; i < kNamespaceCount; ++i) - ScheduleTasks(i, std::vector<Task>(1, Task(i, 0u, 0u, 1u, 0u))); + ScheduleTasks(i, std::vector<TaskInfo>(1, TaskInfo(i, 0u, 0u, 1u, 0u))); for (int i = 0; i < kNamespaceCount; ++i) { RunAllTasks(i); @@ -221,7 +220,7 @@ TEST_P(TaskGraphRunnerTest, Basic) { } for (int i = 0; i < kNamespaceCount; ++i) - ScheduleTasks(i, std::vector<Task>(1, Task(i, 0u, 0u, 2u, 0u))); + ScheduleTasks(i, std::vector<TaskInfo>(1, TaskInfo(i, 0u, 0u, 2u, 0u))); for (int i = 0; i < kNamespaceCount; ++i) { RunAllTasks(i); @@ -234,12 +233,12 @@ TEST_P(TaskGraphRunnerTest, Basic) { TEST_P(TaskGraphRunnerTest, Dependencies) { for (int i = 0; i < kNamespaceCount; ++i) { ScheduleTasks(i, - std::vector<Task>(1, - Task(i, - 0u, - 1u, - 1u, // 1 dependent - 0u))); + std::vector<TaskInfo>(1, + TaskInfo(i, + 0u, + 1u, + 1u, // 1 dependent + 0u))); } for (int i = 0; i < kNamespaceCount; ++i) { @@ -255,12 +254,12 @@ TEST_P(TaskGraphRunnerTest, Dependencies) { for (int i = 0; i < kNamespaceCount; ++i) { ScheduleTasks(i, - std::vector<Task>(1, - Task(i, - 2u, - 3u, - 2u, // 2 dependents - 0u))); + std::vector<TaskInfo>(1, + TaskInfo(i, + 2u, + 3u, + 2u, // 2 dependents + 0u))); } for (int i = 0; i < kNamespaceCount; ++i) { @@ -307,10 +306,10 @@ class TaskGraphRunnerSingleThreadTest TEST_F(TaskGraphRunnerSingleThreadTest, Priority) { for (int i = 0; i < kNamespaceCount; ++i) { - Task tasks[] = {Task(i, 0u, 2u, 1u, 1u), // Priority 1 - Task(i, 1u, 3u, 1u, 0u) // Priority 0 + TaskInfo tasks[] = {TaskInfo(i, 0u, 2u, 1u, 1u), // Priority 1 + TaskInfo(i, 1u, 3u, 1u, 0u) // Priority 0 }; - ScheduleTasks(i, std::vector<Task>(tasks, tasks + arraysize(tasks))); + ScheduleTasks(i, std::vector<TaskInfo>(tasks, tasks + arraysize(tasks))); } for (int i = 0; i < kNamespaceCount; ++i) { diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc index 65a17387dd..f976cfe346 100644 --- a/cc/resources/tile.cc +++ b/cc/resources/tile.cc @@ -24,16 +24,16 @@ Tile::Tile(TileManager* tile_manager, int layer_id, int source_frame_number, int flags) - : RefCountedManaged<Tile>(tile_manager), - tile_manager_(tile_manager), - tile_size_(tile_size), - content_rect_(content_rect), - contents_scale_(contents_scale), - opaque_rect_(opaque_rect), - layer_id_(layer_id), - source_frame_number_(source_frame_number), - flags_(flags), - id_(s_next_id_++) { + : RefCountedManaged<Tile>(tile_manager), + tile_manager_(tile_manager), + tile_size_(tile_size), + content_rect_(content_rect), + contents_scale_(contents_scale), + opaque_rect_(opaque_rect), + layer_id_(layer_id), + source_frame_number_(source_frame_number), + flags_(flags), + id_(s_next_id_++) { set_picture_pile(picture_pile); } diff --git a/cc/resources/tile.h b/cc/resources/tile.h index 7df43e0a36..a1e1c35011 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -43,6 +43,19 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { return priority_[tree]; } + TilePriority priority_for_tree_priority(TreePriority tree_priority) const { + switch (tree_priority) { + case SMOOTHNESS_TAKES_PRIORITY: + return priority_[ACTIVE_TREE]; + case NEW_CONTENT_TAKES_PRIORITY: + return priority_[PENDING_TREE]; + case SAME_PRIORITY_FOR_BOTH_TREES: + return combined_priority(); + } + NOTREACHED(); + return TilePriority(); + } + TilePriority combined_priority() const { return TilePriority(priority_[ACTIVE_TREE], priority_[PENDING_TREE]); diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index 76cdb968ab..963808e20a 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -15,7 +15,8 @@ #include "cc/debug/devtools_instrumentation.h" #include "cc/debug/traced_value.h" #include "cc/layers/picture_layer_impl.h" -#include "cc/resources/raster_worker_pool_delegate.h" +#include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer_delegate.h" #include "cc/resources/tile.h" #include "skia/ext/paint_simplifier.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -44,9 +45,9 @@ class DisableLCDTextFilter : public SkDrawFilter { } }; -class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { +class RasterTaskImpl : public RasterTask { public: - RasterWorkerPoolTaskImpl( + RasterTaskImpl( const Resource* resource, PicturePileImpl* picture_pile, const gfx::Rect& content_rect, @@ -59,8 +60,8 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { bool analyze_picture, RenderingStatsInstrumentation* rendering_stats, const base::Callback<void(const PicturePileImpl::Analysis&, bool)>& reply, - internal::WorkerPoolTask::Vector* dependencies) - : internal::RasterWorkerPoolTask(resource, dependencies), + ImageDecodeTask::Vector* dependencies) + : RasterTask(resource, dependencies), picture_pile_(picture_pile), content_rect_(content_rect), contents_scale_(contents_scale), @@ -74,9 +75,9 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { reply_(reply), canvas_(NULL) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { - TRACE_EVENT0("cc", "RasterWorkerPoolTaskImpl::RunOnWorkerThread"); + TRACE_EVENT0("cc", "RasterizerTaskImpl::RunOnWorkerThread"); DCHECK(picture_pile_); if (canvas_) { @@ -85,21 +86,19 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { } } - // Overridden from internal::WorkerPoolTask: - virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE { + // Overridden from RasterizerTask: + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE { DCHECK(!canvas_); - canvas_ = client->AcquireCanvasForRaster(this, resource()); + canvas_ = client->AcquireCanvasForRaster(this); } virtual void RunOnOriginThread() OVERRIDE { - TRACE_EVENT0("cc", "RasterWorkerPoolTaskImpl::RunOnOriginThread"); + TRACE_EVENT0("cc", "RasterTaskImpl::RunOnOriginThread"); if (canvas_) AnalyzeAndRaster(picture_pile_); } - virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE { + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE { canvas_ = NULL; - client->ReleaseCanvasForRaster(this, resource()); + client->ReleaseCanvasForRaster(this); } virtual void RunReplyOnOriginThread() OVERRIDE { DCHECK(!canvas_); @@ -107,7 +106,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { } protected: - virtual ~RasterWorkerPoolTaskImpl() { DCHECK(!canvas_); } + virtual ~RasterTaskImpl() { DCHECK(!canvas_); } private: scoped_ptr<base::Value> DataAsValue() const { @@ -134,7 +133,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { void Analyze(PicturePileImpl* picture_pile) { TRACE_EVENT1("cc", - "RasterWorkerPoolTaskImpl::Analyze", + "RasterTaskImpl::Analyze", "data", TracedValue::FromValue(DataAsValue().release())); @@ -154,7 +153,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { void Raster(PicturePileImpl* picture_pile) { TRACE_EVENT2( "cc", - "RasterWorkerPoolTaskImpl::Raster", + "RasterTaskImpl::Raster", "data", TracedValue::FromValue(DataAsValue().release()), "raster_mode", @@ -218,42 +217,39 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { const base::Callback<void(const PicturePileImpl::Analysis&, bool)> reply_; SkCanvas* canvas_; - DISALLOW_COPY_AND_ASSIGN(RasterWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); }; -class ImageDecodeWorkerPoolTaskImpl : public internal::WorkerPoolTask { +class ImageDecodeTaskImpl : public ImageDecodeTask { public: - ImageDecodeWorkerPoolTaskImpl( - SkPixelRef* pixel_ref, - int layer_id, - RenderingStatsInstrumentation* rendering_stats, - const base::Callback<void(bool was_canceled)>& reply) + ImageDecodeTaskImpl(SkPixelRef* pixel_ref, + int layer_id, + RenderingStatsInstrumentation* rendering_stats, + const base::Callback<void(bool was_canceled)>& reply) : pixel_ref_(skia::SharePtr(pixel_ref)), layer_id_(layer_id), rendering_stats_(rendering_stats), reply_(reply) {} - // Overridden from internal::Task: + // Overridden from Task: virtual void RunOnWorkerThread() OVERRIDE { - TRACE_EVENT0("cc", "ImageDecodeWorkerPoolTaskImpl::RunOnWorkerThread"); + TRACE_EVENT0("cc", "ImageDecodeTaskImpl::RunOnWorkerThread"); Decode(); } - // Overridden from internal::WorkerPoolTask: - virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE {} + // Overridden from RasterizerTask: + virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {} virtual void RunOnOriginThread() OVERRIDE { - TRACE_EVENT0("cc", "ImageDecodeWorkerPoolTaskImpl::RunOnOriginThread"); + TRACE_EVENT0("cc", "ImageDecodeTaskImpl::RunOnOriginThread"); Decode(); } - virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) - OVERRIDE {} + virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {} virtual void RunReplyOnOriginThread() OVERRIDE { reply_.Run(!HasFinishedRunning()); } protected: - virtual ~ImageDecodeWorkerPoolTaskImpl() {} + virtual ~ImageDecodeTaskImpl() {} private: void Decode() { @@ -269,7 +265,7 @@ class ImageDecodeWorkerPoolTaskImpl : public internal::WorkerPoolTask { RenderingStatsInstrumentation* rendering_stats_; const base::Callback<void(bool was_canceled)> reply_; - DISALLOW_COPY_AND_ASSIGN(ImageDecodeWorkerPoolTaskImpl); + DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); }; const size_t kScheduledRasterTasksLimit = 32u; @@ -397,16 +393,16 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( // static scoped_ptr<TileManager> TileManager::Create( TileManagerClient* client, - ResourceProvider* resource_provider, - RasterWorkerPool* raster_worker_pool, - RasterWorkerPool* gpu_raster_worker_pool, + ResourcePool* resource_pool, + Rasterizer* rasterizer, + Rasterizer* gpu_rasterizer, size_t max_raster_usage_bytes, bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation) { return make_scoped_ptr(new TileManager(client, - resource_provider, - raster_worker_pool, - gpu_raster_worker_pool, + resource_pool, + rasterizer, + gpu_rasterizer, max_raster_usage_bytes, use_rasterize_on_demand, rendering_stats_instrumentation)); @@ -414,17 +410,14 @@ scoped_ptr<TileManager> TileManager::Create( TileManager::TileManager( TileManagerClient* client, - ResourceProvider* resource_provider, - RasterWorkerPool* raster_worker_pool, - RasterWorkerPool* gpu_raster_worker_pool, + ResourcePool* resource_pool, + Rasterizer* rasterizer, + Rasterizer* gpu_rasterizer, size_t max_raster_usage_bytes, bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation) : client_(client), - resource_pool_( - ResourcePool::Create(resource_provider, - raster_worker_pool->GetResourceTarget(), - raster_worker_pool->GetResourceFormat())), + resource_pool_(resource_pool), prioritized_tiles_dirty_(false), all_tiles_that_need_to_be_rasterized_have_memory_(true), all_tiles_required_for_activation_have_memory_(true), @@ -437,14 +430,13 @@ TileManager::TileManager( rendering_stats_instrumentation_(rendering_stats_instrumentation), did_initialize_visible_tile_(false), did_check_for_completed_tasks_since_last_schedule_tasks_(true), - use_rasterize_on_demand_(use_rasterize_on_demand), - resource_format_(raster_worker_pool->GetResourceFormat()) { - RasterWorkerPool* raster_worker_pools[NUM_RASTER_WORKER_POOL_TYPES] = { - raster_worker_pool, // RASTER_WORKER_POOL_TYPE_DEFAULT - gpu_raster_worker_pool, // RASTER_WORKER_POOL_TYPE_GPU + use_rasterize_on_demand_(use_rasterize_on_demand) { + Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { + rasterizer, // RASTERIZER_TYPE_DEFAULT + gpu_rasterizer, // RASTERIZER_TYPE_GPU }; - raster_worker_pool_delegate_ = RasterWorkerPoolDelegate::Create( - this, raster_worker_pools, arraysize(raster_worker_pools)); + rasterizer_delegate_ = + RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); } TileManager::~TileManager() { @@ -455,14 +447,14 @@ TileManager::~TileManager() { CleanUpReleasedTiles(); DCHECK_EQ(0u, tiles_.size()); - RasterTaskQueue empty[NUM_RASTER_WORKER_POOL_TYPES]; - raster_worker_pool_delegate_->ScheduleTasks(empty); + RasterTaskQueue empty[NUM_RASTERIZER_TYPES]; + rasterizer_delegate_->ScheduleTasks(empty); orphan_raster_tasks_.clear(); // This should finish all pending tasks and release any uninitialized // resources. - raster_worker_pool_delegate_->Shutdown(); - raster_worker_pool_delegate_->CheckForCompletedTasks(); + rasterizer_delegate_->Shutdown(); + rasterizer_delegate_->CheckForCompletedTasks(); DCHECK_EQ(0u, bytes_releasable_); DCHECK_EQ(0u, resources_releasable_); @@ -540,7 +532,7 @@ void TileManager::DidFinishRunningTasks() { !memory_usage_above_limit) return; - raster_worker_pool_delegate_->CheckForCompletedTasks(); + rasterizer_delegate_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; TileVector tiles_that_need_to_be_rasterized; @@ -724,18 +716,12 @@ void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { if (state != global_state_) { global_state_ = state; prioritized_tiles_dirty_ = true; - // Soft limit is used for resource pool such that - // memory returns to soft limit after going over. - resource_pool_->SetResourceUsageLimits( - global_state_.soft_memory_limit_in_bytes, - global_state_.unused_memory_limit_in_bytes, - global_state_.num_resources_limit); } // We need to call CheckForCompletedTasks() once in-between each call // to ScheduleTasks() to prevent canceled tasks from being scheduled. if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { - raster_worker_pool_delegate_->CheckForCompletedTasks(); + rasterizer_delegate_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; } @@ -764,7 +750,7 @@ void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { bool TileManager::UpdateVisibleTiles() { TRACE_EVENT0("cc", "TileManager::UpdateVisibleTiles"); - raster_worker_pool_delegate_->CheckForCompletedTasks(); + rasterizer_delegate_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; TRACE_EVENT_INSTANT1( @@ -1050,7 +1036,7 @@ void TileManager::ScheduleTasks( DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); - for (size_t i = 0; i < NUM_RASTER_WORKER_POOL_TYPES; ++i) + for (size_t i = 0; i < NUM_RASTERIZER_TYPES; ++i) raster_queue_[i].Reset(); // Build a new task queue containing all task currently needed. Tasks @@ -1069,9 +1055,8 @@ void TileManager::ScheduleTasks( if (!tile_version.raster_task_) tile_version.raster_task_ = CreateRasterTask(tile); - size_t pool_type = tile->use_gpu_rasterization() - ? RASTER_WORKER_POOL_TYPE_GPU - : RASTER_WORKER_POOL_TYPE_DEFAULT; + size_t pool_type = tile->use_gpu_rasterization() ? RASTERIZER_TYPE_GPU + : RASTERIZER_TYPE_DEFAULT; raster_queue_[pool_type].items.push_back(RasterTaskQueue::Item( tile_version.raster_task_.get(), tile->required_for_activation())); @@ -1086,7 +1071,7 @@ void TileManager::ScheduleTasks( // Schedule running of |raster_tasks_|. This replaces any previously // scheduled tasks and effectively cancels all tasks not present // in |raster_tasks_|. - raster_worker_pool_delegate_->ScheduleTasks(raster_queue_); + rasterizer_delegate_->ScheduleTasks(raster_queue_); // It's now safe to clean up orphan tasks as raster worker pool is not // allowed to keep around unreferenced raster tasks after ScheduleTasks() has @@ -1096,10 +1081,10 @@ void TileManager::ScheduleTasks( did_check_for_completed_tasks_since_last_schedule_tasks_ = false; } -scoped_refptr<internal::WorkerPoolTask> TileManager::CreateImageDecodeTask( +scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask( Tile* tile, SkPixelRef* pixel_ref) { - return make_scoped_refptr(new ImageDecodeWorkerPoolTaskImpl( + return make_scoped_refptr(new ImageDecodeTaskImpl( pixel_ref, tile->layer_id(), rendering_stats_instrumentation_, @@ -1109,8 +1094,7 @@ scoped_refptr<internal::WorkerPoolTask> TileManager::CreateImageDecodeTask( base::Unretained(pixel_ref)))); } -scoped_refptr<internal::RasterWorkerPoolTask> TileManager::CreateRasterTask( - Tile* tile) { +scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { ManagedTileState& mts = tile->managed_state(); scoped_ptr<ScopedResource> resource = @@ -1118,7 +1102,7 @@ scoped_refptr<internal::RasterWorkerPoolTask> TileManager::CreateRasterTask( const ScopedResource* const_resource = resource.get(); // Create and queue all image decode tasks that this tile depends on. - internal::WorkerPoolTask::Vector decode_tasks; + ImageDecodeTask::Vector decode_tasks; PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; for (PicturePileImpl::PixelRefIterator iter( tile->content_rect(), tile->contents_scale(), tile->picture_pile()); @@ -1135,7 +1119,7 @@ scoped_refptr<internal::RasterWorkerPoolTask> TileManager::CreateRasterTask( } // Create and append new image decode task for this pixel ref. - scoped_refptr<internal::WorkerPoolTask> decode_task = + scoped_refptr<ImageDecodeTask> decode_task = CreateImageDecodeTask(tile, pixel_ref); decode_tasks.push_back(decode_task); existing_pixel_refs[id] = decode_task; @@ -1159,24 +1143,24 @@ scoped_refptr<internal::RasterWorkerPoolTask> TileManager::CreateRasterTask( std::min(pile_size.width(), pile_size.height()) >= kMinDimensionsForAnalysis; - return make_scoped_refptr(new RasterWorkerPoolTaskImpl( - const_resource, - tile->picture_pile(), - tile->content_rect(), - tile->contents_scale(), - mts.raster_mode, - mts.resolution, - tile->layer_id(), - static_cast<const void*>(tile), - tile->source_frame_number(), - analyze_picture, - rendering_stats_instrumentation_, - base::Bind(&TileManager::OnRasterTaskCompleted, - base::Unretained(this), - tile->id(), - base::Passed(&resource), - mts.raster_mode), - &decode_tasks)); + return make_scoped_refptr( + new RasterTaskImpl(const_resource, + tile->picture_pile(), + tile->content_rect(), + tile->contents_scale(), + mts.raster_mode, + mts.resolution, + tile->layer_id(), + static_cast<const void*>(tile), + tile->source_frame_number(), + analyze_picture, + rendering_stats_instrumentation_, + base::Bind(&TileManager::OnRasterTaskCompleted, + base::Unretained(this), + tile->id(), + base::Passed(&resource), + mts.raster_mode), + &decode_tasks)); } void TileManager::OnImageDecodeTaskCompleted(int layer_id, @@ -1188,7 +1172,6 @@ void TileManager::OnImageDecodeTaskCompleted(int layer_id, return; LayerPixelRefTaskMap::iterator layer_it = image_decode_tasks_.find(layer_id); - if (layer_it == image_decode_tasks_.end()) return; @@ -1293,10 +1276,8 @@ void TileManager::GetPairedPictureLayers( ++it) { PictureLayerImpl* layer = *it; - // This is a recycle tree layer, so it shouldn't be included in the raster - // tile generation. - // TODO(vmpstr): We need these layers for eviction, so they should probably - // go into a separate vector as an output. + // This is a recycle tree layer, we can safely skip since the tiles on this + // layer have to be accessible via the active tree. if (!layer->IsOnActiveOrPendingTree()) continue; @@ -1477,19 +1458,6 @@ TileManager::RasterTileIterator::RasterOrderComparator::RasterOrderComparator( TreePriority tree_priority) : tree_priority_(tree_priority) {} -bool TileManager::RasterTileIterator::RasterOrderComparator::ComparePriorities( - const TilePriority& a_priority, - const TilePriority& b_priority, - bool prioritize_low_res) const { - if (b_priority.resolution != a_priority.resolution) { - return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || - (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || - (a_priority.resolution == NON_IDEAL_RESOLUTION); - } - - return b_priority.IsHigherPriorityThan(a_priority); -} - bool TileManager::RasterTileIterator::RasterOrderComparator::operator()( PairedPictureLayerIterator* a, PairedPictureLayerIterator* b) const { @@ -1506,24 +1474,184 @@ bool TileManager::RasterTileIterator::RasterOrderComparator::operator()( Tile* a_tile = **a_pair.first; Tile* b_tile = **b_pair.first; - switch (tree_priority_) { - case SMOOTHNESS_TAKES_PRIORITY: - return ComparePriorities(a_tile->priority(ACTIVE_TREE), - b_tile->priority(ACTIVE_TREE), - true /* prioritize low res */); - case NEW_CONTENT_TAKES_PRIORITY: - return ComparePriorities(a_tile->priority(PENDING_TREE), - b_tile->priority(PENDING_TREE), - false /* prioritize low res */); - case SAME_PRIORITY_FOR_BOTH_TREES: - return ComparePriorities(a_tile->priority(a_pair.second), - b_tile->priority(b_pair.second), - false /* prioritize low res */); + const TilePriority& a_priority = + a_tile->priority_for_tree_priority(tree_priority_); + const TilePriority& b_priority = + b_tile->priority_for_tree_priority(tree_priority_); + bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; + + if (b_priority.resolution != a_priority.resolution) { + return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || + (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || + (a_priority.resolution == NON_IDEAL_RESOLUTION); } - NOTREACHED(); - // Keep the compiler happy. - return false; + return b_priority.IsHigherPriorityThan(a_priority); +} + +TileManager::EvictionTileIterator::EvictionTileIterator() + : comparator_(SAME_PRIORITY_FOR_BOTH_TREES) {} + +TileManager::EvictionTileIterator::EvictionTileIterator( + TileManager* tile_manager, + TreePriority tree_priority) + : tree_priority_(tree_priority), comparator_(tree_priority) { + std::vector<TileManager::PairedPictureLayer> paired_layers; + + tile_manager->GetPairedPictureLayers(&paired_layers); + + paired_iterators_.reserve(paired_layers.size()); + iterator_heap_.reserve(paired_layers.size()); + for (std::vector<TileManager::PairedPictureLayer>::iterator it = + paired_layers.begin(); + it != paired_layers.end(); + ++it) { + PairedPictureLayerIterator paired_iterator; + if (it->active_layer) { + paired_iterator.active_iterator = + PictureLayerImpl::LayerEvictionTileIterator(it->active_layer, + tree_priority_); + } + + if (it->pending_layer) { + paired_iterator.pending_iterator = + PictureLayerImpl::LayerEvictionTileIterator(it->pending_layer, + tree_priority_); + } + + if (paired_iterator.PeekTile(tree_priority_) != NULL) { + paired_iterators_.push_back(paired_iterator); + iterator_heap_.push_back(&paired_iterators_.back()); + } + } + + std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); +} + +TileManager::EvictionTileIterator::~EvictionTileIterator() {} + +TileManager::EvictionTileIterator& TileManager::EvictionTileIterator:: +operator++() { + std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); + PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); + iterator_heap_.pop_back(); + + paired_iterator->PopTile(tree_priority_); + if (paired_iterator->PeekTile(tree_priority_) != NULL) { + iterator_heap_.push_back(paired_iterator); + std::push_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); + } + return *this; +} + +TileManager::EvictionTileIterator::operator bool() const { + return !iterator_heap_.empty(); +} + +Tile* TileManager::EvictionTileIterator::operator*() { + DCHECK(*this); + return iterator_heap_.front()->PeekTile(tree_priority_); +} + +TileManager::EvictionTileIterator::PairedPictureLayerIterator:: + PairedPictureLayerIterator() {} + +TileManager::EvictionTileIterator::PairedPictureLayerIterator:: + ~PairedPictureLayerIterator() {} + +Tile* TileManager::EvictionTileIterator::PairedPictureLayerIterator::PeekTile( + TreePriority tree_priority) { + PictureLayerImpl::LayerEvictionTileIterator* next_iterator = + NextTileIterator(tree_priority); + if (!next_iterator) + return NULL; + + DCHECK(*next_iterator); + DCHECK(std::find(returned_shared_tiles.begin(), + returned_shared_tiles.end(), + **next_iterator) == returned_shared_tiles.end()); + return **next_iterator; +} + +void TileManager::EvictionTileIterator::PairedPictureLayerIterator::PopTile( + TreePriority tree_priority) { + PictureLayerImpl::LayerEvictionTileIterator* next_iterator = + NextTileIterator(tree_priority); + DCHECK(next_iterator); + DCHECK(*next_iterator); + returned_shared_tiles.push_back(**next_iterator); + ++(*next_iterator); + + next_iterator = NextTileIterator(tree_priority); + while (next_iterator && + std::find(returned_shared_tiles.begin(), + returned_shared_tiles.end(), + **next_iterator) != returned_shared_tiles.end()) { + ++(*next_iterator); + next_iterator = NextTileIterator(tree_priority); + } +} + +PictureLayerImpl::LayerEvictionTileIterator* +TileManager::EvictionTileIterator::PairedPictureLayerIterator::NextTileIterator( + TreePriority tree_priority) { + // If both iterators are out of tiles, return NULL. + if (!active_iterator && !pending_iterator) + return NULL; + + // If we only have one iterator with tiles, return it. + if (!active_iterator) + return &pending_iterator; + if (!pending_iterator) + return &active_iterator; + + Tile* active_tile = *active_iterator; + Tile* pending_tile = *pending_iterator; + if (active_tile == pending_tile) + return &active_iterator; + + const TilePriority& active_priority = + active_tile->priority_for_tree_priority(tree_priority); + const TilePriority& pending_priority = + pending_tile->priority_for_tree_priority(tree_priority); + + if (pending_priority.IsHigherPriorityThan(active_priority)) + return &active_iterator; + return &pending_iterator; +} + +TileManager::EvictionTileIterator::EvictionOrderComparator:: + EvictionOrderComparator(TreePriority tree_priority) + : tree_priority_(tree_priority) {} + +bool TileManager::EvictionTileIterator::EvictionOrderComparator::operator()( + PairedPictureLayerIterator* a, + PairedPictureLayerIterator* b) const { + PictureLayerImpl::LayerEvictionTileIterator* a_iterator = + a->NextTileIterator(tree_priority_); + DCHECK(a_iterator); + DCHECK(*a_iterator); + + PictureLayerImpl::LayerEvictionTileIterator* b_iterator = + b->NextTileIterator(tree_priority_); + DCHECK(b_iterator); + DCHECK(*b_iterator); + + Tile* a_tile = **a_iterator; + Tile* b_tile = **b_iterator; + + const TilePriority& a_priority = + a_tile->priority_for_tree_priority(tree_priority_); + const TilePriority& b_priority = + b_tile->priority_for_tree_priority(tree_priority_); + bool prioritize_low_res = tree_priority_ != SMOOTHNESS_TAKES_PRIORITY; + + if (b_priority.resolution != a_priority.resolution) { + return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || + (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || + (a_priority.resolution == NON_IDEAL_RESOLUTION); + } + return a_priority.IsHigherPriorityThan(b_priority); } } // namespace cc diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h index 97b785a087..6c71152b2c 100644 --- a/cc/resources/tile_manager.h +++ b/cc/resources/tile_manager.h @@ -5,6 +5,7 @@ #ifndef CC_RESOURCES_TILE_MANAGER_H_ #define CC_RESOURCES_TILE_MANAGER_H_ +#include <deque> #include <queue> #include <set> #include <utility> @@ -20,12 +21,12 @@ #include "cc/resources/memory_history.h" #include "cc/resources/picture_pile_impl.h" #include "cc/resources/prioritized_tile_set.h" -#include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer.h" #include "cc/resources/resource_pool.h" #include "cc/resources/tile.h" namespace cc { -class RasterWorkerPoolDelegate; +class RasterizerDelegate; class ResourceProvider; class CC_EXPORT TileManagerClient { @@ -49,7 +50,7 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( // should no longer have any memory assigned to them. Tile objects are "owned" // by layers; they automatically register with the manager when they are // created, and unregister from the manager when they are deleted. -class CC_EXPORT TileManager : public RasterWorkerPoolClient, +class CC_EXPORT TileManager : public RasterizerClient, public RefCountedManager<Tile> { public: struct CC_EXPORT PairedPictureLayer { @@ -94,9 +95,6 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, PairedPictureLayerIterator* b) const; private: - bool ComparePriorities(const TilePriority& a_priority, - const TilePriority& b_priority, - bool prioritize_low_res) const; TreePriority tree_priority_; }; @@ -106,11 +104,55 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, RasterOrderComparator comparator_; }; + struct CC_EXPORT EvictionTileIterator { + public: + EvictionTileIterator(); + EvictionTileIterator(TileManager* tile_manager, TreePriority tree_priority); + ~EvictionTileIterator(); + + EvictionTileIterator& operator++(); + operator bool() const; + Tile* operator*(); + + private: + struct PairedPictureLayerIterator { + PairedPictureLayerIterator(); + ~PairedPictureLayerIterator(); + + Tile* PeekTile(TreePriority tree_priority); + void PopTile(TreePriority tree_priority); + + PictureLayerImpl::LayerEvictionTileIterator* NextTileIterator( + TreePriority tree_priority); + + PictureLayerImpl::LayerEvictionTileIterator active_iterator; + PictureLayerImpl::LayerEvictionTileIterator pending_iterator; + + std::vector<Tile*> returned_shared_tiles; + }; + + class EvictionOrderComparator { + public: + explicit EvictionOrderComparator(TreePriority tree_priority); + + bool operator()(PairedPictureLayerIterator* a, + PairedPictureLayerIterator* b) const; + + private: + TreePriority tree_priority_; + }; + + std::vector<PairedPictureLayerIterator> paired_iterators_; + std::vector<PairedPictureLayerIterator*> iterator_heap_; + TreePriority tree_priority_; + EvictionOrderComparator comparator_; + }; + static scoped_ptr<TileManager> Create( TileManagerClient* client, - ResourceProvider* resource_provider, - RasterWorkerPool* raster_worker_pool, - RasterWorkerPool* gpu_raster_worker_pool, + ResourcePool* resource_pool, + Rasterizer* rasterizer, + Rasterizer* gpu_rasterizer, size_t max_raster_usage_bytes, bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation); @@ -146,8 +188,6 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, void GetPairedPictureLayers(std::vector<PairedPictureLayer>* layers) const; - ResourcePool* resource_pool() { return resource_pool_.get(); } - void InitializeTilesWithResourcesForTesting(const std::vector<Tile*>& tiles) { for (size_t i = 0; i < tiles.size(); ++i) { ManagedTileState& mts = tiles[i]->managed_state(); @@ -161,6 +201,15 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, } } + void ReleaseTileResourcesForTesting(const std::vector<Tile*>& tiles) { + for (size_t i = 0; i < tiles.size(); ++i) { + Tile* tile = tiles[i]; + for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { + FreeResourceForTile(tile, static_cast<RasterMode>(mode)); + } + } + } + void SetGlobalStateForTesting( const GlobalStateThatImpactsTilePriority& state) { // Soft limit is used for resource pool such that @@ -177,9 +226,9 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, protected: TileManager(TileManagerClient* client, - ResourceProvider* resource_provider, - RasterWorkerPool* raster_worker_pool, - RasterWorkerPool* gpu_raster_worker_pool, + ResourcePool* resource_pool, + Rasterizer* rasterizer, + Rasterizer* gpu_rasterizer, size_t max_raster_usage_bytes, bool use_rasterize_on_demand, RenderingStatsInstrumentation* rendering_stats_instrumentation); @@ -193,7 +242,7 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, // Overriden from RefCountedManager<Tile>: virtual void Release(Tile* tile) OVERRIDE; - // Overriden from RasterWorkerPoolClient: + // Overriden from RasterizerClient: virtual bool ShouldForceTasksRequiredForActivationToComplete() const OVERRIDE; virtual void DidFinishRunningTasks() OVERRIDE; virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE; @@ -210,10 +259,10 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, void GetTilesWithAssignedBins(PrioritizedTileSet* tiles); private: - enum RasterWorkerPoolType { - RASTER_WORKER_POOL_TYPE_DEFAULT, - RASTER_WORKER_POOL_TYPE_GPU, - NUM_RASTER_WORKER_POOL_TYPES + enum RasterizerType { + RASTERIZER_TYPE_DEFAULT, + RASTERIZER_TYPE_GPU, + NUM_RASTERIZER_TYPES }; void OnImageDecodeTaskCompleted(int layer_id, @@ -226,22 +275,22 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, bool was_canceled); inline size_t BytesConsumedIfAllocated(const Tile* tile) const { - return Resource::MemorySizeBytes(tile->size(), resource_format_); + return Resource::MemorySizeBytes(tile->size(), + resource_pool_->resource_format()); } void FreeResourceForTile(Tile* tile, RasterMode mode); void FreeResourcesForTile(Tile* tile); void FreeUnusedResourcesForTile(Tile* tile); - scoped_refptr<internal::WorkerPoolTask> CreateImageDecodeTask( - Tile* tile, - SkPixelRef* pixel_ref); - scoped_refptr<internal::RasterWorkerPoolTask> CreateRasterTask(Tile* tile); + scoped_refptr<ImageDecodeTask> CreateImageDecodeTask(Tile* tile, + SkPixelRef* pixel_ref); + scoped_refptr<RasterTask> CreateRasterTask(Tile* tile); scoped_ptr<base::Value> GetMemoryRequirementsAsValue() const; void UpdatePrioritizedTileSetIfNeeded(); TileManagerClient* client_; - scoped_ptr<ResourcePool> resource_pool_; - scoped_ptr<RasterWorkerPoolDelegate> raster_worker_pool_delegate_; + ResourcePool* resource_pool_; + scoped_ptr<RasterizerDelegate> rasterizer_delegate_; GlobalStateThatImpactsTilePriority global_state_; typedef base::hash_map<Tile::Id, Tile*> TileMap; @@ -268,7 +317,7 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, bool did_initialize_visible_tile_; bool did_check_for_completed_tasks_since_last_schedule_tasks_; - typedef base::hash_map<uint32_t, scoped_refptr<internal::WorkerPoolTask> > + typedef base::hash_map<uint32_t, scoped_refptr<ImageDecodeTask> > PixelRefTaskMap; typedef base::hash_map<int, PixelRefTaskMap> LayerPixelRefTaskMap; LayerPixelRefTaskMap image_decode_tasks_; @@ -285,9 +334,9 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, ResourceFormat resource_format_; // Queues used when scheduling raster tasks. - RasterTaskQueue raster_queue_[NUM_RASTER_WORKER_POOL_TYPES]; + RasterTaskQueue raster_queue_[NUM_RASTERIZER_TYPES]; - std::vector<scoped_refptr<internal::Task> > orphan_raster_tasks_; + std::vector<scoped_refptr<RasterTask> > orphan_raster_tasks_; std::vector<PictureLayerImpl*> layers_; diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc index b4bc4f5c0a..9a1642ae27 100644 --- a/cc/resources/tile_manager_perftest.cc +++ b/cc/resources/tile_manager_perftest.cc @@ -48,11 +48,11 @@ class TileManagerPerfTest : public testing::Test { shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = ResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1); + resource_pool_ = ResourcePool::Create( + resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); size_t raster_task_limit_bytes = 32 * 1024 * 1024; // 16-64MB in practice. - tile_manager_ = - make_scoped_ptr(new FakeTileManager(&tile_manager_client_, - resource_provider_.get(), - raster_task_limit_bytes)); + tile_manager_ = make_scoped_ptr(new FakeTileManager( + &tile_manager_client_, resource_pool_.get(), raster_task_limit_bytes)); picture_pile_ = FakePicturePileImpl::CreateInfiniteFilledPile(); } @@ -179,6 +179,7 @@ class TileManagerPerfTest : public testing::Test { scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; + scoped_ptr<ResourcePool> resource_pool_; LapTimer timer_; }; diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index 849f4a7f8e..fac13d64a5 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -40,8 +40,10 @@ class TileManagerTest : public testing::TestWithParam<bool>, shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = ResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1); + resource_pool_ = ResourcePool::Create( + resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); tile_manager_ = make_scoped_ptr(new FakeTileManager( - this, resource_provider_.get(), allow_on_demand_raster)); + this, resource_pool_.get(), allow_on_demand_raster)); memory_limit_policy_ = memory_limit_policy; max_tiles_ = max_tiles; @@ -149,6 +151,7 @@ class TileManagerTest : public testing::TestWithParam<bool>, scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; + scoped_ptr<ResourcePool> resource_pool_; TileMemoryLimitPolicy memory_limit_policy_; int max_tiles_; bool ready_to_activate_; @@ -971,5 +974,165 @@ TEST_F(TileManagerTileIteratorTest, RasterTileIterator) { EXPECT_GT(increasing_distance_tiles, 3 * tile_count / 4); } +TEST_F(TileManagerTileIteratorTest, EvictionTileIterator) { + SetupDefaultTrees(gfx::Size(1000, 1000)); + TileManager* tile_manager = TileManagerTileIteratorTest::tile_manager(); + EXPECT_TRUE(tile_manager); + + active_layer_->CreateDefaultTilingsAndTiles(); + pending_layer_->CreateDefaultTilingsAndTiles(); + + std::vector<TileManager::PairedPictureLayer> paired_layers; + tile_manager->GetPairedPictureLayers(&paired_layers); + EXPECT_EQ(1u, paired_layers.size()); + + TileManager::EvictionTileIterator it(tile_manager, + SAME_PRIORITY_FOR_BOTH_TREES); + EXPECT_FALSE(it); + std::set<Tile*> all_tiles; + size_t tile_count = 0; + + for (TileManager::RasterTileIterator raster_it(tile_manager, + SAME_PRIORITY_FOR_BOTH_TREES); + raster_it; + ++raster_it) { + ++tile_count; + EXPECT_TRUE(*raster_it); + all_tiles.insert(*raster_it); + } + + EXPECT_EQ(tile_count, all_tiles.size()); + EXPECT_EQ(17u, tile_count); + + tile_manager->InitializeTilesWithResourcesForTesting( + std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); + + it = TileManager::EvictionTileIterator(tile_manager, + SAME_PRIORITY_FOR_BOTH_TREES); + EXPECT_TRUE(it); + + // Sanity check, all tiles should be visible. + std::set<Tile*> smoothness_tiles; + for (TileManager::EvictionTileIterator it(tile_manager, + SMOOTHNESS_TAKES_PRIORITY); + it; + ++it) { + Tile* tile = *it; + EXPECT_TRUE(tile); + EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin); + EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin); + EXPECT_TRUE(tile->HasResources()); + smoothness_tiles.insert(tile); + } + EXPECT_EQ(all_tiles, smoothness_tiles); + + tile_manager->ReleaseTileResourcesForTesting( + std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); + + Region invalidation(gfx::Rect(0, 0, 500, 500)); + + // Invalidate the pending tree. + pending_layer_->set_invalidation(invalidation); + pending_layer_->HighResTiling()->Invalidate(invalidation); + pending_layer_->LowResTiling()->Invalidate(invalidation); + + active_layer_->ResetAllTilesPriorities(); + pending_layer_->ResetAllTilesPriorities(); + + // Renew all of the tile priorities. + gfx::Rect viewport(50, 50, 100, 100); + pending_layer_->HighResTiling()->UpdateTilePriorities( + PENDING_TREE, viewport, 1.0f, 1.0); + pending_layer_->LowResTiling()->UpdateTilePriorities( + PENDING_TREE, viewport, 1.0f, 1.0); + active_layer_->HighResTiling()->UpdateTilePriorities( + ACTIVE_TREE, viewport, 1.0f, 1.0); + active_layer_->LowResTiling()->UpdateTilePriorities( + ACTIVE_TREE, viewport, 1.0f, 1.0); + + // Populate all tiles directly from the tilings. + all_tiles.clear(); + std::vector<Tile*> pending_high_res_tiles = + pending_layer_->HighResTiling()->AllTilesForTesting(); + for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) + all_tiles.insert(pending_high_res_tiles[i]); + + std::vector<Tile*> pending_low_res_tiles = + pending_layer_->LowResTiling()->AllTilesForTesting(); + for (size_t i = 0; i < pending_low_res_tiles.size(); ++i) + all_tiles.insert(pending_low_res_tiles[i]); + + std::vector<Tile*> active_high_res_tiles = + active_layer_->HighResTiling()->AllTilesForTesting(); + for (size_t i = 0; i < active_high_res_tiles.size(); ++i) + all_tiles.insert(active_high_res_tiles[i]); + + std::vector<Tile*> active_low_res_tiles = + active_layer_->LowResTiling()->AllTilesForTesting(); + for (size_t i = 0; i < active_low_res_tiles.size(); ++i) + all_tiles.insert(active_low_res_tiles[i]); + + tile_manager->InitializeTilesWithResourcesForTesting( + std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); + + Tile* last_tile = NULL; + smoothness_tiles.clear(); + tile_count = 0; + // Here we expect to get increasing ACTIVE_TREE priority_bin. + for (TileManager::EvictionTileIterator it(tile_manager, + SMOOTHNESS_TAKES_PRIORITY); + it; + ++it) { + Tile* tile = *it; + EXPECT_TRUE(tile); + EXPECT_TRUE(tile->HasResources()); + + if (!last_tile) + last_tile = tile; + + EXPECT_GE(last_tile->priority(ACTIVE_TREE).priority_bin, + tile->priority(ACTIVE_TREE).priority_bin); + if (last_tile->priority(ACTIVE_TREE).priority_bin == + tile->priority(ACTIVE_TREE).priority_bin) { + EXPECT_GE(last_tile->priority(ACTIVE_TREE).distance_to_visible, + tile->priority(ACTIVE_TREE).distance_to_visible); + } + + last_tile = tile; + ++tile_count; + smoothness_tiles.insert(tile); + } + + EXPECT_EQ(tile_count, smoothness_tiles.size()); + EXPECT_EQ(all_tiles, smoothness_tiles); + + std::set<Tile*> new_content_tiles; + last_tile = NULL; + // Here we expect to get increasing PENDING_TREE priority_bin. + for (TileManager::EvictionTileIterator it(tile_manager, + NEW_CONTENT_TAKES_PRIORITY); + it; + ++it) { + Tile* tile = *it; + EXPECT_TRUE(tile); + + if (!last_tile) + last_tile = tile; + + EXPECT_GE(last_tile->priority(PENDING_TREE).priority_bin, + tile->priority(PENDING_TREE).priority_bin); + if (last_tile->priority(PENDING_TREE).priority_bin == + tile->priority(PENDING_TREE).priority_bin) { + EXPECT_GE(last_tile->priority(PENDING_TREE).distance_to_visible, + tile->priority(PENDING_TREE).distance_to_visible); + } + + last_tile = tile; + new_content_tiles.insert(tile); + } + + EXPECT_EQ(tile_count, new_content_tiles.size()); + EXPECT_EQ(all_tiles, new_content_tiles); +} } // namespace } // namespace cc diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 20f1edebbe..5d7001065f 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -23,17 +23,20 @@ Scheduler::Scheduler( client_(client), layer_tree_host_id_(layer_tree_host_id), impl_task_runner_(impl_task_runner), - last_set_needs_begin_impl_frame_(false), + last_set_needs_begin_frame_(false), + begin_retro_frame_posted_(false), state_machine_(scheduler_settings), inside_process_scheduled_actions_(false), inside_action_(SchedulerStateMachine::ACTION_NONE), weak_factory_(this) { DCHECK(client_); - DCHECK(!state_machine_.BeginImplFrameNeeded()); + DCHECK(!state_machine_.BeginFrameNeeded()); if (settings_.main_frame_before_activation_enabled) { DCHECK(settings_.main_frame_before_draw_enabled); } + begin_retro_frame_closure_ = + base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); begin_impl_frame_deadline_closure_ = base::Bind( &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); poll_for_draw_triggers_closure_ = base::Bind( @@ -118,13 +121,14 @@ void Scheduler::DidManageTiles() { void Scheduler::DidLoseOutputSurface() { TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); state_machine_.DidLoseOutputSurface(); - last_set_needs_begin_impl_frame_ = false; + last_set_needs_begin_frame_ = false; + begin_retro_frame_args_.clear(); ProcessScheduledActions(); } void Scheduler::DidCreateAndInitializeOutputSurface() { TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); - DCHECK(!last_set_needs_begin_impl_frame_); + DCHECK(!last_set_needs_begin_frame_); DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); state_machine_.DidCreateAndInitializeOutputSurface(); ProcessScheduledActions(); @@ -136,53 +140,54 @@ void Scheduler::NotifyBeginMainFrameStarted() { } base::TimeTicks Scheduler::AnticipatedDrawTime() const { - if (!last_set_needs_begin_impl_frame_ || - last_begin_impl_frame_args_.interval <= base::TimeDelta()) + if (!last_set_needs_begin_frame_ || + begin_impl_frame_args_.interval <= base::TimeDelta()) return base::TimeTicks(); base::TimeTicks now = gfx::FrameTime::Now(); - base::TimeTicks timebase = std::max(last_begin_impl_frame_args_.frame_time, - last_begin_impl_frame_args_.deadline); - int64 intervals = - 1 + ((now - timebase) / last_begin_impl_frame_args_.interval); - return timebase + (last_begin_impl_frame_args_.interval * intervals); + base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, + begin_impl_frame_args_.deadline); + int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); + return timebase + (begin_impl_frame_args_.interval * intervals); } base::TimeTicks Scheduler::LastBeginImplFrameTime() { - return last_begin_impl_frame_args_.frame_time; + return begin_impl_frame_args_.frame_time; } -void Scheduler::SetupNextBeginImplFrameIfNeeded() { - bool needs_begin_impl_frame = - state_machine_.BeginImplFrameNeeded(); +void Scheduler::SetupNextBeginFrameIfNeeded() { + bool needs_begin_frame = state_machine_.BeginFrameNeeded(); bool at_end_of_deadline = state_machine_.begin_impl_frame_state() == SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; - bool should_call_set_needs_begin_impl_frame = - // Always request the BeginImplFrame immediately if it wasn't needed - // before. - (needs_begin_impl_frame && !last_set_needs_begin_impl_frame_) || - // We always need to explicitly request our next BeginImplFrame. + bool should_call_set_needs_begin_frame = + // Always request the BeginFrame immediately if it wasn't needed before. + (needs_begin_frame && !last_set_needs_begin_frame_) || + // We always need to explicitly request our next BeginFrame. at_end_of_deadline; - if (should_call_set_needs_begin_impl_frame) { - client_->SetNeedsBeginImplFrame(needs_begin_impl_frame); - last_set_needs_begin_impl_frame_ = needs_begin_impl_frame; + if (should_call_set_needs_begin_frame) { + client_->SetNeedsBeginFrame(needs_begin_frame); + last_set_needs_begin_frame_ = needs_begin_frame; } + // Handle retroactive BeginFrames. + if (last_set_needs_begin_frame_) + PostBeginRetroFrameIfNeeded(); + bool needs_advance_commit_state_timer = false; // Setup PollForAnticipatedDrawTriggers if we need to monitor state but - // aren't expecting any more BeginImplFrames. This should only be needed by - // the synchronous compositor when BeginImplFrameNeeded is false. + // aren't expecting any more BeginFrames. This should only be needed by + // the synchronous compositor when BeginFrameNeeded is false. if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { - DCHECK(!state_machine_.SupportsProactiveBeginImplFrame()); - DCHECK(!needs_begin_impl_frame); + DCHECK(!state_machine_.SupportsProactiveBeginFrame()); + DCHECK(!needs_begin_frame); if (poll_for_draw_triggers_task_.IsCancelled()) { poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); - base::TimeDelta delay = last_begin_impl_frame_args_.IsValid() - ? last_begin_impl_frame_args_.interval + base::TimeDelta delay = begin_impl_frame_args_.IsValid() + ? begin_impl_frame_args_.interval : BeginFrameArgs::DefaultInterval(); impl_task_runner_->PostDelayedTask( FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); @@ -192,10 +197,10 @@ void Scheduler::SetupNextBeginImplFrameIfNeeded() { // At this point we'd prefer to advance through the commit flow by // drawing a frame, however it's possible that the frame rate controller - // will not give us a BeginImplFrame until the commit completes. See + // will not give us a BeginFrame until the commit completes. See // crbug.com/317430 for an example of a swap ack being held on commit. Thus // we set a repeating timer to poll on ProcessScheduledActions until we - // successfully reach BeginImplFrame. Synchronous compositor does not use + // successfully reach BeginFrame. Synchronous compositor does not use // frame rate controller or have the circular wait in the bug. if (IsBeginMainFrameSentOrStarted() && !settings_.using_synchronous_renderer_compositor) { @@ -205,20 +210,102 @@ void Scheduler::SetupNextBeginImplFrameIfNeeded() { if (needs_advance_commit_state_timer) { if (advance_commit_state_task_.IsCancelled() && - last_begin_impl_frame_args_.IsValid()) { + begin_impl_frame_args_.IsValid()) { // Since we'd rather get a BeginImplFrame by the normal mechanism, we // set the interval to twice the interval from the previous frame. advance_commit_state_task_.Reset(advance_commit_state_closure_); - impl_task_runner_->PostDelayedTask( - FROM_HERE, - advance_commit_state_task_.callback(), - last_begin_impl_frame_args_.interval * 2); + impl_task_runner_->PostDelayedTask(FROM_HERE, + advance_commit_state_task_.callback(), + begin_impl_frame_args_.interval * 2); } } else { advance_commit_state_task_.Cancel(); } } +// BeginFrame is the mechanism that tells us that now is a good time to start +// making a frame. Usually this means that user input for the frame is complete. +// If the scheduler is busy, we queue the BeginFrame to be handled later as +// a BeginRetroFrame. +void Scheduler::BeginFrame(const BeginFrameArgs& args) { + bool should_defer_begin_frame; + if (settings_.using_synchronous_renderer_compositor) { + should_defer_begin_frame = false; + } else { + should_defer_begin_frame = + !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || + !last_set_needs_begin_frame_ || + (state_machine_.begin_impl_frame_state() != + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); + } + + if (should_defer_begin_frame) { + begin_retro_frame_args_.push_back(args); + TRACE_EVENT_INSTANT0( + "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); + return; + } + + BeginImplFrame(args); +} + +// BeginRetroFrame is called for BeginFrames that we've deferred because +// the scheduler was in the middle of processing a previous BeginFrame. +void Scheduler::BeginRetroFrame() { + TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame"); + DCHECK(begin_retro_frame_posted_); + DCHECK(!begin_retro_frame_args_.empty()); + DCHECK(!settings_.using_synchronous_renderer_compositor); + + // Discard expired BeginRetroFrames + // Today, we should always end up with at most one un-expired BeginRetroFrame + // because deadlines will not be greater than the next frame time. We don't + // DCHECK though because some systems don't always have monotonic timestamps. + // TODO(brianderson): In the future, long deadlines could result in us not + // draining the queue if we don't catch up. If we consistently can't catch + // up, our fallback should be to lower our frame rate. + base::TimeTicks now = gfx::FrameTime::Now(); + base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); + while (!begin_retro_frame_args_.empty() && + now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(), + draw_duration_estimate)) { + begin_retro_frame_args_.pop_front(); + } + + if (begin_retro_frame_args_.empty()) { + TRACE_EVENT_INSTANT0( + "cc", "Scheduler::BeginRetroFrames expired", TRACE_EVENT_SCOPE_THREAD); + } else { + BeginImplFrame(begin_retro_frame_args_.front()); + begin_retro_frame_args_.pop_front(); + } + + begin_retro_frame_posted_ = false; +} + +// There could be a race between the posted BeginRetroFrame and a new +// BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame +// will check if there is a pending BeginRetroFrame to ensure we handle +// BeginFrames in FIFO order. +void Scheduler::PostBeginRetroFrameIfNeeded() { + if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_) + return; + + // begin_retro_frame_args_ should always be empty for the + // synchronous compositor. + DCHECK(!settings_.using_synchronous_renderer_compositor); + + if (state_machine_.begin_impl_frame_state() != + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) + return; + + begin_retro_frame_posted_ = true; + impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); +} + +// BeginImplFrame starts a compositor frame that will wait up until a deadline +// for a BeginMainFrame+activation to complete before it times out and draws +// any asynchronous animation and scroll/pinch updates. void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { TRACE_EVENT0("cc", "Scheduler::BeginImplFrame"); DCHECK(state_machine_.begin_impl_frame_state() == @@ -227,8 +314,9 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { advance_commit_state_task_.Cancel(); - last_begin_impl_frame_args_ = args; - last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); + base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); + begin_impl_frame_args_ = args; + begin_impl_frame_args_.deadline -= draw_duration_estimate; if (!state_machine_.smoothness_takes_priority() && state_machine_.MainThreadIsInHighLatencyMode() && @@ -236,7 +324,8 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); } - state_machine_.OnBeginImplFrame(last_begin_impl_frame_args_); + client_->WillBeginImplFrame(begin_impl_frame_args_); + state_machine_.OnBeginImplFrame(begin_impl_frame_args_); devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); ProcessScheduledActions(); @@ -245,11 +334,13 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { return; state_machine_.OnBeginImplFrameDeadlinePending(); - base::TimeTicks adjusted_deadline = AdjustedBeginImplFrameDeadline(); - ScheduleBeginImplFrameDeadline(adjusted_deadline); + ScheduleBeginImplFrameDeadline( + AdjustedBeginImplFrameDeadline(args, draw_duration_estimate)); } -base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const { +base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline( + const BeginFrameArgs& args, + base::TimeDelta draw_duration_estimate) const { if (settings_.using_synchronous_renderer_compositor) { // The synchronous compositor needs to draw right away. return base::TimeTicks(); @@ -259,7 +350,7 @@ base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const { } else if (state_machine_.needs_redraw()) { // We have an animation or fast input path on the impl thread that wants // to draw, so don't wait too long for a new active tree. - return last_begin_impl_frame_args_.deadline; + return args.deadline - draw_duration_estimate; } else { // The impl thread doesn't have anything it wants to draw and we are just // waiting for a new active tree, so post the deadline for the next @@ -268,8 +359,7 @@ base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const { // BeginImplFrame. // TODO(brianderson): Handle long deadlines (that are past the next frame's // frame time) properly instead of using this hack. - return last_begin_impl_frame_args_.frame_time + - last_begin_impl_frame_args_.interval; + return args.frame_time + args.interval; } } @@ -402,7 +492,7 @@ void Scheduler::ProcessScheduledActions() { } } while (action != SchedulerStateMachine::ACTION_NONE); - SetupNextBeginImplFrameIfNeeded(); + SetupNextBeginFrameIfNeeded(); client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { @@ -423,8 +513,8 @@ scoped_ptr<base::Value> Scheduler::StateAsValue() const { scheduler_state->SetDouble( "time_until_anticipated_draw_time_ms", (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); - scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_", - last_set_needs_begin_impl_frame_); + scheduler_state->SetBoolean("last_set_needs_begin_frame_", + last_set_needs_begin_frame_); scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", !begin_impl_frame_deadline_task_.IsCancelled()); scheduler_state->SetBoolean("poll_for_draw_triggers_task_", @@ -450,19 +540,19 @@ bool Scheduler::CanCommitAndActivateBeforeDeadline() const { // Check if the main thread computation and commit can be finished before the // impl thread's deadline. base::TimeTicks estimated_draw_time = - last_begin_impl_frame_args_.frame_time + + begin_impl_frame_args_.frame_time + client_->BeginMainFrameToCommitDurationEstimate() + client_->CommitToActivateDurationEstimate(); - TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), - "CanCommitAndActivateBeforeDeadline", - "time_left_after_drawing_ms", - (last_begin_impl_frame_args_.deadline - estimated_draw_time) - .InMillisecondsF(), - "state", - TracedValue::FromValue(StateAsValue().release())); + TRACE_EVENT2( + TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), + "CanCommitAndActivateBeforeDeadline", + "time_left_after_drawing_ms", + (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), + "state", + TracedValue::FromValue(StateAsValue().release())); - return estimated_draw_time < last_begin_impl_frame_args_.deadline; + return estimated_draw_time < begin_impl_frame_args_.deadline; } bool Scheduler::IsBeginMainFrameSentOrStarted() const { diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 4aa40acb67..18ecb50cf6 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -5,6 +5,7 @@ #ifndef CC_SCHEDULER_SCHEDULER_H_ #define CC_SCHEDULER_SCHEDULER_H_ +#include <deque> #include <string> #include "base/basictypes.h" @@ -24,7 +25,8 @@ class Thread; class SchedulerClient { public: - virtual void SetNeedsBeginImplFrame(bool enable) = 0; + virtual void SetNeedsBeginFrame(bool enable) = 0; + virtual void WillBeginImplFrame(const BeginFrameArgs& args) = 0; virtual void ScheduledActionSendBeginMainFrame() = 0; virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() = 0; virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() = 0; @@ -107,6 +109,8 @@ class CC_EXPORT Scheduler { base::TimeTicks LastBeginImplFrameTime(); + void BeginFrame(const BeginFrameArgs& args); + void BeginRetroFrame(); void BeginImplFrame(const BeginFrameArgs& args); void OnBeginImplFrameDeadline(); void PollForAnticipatedDrawTriggers(); @@ -129,9 +133,12 @@ class CC_EXPORT Scheduler { int layer_tree_host_id, const scoped_refptr<base::SequencedTaskRunner>& impl_task_runner); - base::TimeTicks AdjustedBeginImplFrameDeadline() const; + base::TimeTicks AdjustedBeginImplFrameDeadline( + const BeginFrameArgs& args, + base::TimeDelta draw_duration_estimate) const; void ScheduleBeginImplFrameDeadline(base::TimeTicks deadline); - void SetupNextBeginImplFrameIfNeeded(); + void SetupNextBeginFrameIfNeeded(); + void PostBeginRetroFrameIfNeeded(); void ActivatePendingTree(); void DrawAndSwapIfPossible(); void DrawAndSwapForced(); @@ -148,9 +155,13 @@ class CC_EXPORT Scheduler { int layer_tree_host_id_; scoped_refptr<base::SequencedTaskRunner> impl_task_runner_; - bool last_set_needs_begin_impl_frame_; - BeginFrameArgs last_begin_impl_frame_args_; + bool last_set_needs_begin_frame_; + bool begin_retro_frame_posted_; + std::deque<BeginFrameArgs> begin_retro_frame_args_; + BeginFrameArgs begin_impl_frame_args_; + + base::Closure begin_retro_frame_closure_; base::Closure begin_impl_frame_deadline_closure_; base::Closure poll_for_draw_triggers_closure_; base::Closure advance_commit_state_closure_; diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index 886868dd37..9a08819081 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc @@ -186,31 +186,27 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue); base::TimeTicks now = gfx::FrameTime::Now(); timestamps_state->SetDouble( - "0_interval", - last_begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); + "0_interval", begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); timestamps_state->SetDouble( "1_now_to_deadline", - (last_begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); + (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); timestamps_state->SetDouble( "2_frame_time_to_now", - (now - last_begin_impl_frame_args_.frame_time).InMicroseconds() / - 1000.0L); + (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L); timestamps_state->SetDouble( "3_frame_time_to_deadline", - (last_begin_impl_frame_args_.deadline - - last_begin_impl_frame_args_.frame_time).InMicroseconds() / + (begin_impl_frame_args_.deadline - begin_impl_frame_args_.frame_time) + .InMicroseconds() / 1000.0L); timestamps_state->SetDouble( "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L); timestamps_state->SetDouble( "5_frame_time", - (last_begin_impl_frame_args_.frame_time - base::TimeTicks()) - .InMicroseconds() / + (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / 1000.0L); timestamps_state->SetDouble( "6_deadline", - (last_begin_impl_frame_args_.deadline - base::TimeTicks()) - .InMicroseconds() / + (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / 1000.0L); state->Set("major_timestamps_in_ms", timestamps_state.release()); @@ -460,7 +456,7 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { // TODO(brianderson): Allow sending BeginMainFrame while idle when the main // thread isn't consuming user input. if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && - BeginImplFrameNeeded()) + BeginFrameNeeded()) return false; // We need a new commit for the forced redraw. This honors the @@ -767,34 +763,32 @@ void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { skip_next_begin_main_frame_to_reduce_latency_ = true; } -bool SchedulerStateMachine::BeginImplFrameNeeded() const { - // Proactive BeginImplFrames are bad for the synchronous compositor because we - // have to draw when we get the BeginImplFrame and could end up drawing many +bool SchedulerStateMachine::BeginFrameNeeded() const { + // Proactive BeginFrames are bad for the synchronous compositor because we + // have to draw when we get the BeginFrame and could end up drawing many // duplicate frames if our new frame isn't ready in time. // To poll for state with the synchronous compositor without having to draw, // we rely on ShouldPollForAnticipatedDrawTriggers instead. - if (!SupportsProactiveBeginImplFrame()) - return BeginImplFrameNeededToDraw(); + if (!SupportsProactiveBeginFrame()) + return BeginFrameNeededToDraw(); - return BeginImplFrameNeededToDraw() || - ProactiveBeginImplFrameWanted(); + return BeginFrameNeededToDraw() || ProactiveBeginFrameWanted(); } bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { // ShouldPollForAnticipatedDrawTriggers is what we use in place of - // ProactiveBeginImplFrameWanted when we are using the synchronous + // ProactiveBeginFrameWanted when we are using the synchronous // compositor. - if (!SupportsProactiveBeginImplFrame()) { - return !BeginImplFrameNeededToDraw() && - ProactiveBeginImplFrameWanted(); + if (!SupportsProactiveBeginFrame()) { + return !BeginFrameNeededToDraw() && ProactiveBeginFrameWanted(); } // Non synchronous compositors should rely on - // ProactiveBeginImplFrameWanted to poll for state instead. + // ProactiveBeginFrameWanted to poll for state instead. return false; } -bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const { +bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { // Both the synchronous compositor and disabled vsync settings // make it undesirable to proactively request BeginImplFrames. // If this is true, the scheduler should poll. @@ -804,7 +798,7 @@ bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const { // These are the cases where we definitely (or almost definitely) have a // new frame to draw and can draw. -bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const { +bool SchedulerStateMachine::BeginFrameNeededToDraw() const { // The output surface is the provider of BeginImplFrames, so we are not going // to get them even if we ask for them. if (!HasInitializedOutputSurface()) @@ -835,8 +829,8 @@ bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const { // These are cases where we are very likely to draw soon, but might not // actually have a new frame to draw when we receive the next BeginImplFrame. // Proactively requesting the BeginImplFrame helps hide the round trip latency -// of the SetNeedsBeginImplFrame request that has to go to the Browser. -bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const { +// of the SetNeedsBeginFrame request that has to go to the Browser. +bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { // The output surface is the provider of BeginImplFrames, // so we are not going to get them even if we ask for them. if (!HasInitializedOutputSurface()) @@ -863,7 +857,7 @@ bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const { // If we just swapped, it's likely that we are going to produce another // frame soon. This helps avoid negative glitches in our - // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame + // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame // provider and get sampled at an inopportune time, delaying the next // BeginImplFrame. if (last_frame_number_swap_performed_ == current_frame_number_) @@ -874,7 +868,7 @@ bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const { void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { AdvanceCurrentFrameNumber(); - last_begin_impl_frame_args_ = args; + begin_impl_frame_args_ = args; DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; } diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index 7426d9606f..c8d68fc429 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h @@ -123,7 +123,7 @@ class CC_EXPORT SchedulerStateMachine { // Indicates whether the impl thread needs a BeginImplFrame callback in order // to make progress. - bool BeginImplFrameNeeded() const; + bool BeginFrameNeeded() const; // Indicates that we need to independently poll for new state and actions // because we can't expect a BeginImplFrame. This is mostly used to avoid @@ -230,15 +230,15 @@ class CC_EXPORT SchedulerStateMachine { // True if we need to abort draws to make forward progress. bool PendingDrawsShouldBeAborted() const; - bool SupportsProactiveBeginImplFrame() const; + bool SupportsProactiveBeginFrame() const; void SetContinuousPainting(bool continuous_painting) { continuous_painting_ = continuous_painting; } protected: - bool BeginImplFrameNeededToDraw() const; - bool ProactiveBeginImplFrameWanted() const; + bool BeginFrameNeededToDraw() const; + bool ProactiveBeginFrameWanted() const; // True if we need to force activations to make forward progress. bool PendingActivationsShouldBeForced() const; @@ -271,7 +271,7 @@ class CC_EXPORT SchedulerStateMachine { ForcedRedrawOnTimeoutState forced_redraw_state_; SynchronousReadbackState readback_state_; - BeginFrameArgs last_begin_impl_frame_args_; + BeginFrameArgs begin_impl_frame_args_; int commit_count_; int current_frame_number_; diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc index 4d7ef3fc1c..060269d11e 100644 --- a/cc/scheduler/scheduler_state_machine_unittest.cc +++ b/cc/scheduler/scheduler_state_machine_unittest.cc @@ -127,10 +127,10 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { state.SetNeedsRedraw(false); state.SetVisible(true); - EXPECT_FALSE(state.BeginImplFrameNeeded()); + EXPECT_FALSE(state.BeginFrameNeeded()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - EXPECT_FALSE(state.BeginImplFrameNeeded()); + EXPECT_FALSE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -145,10 +145,10 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { state.SetVisible(true); state.SetNeedsCommit(); - EXPECT_FALSE(state.BeginImplFrameNeeded()); + EXPECT_FALSE(state.BeginFrameNeeded()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - EXPECT_FALSE(state.BeginImplFrameNeeded()); + EXPECT_FALSE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); @@ -165,7 +165,7 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { state.SetVisible(true); state.SetNeedsCommit(); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE( @@ -201,7 +201,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeDrawDisabled) { state.SetCanDraw(true); state.SetNeedsCommit(); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); // Commit to the pending tree. state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); @@ -269,7 +269,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) { state.SetCanDraw(true); state.SetNeedsCommit(); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); // Commit to the pending tree. state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); @@ -326,7 +326,7 @@ TEST(SchedulerStateMachineTest, state.SetCanDraw(true); state.SetNeedsRedraw(true); EXPECT_TRUE(state.RedrawPending()); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); @@ -359,7 +359,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) { state.SetCanDraw(true); state.SetNeedsRedraw(true); EXPECT_TRUE(state.RedrawPending()); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -392,7 +392,7 @@ TEST(SchedulerStateMachineTest, state.SetCanDraw(true); state.SetNeedsRedraw(true); EXPECT_TRUE(state.RedrawPending()); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); @@ -450,7 +450,7 @@ void TestFailedDrawsEventuallyForceDrawAfterNextCommit( state.DidDrawIfPossibleCompleted( DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); EXPECT_TRUE(state.RedrawPending()); // But the commit is ongoing. EXPECT_TRUE(state.CommitPending()); @@ -524,7 +524,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); } EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); EXPECT_TRUE(state.RedrawPending()); // But the commit is ongoing. EXPECT_TRUE(state.CommitPending()); @@ -564,7 +564,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) { // Start a draw. state.SetNeedsRedraw(true); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); @@ -581,7 +581,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) { EXPECT_TRUE(state.RedrawPending()); // We should not be trying to draw again now, but we have a commit pending. - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -604,7 +604,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { state.SetNeedsRedraw(true); // Draw the first frame. - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -620,7 +620,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Move to another frame. This should now draw. - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -632,7 +632,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // We just swapped, so we should proactively request another BeginImplFrame. - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); } TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { @@ -705,14 +705,12 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { } // Case 1: needs_commit=false. - EXPECT_NE(state.BeginImplFrameNeeded(), request_readback) - << *state.AsValue(); + EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue(); EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue(); // Case 2: needs_commit=true. state.SetNeedsCommit(); - EXPECT_NE(state.BeginImplFrameNeeded(), request_readback) - << *state.AsValue(); + EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue(); EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue(); } } @@ -814,7 +812,7 @@ void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled) { state.SetVisible(true); state.SetCanDraw(true); - EXPECT_TRUE(state.BeginImplFrameNeeded()); + EXPECT_TRUE(state.BeginFrameNeeded()); // Begin the frame. state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc index c40185063d..68dc0d1a49 100644 --- a/cc/scheduler/scheduler_unittest.cc +++ b/cc/scheduler/scheduler_unittest.cc @@ -94,11 +94,15 @@ class FakeSchedulerClient : public SchedulerClient { } // SchedulerClient implementation. - virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE { - actions_.push_back("SetNeedsBeginImplFrame"); + virtual void SetNeedsBeginFrame(bool enable) OVERRIDE { + actions_.push_back("SetNeedsBeginFrame"); states_.push_back(scheduler_->StateAsValue().release()); needs_begin_impl_frame_ = enable; } + virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE { + actions_.push_back("WillBeginImplFrame"); + states_.push_back(scheduler_->StateAsValue().release()); + } virtual void ScheduledActionSendBeginMainFrame() OVERRIDE { actions_.push_back("ScheduledActionSendBeginMainFrame"); states_.push_back(scheduler_->StateAsValue().release()); @@ -190,7 +194,7 @@ void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler, scheduler->NotifyBeginMainFrameStarted(); scheduler->NotifyReadyToCommit(); // Go through the motions to draw the commit. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); // Run the posted deadline task. EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); @@ -198,8 +202,8 @@ void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler, EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); // We need another BeginImplFrame so Scheduler calls - // SetNeedsBeginImplFrame(false). - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); + // SetNeedsBeginFrame(false). + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); // Run the posted deadline task. EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); @@ -236,19 +240,20 @@ TEST(SchedulerTest, RequestCommit) { client.Reset(); scheduler->SetNeedsCommit(); EXPECT_TRUE(client.needs_begin_impl_frame()); - EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client); + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(client.needs_begin_impl_frame()); client.Reset(); // If we don't swap on the deadline, we need to request another // BeginImplFrame. - scheduler->OnBeginImplFrameDeadline(); - EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client); + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(client.needs_begin_impl_frame()); client.Reset(); @@ -261,29 +266,29 @@ TEST(SchedulerTest, RequestCommit) { client.Reset(); // BeginImplFrame should prepare the draw. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(client.needs_begin_impl_frame()); client.Reset(); // BeginImplFrame deadline should draw. - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); - EXPECT_ACTION("SetNeedsBeginImplFrame", client, 1, 2); + EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2); EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(client.needs_begin_impl_frame()); client.Reset(); - // The following BeginImplFrame deadline should SetNeedsBeginImplFrame(false) + // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) // to avoid excessive toggles. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); - EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client); + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); EXPECT_FALSE(client.needs_begin_impl_frame()); client.Reset(); } @@ -302,11 +307,12 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) { // SetNeedsCommit should begin the frame. scheduler->SetNeedsCommit(); - EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client); + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(client.needs_begin_impl_frame()); @@ -323,20 +329,20 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) { EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); - EXPECT_ACTION("SetNeedsBeginImplFrame", client, 1, 2); + EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2); EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); // Because we just swapped, the Scheduler should also request the next // BeginImplFrame from the OutputSurface. EXPECT_TRUE(client.needs_begin_impl_frame()); client.Reset(); - // Since another commit is needed, the next BeginImplFrame should initiate // the second commit. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); @@ -347,17 +353,17 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) { EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); - EXPECT_ACTION("SetNeedsBeginImplFrame", client, 1, 2); + EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2); EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(client.needs_begin_impl_frame()); client.Reset(); // On the next BeginImplFrame, verify we go back to a quiescent state and // no longer request BeginImplFrames. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_FALSE(client.needs_begin_impl_frame()); client.Reset(); } @@ -405,22 +411,22 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) { EXPECT_TRUE(client.needs_begin_impl_frame()); EXPECT_EQ(0, client.num_draws()); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(scheduler->RedrawPending()); EXPECT_TRUE(client.needs_begin_impl_frame()); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); EXPECT_FALSE(scheduler->RedrawPending()); EXPECT_TRUE(client.needs_begin_impl_frame()); // We stop requesting BeginImplFrames after a BeginImplFrame where we don't // swap. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); EXPECT_FALSE(scheduler->RedrawPending()); EXPECT_FALSE(client.needs_begin_impl_frame()); @@ -445,8 +451,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { EXPECT_EQ(0, client.num_draws()); // Fail the draw. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); // We have a commit pending and the draw failed, and we didn't lose the redraw @@ -456,8 +462,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { EXPECT_TRUE(client.needs_begin_impl_frame()); // Fail the draw again. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_TRUE(scheduler->RedrawPending()); @@ -465,8 +471,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { // Draw successfully. client.SetDrawWillHappen(true); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(3, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_FALSE(scheduler->RedrawPending()); @@ -526,17 +532,17 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { EXPECT_TRUE(client.needs_begin_impl_frame()); client.SetNeedsCommitOnNextDraw(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); client.SetNeedsCommitOnNextDraw(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_TRUE(client.needs_begin_impl_frame()); scheduler->NotifyBeginMainFrameStarted(); scheduler->NotifyReadyToCommit(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); EXPECT_FALSE(scheduler->RedrawPending()); @@ -545,8 +551,8 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { // We stop requesting BeginImplFrames after a BeginImplFrame where we don't // swap. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); EXPECT_FALSE(scheduler->RedrawPending()); EXPECT_FALSE(scheduler->CommitPending()); @@ -572,8 +578,8 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { EXPECT_EQ(0, client.num_draws()); // Fail the draw. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); // We have a commit pending and the draw failed, and we didn't lose the commit @@ -583,8 +589,9 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { EXPECT_TRUE(client.needs_begin_impl_frame()); // Fail the draw again. - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_TRUE(scheduler->RedrawPending()); @@ -592,8 +599,8 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { // Draw successfully. client.SetDrawWillHappen(true); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(3, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_FALSE(scheduler->RedrawPending()); @@ -617,8 +624,8 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { // Draw successfully, this starts a new frame. client.SetNeedsCommitOnNextDraw(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); scheduler->SetNeedsRedraw(); @@ -628,8 +635,8 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { // Fail to draw, this should not start a frame. client.SetDrawWillHappen(false); client.SetNeedsCommitOnNextDraw(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - scheduler->OnBeginImplFrameDeadline(); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(2, client.num_draws()); } @@ -714,13 +721,13 @@ TEST(SchedulerTest, ManageTiles) { // We have no immediate actions to perform, so the BeginImplFrame should post // the deadline task. client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); // On the deadline, he actions should have occured in the right order. client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); @@ -741,15 +748,15 @@ TEST(SchedulerTest, ManageTiles) { // We have no immediate actions to perform, so the BeginImplFrame should post // the deadline task. client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); // Draw. The draw will trigger SetNeedsManageTiles, and // then the ManageTiles action will be triggered after the Draw. // Afterwards, neither a draw nor ManageTiles are pending. client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); @@ -761,12 +768,12 @@ TEST(SchedulerTest, ManageTiles) { // We need a BeginImplFrame where we don't swap to go idle. client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); - EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client); + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_EQ(0, client.num_draws()); @@ -781,11 +788,11 @@ TEST(SchedulerTest, ManageTiles) { // BeginImplFrame. There will be no draw, only ManageTiles. client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(0, client.num_draws()); EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); @@ -807,8 +814,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { scheduler->SetNeedsManageTiles(); scheduler->SetNeedsRedraw(); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(scheduler->ManageTilesPending()); @@ -816,7 +823,7 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { EXPECT_FALSE(scheduler->ManageTilesPending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles")); @@ -828,12 +835,12 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { scheduler->SetNeedsManageTiles(); scheduler->SetNeedsRedraw(); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); @@ -850,14 +857,14 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { scheduler->SetNeedsManageTiles(); scheduler->SetNeedsRedraw(); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(scheduler->ManageTilesPending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles")); @@ -872,14 +879,14 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { scheduler->SetNeedsManageTiles(); scheduler->SetNeedsRedraw(); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); EXPECT_TRUE(scheduler->ManageTilesPending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles")); @@ -890,12 +897,12 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { scheduler->SetNeedsManageTiles(); scheduler->SetNeedsRedraw(); client.Reset(); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); - EXPECT_EQ(client.num_actions_(), 0); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.Reset(); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); @@ -917,9 +924,8 @@ TEST(SchedulerTest, TriggerBeginFrameDeadlineEarly) { InitializeOutputSurfaceAndFirstCommit(scheduler, &client); client.Reset(); - BeginFrameArgs impl_frame_args = BeginFrameArgs::CreateForTesting(); scheduler->SetNeedsRedraw(); - scheduler->BeginImplFrame(impl_frame_args); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); // The deadline should be zero since there is no work other than drawing // pending. @@ -975,9 +981,9 @@ void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms, client.Reset(); scheduler->SetNeedsCommit(); EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode()); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode()); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode()); scheduler->NotifyBeginMainFrameStarted(); scheduler->NotifyReadyToCommit(); @@ -987,9 +993,9 @@ void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms, client.Reset(); scheduler->SetNeedsCommit(); EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode()); - scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode()); - scheduler->OnBeginImplFrameDeadline(); + client.task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(scheduler->MainThreadIsInHighLatencyMode(), should_send_begin_main_frame); EXPECT_EQ(client.HasAction("ScheduledActionSendBeginMainFrame"), @@ -1044,9 +1050,9 @@ TEST(SchedulerTest, PollForCommitCompletion) { scheduler->NotifyReadyToCommit(); scheduler->SetNeedsRedraw(); - BeginFrameArgs impl_frame_args = BeginFrameArgs::CreateForTesting(); - impl_frame_args.interval = base::TimeDelta::FromMilliseconds(1000); - scheduler->BeginImplFrame(impl_frame_args); + BeginFrameArgs frame_args = BeginFrameArgs::CreateForTesting(); + frame_args.interval = base::TimeDelta::FromMilliseconds(1000); + scheduler->BeginFrame(frame_args); EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); client.task_runner().RunPendingTasks(); // Run posted deadline. @@ -1056,7 +1062,7 @@ TEST(SchedulerTest, PollForCommitCompletion) { // the NotifyReadyToCommit for now. EXPECT_FALSE(scheduler->CommitPending()); scheduler->SetNeedsCommit(); - scheduler->BeginImplFrame(impl_frame_args); + scheduler->BeginFrame(frame_args); EXPECT_TRUE(scheduler->CommitPending()); // Spin the event loop a few times and make sure we get more @@ -1065,7 +1071,7 @@ TEST(SchedulerTest, PollForCommitCompletion) { // Does three iterations to make sure that the timer is properly repeating. for (int i = 0; i < 3; ++i) { - EXPECT_EQ((impl_frame_args.interval * 2).InMicroseconds(), + EXPECT_EQ((frame_args.interval * 2).InMicroseconds(), client.task_runner().NextPendingTaskDelay().InMicroseconds()) << *scheduler->StateAsValue(); client.task_runner().RunPendingTasks(); @@ -1078,7 +1084,7 @@ TEST(SchedulerTest, PollForCommitCompletion) { // Do the same thing after BeginMainFrame starts but still before activation. scheduler->NotifyBeginMainFrameStarted(); for (int i = 0; i < 3; ++i) { - EXPECT_EQ((impl_frame_args.interval * 2).InMicroseconds(), + EXPECT_EQ((frame_args.interval * 2).InMicroseconds(), client.task_runner().NextPendingTaskDelay().InMicroseconds()) << *scheduler->StateAsValue(); client.task_runner().RunPendingTasks(); @@ -1089,5 +1095,82 @@ TEST(SchedulerTest, PollForCommitCompletion) { } } +TEST(SchedulerTest, BeginRetroFrame) { + FakeSchedulerClient client; + SchedulerSettings scheduler_settings; + Scheduler* scheduler = client.CreateScheduler(scheduler_settings); + scheduler->SetCanStart(); + scheduler->SetVisible(true); + scheduler->SetCanDraw(true); + InitializeOutputSurfaceAndFirstCommit(scheduler, &client); + + // SetNeedsCommit should begin the frame on the next BeginImplFrame. + client.Reset(); + scheduler->SetNeedsCommit(); + EXPECT_TRUE(client.needs_begin_impl_frame()); + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); + client.Reset(); + + // Create a BeginFrame with a long deadline to avoid race conditions. + // This is the first BeginFrame, which will be handled immediately. + BeginFrameArgs args = BeginFrameArgs::CreateForTesting(); + args.deadline += base::TimeDelta::FromHours(1); + scheduler->BeginFrame(args); + + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_impl_frame()); + client.Reset(); + + // Queue BeginFrames while we are still handling the previous BeginFrame. + args.frame_time += base::TimeDelta::FromSeconds(1); + scheduler->BeginFrame(args); + args.frame_time += base::TimeDelta::FromSeconds(1); + scheduler->BeginFrame(args); + + // If we don't swap on the deadline, we need to request another + // BeginImplFrame. + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); + EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_impl_frame()); + client.Reset(); + + // NotifyReadyToCommit should trigger the commit. + scheduler->NotifyBeginMainFrameStarted(); + scheduler->NotifyReadyToCommit(); + EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); + EXPECT_TRUE(client.needs_begin_impl_frame()); + client.Reset(); + + // BeginImplFrame should prepare the draw. + client.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_impl_frame()); + client.Reset(); + + // BeginImplFrame deadline should draw. + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); + EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2); + EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_impl_frame()); + client.Reset(); + + // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) + // to avoid excessive toggles. + client.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + client.Reset(); + + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client); + EXPECT_FALSE(client.needs_begin_impl_frame()); + client.Reset(); +} + } // namespace } // namespace cc diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h index 123a66160c..975992d995 100644 --- a/cc/test/fake_layer_tree_host_impl_client.h +++ b/cc/test/fake_layer_tree_host_impl_client.h @@ -17,8 +17,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient { virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} virtual void DidSwapBuffersOnImplThread() OVERRIDE {} virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {} - virtual void BeginImplFrame(const BeginFrameArgs& args) - OVERRIDE {} + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {} virtual void NotifyReadyToActivate() OVERRIDE {} virtual void SetNeedsRedrawOnImplThread() OVERRIDE {} diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index e72253ca69..920b68940c 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -19,7 +19,7 @@ FakeOutputSurface::FakeOutputSurface( : OutputSurface(context_provider), client_(NULL), num_sent_frames_(0), - needs_begin_impl_frame_(false), + needs_begin_frame_(false), forced_draw_to_software_device_(false), has_external_stencil_test_(false), fake_weak_ptr_factory_(this) { @@ -84,22 +84,23 @@ void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) { } } -void FakeOutputSurface::SetNeedsBeginImplFrame(bool enable) { - needs_begin_impl_frame_ = enable; - OutputSurface::SetNeedsBeginImplFrame(enable); +void FakeOutputSurface::SetNeedsBeginFrame(bool enable) { + needs_begin_frame_ = enable; + OutputSurface::SetNeedsBeginFrame(enable); - // If there is not BeginImplFrame emulation from the FrameRateController, - // then we just post a BeginImplFrame to emulate it as part of the test. + // If there is not BeginFrame emulation from the FrameRateController, + // then we just post a BeginFrame to emulate it as part of the test. if (enable && !frame_rate_controller_) { base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, base::Bind(&FakeOutputSurface::OnBeginImplFrame, - fake_weak_ptr_factory_.GetWeakPtr()), + FROM_HERE, + base::Bind(&FakeOutputSurface::OnBeginFrame, + fake_weak_ptr_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(16)); } } -void FakeOutputSurface::OnBeginImplFrame() { - OutputSurface::BeginImplFrame(BeginFrameArgs::CreateForTesting()); +void FakeOutputSurface::OnBeginFrame() { + OutputSurface::BeginFrame(BeginFrameArgs::CreateForTesting()); } diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 965f54347a..e44153c759 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -94,10 +94,8 @@ class FakeOutputSurface : public OutputSurface { virtual void SwapBuffers(CompositorFrame* frame) OVERRIDE; - virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE; - bool needs_begin_impl_frame() const { - return needs_begin_impl_frame_; - } + virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; + bool needs_begin_frame() const { return needs_begin_frame_; } void set_forced_draw_to_software_device(bool forced) { forced_draw_to_software_device_ = forced; @@ -140,12 +138,12 @@ class FakeOutputSurface : public OutputSurface { scoped_ptr<SoftwareOutputDevice> software_device, bool delegated_rendering); - void OnBeginImplFrame(); + void OnBeginFrame(); OutputSurfaceClient* client_; CompositorFrame last_sent_frame_; size_t num_sent_frames_; - bool needs_begin_impl_frame_; + bool needs_begin_frame_; bool forced_draw_to_software_device_; bool has_external_stencil_test_; TransferableResourceArray resources_held_by_parent_; diff --git a/cc/test/fake_output_surface_client.cc b/cc/test/fake_output_surface_client.cc index ce4feef64a..20de00e6bb 100644 --- a/cc/test/fake_output_surface_client.cc +++ b/cc/test/fake_output_surface_client.cc @@ -12,8 +12,8 @@ bool FakeOutputSurfaceClient::DeferredInitialize( return deferred_initialize_result_; } -void FakeOutputSurfaceClient::BeginImplFrame(const BeginFrameArgs& args) { - begin_impl_frame_count_++; +void FakeOutputSurfaceClient::BeginFrame(const BeginFrameArgs& args) { + begin_frame_count_++; } void FakeOutputSurfaceClient::DidLoseOutputSurface() { diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h index b944d09b9b..d64e063ff7 100644 --- a/cc/test/fake_output_surface_client.h +++ b/cc/test/fake_output_surface_client.h @@ -13,7 +13,7 @@ namespace cc { class FakeOutputSurfaceClient : public OutputSurfaceClient { public: FakeOutputSurfaceClient() - : begin_impl_frame_count_(0), + : begin_frame_count_(0), deferred_initialize_result_(true), deferred_initialize_called_(false), did_lose_output_surface_called_(false), @@ -23,7 +23,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE; virtual void ReleaseGL() OVERRIDE {} virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) OVERRIDE {} - virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE; + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; virtual void DidSwapBuffers() OVERRIDE {} virtual void OnSwapBuffersComplete() OVERRIDE {} virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {} @@ -36,9 +36,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE; virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {} - int begin_impl_frame_count() { - return begin_impl_frame_count_; - } + int begin_frame_count() { return begin_frame_count_; } void set_deferred_initialize_result(bool result) { deferred_initialize_result_ = result; @@ -55,7 +53,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { const ManagedMemoryPolicy& memory_policy() const { return memory_policy_; } private: - int begin_impl_frame_count_; + int begin_frame_count_; bool deferred_initialize_result_; bool deferred_initialize_called_; bool did_lose_output_surface_called_; diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc index 4289b9d449..0c0fce69a0 100644 --- a/cc/test/fake_picture_layer_tiling_client.cc +++ b/cc/test/fake_picture_layer_tiling_client.cc @@ -22,8 +22,10 @@ FakePictureLayerTilingClient::FakePictureLayerTilingClient() FakePictureLayerTilingClient::FakePictureLayerTilingClient( ResourceProvider* resource_provider) - : tile_manager_( - new FakeTileManager(&tile_manager_client_, resource_provider)), + : resource_pool_( + ResourcePool::Create(resource_provider, GL_TEXTURE_2D, RGBA_8888)), + tile_manager_( + new FakeTileManager(&tile_manager_client_, resource_pool_.get())), pile_(FakePicturePileImpl::CreateInfiniteFilledPile()), twin_tiling_(NULL), allow_create_tile_(true), diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h index 5989bba5c6..7440ea77c3 100644 --- a/cc/test/fake_picture_layer_tiling_client.h +++ b/cc/test/fake_picture_layer_tiling_client.h @@ -59,6 +59,7 @@ class FakePictureLayerTilingClient : public PictureLayerTilingClient { protected: FakeTileManagerClient tile_manager_client_; + scoped_ptr<ResourcePool> resource_pool_; scoped_ptr<TileManager> tile_manager_; scoped_refptr<PicturePileImpl> pile_; gfx::Size tile_size_; diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc index da365e70c7..3b86035ad4 100644 --- a/cc/test/fake_tile_manager.cc +++ b/cc/test/fake_tile_manager.cc @@ -8,24 +8,23 @@ #include <limits> #include "base/lazy_instance.h" -#include "cc/resources/raster_worker_pool.h" +#include "cc/resources/rasterizer.h" namespace cc { namespace { -class FakeRasterWorkerPool : public RasterWorkerPool, - public internal::WorkerPoolTaskClient { +class FakeRasterizerImpl : public Rasterizer, public RasterizerTaskClient { public: - // Overridden from RasterWorkerPool: - virtual void SetClient(RasterWorkerPoolClient* client) OVERRIDE {} + // Overridden from Rasterizer: + virtual void SetClient(RasterizerClient* client) OVERRIDE {} virtual void Shutdown() OVERRIDE {} virtual void ScheduleTasks(RasterTaskQueue* queue) OVERRIDE { for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); it != queue->items.end(); ++it) { - internal::RasterWorkerPoolTask* task = it->task; + RasterTask* task = it->task; task->WillSchedule(); task->ScheduleOnOriginThread(this); @@ -35,11 +34,10 @@ class FakeRasterWorkerPool : public RasterWorkerPool, } } virtual void CheckForCompletedTasks() OVERRIDE { - for (internal::WorkerPoolTask::Vector::iterator it = - completed_tasks_.begin(); + for (RasterTask::Vector::iterator it = completed_tasks_.begin(); it != completed_tasks_.end(); ++it) { - internal::WorkerPoolTask* task = it->get(); + RasterTask* task = it->get(); task->WillComplete(); task->CompleteOnOriginThread(this); @@ -49,25 +47,17 @@ class FakeRasterWorkerPool : public RasterWorkerPool, } completed_tasks_.clear(); } - virtual GLenum GetResourceTarget() const OVERRIDE { - return GL_TEXTURE_2D; - } - virtual ResourceFormat GetResourceFormat() const OVERRIDE { - return RGBA_8888; - } - // Overridden from internal::WorkerPoolTaskClient: - virtual SkCanvas* AcquireCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE { + // Overridden from RasterizerTaskClient: + virtual SkCanvas* AcquireCanvasForRaster(RasterTask* task) OVERRIDE { return NULL; } - virtual void ReleaseCanvasForRaster(internal::WorkerPoolTask* task, - const Resource* resource) OVERRIDE {} + virtual void ReleaseCanvasForRaster(RasterTask* task) OVERRIDE {} private: - internal::WorkerPoolTask::Vector completed_tasks_; + RasterTask::Vector completed_tasks_; }; -base::LazyInstance<FakeRasterWorkerPool> g_fake_raster_worker_pool = +base::LazyInstance<FakeRasterizerImpl> g_fake_rasterizer = LAZY_INSTANCE_INITIALIZER; } // namespace @@ -75,40 +65,40 @@ base::LazyInstance<FakeRasterWorkerPool> g_fake_raster_worker_pool = FakeTileManager::FakeTileManager(TileManagerClient* client) : TileManager(client, NULL, - g_fake_raster_worker_pool.Pointer(), - g_fake_raster_worker_pool.Pointer(), + g_fake_rasterizer.Pointer(), + g_fake_rasterizer.Pointer(), std::numeric_limits<unsigned>::max(), true, NULL) {} FakeTileManager::FakeTileManager(TileManagerClient* client, - ResourceProvider* resource_provider) + ResourcePool* resource_pool) : TileManager(client, - resource_provider, - g_fake_raster_worker_pool.Pointer(), - g_fake_raster_worker_pool.Pointer(), + resource_pool, + g_fake_rasterizer.Pointer(), + g_fake_rasterizer.Pointer(), std::numeric_limits<unsigned>::max(), true, NULL) {} FakeTileManager::FakeTileManager(TileManagerClient* client, - ResourceProvider* resource_provider, + ResourcePool* resource_pool, bool allow_on_demand_raster) : TileManager(client, - resource_provider, - g_fake_raster_worker_pool.Pointer(), - g_fake_raster_worker_pool.Pointer(), + resource_pool, + g_fake_rasterizer.Pointer(), + g_fake_rasterizer.Pointer(), std::numeric_limits<unsigned>::max(), allow_on_demand_raster, NULL) {} FakeTileManager::FakeTileManager(TileManagerClient* client, - ResourceProvider* resource_provider, + ResourcePool* resource_pool, size_t raster_task_limit_bytes) : TileManager(client, - resource_provider, - g_fake_raster_worker_pool.Pointer(), - g_fake_raster_worker_pool.Pointer(), + resource_pool, + g_fake_rasterizer.Pointer(), + g_fake_rasterizer.Pointer(), raster_task_limit_bytes, true, NULL) {} diff --git a/cc/test/fake_tile_manager.h b/cc/test/fake_tile_manager.h index 039998409d..162aebeafc 100644 --- a/cc/test/fake_tile_manager.h +++ b/cc/test/fake_tile_manager.h @@ -15,13 +15,12 @@ namespace cc { class FakeTileManager : public TileManager { public: explicit FakeTileManager(TileManagerClient* client); + FakeTileManager(TileManagerClient* client, ResourcePool* resource_pool); FakeTileManager(TileManagerClient* client, - ResourceProvider* resource_provider); - FakeTileManager(TileManagerClient* client, - ResourceProvider* resource_provider, + ResourcePool* resource_pool, bool allow_on_demand_raster); FakeTileManager(TileManagerClient* client, - ResourceProvider* resource_provider, + ResourcePool* resource_pool, size_t raster_task_limit_bytes); virtual ~FakeTileManager(); diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h index 2cbd56381b..ee7d1328b2 100644 --- a/cc/test/layer_test_common.h +++ b/cc/test/layer_test_common.h @@ -77,6 +77,24 @@ class LayerTestCommon { return ptr; } + template <typename T, + typename A, + typename B, + typename C, + typename D, + typename E> + T* AddChildToRoot(const A& a, + const B& b, + const C& c, + const D& d, + const E& e) { + scoped_ptr<T> layer = + T::Create(host_->host_impl()->active_tree(), 2, a, b, c, d, e); + T* ptr = layer.get(); + root_layer_impl_->AddChild(layer.template PassAs<LayerImpl>()); + return ptr; + } + void CalcDrawProps(const gfx::Size& viewport_size); void AppendQuadsWithOcclusion(LayerImpl* layer_impl, const gfx::Rect& occluded); diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 69f42e00d8..ed8de3406c 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -83,10 +83,9 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl { block_notify_ready_to_activate_for_testing_(false), notify_ready_to_activate_was_blocked_(false) {} - virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE { + virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE { + LayerTreeHostImpl::WillBeginImplFrame(args); test_hooks_->WillBeginImplFrameOnThread(this, args); - LayerTreeHostImpl::BeginImplFrame(args); - test_hooks_->DidBeginImplFrameOnThread(this, args); } virtual void BeginMainFrameAborted(bool did_handle) OVERRIDE { @@ -628,7 +627,7 @@ void LayerTreeTest::RunTest(bool threaded, delegating_renderer_ = delegating_renderer; - // Spend less time waiting for BeginImplFrame because the output is + // Spend less time waiting for BeginFrame because the output is // mocked out. settings_.refresh_rate = 200.0; if (impl_side_painting) { diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 86208f2f30..19a379be5a 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h @@ -36,8 +36,6 @@ class TestHooks : public AnimationDelegate { virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const BeginFrameArgs& args) {} - virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, - const BeginFrameArgs& args) {} virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, bool did_handle) {} virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {} diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 96d0536361..4a945a2243 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -49,6 +49,8 @@ #include "cc/resources/picture_layer_tiling.h" #include "cc/resources/pixel_buffer_raster_worker_pool.h" #include "cc/resources/prioritized_resource_manager.h" +#include "cc/resources/raster_worker_pool.h" +#include "cc/resources/resource_pool.h" #include "cc/resources/texture_mailbox_deleter.h" #include "cc/resources/ui_resource_bitmap.h" #include "cc/scheduler/delay_based_time_source.h" @@ -306,8 +308,8 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { pending_tree_.reset(); active_tree_.reset(); tile_manager_.reset(); - image_raster_worker_pool_.reset(); - pixel_buffer_raster_worker_pool_.reset(); + resource_pool_.reset(); + raster_worker_pool_.reset(); direct_raster_worker_pool_.reset(); } @@ -1190,6 +1192,15 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING); global_tile_state_.num_resources_limit = policy.num_resources_limit; + DCHECK(resource_pool_); + resource_pool_->CheckBusyResources(); + // Soft limit is used for resource pool such that memory returns to soft + // limit after going over. + resource_pool_->SetResourceUsageLimits( + global_tile_state_.soft_memory_limit_in_bytes, + global_tile_state_.unused_memory_limit_in_bytes, + global_tile_state_.num_resources_limit); + DidModifyTilePriorities(); } @@ -1282,8 +1293,8 @@ void LayerTreeHostImpl::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { client_->SetNeedsRedrawRectOnImplThread(damage_rect); } -void LayerTreeHostImpl::BeginImplFrame(const BeginFrameArgs& args) { - client_->BeginImplFrame(args); +void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) { + client_->BeginFrame(args); } void LayerTreeHostImpl::DidSwapBuffers() { @@ -1303,11 +1314,10 @@ void LayerTreeHostImpl::ReclaimResources(const CompositorFrameAck* ack) { // In OOM, we now might be able to release more resources that were held // because they were exported. if (tile_manager_) { - DCHECK(tile_manager_->resource_pool()); + DCHECK(resource_pool_); - // TODO(vmpstr): Move resource pool to be LTHI member. - tile_manager_->resource_pool()->CheckBusyResources(); - tile_manager_->resource_pool()->ReduceResourceUsage(); + resource_pool_->CheckBusyResources(); + resource_pool_->ReduceResourceUsage(); } // If we're not visible, we likely released resources, so we want to // aggressively flush here to make sure those DeleteTextures make it to the @@ -1499,9 +1509,15 @@ bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) { return true; } -void LayerTreeHostImpl::SetNeedsBeginImplFrame(bool enable) { +void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) { if (output_surface_) - output_surface_->SetNeedsBeginImplFrame(enable); + output_surface_->SetNeedsBeginFrame(enable); +} + +void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) { + // Sample the frame time now. This time will be used for updating animations + // when we draw. + UpdateCurrentFrameTime(); } gfx::SizeF LayerTreeHostImpl::ComputeInnerViewportContainerSize() const { @@ -1796,27 +1812,33 @@ void LayerTreeHostImpl::CreateAndSetTileManager( DCHECK(resource_provider); DCHECK(proxy_->ImplThreadTaskRunner()); - RasterWorkerPool* default_raster_worker_pool = NULL; if (using_map_image) { - image_raster_worker_pool_ = ImageRasterWorkerPool::Create( - proxy_->ImplThreadTaskRunner(), - resource_provider, - GetMapImageTextureTarget(context_provider)); - default_raster_worker_pool = image_raster_worker_pool_.get(); + raster_worker_pool_ = + ImageRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), + RasterWorkerPool::GetTaskGraphRunner(), + resource_provider); + resource_pool_ = + ResourcePool::Create(resource_provider, + GetMapImageTextureTarget(context_provider), + resource_provider->best_texture_format()); } else { - pixel_buffer_raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( + raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( proxy_->ImplThreadTaskRunner(), + RasterWorkerPool::GetTaskGraphRunner(), resource_provider, GetMaxTransferBufferUsageBytes(context_provider)); - default_raster_worker_pool = pixel_buffer_raster_worker_pool_.get(); + resource_pool_ = ResourcePool::Create( + resource_provider, + GL_TEXTURE_2D, + resource_provider->memory_efficient_texture_format()); } direct_raster_worker_pool_ = DirectRasterWorkerPool::Create( proxy_->ImplThreadTaskRunner(), resource_provider, context_provider); tile_manager_ = TileManager::Create(this, - resource_provider, - default_raster_worker_pool, - direct_raster_worker_pool_.get(), + resource_pool_.get(), + raster_worker_pool_->AsRasterizer(), + direct_raster_worker_pool_->AsRasterizer(), GetMaxRasterTasksUsageBytes(context_provider), allow_rasterize_on_demand, rendering_stats_instrumentation_); @@ -1843,8 +1865,8 @@ bool LayerTreeHostImpl::InitializeRenderer( // Note: order is important here. renderer_.reset(); tile_manager_.reset(); - image_raster_worker_pool_.reset(); - pixel_buffer_raster_worker_pool_.reset(); + resource_pool_.reset(); + raster_worker_pool_.reset(); direct_raster_worker_pool_.reset(); resource_provider_.reset(); output_surface_.reset(); @@ -1879,14 +1901,14 @@ bool LayerTreeHostImpl::InitializeRenderer( GetRendererCapabilities().allow_rasterize_on_demand); } - // Setup BeginImplFrameEmulation if it's not supported natively + // Setup BeginFrameEmulation if it's not supported natively if (!settings_.begin_impl_frame_scheduling_enabled) { const base::TimeDelta display_refresh_interval = base::TimeDelta::FromMicroseconds( base::Time::kMicrosecondsPerSecond / settings_.refresh_rate); - output_surface->InitializeBeginImplFrameEmulation( + output_surface->InitializeBeginFrameEmulation( proxy_->ImplThreadTaskRunner(), settings_.throttle_frame_production, display_refresh_interval); @@ -1971,8 +1993,8 @@ void LayerTreeHostImpl::ReleaseGL() { ReleaseTreeResources(); renderer_.reset(); tile_manager_.reset(); - image_raster_worker_pool_.reset(); - pixel_buffer_raster_worker_pool_.reset(); + resource_pool_.reset(); + raster_worker_pool_.reset(); direct_raster_worker_pool_.reset(); resource_provider_->InitializeSoftware(); @@ -2318,6 +2340,13 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, unused_root_delta.set_x(0.0f); if (std::abs(unused_root_delta.y()) < kEpsilon) unused_root_delta.set_y(0.0f); + // Disable overscroll on axes which is impossible to scroll. + if (settings_.report_overscroll_only_for_scrollable_axes) { + if (std::abs(active_tree_->TotalMaxScrollOffset().x()) <= kEpsilon) + unused_root_delta.set_x(0.0f); + if (std::abs(active_tree_->TotalMaxScrollOffset().y()) <= kEpsilon) + unused_root_delta.set_y(0.0f); + } } // If the layer wasn't able to move, try the next one in the hierarchy. diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 7c528fbc17..9b51b6ba34 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -40,18 +40,17 @@ namespace cc { class CompletionEvent; class CompositorFrameMetadata; class DebugRectHistory; -class DirectRasterWorkerPool; class FrameRateCounter; -class ImageRasterWorkerPool; class LayerImpl; class LayerTreeHostImplTimeSourceAdapter; class LayerTreeImpl; class MemoryHistory; class PageScaleAnimation; class PaintTimeCounter; -class PixelBufferRasterWorkerPool; +class RasterWorkerPool; class RenderPassDrawQuad; class RenderingStatsInstrumentation; +class ResourcePool; class ScrollbarLayerImplBase; class TextureMailboxDeleter; class TopControlsManager; @@ -66,7 +65,7 @@ class LayerTreeHostImplClient { virtual void DidLoseOutputSurfaceOnImplThread() = 0; virtual void DidSwapBuffersOnImplThread() = 0; virtual void OnSwapBuffersCompleteOnImplThread() = 0; - virtual void BeginImplFrame(const BeginFrameArgs& args) = 0; + virtual void BeginFrame(const BeginFrameArgs& args) = 0; virtual void OnCanDrawStateChanged(bool can_draw) = 0; virtual void NotifyReadyToActivate() = 0; // Please call these 2 functions through @@ -226,7 +225,7 @@ class CC_EXPORT LayerTreeHostImpl scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE; virtual void ReleaseGL() OVERRIDE; virtual void SetNeedsRedrawRect(const gfx::Rect& rect) OVERRIDE; - virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE; + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; virtual void SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, @@ -265,7 +264,8 @@ class CC_EXPORT LayerTreeHostImpl const RendererCapabilitiesImpl& GetRendererCapabilities() const; virtual bool SwapBuffers(const FrameData& frame); - void SetNeedsBeginImplFrame(bool enable); + void SetNeedsBeginFrame(bool enable); + virtual void WillBeginImplFrame(const BeginFrameArgs& args); void DidModifyTilePriorities(); void Readback(void* pixels, const gfx::Rect& rect_in_device_viewport); @@ -540,9 +540,9 @@ class CC_EXPORT LayerTreeHostImpl // free rendering - see OutputSurface::ForcedDrawToSoftwareDevice(). scoped_ptr<ResourceProvider> resource_provider_; scoped_ptr<TileManager> tile_manager_; - scoped_ptr<ImageRasterWorkerPool> image_raster_worker_pool_; - scoped_ptr<PixelBufferRasterWorkerPool> pixel_buffer_raster_worker_pool_; - scoped_ptr<DirectRasterWorkerPool> direct_raster_worker_pool_; + scoped_ptr<RasterWorkerPool> raster_worker_pool_; + scoped_ptr<RasterWorkerPool> direct_raster_worker_pool_; + scoped_ptr<ResourcePool> resource_pool_; scoped_ptr<Renderer> renderer_; GlobalStateThatImpactsTilePriority global_tile_state_; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index f8dbcec723..0fff5ffc33 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -110,7 +110,7 @@ class LayerTreeHostImplTest : public testing::Test, virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} virtual void DidSwapBuffersOnImplThread() OVERRIDE {} virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {} - virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {} + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE { on_can_draw_state_changed_called_ = true; } diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index f2012a4195..b1e33dd48e 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -1046,15 +1046,11 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails if (impl->pending_tree()) frame_count_with_pending_tree_++; - if (frame_count_with_pending_tree_ == 2) - impl->BlockNotifyReadyToActivateForTesting(false); - } - - virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* impl, - const BeginFrameArgs& args) OVERRIDE { if (frame_count_with_pending_tree_ == 1) { EXPECT_EQ(first_frame_time_.ToInternalValue(), 0); first_frame_time_ = impl->CurrentFrameTimeTicks(); + } else if (frame_count_with_pending_tree_ == 2) { + impl->BlockNotifyReadyToActivateForTesting(false); } } @@ -2604,16 +2600,16 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification); -// Verify that the BeginImplFrame notification is used to initiate rendering. -class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest { +// Verify that the BeginFrame notification is used to initiate rendering. +class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { public: virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { settings->begin_impl_frame_scheduling_enabled = true; } virtual void BeginTest() OVERRIDE { - // This will trigger a SetNeedsBeginImplFrame which will trigger a - // BeginImplFrame. + // This will trigger a SetNeedsBeginFrame which will trigger a + // BeginFrame. PostSetNeedsCommitToMainThread(); } @@ -2631,9 +2627,9 @@ class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest { base::TimeTicks frame_time_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification); +MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); -class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled +class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled : public LayerTreeHostTest { public: virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { @@ -2644,11 +2640,11 @@ class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - // The BeginImplFrame notification is turned off now but will get enabled + // The BeginFrame notification is turned off now but will get enabled // once we return. End test while it's enabled. ImplThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest, + base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest, base::Unretained(this))); } @@ -2656,7 +2652,7 @@ class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled }; MULTI_THREAD_TEST_F( - LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled); + LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled); class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { protected: diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index e3e1b50e59..7ae0cde998 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -20,6 +20,7 @@ LayerTreeSettings::LayerTreeSettings() main_frame_before_draw_enabled(true), main_frame_before_activation_enabled(false), using_synchronous_renderer_compositor(false), + report_overscroll_only_for_scrollable_axes(false), per_tile_painting_enabled(false), partial_swap_enabled(false), accelerated_animation_enabled(true), diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index dc97c84247..e85ef7d4db 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -25,6 +25,7 @@ class CC_EXPORT LayerTreeSettings { bool main_frame_before_draw_enabled; bool main_frame_before_activation_enabled; bool using_synchronous_renderer_compositor; + bool report_overscroll_only_for_scrollable_axes; bool per_tile_painting_enabled; bool partial_swap_enabled; bool accelerated_animation_enabled; diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index dc1bb13e7e..a52a6f52a4 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -57,8 +57,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; virtual void DidSwapBuffersOnImplThread() OVERRIDE; virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE; - virtual void BeginImplFrame(const BeginFrameArgs& args) - OVERRIDE {} + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; virtual void NotifyReadyToActivate() OVERRIDE; virtual void SetNeedsRedrawOnImplThread() OVERRIDE; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index e30edd741d..e84937b419 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -441,22 +441,18 @@ void ThreadProxy::OnSwapBuffersCompleteOnImplThread() { base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); } -void ThreadProxy::SetNeedsBeginImplFrame(bool enable) { - TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable); - DCHECK(IsImplThread()); - impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable); +void ThreadProxy::SetNeedsBeginFrame(bool enable) { + TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrame", "enable", enable); + impl().layer_tree_host_impl->SetNeedsBeginFrame(enable); UpdateBackgroundAnimateTicking(); } -void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) { - TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame"); - DCHECK(IsImplThread()); - - // Sample the frame time now. This time will be used for updating animations - // when we draw. - impl().layer_tree_host_impl->UpdateCurrentFrameTime(); +void ThreadProxy::BeginFrame(const BeginFrameArgs& args) { + impl().scheduler->BeginFrame(args); +} - impl().scheduler->BeginImplFrame(args); +void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { + impl().layer_tree_host_impl->WillBeginImplFrame(args); } void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { @@ -1113,9 +1109,6 @@ void ThreadProxy::ScheduledActionCommit() { impl().next_frame_is_newly_committed_frame = true; impl().timing_history.DidCommit(); - - // SetVisible kicks off the next scheduler action, so this must be last. - impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); } void ThreadProxy::ScheduledActionUpdateVisibleTiles() { @@ -1496,7 +1489,7 @@ void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { layer_tree_host()->DeleteContentsTexturesOnImplThread( impl().layer_tree_host_impl->resource_provider()); impl().current_resource_update_controller.reset(); - impl().layer_tree_host_impl->SetNeedsBeginImplFrame(false); + impl().layer_tree_host_impl->SetNeedsBeginFrame(false); impl().scheduler.reset(); impl().layer_tree_host_impl.reset(); impl().weak_factory.InvalidateWeakPtrs(); diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h index 540e83a3c7..b105c9306d 100644 --- a/cc/trees/thread_proxy.h +++ b/cc/trees/thread_proxy.h @@ -75,7 +75,7 @@ class ThreadProxy : public Proxy, virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; virtual void DidSwapBuffersOnImplThread() OVERRIDE {} virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE; - virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE; + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; virtual void NotifyReadyToActivate() OVERRIDE; // Please call these 2 functions through @@ -100,7 +100,8 @@ class ThreadProxy : public Proxy, virtual void DidManageTiles() OVERRIDE; // SchedulerClient implementation - virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE; + virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; + virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE; virtual void ScheduledActionSendBeginMainFrame() OVERRIDE; virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() OVERRIDE; |