diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-20 10:33:36 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-22 11:45:12 +0000 |
commit | be59a35641616a4cf23c4a13fa0632624b021c1b (patch) | |
tree | 9da183258bdf9cc413f7562079d25ace6955467f /chromium/ui/compositor | |
parent | d702e4b6a64574e97fc7df8fe3238cde70242080 (diff) | |
download | qtwebengine-chromium-be59a35641616a4cf23c4a13fa0632624b021c1b.tar.gz |
BASELINE: Update Chromium to 62.0.3202.101
Change-Id: I2d5eca8117600df6d331f6166ab24d943d9814ac
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ui/compositor')
41 files changed, 802 insertions, 271 deletions
diff --git a/chromium/ui/compositor/BUILD.gn b/chromium/ui/compositor/BUILD.gn index a992c2722fe..82793dca686 100644 --- a/chromium/ui/compositor/BUILD.gn +++ b/chromium/ui/compositor/BUILD.gn @@ -20,21 +20,19 @@ component("compositor") { "compositor.cc", "compositor.h", "compositor_animation_observer.h", - "compositor_constants.h", "compositor_export.h", "compositor_lock.cc", "compositor_lock.h", "compositor_observer.h", "compositor_switches.cc", "compositor_switches.h", - "compositor_util.cc", - "compositor_util.h", "compositor_vsync_manager.cc", "compositor_vsync_manager.h", "debug_utils.cc", "debug_utils.h", "dip_util.cc", "dip_util.h", + "external_begin_frame_client.h", "float_animation_curve_adapter.cc", "float_animation_curve_adapter.h", "layer.cc", @@ -86,13 +84,12 @@ component("compositor") { "//cc", "//cc/animation", "//cc/paint", - "//cc/surfaces", - "//cc/surfaces:surfaces", "//components/viz/common", "//components/viz/host", "//components/viz/service", "//gpu/command_buffer/common", "//skia", + "//ui/base", "//ui/display", "//ui/gfx", "//ui/gfx/animation", @@ -156,9 +153,9 @@ static_library("test_support") { "//base/test:test_support", "//cc", "//cc:test_support", - "//cc/surfaces", "//components/viz/host", "//components/viz/service", + "//components/viz/test:test_support", "//gpu/command_buffer/client:gles2_c_lib", "//gpu/command_buffer/client:gles2_implementation", "//gpu/command_buffer/common:gles2_utils", @@ -211,8 +208,9 @@ test("compositor_unittests") { "//base/test:test_support", "//cc", "//cc:test_support", - "//cc/surfaces", "//components/viz/common", + "//components/viz/service", + "//components/viz/test:test_support", "//mojo/edk/system", "//skia", "//testing/gmock", diff --git a/chromium/ui/compositor/DEPS b/chromium/ui/compositor/DEPS index 75b24eca257..69f116388f5 100644 --- a/chromium/ui/compositor/DEPS +++ b/chromium/ui/compositor/DEPS @@ -18,5 +18,8 @@ include_rules = [ specific_include_rules = { "run_all_unittests\.cc": [ "+mojo/edk/embedder", - ] + ], + ".*_(unit|pixel|perf)test.*\.cc": [ + "+components/viz/test", + ], } diff --git a/chromium/ui/compositor/canvas_painter.cc b/chromium/ui/compositor/canvas_painter.cc index a12e85ab06e..864d8b03e84 100644 --- a/chromium/ui/compositor/canvas_painter.cc +++ b/chromium/ui/compositor/canvas_painter.cc @@ -11,13 +11,17 @@ namespace ui { CanvasPainter::CanvasPainter(SkBitmap* output, const gfx::Size& paint_size, float raster_scale, - SkColor clear_color) + SkColor clear_color, + bool is_pixel_canvas) : output_(output), paint_size_(paint_size), raster_scale_(raster_scale), clear_color_(clear_color), list_(new cc::DisplayItemList), - context_(list_.get(), raster_scale, gfx::Rect(paint_size_)) {} + context_(list_.get(), + raster_scale, + gfx::Rect(paint_size_), + is_pixel_canvas) {} CanvasPainter::~CanvasPainter() { gfx::Size pixel_size = gfx::ScaleToCeiledSize(paint_size_, raster_scale_); diff --git a/chromium/ui/compositor/canvas_painter.h b/chromium/ui/compositor/canvas_painter.h index 1db206f36b0..da44d7bb166 100644 --- a/chromium/ui/compositor/canvas_painter.h +++ b/chromium/ui/compositor/canvas_painter.h @@ -29,7 +29,8 @@ class COMPOSITOR_EXPORT CanvasPainter { CanvasPainter(SkBitmap* output, const gfx::Size& paint_size, float raster_scale, - SkColor clear_color); + SkColor clear_color, + bool is_pixel_canvas); ~CanvasPainter(); const PaintContext& context() const { return context_; } diff --git a/chromium/ui/compositor/clip_recorder.cc b/chromium/ui/compositor/clip_recorder.cc index 5f8133f2abf..77acf0f7cfc 100644 --- a/chromium/ui/compositor/clip_recorder.cc +++ b/chromium/ui/compositor/clip_recorder.cc @@ -21,8 +21,8 @@ ClipRecorder::~ClipRecorder() { for (int i = 0; i < num_closers_; ++i) { // Each restore is part of a separate visual rect, so gets its own // StartPaint/EndPaintOfPairedEnd. - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::RestoreOp>(); + context_.list_->StartPaint(); + context_.list_->push<cc::RestoreOp>(); context_.list_->EndPaintOfPairedEnd(); } } @@ -30,10 +30,10 @@ ClipRecorder::~ClipRecorder() { void ClipRecorder::ClipRect(const gfx::Rect& clip_rect) { bool antialias = false; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::SaveOp>(); - buffer->push<cc::ClipRectOp>(gfx::RectToSkRect(clip_rect), - SkClipOp::kIntersect, antialias); + context_.list_->StartPaint(); + context_.list_->push<cc::SaveOp>(); + context_.list_->push<cc::ClipRectOp>(gfx::RectToSkRect(clip_rect), + SkClipOp::kIntersect, antialias); context_.list_->EndPaintOfPairedBegin(); ++num_closers_; } @@ -41,9 +41,10 @@ void ClipRecorder::ClipRect(const gfx::Rect& clip_rect) { void ClipRecorder::ClipPath(const gfx::Path& clip_path) { bool antialias = false; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::SaveOp>(); - buffer->push<cc::ClipPathOp>(clip_path, SkClipOp::kIntersect, antialias); + context_.list_->StartPaint(); + context_.list_->push<cc::SaveOp>(); + context_.list_->push<cc::ClipPathOp>(clip_path, SkClipOp::kIntersect, + antialias); context_.list_->EndPaintOfPairedBegin(); ++num_closers_; } @@ -51,9 +52,10 @@ void ClipRecorder::ClipPath(const gfx::Path& clip_path) { void ClipRecorder::ClipPathWithAntiAliasing(const gfx::Path& clip_path) { bool antialias = true; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::SaveOp>(); - buffer->push<cc::ClipPathOp>(clip_path, SkClipOp::kIntersect, antialias); + context_.list_->StartPaint(); + context_.list_->push<cc::SaveOp>(); + context_.list_->push<cc::ClipPathOp>(clip_path, SkClipOp::kIntersect, + antialias); context_.list_->EndPaintOfPairedBegin(); ++num_closers_; } diff --git a/chromium/ui/compositor/compositing_recorder.cc b/chromium/ui/compositor/compositing_recorder.cc index 4270342a13a..ab4bf8826ab 100644 --- a/chromium/ui/compositor/compositing_recorder.cc +++ b/chromium/ui/compositor/compositing_recorder.cc @@ -19,9 +19,9 @@ CompositingRecorder::CompositingRecorder(const PaintContext& context, if (!saved_) return; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::SaveLayerAlphaOp>(nullptr, alpha, - !lcd_text_requires_opaque_layer); + context_.list_->StartPaint(); + context_.list_->push<cc::SaveLayerAlphaOp>(nullptr, alpha, + !lcd_text_requires_opaque_layer); context_.list_->EndPaintOfPairedBegin(); } @@ -29,8 +29,8 @@ CompositingRecorder::~CompositingRecorder() { if (!saved_) return; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::RestoreOp>(); + context_.list_->StartPaint(); + context_.list_->push<cc::RestoreOp>(); context_.list_->EndPaintOfPairedEnd(); } diff --git a/chromium/ui/compositor/compositor.cc b/chromium/ui/compositor/compositor.cc index 70eab90261e..68e7df216cd 100644 --- a/chromium/ui/compositor/compositor.cc +++ b/chromium/ui/compositor/compositor.cc @@ -27,21 +27,24 @@ #include "cc/base/switches.h" #include "cc/input/input_handler.h" #include "cc/layers/layer.h" -#include "cc/output/begin_frame_args.h" #include "cc/output/latency_info_swap_promise.h" -#include "cc/scheduler/begin_frame_source.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" +#include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/gpu/context_provider.h" -#include "components/viz/common/quads/resource_format.h" +#include "components/viz/common/resources/resource_format.h" #include "components/viz/common/resources/resource_settings.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" +#include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "ui/base/ui_base_switches.h" #include "ui/compositor/compositor_observer.h" #include "ui/compositor/compositor_switches.h" #include "ui/compositor/compositor_vsync_manager.h" #include "ui/compositor/dip_util.h" +#include "ui/compositor/external_begin_frame_client.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator_collection.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -57,21 +60,27 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id, ui::ContextFactory* context_factory, ui::ContextFactoryPrivate* context_factory_private, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - bool enable_surface_synchronization) + bool enable_surface_synchronization, + bool enable_pixel_canvas, + bool external_begin_frames_enabled, + bool force_software_compositor) : context_factory_(context_factory), context_factory_private_(context_factory_private), frame_sink_id_(frame_sink_id), task_runner_(task_runner), vsync_manager_(new CompositorVSyncManager()), + external_begin_frames_enabled_(external_begin_frames_enabled), + force_software_compositor_(force_software_compositor), layer_animator_collection_(this), scheduled_timeout_(base::TimeTicks()), allow_locks_to_extend_timeout_(false), + is_pixel_canvas_(enable_pixel_canvas), weak_ptr_factory_(this), lock_timeout_weak_ptr_factory_(this) { if (context_factory_private) { - context_factory_private->GetFrameSinkManager() - ->surface_manager() - ->RegisterFrameSinkId(frame_sink_id_); + auto* host_frame_sink_manager = + context_factory_private_->GetHostFrameSinkManager(); + host_frame_sink_manager->RegisterFrameSinkId(frame_sink_id_, this); } root_web_layer_ = cc::Layer::Create(); @@ -162,7 +171,10 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id, gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; settings.disallow_non_exact_resource_reuse = - command_line->HasSwitch(cc::switches::kDisallowNonExactResourceReuse); + command_line->HasSwitch(switches::kDisallowNonExactResourceReuse); + + settings.wait_for_all_pipeline_stages_before_draw = + command_line->HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw); base::TimeTicks before_create = base::TimeTicks::Now(); @@ -213,12 +225,14 @@ Compositor::~Compositor() { context_factory_->RemoveCompositor(this); if (context_factory_private_) { - auto* manager = context_factory_private_->GetFrameSinkManager(); + auto* host_frame_sink_manager = + context_factory_private_->GetHostFrameSinkManager(); for (auto& client : child_frame_sinks_) { DCHECK(client.is_valid()); - manager->UnregisterFrameSinkHierarchy(frame_sink_id_, client); + host_frame_sink_manager->UnregisterFrameSinkHierarchy(frame_sink_id_, + client); } - manager->surface_manager()->InvalidateFrameSinkId(frame_sink_id_); + host_frame_sink_manager->InvalidateFrameSinkId(frame_sink_id_); } } @@ -229,8 +243,8 @@ bool Compositor::IsForSubframe() { void Compositor::AddFrameSink(const viz::FrameSinkId& frame_sink_id) { if (!context_factory_private_) return; - context_factory_private_->GetFrameSinkManager()->RegisterFrameSinkHierarchy( - frame_sink_id_, frame_sink_id); + context_factory_private_->GetHostFrameSinkManager() + ->RegisterFrameSinkHierarchy(frame_sink_id_, frame_sink_id); child_frame_sinks_.insert(frame_sink_id); } @@ -240,8 +254,8 @@ void Compositor::RemoveFrameSink(const viz::FrameSinkId& frame_sink_id) { auto it = child_frame_sinks_.find(frame_sink_id); DCHECK(it != child_frame_sinks_.end()); DCHECK(it->is_valid()); - context_factory_private_->GetFrameSinkManager()->UnregisterFrameSinkHierarchy( - frame_sink_id_, *it); + context_factory_private_->GetHostFrameSinkManager() + ->UnregisterFrameSinkHierarchy(frame_sink_id_, *it); child_frame_sinks_.erase(it); } @@ -312,11 +326,13 @@ void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) { host_->QueueSwapPromise(std::move(swap_promise)); } -void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { +void Compositor::SetScaleAndSize(float scale, + const gfx::Size& size_in_pixel, + const viz::LocalSurfaceId& local_surface_id) { DCHECK_GT(scale, 0); if (!size_in_pixel.IsEmpty()) { size_ = size_in_pixel; - host_->SetViewportSize(size_in_pixel); + host_->SetViewportSize(size_in_pixel, local_surface_id); root_web_layer_->SetBounds(size_in_pixel); // TODO(fsamuel): Get rid of ContextFactoryPrivate. if (context_factory_private_) @@ -325,19 +341,17 @@ void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { if (device_scale_factor_ != scale) { device_scale_factor_ = scale; host_->SetDeviceScaleFactor(scale); + if (is_pixel_canvas()) + host_->SetRecordingScaleFactor(scale); if (root_layer_) root_layer_->OnDeviceScaleFactorChanged(scale); } } void Compositor::SetDisplayColorSpace(const gfx::ColorSpace& color_space) { - blending_color_space_ = color_space; - output_color_space_ = blending_color_space_; - if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableHDR)) { - blending_color_space_ = gfx::ColorSpace::CreateExtendedSRGB(); - output_color_space_ = gfx::ColorSpace::CreateSCRGBLinear(); - } - host_->SetRasterColorSpace(color_space.GetParametricApproximation()); + output_color_space_ = color_space; + blending_color_space_ = output_color_space_.GetBlendingColorSpace(); + host_->SetRasterColorSpace(output_color_space_.GetRasterColorSpace()); // Color space is reset when the output surface is lost, so this must also be // updated then. // TODO(fsamuel): Get rid of this. @@ -392,7 +406,7 @@ void Compositor::SetDisplayVSyncParameters(base::TimeTicks timebase, } if (interval.is_zero()) { // TODO(brianderson): We should not be receiving 0 intervals. - interval = cc::BeginFrameArgs::DefaultInterval(); + interval = viz::BeginFrameArgs::DefaultInterval(); } DCHECK_GT(interval.InMillisecondsF(), 0); refresh_rate_ = @@ -433,6 +447,34 @@ scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const { return vsync_manager_; } +void Compositor::IssueExternalBeginFrame(const viz::BeginFrameArgs& args) { + DCHECK(external_begin_frames_enabled_); + if (context_factory_private_) + context_factory_private_->IssueExternalBeginFrame(this, args); +} + +void Compositor::SetExternalBeginFrameClient(ExternalBeginFrameClient* client) { + DCHECK(external_begin_frames_enabled_); + external_begin_frame_client_ = client; + if (needs_external_begin_frames_) + external_begin_frame_client_->OnNeedsExternalBeginFrames(true); +} + +void Compositor::OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) { + DCHECK(external_begin_frames_enabled_); + if (external_begin_frame_client_) + external_begin_frame_client_->OnDisplayDidFinishFrame(ack); +} + +void Compositor::OnNeedsExternalBeginFrames(bool needs_begin_frames) { + DCHECK(external_begin_frames_enabled_); + if (external_begin_frame_client_) { + external_begin_frame_client_->OnNeedsExternalBeginFrames( + needs_begin_frames); + } + needs_external_begin_frames_ = needs_begin_frames; +} + void Compositor::AddObserver(CompositorObserver* observer) { observer_list_.AddObserver(observer); } @@ -460,7 +502,7 @@ bool Compositor::HasAnimationObserver( return animation_observer_list_.HasObserver(observer); } -void Compositor::BeginMainFrame(const cc::BeginFrameArgs& args) { +void Compositor::BeginMainFrame(const viz::BeginFrameArgs& args) { DCHECK(!IsLocked()); for (auto& observer : animation_observer_list_) observer.OnAnimationStep(args.frame_time); @@ -517,6 +559,12 @@ void Compositor::DidSubmitCompositorFrame() { observer.OnCompositingStarted(this, start_time); } +void Compositor::OnFirstSurfaceActivation( + const viz::SurfaceInfo& surface_info) { + // TODO(fsamuel): Once surface synchronization is turned on, the fallback + // surface should be set here. +} + void Compositor::SetOutputIsSecure(bool output_is_secure) { if (context_factory_private_) context_factory_private_->SetOutputIsSecure(this, output_is_secure); diff --git a/chromium/ui/compositor/compositor.h b/chromium/ui/compositor/compositor.h index 163fbb01646..a3bc8cafc57 100644 --- a/chromium/ui/compositor/compositor.h +++ b/chromium/ui/compositor/compositor.h @@ -17,10 +17,12 @@ #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "build/build_config.h" -#include "cc/output/begin_frame_args.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_single_thread_client.h" +#include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "components/viz/common/surfaces/local_surface_id.h" #include "components/viz/common/surfaces/surface_sequence.h" +#include "components/viz/host/host_frame_sink_client.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/compositor/compositor_animation_observer.h" #include "ui/compositor/compositor_export.h" @@ -69,6 +71,7 @@ namespace ui { class Compositor; class CompositorVSyncManager; +class ExternalBeginFrameClient; class LatencyInfo; class Layer; class Reflector; @@ -133,6 +136,8 @@ class COMPOSITOR_EXPORT ContextFactoryPrivate { virtual void SetDisplayVSyncParameters(ui::Compositor* compositor, base::TimeTicks timebase, base::TimeDelta interval) = 0; + virtual void IssueExternalBeginFrame(ui::Compositor* compositor, + const viz::BeginFrameArgs& args) = 0; virtual void SetOutputIsSecure(Compositor* compositor, bool secure) = 0; }; @@ -179,16 +184,19 @@ class COMPOSITOR_EXPORT ContextFactory { // displayable form of pixels comprising a single widget's contents. It draws an // appropriately transformed texture for each transformed view in the widget's // view hierarchy. -class COMPOSITOR_EXPORT Compositor - : NON_EXPORTED_BASE(public cc::LayerTreeHostClient), - NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient), - NON_EXPORTED_BASE(public CompositorLockDelegate) { +class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, + public cc::LayerTreeHostSingleThreadClient, + public CompositorLockDelegate, + public viz::HostFrameSinkClient { public: Compositor(const viz::FrameSinkId& frame_sink_id, ui::ContextFactory* context_factory, ui::ContextFactoryPrivate* context_factory_private, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - bool enable_surface_synchronization); + bool enable_surface_synchronization, + bool enable_pixel_canvas, + bool external_begin_frames_enabled = false, + bool force_software_compositor = false); ~Compositor() override; ui::ContextFactory* context_factory() { return context_factory_; } @@ -227,6 +235,11 @@ class COMPOSITOR_EXPORT Compositor // compositing layers on. float device_scale_factor() const { return device_scale_factor_; } + // The color space of the device that this compositor is being displayed on. + const gfx::ColorSpace& output_color_space() const { + return output_color_space_; + } + // Where possible, draws are scissored to a damage region calculated from // changes to layer properties. This bypasses that and indicates that // the whole frame needs to be drawn. @@ -243,7 +256,10 @@ class COMPOSITOR_EXPORT Compositor void SetLatencyInfo(const LatencyInfo& latency_info); // Sets the compositor's device scale factor and size. - void SetScaleAndSize(float scale, const gfx::Size& size_in_pixel); + void SetScaleAndSize( + float scale, + const gfx::Size& size_in_pixel, + const viz::LocalSurfaceId& local_surface_id = viz::LocalSurfaceId()); // Set the output color profile into which this compositor should render. void SetDisplayColorSpace(const gfx::ColorSpace& color_space); @@ -291,6 +307,26 @@ class COMPOSITOR_EXPORT Compositor // Returns the vsync manager for this compositor. scoped_refptr<CompositorVSyncManager> vsync_manager() const; + bool external_begin_frames_enabled() { + return external_begin_frames_enabled_; + } + + void SetExternalBeginFrameClient(ExternalBeginFrameClient* client); + + // The ExternalBeginFrameClient calls this to issue a BeginFrame with the + // given |args|. + void IssueExternalBeginFrame(const viz::BeginFrameArgs& args); + + // Called by the ContextFactory when a BeginFrame was completed by the Display + // if the enable_external_begin_frames setting is true. + void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack); + + // Called by the ContextFactory to signal whether BeginFrames are needed by + // the compositor if the enable_external_begin_frames setting is true. + void OnNeedsExternalBeginFrames(bool needs_begin_frames); + + bool force_software_compositor() { return force_software_compositor_; } + // Returns the main thread task runner this compositor uses. Users of the // compositor generally shouldn't use this. scoped_refptr<base::SingleThreadTaskRunner> task_runner() const { @@ -330,7 +366,7 @@ class COMPOSITOR_EXPORT Compositor // LayerTreeHostClient implementation. void WillBeginMainFrame() override {} void DidBeginMainFrame() override {} - void BeginMainFrame(const cc::BeginFrameArgs& args) override; + void BeginMainFrame(const viz::BeginFrameArgs& args) override; void BeginMainFrameNotExpectedSoon() override; void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override; void UpdateLayerTreeHost() override; @@ -356,6 +392,9 @@ class COMPOSITOR_EXPORT Compositor void DidSubmitCompositorFrame() override; void DidLoseLayerTreeFrameSink() override {} + // viz::HostFrameSinkClient implementation. + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; + bool IsLocked() { return !active_locks_.empty(); } void SetOutputIsSecure(bool output_is_secure); @@ -375,6 +414,9 @@ class COMPOSITOR_EXPORT Compositor allow_locks_to_extend_timeout_ = allowed; } + // If true, all paint commands are recorded at pixel size instead of DIP. + bool is_pixel_canvas() const { return is_pixel_canvas_; } + private: friend class base::RefCounted<Compositor>; @@ -418,6 +460,12 @@ class COMPOSITOR_EXPORT Compositor // The manager of vsync parameters for this compositor. scoped_refptr<CompositorVSyncManager> vsync_manager_; + bool external_begin_frames_enabled_; + ExternalBeginFrameClient* external_begin_frame_client_ = nullptr; + bool needs_external_begin_frames_ = false; + + const bool force_software_compositor_; + // The device scale factor of the monitor that this compositor is compositing // layers on. float device_scale_factor_ = 0.f; @@ -435,6 +483,8 @@ class COMPOSITOR_EXPORT Compositor base::TimeTicks scheduled_timeout_; // If true, the |scheduled_timeout_| might be recalculated and extended. bool allow_locks_to_extend_timeout_; + // If true, all paint commands are recorded at pixel size instead of DIP. + const bool is_pixel_canvas_; base::WeakPtrFactory<Compositor> weak_ptr_factory_; base::WeakPtrFactory<Compositor> lock_timeout_weak_ptr_factory_; diff --git a/chromium/ui/compositor/compositor_constants.h b/chromium/ui/compositor/compositor_constants.h deleted file mode 100644 index ef007b0ff7f..00000000000 --- a/chromium/ui/compositor/compositor_constants.h +++ /dev/null @@ -1,18 +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 UI_COMPOSITOR_COMPOSITOR_CONSTANTS_H_ -#define UI_COMPOSITOR_COMPOSITOR_CONSTANTS_H_ - -// This flag is used to work around a rendering bug in Windows where the -// software surface becomes inconsistent with the hardware surface. This -// happens in particular circumstances (Classic mode, Chrome using hardware -// rendering, and the window on a secondary monitor) and when moving the mouse -// over the window, Windows restores the GDI software surface underneath the -// mouse, rather than the hardware surface we've painted. As a result, for -// small or infrequently painting windows, we force back to the software -// compositor to avoid this bug. See http://crbug.com/333380. -const wchar_t kForceSoftwareCompositor[] = L"Chrome.ForceSoftwareCompositor"; - -#endif // UI_COMPOSITOR_COMPOSITOR_CONSTANTS_H_ diff --git a/chromium/ui/compositor/compositor_switches.cc b/chromium/ui/compositor/compositor_switches.cc index 991aba5e0ef..f8179b84a74 100644 --- a/chromium/ui/compositor/compositor_switches.cc +++ b/chromium/ui/compositor/compositor_switches.cc @@ -21,9 +21,6 @@ const char kEnablePixelOutputInTests[] = "enable-pixel-output-in-tests"; // maximum. const char kLimitFps[] = "limit-fps"; -// Disable partial swap which is needed for some OpenGL drivers / emulators. -const char kUIDisablePartialSwap[] = "ui-disable-partial-swap"; - const char kUIEnableRGBA4444Textures[] = "ui-enable-rgba-4444-textures"; const char kUIEnableZeroCopy[] = "ui-enable-zero-copy"; @@ -32,6 +29,11 @@ const char kUIShowPaintRects[] = "ui-show-paint-rects"; const char kUISlowAnimations[] = "ui-slow-animations"; +// If enabled, all draw commands recorded on canvas are done in pixel aligned +// measurements. This also enables scaling of all elements in views and layers +// to be done via corner points. See https://goo.gl/Dqig5s +const char kEnablePixelCanvasRecording[] = "enable-pixel-canvas-recording"; + } // namespace switches namespace ui { @@ -42,4 +44,9 @@ bool IsUIZeroCopyEnabled() { return command_line.HasSwitch(switches::kUIEnableZeroCopy); } +bool IsPixelCanvasRecordingEnabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnablePixelCanvasRecording); +} + } // namespace ui diff --git a/chromium/ui/compositor/compositor_switches.h b/chromium/ui/compositor/compositor_switches.h index 54fc3354217..5c03be4898b 100644 --- a/chromium/ui/compositor/compositor_switches.h +++ b/chromium/ui/compositor/compositor_switches.h @@ -12,11 +12,11 @@ namespace switches { COMPOSITOR_EXPORT extern const char kEnableHardwareOverlays[]; COMPOSITOR_EXPORT extern const char kEnablePixelOutputInTests[]; COMPOSITOR_EXPORT extern const char kLimitFps[]; -COMPOSITOR_EXPORT extern const char kUIDisablePartialSwap[]; COMPOSITOR_EXPORT extern const char kUIEnableRGBA4444Textures[]; COMPOSITOR_EXPORT extern const char kUIEnableZeroCopy[]; COMPOSITOR_EXPORT extern const char kUIShowPaintRects[]; COMPOSITOR_EXPORT extern const char kUISlowAnimations[]; +COMPOSITOR_EXPORT extern const char kEnablePixelCanvasRecording[]; } // namespace switches @@ -24,6 +24,8 @@ namespace ui { bool IsUIZeroCopyEnabled(); +bool COMPOSITOR_EXPORT IsPixelCanvasRecordingEnabled(); + } // namespace ui #endif // UI_COMPOSITOR_COMPOSITOR_SWITCHES_H_ diff --git a/chromium/ui/compositor/compositor_unittest.cc b/chromium/ui/compositor/compositor_unittest.cc index 12fa0ba4974..83878b0a424 100644 --- a/chromium/ui/compositor/compositor_unittest.cc +++ b/chromium/ui/compositor/compositor_unittest.cc @@ -9,10 +9,10 @@ #include "base/single_thread_task_runner.h" #include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "cc/output/begin_frame_args.h" -#include "cc/surfaces/surface_manager.h" -#include "cc/test/begin_frame_args_test.h" +#include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" +#include "components/viz/service/surfaces/surface_manager.h" +#include "components/viz/test/begin_frame_args_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/compositor/compositor.h" @@ -40,7 +40,8 @@ class CompositorTest : public testing::Test { compositor_.reset(new ui::Compositor( context_factory_private->AllocateFrameSinkId(), context_factory, context_factory_private, CreateTaskRunner(), - false /* enable_surface_synchronization */)); + false /* enable_surface_synchronization */, + false /* enable_pixel_canvas */)); compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); } @@ -114,8 +115,7 @@ class CompositorObserverForLocks : public CompositorObserver { bool locked_ = false; }; -class MockCompositorLockClient - : NON_EXPORTED_BASE(public ui::CompositorLockClient) { +class MockCompositorLockClient : public ui::CompositorLockClient { public: MOCK_METHOD0(CompositorLockTimedOut, void()); }; diff --git a/chromium/ui/compositor/compositor_util.cc b/chromium/ui/compositor/compositor_util.cc deleted file mode 100644 index 91b254340c0..00000000000 --- a/chromium/ui/compositor/compositor_util.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 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 "ui/compositor/compositor_util.h" - -#include "base/command_line.h" -#include "cc/base/switches.h" -#include "components/viz/common/display/renderer_settings.h" -#include "ui/compositor/compositor_switches.h" -#include "ui/display/display_switches.h" -#include "ui/gfx/color_space_switches.h" - -namespace ui { - -viz::RendererSettings CreateRendererSettings( - const viz::BufferToTextureTargetMap& image_targets) { - viz::RendererSettings renderer_settings; - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - renderer_settings.partial_swap_enabled = - !command_line->HasSwitch(switches::kUIDisablePartialSwap); -#if defined(OS_WIN) - renderer_settings.finish_rendering_on_resize = true; -#elif defined(OS_MACOSX) - renderer_settings.release_overlay_resources_after_gpu_query = true; -#endif - renderer_settings.gl_composited_overlay_candidate_quad_border = - command_line->HasSwitch( - cc::switches::kGlCompositedOverlayCandidateQuadBorder); - renderer_settings.show_overdraw_feedback = - command_line->HasSwitch(cc::switches::kShowOverdrawFeedback); - renderer_settings.enable_color_correct_rendering = - base::FeatureList::IsEnabled(features::kColorCorrectRendering) || - command_line->HasSwitch(switches::kEnableHDR); - renderer_settings.resource_settings.buffer_to_texture_target_map = - image_targets; - - renderer_settings.disallow_non_exact_resource_reuse = - command_line->HasSwitch(cc::switches::kDisallowNonExactResourceReuse); - renderer_settings.allow_antialiasing = - !command_line->HasSwitch(cc::switches::kDisableCompositedAntialiasing); - - return renderer_settings; -} - -} // namespace ui diff --git a/chromium/ui/compositor/compositor_util.h b/chromium/ui/compositor/compositor_util.h deleted file mode 100644 index 1939514833f..00000000000 --- a/chromium/ui/compositor/compositor_util.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 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 UI_COMPOSITOR_COMPOSITOR_UTIL_H_ -#define UI_COMPOSITOR_COMPOSITOR_UTIL_H_ - -#include <stdint.h> - -#include "components/viz/common/resources/buffer_to_texture_target_map.h" -#include "ui/compositor/compositor_export.h" - -namespace viz { -class RendererSettings; -} - -namespace ui { - -COMPOSITOR_EXPORT viz::RendererSettings CreateRendererSettings( - const viz::BufferToTextureTargetMap& image_targets); - -} // namespace ui - -#endif // UI_COMPOSITOR_COMPOSITOR_UTIL_H_ diff --git a/chromium/ui/compositor/external_begin_frame_client.h b/chromium/ui/compositor/external_begin_frame_client.h new file mode 100644 index 00000000000..764c901df30 --- /dev/null +++ b/chromium/ui/compositor/external_begin_frame_client.h @@ -0,0 +1,23 @@ +// Copyright (c) 2017 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 UI_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CLIENT_H_ +#define UI_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CLIENT_H_ + +#include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "ui/compositor/compositor_export.h" + +namespace ui { + +class COMPOSITOR_EXPORT ExternalBeginFrameClient { + public: + virtual ~ExternalBeginFrameClient() {} + + virtual void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) = 0; + virtual void OnNeedsExternalBeginFrames(bool needs_begin_frames) = 0; +}; + +} // namespace ui + +#endif // UI_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CLIENT_H_ diff --git a/chromium/ui/compositor/layer.cc b/chromium/ui/compositor/layer.cc index d2248572c2a..72ccf5e861c 100644 --- a/chromium/ui/compositor/layer.cc +++ b/chromium/ui/compositor/layer.cc @@ -21,9 +21,9 @@ #include "cc/layers/solid_color_layer.h" #include "cc/layers/surface_layer.h" #include "cc/layers/texture_layer.h" -#include "cc/output/copy_output_request.h" -#include "cc/resources/transferable_resource.h" #include "cc/trees/layer_tree_settings.h" +#include "components/viz/common/quads/copy_output_request.h" +#include "components/viz/common/resources/transferable_resource.h" #include "ui/compositor/compositor_switches.h" #include "ui/compositor/dip_util.h" #include "ui/compositor/layer_animator.h" @@ -40,6 +40,10 @@ namespace { const ui::Layer* GetRoot(const ui::Layer* layer) { + // Parent walk cannot be done on a layer that is being used as a mask. Get the + // layer to which this layer is a mask of. + if (layer->layer_mask_back_link()) + layer = layer->layer_mask_back_link(); while (layer->parent()) layer = layer->parent(); return layer; @@ -108,7 +112,8 @@ Layer::Layer() delegate_(NULL), owner_(NULL), cc_layer_(NULL), - device_scale_factor_(1.0f) { + device_scale_factor_(1.0f), + cache_render_surface_requests_(0) { CreateCcLayer(); } @@ -135,7 +140,8 @@ Layer::Layer(LayerType type) delegate_(NULL), owner_(NULL), cc_layer_(NULL), - device_scale_factor_(1.0f) { + device_scale_factor_(1.0f), + cache_render_surface_requests_(0) { CreateCcLayer(); } @@ -178,7 +184,7 @@ std::unique_ptr<Layer> Layer::Clone() const { clone->SetLayerInverted(layer_inverted_); clone->SetLayerBlur(layer_blur_sigma_); if (alpha_shape_) - clone->SetAlphaShape(base::MakeUnique<SkRegion>(*alpha_shape_)); + clone->SetAlphaShape(base::MakeUnique<ShapeRects>(*alpha_shape_)); // cc::Layer state. if (surface_layer_) { @@ -315,7 +321,7 @@ void Layer::SetAnimator(LayerAnimator* animator) { Compositor* compositor = GetCompositor(); if (animator_) { - if (compositor) + if (compositor && !layer_mask_back_link()) animator_->DetachLayerAndTimeline(compositor); animator_->SetDelegate(nullptr); } @@ -324,7 +330,7 @@ void Layer::SetAnimator(LayerAnimator* animator) { if (animator_) { animator_->SetDelegate(this); - if (compositor) + if (compositor && !layer_mask_back_link()) animator_->AttachLayerAndTimeline(compositor); } } @@ -445,14 +451,13 @@ void Layer::SetLayerInverted(bool inverted) { } void Layer::SetMaskLayer(Layer* layer_mask) { + if (layer_mask_ == layer_mask) + return; // The provided mask should not have a layer mask itself. DCHECK(!layer_mask || - (!layer_mask->layer_mask_layer() && - layer_mask->children().empty() && + (!layer_mask->layer_mask_layer() && layer_mask->children().empty() && !layer_mask->layer_mask_back_link_)); DCHECK(!layer_mask_back_link_); - if (layer_mask_ == layer_mask) - return; // We need to de-reference the currently linked object so that no problem // arises if the mask layer gets deleted before this object. if (layer_mask_) @@ -474,8 +479,8 @@ void Layer::SetBackgroundZoom(float zoom, int inset) { SetLayerBackgroundFilters(); } -void Layer::SetAlphaShape(std::unique_ptr<SkRegion> region) { - alpha_shape_ = std::move(region); +void Layer::SetAlphaShape(std::unique_ptr<ShapeRects> shape) { + alpha_shape_ = std::move(shape); SetLayerFilters(); } @@ -661,13 +666,27 @@ void Layer::SwitchCCLayerForTest() { // which could be a supprise. But we want to preserve it after switching to a // new cc::Layer. There could be a whole subtree and the root changed, but does // not mean we want to treat the cache all different. -void Layer::SetCacheRenderSurface(bool cache_render_surface) { - cc_layer_->SetCacheRenderSurface(cache_render_surface); +void Layer::AddCacheRenderSurfaceRequest() { + ++cache_render_surface_requests_; + TRACE_COUNTER_ID1("ui", "CacheRenderSurfaceRequests", this, + cache_render_surface_requests_); + if (cache_render_surface_requests_ == 1) + cc_layer_->SetCacheRenderSurface(true); +} + +void Layer::RemoveCacheRenderSurfaceRequest() { + DCHECK_GT(cache_render_surface_requests_, 0u); + + --cache_render_surface_requests_; + TRACE_COUNTER_ID1("ui", "CacheRenderSurfaceRequests", this, + cache_render_surface_requests_); + if (cache_render_surface_requests_ == 0) + cc_layer_->SetCacheRenderSurface(false); } void Layer::SetTextureMailbox( const viz::TextureMailbox& mailbox, - std::unique_ptr<cc::SingleReleaseCallback> release_callback, + std::unique_ptr<viz::SingleReleaseCallback> release_callback, gfx::Size texture_size_in_dip) { DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR); DCHECK(mailbox.IsValid()); @@ -741,6 +760,12 @@ void Layer::SetFallbackSurface(const viz::SurfaceInfo& surface_info) { mirror->dest()->SetFallbackSurface(surface_info); } +const viz::SurfaceInfo* Layer::GetPrimarySurfaceInfo() const { + if (surface_layer_) + return &surface_layer_->primary_surface_info(); + return nullptr; +} + const viz::SurfaceInfo* Layer::GetFallbackSurfaceInfo() const { if (surface_layer_) return &surface_layer_->fallback_surface_info(); @@ -896,7 +921,8 @@ void Layer::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) { } void Layer::SetDidScrollCallback( - base::Callback<void(const gfx::ScrollOffset&)> callback) { + base::Callback<void(const gfx::ScrollOffset&, const cc::ElementId&)> + callback) { cc_layer_->set_did_scroll_callback(std::move(callback)); } @@ -927,7 +953,7 @@ void Layer::SetScrollOffset(const gfx::ScrollOffset& offset) { } void Layer::RequestCopyOfOutput( - std::unique_ptr<cc::CopyOutputRequest> request) { + std::unique_ptr<viz::CopyOutputRequest> request) { cc_layer_->RequestCopyOfOutput(std::move(request)); } @@ -944,8 +970,9 @@ scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList( paint_region_.Clear(); auto display_list = make_scoped_refptr(new cc::DisplayItemList); if (delegate_) { - delegate_->OnPaintLayer( - PaintContext(display_list.get(), device_scale_factor_, invalidation)); + delegate_->OnPaintLayer(PaintContext(display_list.get(), + device_scale_factor_, invalidation, + GetCompositor()->is_pixel_canvas())); } display_list->Finalize(); // TODO(domlaskowski): Move mirror invalidation to Layer::SchedulePaint. @@ -964,7 +991,7 @@ size_t Layer::GetApproximateUnsharedMemoryUsage() const { bool Layer::PrepareTextureMailbox( viz::TextureMailbox* mailbox, - std::unique_ptr<cc::SingleReleaseCallback>* release_callback) { + std::unique_ptr<viz::SingleReleaseCallback>* release_callback) { if (!mailbox_release_callback_) return false; *mailbox = mailbox_; @@ -1181,6 +1208,10 @@ float Layer::GetRefreshRate() const { return compositor ? compositor->refresh_rate() : 60.0; } +ui::Layer* Layer::GetLayer() { + return this; +} + cc::Layer* Layer::GetCcLayer() const { return cc_layer_; } diff --git a/chromium/ui/compositor/layer.h b/chromium/ui/compositor/layer.h index e89acf51120..869c00c6f91 100644 --- a/chromium/ui/compositor/layer.h +++ b/chromium/ui/compositor/layer.h @@ -24,7 +24,6 @@ #include "components/viz/common/quads/texture_mailbox.h" #include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/core/SkRegion.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer_animation_delegate.h" #include "ui/compositor/layer_delegate.h" @@ -34,7 +33,6 @@ #include "ui/gfx/transform.h" namespace cc { -class CopyOutputRequest; class Layer; class NinePatchLayer; class SolidColorLayer; @@ -42,6 +40,10 @@ class SurfaceLayer; class TextureLayer; } +namespace viz { +class CopyOutputRequest; +} + namespace ui { class Compositor; @@ -60,12 +62,12 @@ class LayerThreadedAnimationDelegate; // NOTE: Unlike Views, each Layer does *not* own its child Layers. If you // delete a Layer and it has children, the parent of each child Layer is set to // NULL, but the children are not deleted. -class COMPOSITOR_EXPORT Layer - : public LayerAnimationDelegate, - NON_EXPORTED_BASE(public cc::ContentLayerClient), - NON_EXPORTED_BASE(public cc::TextureLayerClient), - NON_EXPORTED_BASE(public cc::LayerClient) { +class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate, + public cc::ContentLayerClient, + public cc::TextureLayerClient, + public cc::LayerClient { public: + using ShapeRects = std::vector<gfx::Rect>; Layer(); explicit Layer(LayerType type); ~Layer() override; @@ -233,8 +235,8 @@ class COMPOSITOR_EXPORT Layer void SetBackgroundZoom(float zoom, int inset); // Set the shape of this layer. - SkRegion* alpha_shape() const { return alpha_shape_.get(); } - void SetAlphaShape(std::unique_ptr<SkRegion> region); + const ShapeRects* alpha_shape() const { return alpha_shape_.get(); } + void SetAlphaShape(std::unique_ptr<ShapeRects> shape); // Invert the layer. bool layer_inverted() const { return layer_inverted_; } @@ -299,7 +301,7 @@ class COMPOSITOR_EXPORT Layer // shared memory resource or an actual mailbox for a texture. void SetTextureMailbox( const viz::TextureMailbox& mailbox, - std::unique_ptr<cc::SingleReleaseCallback> release_callback, + std::unique_ptr<viz::SingleReleaseCallback> release_callback, gfx::Size texture_size_in_dip); void SetTextureSize(gfx::Size texture_size_in_dip); void SetTextureFlipped(bool flipped); @@ -314,6 +316,9 @@ class COMPOSITOR_EXPORT Layer // display compositor, the fallback surface will be used. void SetFallbackSurface(const viz::SurfaceInfo& surface_info); + // Returns the primary SurfaceInfo set by SetShowPrimarySurface. + const viz::SurfaceInfo* GetPrimarySurfaceInfo() const; + // Returns the fallback SurfaceInfo set by SetFallbackSurface. const viz::SurfaceInfo* GetFallbackSurfaceInfo() const; @@ -366,12 +371,15 @@ class COMPOSITOR_EXPORT Layer void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip); // Requets a copy of the layer's output as a texture or bitmap. - void RequestCopyOfOutput(std::unique_ptr<cc::CopyOutputRequest> request); + void RequestCopyOfOutput(std::unique_ptr<viz::CopyOutputRequest> request); // Invoked when scrolling performed by the cc::InputHandler is committed. This // will only occur if the Layer has set scroll container bounds. void SetDidScrollCallback( - base::Callback<void(const gfx::ScrollOffset&)> callback); + base::Callback<void(const gfx::ScrollOffset&, const cc::ElementId&)> + callback); + + cc::ElementId element_id() const { return cc_layer_->element_id(); } // Marks this layer as scrollable inside the provided bounds. This size only // affects scrolling so if clipping is desired, a separate clipping layer @@ -394,7 +402,7 @@ class COMPOSITOR_EXPORT Layer // TextureLayerClient bool PrepareTextureMailbox( viz::TextureMailbox* mailbox, - std::unique_ptr<cc::SingleReleaseCallback>* release_callback) override; + std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override; float device_scale_factor() const { return device_scale_factor_; } @@ -419,7 +427,13 @@ class COMPOSITOR_EXPORT Layer // occlusion culling in favor of efficient caching. This should // only be used when paying the cost of creating a render // surface even if layer is invisible is not a problem. - void SetCacheRenderSurface(bool cache_render_surface); + void AddCacheRenderSurfaceRequest(); + void RemoveCacheRenderSurfaceRequest(); + + // The back link from the mask layer to it's associated masked layer. + // We keep this reference for the case that if the mask layer gets deleted + // while attached to the main layer before the main layer is deleted. + const Layer* layer_mask_back_link() const { return layer_mask_back_link_; } private: friend class LayerOwner; @@ -453,6 +467,7 @@ class COMPOSITOR_EXPORT Layer SkColor GetColorForAnimation() const override; float GetTemperatureFromAnimation() const override; float GetDeviceScaleFactor() const override; + ui::Layer* GetLayer() override; cc::Layer* GetCcLayer() const override; LayerThreadedAnimationDelegate* GetThreadedAnimationDelegate() override; LayerAnimatorCollection* GetLayerAnimatorCollection() override; @@ -546,7 +561,7 @@ class COMPOSITOR_EXPORT Layer int zoom_inset_; // Shape of the window. - std::unique_ptr<SkRegion> alpha_shape_; + std::unique_ptr<ShapeRects> alpha_shape_; std::string name_; @@ -580,12 +595,17 @@ class COMPOSITOR_EXPORT Layer // The callback to release the mailbox. This is only set after // SetTextureMailbox is called, before we give it to the TextureLayer. - std::unique_ptr<cc::SingleReleaseCallback> mailbox_release_callback_; + std::unique_ptr<viz::SingleReleaseCallback> mailbox_release_callback_; // The size of the frame or texture in DIP, set when SetShowDelegatedContent // or SetTextureMailbox was called. gfx::Size frame_size_in_dip_; + // The counter to maintain how many cache render surface requests we have. If + // the value > 0, means we need to cache the render surface. If the value + // == 0, means we should not cache the render surface. + unsigned cache_render_surface_requests_; + DISALLOW_COPY_AND_ASSIGN(Layer); }; diff --git a/chromium/ui/compositor/layer_animation_delegate.h b/chromium/ui/compositor/layer_animation_delegate.h index 827647be7a4..45bf8bad926 100644 --- a/chromium/ui/compositor/layer_animation_delegate.h +++ b/chromium/ui/compositor/layer_animation_delegate.h @@ -16,6 +16,7 @@ class Layer; namespace ui { +class Layer; class LayerAnimatorCollection; class LayerThreadedAnimationDelegate; @@ -40,6 +41,7 @@ class COMPOSITOR_EXPORT LayerAnimationDelegate { virtual SkColor GetColorForAnimation() const = 0; virtual float GetTemperatureFromAnimation() const = 0; virtual float GetDeviceScaleFactor() const = 0; + virtual ui::Layer* GetLayer() = 0; virtual cc::Layer* GetCcLayer() const = 0; virtual LayerAnimatorCollection* GetLayerAnimatorCollection() = 0; virtual LayerThreadedAnimationDelegate* GetThreadedAnimationDelegate() = 0; diff --git a/chromium/ui/compositor/layer_animation_element.cc b/chromium/ui/compositor/layer_animation_element.cc index 9f6797fa9cd..82cdb89f5d6 100644 --- a/chromium/ui/compositor/layer_animation_element.cc +++ b/chromium/ui/compositor/layer_animation_element.cc @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/strings/stringprintf.h" #include "cc/animation/animation.h" #include "cc/animation/animation_id_provider.h" #include "ui/compositor/float_animation_curve_adapter.h" @@ -39,6 +40,7 @@ class Pause : public LayerAnimationElement { ~Pause() override {} private: + std::string DebugName() const override { return "Pause"; } void OnStart(LayerAnimationDelegate* delegate) override {} bool OnProgress(double t, LayerAnimationDelegate* delegate) override { return false; @@ -61,6 +63,9 @@ class InterpolatedTransformTransition : public LayerAnimationElement { ~InterpolatedTransformTransition() override {} protected: + std::string DebugName() const override { + return "InterpolatedTransformTransition"; + } void OnStart(LayerAnimationDelegate* delegate) override {} bool OnProgress(double t, LayerAnimationDelegate* delegate) override { @@ -92,6 +97,7 @@ class BoundsTransition : public LayerAnimationElement { ~BoundsTransition() override {} protected: + std::string DebugName() const override { return "BoundsTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetBoundsForAnimation(); } @@ -127,6 +133,7 @@ class VisibilityTransition : public LayerAnimationElement { ~VisibilityTransition() override {} protected: + std::string DebugName() const override { return "VisibilityTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetVisibilityForAnimation(); } @@ -161,6 +168,7 @@ class BrightnessTransition : public LayerAnimationElement { ~BrightnessTransition() override {} protected: + std::string DebugName() const override { return "BrightnessTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetBrightnessForAnimation(); } @@ -196,6 +204,7 @@ class GrayscaleTransition : public LayerAnimationElement { ~GrayscaleTransition() override {} protected: + std::string DebugName() const override { return "GrayscaleTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetGrayscaleForAnimation(); } @@ -231,6 +240,7 @@ class ColorTransition : public LayerAnimationElement { ~ColorTransition() override {} protected: + std::string DebugName() const override { return "ColorTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetColorForAnimation(); } @@ -265,6 +275,7 @@ class TemperatureTransition : public LayerAnimationElement { ~TemperatureTransition() override {} protected: + std::string DebugName() const override { return "TemperatureTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetTemperatureFromAnimation(); } @@ -304,6 +315,9 @@ class ThreadedLayerAnimationElement : public LayerAnimationElement { explicit ThreadedLayerAnimationElement(const LayerAnimationElement& element) : LayerAnimationElement(element) { } + std::string DebugName() const override { + return "ThreadedLayerAnimationElement"; + } bool OnProgress(double t, LayerAnimationDelegate* delegate) override { if (t < 1.0) @@ -365,6 +379,7 @@ class ThreadedOpacityTransition : public ThreadedLayerAnimationElement { ~ThreadedOpacityTransition() override {} protected: + std::string DebugName() const override { return "ThreadedOpacityTransition"; } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetOpacityForAnimation(); } @@ -416,6 +431,9 @@ class ThreadedTransformTransition : public ThreadedLayerAnimationElement { ~ThreadedTransformTransition() override {} protected: + std::string DebugName() const override { + return "ThreadedTransformTransition"; + } void OnStart(LayerAnimationDelegate* delegate) override { start_ = delegate->GetTransformForAnimation(); } @@ -621,6 +639,21 @@ void LayerAnimationElement::RequestEffectiveStart( effective_start_time_ = requested_start_time_; } +std::string LayerAnimationElement::ToString() const { + // TODO(wkorman): Add support for subclasses to tack on more info + // beyond just their name. + return base::StringPrintf( + "LayerAnimationElement{name=%s, id=%d, group=%d, " + "last_progressed_fraction=%0.2f, " + "start_frame_number=%d}", + DebugName().c_str(), animation_id_, animation_group_id_, + last_progressed_fraction_, start_frame_number_); +} + +std::string LayerAnimationElement::DebugName() const { + return "Default"; +} + // static LayerAnimationElement::AnimatableProperty LayerAnimationElement::ToAnimatableProperty(cc::TargetProperty::Type property) { @@ -636,6 +669,57 @@ LayerAnimationElement::ToAnimatableProperty(cc::TargetProperty::Type property) { } // static +std::string LayerAnimationElement::AnimatablePropertiesToString( + AnimatableProperties properties) { + std::string str; + int property_count = 0; + for (unsigned i = FIRST_PROPERTY; i != SENTINEL; i = i << 1) { + if (i & properties) { + LayerAnimationElement::AnimatableProperty property = + static_cast<LayerAnimationElement::AnimatableProperty>(i); + if (property_count > 0) + str.append("|"); + // TODO(wkorman): Consider reworking enum definition to follow + // #define pattern that includes easier string output. + switch (property) { + case UNKNOWN: + str.append("UNKNOWN"); + break; + case TRANSFORM: + str.append("TRANSFORM"); + break; + case BOUNDS: + str.append("BOUNDS"); + break; + case OPACITY: + str.append("OPACITY"); + break; + case VISIBILITY: + str.append("VISIBILITY"); + break; + case BRIGHTNESS: + str.append("BRIGHTNESS"); + break; + case GRAYSCALE: + str.append("GRAYSCALE"); + break; + case COLOR: + str.append("COLOR"); + break; + case TEMPERATURE: + str.append("TEMPERATURE"); + break; + case SENTINEL: + NOTREACHED(); + break; + } + property_count++; + } + } + return str; +} + +// static base::TimeDelta LayerAnimationElement::GetEffectiveDuration( const base::TimeDelta& duration) { switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) { diff --git a/chromium/ui/compositor/layer_animation_element.h b/chromium/ui/compositor/layer_animation_element.h index d4f248dece5..9a11b97cc5e 100644 --- a/chromium/ui/compositor/layer_animation_element.h +++ b/chromium/ui/compositor/layer_animation_element.h @@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "cc/animation/animation.h" +#include "cc/trees/target_property.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/compositor/compositor_export.h" #include "ui/gfx/animation/tween.h" @@ -77,6 +78,9 @@ class COMPOSITOR_EXPORT LayerAnimationElement { virtual ~LayerAnimationElement(); + static std::string AnimatablePropertiesToString( + AnimatableProperties properties); + // Creates an element that transitions to the given transform. The caller owns // the return value. static std::unique_ptr<LayerAnimationElement> CreateTransformElement( @@ -213,7 +217,11 @@ class COMPOSITOR_EXPORT LayerAnimationElement { // call made to {Progress, ProgressToEnd}. double last_progressed_fraction() const { return last_progressed_fraction_; } + std::string ToString() const; + protected: + virtual std::string DebugName() const; + // Called once each time the animation element is run before any call to // OnProgress. virtual void OnStart(LayerAnimationDelegate* delegate) = 0; diff --git a/chromium/ui/compositor/layer_animation_element_unittest.cc b/chromium/ui/compositor/layer_animation_element_unittest.cc index 93714e505e8..6baad140ab6 100644 --- a/chromium/ui/compositor/layer_animation_element_unittest.cc +++ b/chromium/ui/compositor/layer_animation_element_unittest.cc @@ -400,6 +400,20 @@ TEST(LayerAnimationElementTest, AbortTransformElement) { delegate.GetTransformForAnimation()); } +TEST(LayerAnimationElementTest, ToString) { + float target = 1.0; + base::TimeDelta delta = base::TimeDelta::FromSeconds(1); + std::unique_ptr<LayerAnimationElement> element = + LayerAnimationElement::CreateOpacityElement(target, delta); + element->set_animation_group_id(42); + // TODO(wkorman): Test varying last_progressed_fraction and + // start_frame_number. + EXPECT_EQ( + "LayerAnimationElement{name=ThreadedOpacityTransition, id=1, group=42, " + "last_progressed_fraction=0.00, start_frame_number=0}", + element->ToString()); +} + } // namespace } // namespace ui diff --git a/chromium/ui/compositor/layer_animation_sequence.cc b/chromium/ui/compositor/layer_animation_sequence.cc index f13db19d1d1..a7a7b1c596e 100644 --- a/chromium/ui/compositor/layer_animation_sequence.cc +++ b/chromium/ui/compositor/layer_animation_sequence.cc @@ -7,6 +7,7 @@ #include <algorithm> #include <iterator> +#include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "cc/animation/animation_id_provider.h" #include "ui/compositor/layer_animation_delegate.h" @@ -290,4 +291,23 @@ LayerAnimationElement* LayerAnimationSequence::CurrentElement() const { return elements_[current_index].get(); } +std::string LayerAnimationSequence::ElementsToString() const { + std::string str; + for (size_t i = 0; i < elements_.size(); i++) { + if (i > 0) + str.append(", "); + str.append(elements_[i]->ToString()); + } + return str; +} + +std::string LayerAnimationSequence::ToString() const { + return base::StringPrintf( + "LayerAnimationSequence{size=%zu, properties=%s, " + "elements=[%s], is_cyclic=%d, group_id=%d}", + size(), + LayerAnimationElement::AnimatablePropertiesToString(properties_).c_str(), + ElementsToString().c_str(), is_cyclic_, animation_group_id_); +} + } // namespace ui diff --git a/chromium/ui/compositor/layer_animation_sequence.h b/chromium/ui/compositor/layer_animation_sequence.h index 379ff54a020..cee0500a7f0 100644 --- a/chromium/ui/compositor/layer_animation_sequence.h +++ b/chromium/ui/compositor/layer_animation_sequence.h @@ -138,6 +138,8 @@ class COMPOSITOR_EXPORT LayerAnimationSequence LayerAnimationElement* FirstElement() const; + std::string ToString() const; + private: friend class LayerAnimatorTestController; @@ -146,6 +148,8 @@ class COMPOSITOR_EXPORT LayerAnimationSequence FRIEND_TEST_ALL_PREFIXES(LayerAnimatorTest, ObserverReleasedBeforeAnimationSequenceEnds); + std::string ElementsToString() const; + // Notifies the observers that this sequence has been scheduled. void NotifyScheduled(); diff --git a/chromium/ui/compositor/layer_animation_sequence_unittest.cc b/chromium/ui/compositor/layer_animation_sequence_unittest.cc index 9222046fb28..3ce4001408c 100644 --- a/chromium/ui/compositor/layer_animation_sequence_unittest.cc +++ b/chromium/ui/compositor/layer_animation_sequence_unittest.cc @@ -7,6 +7,7 @@ #include <memory> #include "base/compiler_specific.h" +#include "base/strings/stringprintf.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/compositor/layer_animation_delegate.h" @@ -268,6 +269,46 @@ TEST(LayerAnimationSequenceTest, AddObserver) { } } +TEST(LayerAnimationSequenceTest, ToString) { + base::TimeDelta delta = base::TimeDelta::FromSeconds(1); + LayerAnimationSequence sequence; + EXPECT_EQ( + "LayerAnimationSequence{size=0, properties=, elements=[], is_cyclic=0, " + "group_id=0}", + sequence.ToString()); + + std::unique_ptr<LayerAnimationElement> brightness = + LayerAnimationElement::CreateBrightnessElement(1.0f, delta); + int brightness_id = brightness->animation_id(); + sequence.AddElement(std::move(brightness)); + EXPECT_EQ( + base::StringPrintf( + "LayerAnimationSequence{size=1, properties=BRIGHTNESS, " + "elements=[LayerAnimationElement{name=BrightnessTransition, id=%d, " + "group=0, last_progressed_fraction=0.00, start_frame_number=0}], " + "is_cyclic=0, group_id=0}", + brightness_id), + sequence.ToString()); + + std::unique_ptr<LayerAnimationElement> opacity = + LayerAnimationElement::CreateOpacityElement(1.0f, delta); + int opacity_id = opacity->animation_id(); + sequence.AddElement(std::move(opacity)); + sequence.set_is_cyclic(true); + sequence.set_animation_group_id(1973); + EXPECT_EQ( + base::StringPrintf( + "LayerAnimationSequence{size=2, properties=OPACITY|BRIGHTNESS, " + "elements=[LayerAnimationElement{name=BrightnessTransition, id=%d, " + "group=0, last_progressed_fraction=0.00, start_frame_number=0}, " + "LayerAnimationElement{name=ThreadedOpacityTransition, id=%d, " + "group=0, " + "last_progressed_fraction=0.00, start_frame_number=0}], is_cyclic=1, " + "group_id=1973}", + brightness_id, opacity_id), + sequence.ToString()); +} + } // namespace } // namespace ui diff --git a/chromium/ui/compositor/layer_animator.cc b/chromium/ui/compositor/layer_animator.cc index 09e5b17f16c..5902c14a039 100644 --- a/chromium/ui/compositor/layer_animator.cc +++ b/chromium/ui/compositor/layer_animator.cc @@ -15,7 +15,7 @@ #include "cc/animation/animation_player.h" #include "cc/animation/animation_timeline.h" #include "cc/animation/element_animations.h" -#include "cc/output/begin_frame_args.h" +#include "components/viz/common/frame_sinks/begin_frame_args.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_delegate.h" @@ -919,11 +919,12 @@ LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() { return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL; } -void LayerAnimator::NotifyAnimationStarted( - base::TimeTicks monotonic_time, - cc::TargetProperty::Type target_property, - int group) { - OnThreadedAnimationStarted(monotonic_time, target_property, group); +void LayerAnimator::NotifyAnimationStarted(base::TimeTicks monotonic_time, + int target_property, + int group) { + OnThreadedAnimationStarted( + monotonic_time, static_cast<cc::TargetProperty::Type>(target_property), + group); } LayerAnimator::RunningAnimation::RunningAnimation( diff --git a/chromium/ui/compositor/layer_animator.h b/chromium/ui/compositor/layer_animator.h index 19dc61dad58..a86864cb315 100644 --- a/chromium/ui/compositor/layer_animator.h +++ b/chromium/ui/compositor/layer_animator.h @@ -53,10 +53,9 @@ class ScopedLayerAnimationSettings; // ensure that it is not disposed of until it finishes executing. It does this // by holding a reference to itself for the duration of methods for which it // must guarantee that |this| is valid. -class COMPOSITOR_EXPORT LayerAnimator - : public base::RefCounted<LayerAnimator>, - public LayerThreadedAnimationDelegate, - NON_EXPORTED_BASE(public cc::AnimationDelegate) { +class COMPOSITOR_EXPORT LayerAnimator : public base::RefCounted<LayerAnimator>, + public LayerThreadedAnimationDelegate, + public cc::AnimationDelegate { public: enum PreemptionStrategy { IMMEDIATELY_SET_NEW_TARGET, @@ -345,18 +344,18 @@ class COMPOSITOR_EXPORT LayerAnimator // cc::AnimationDelegate implementation. void NotifyAnimationStarted(base::TimeTicks monotonic_time, - cc::TargetProperty::Type target_property, + int target_property, int group_id) override; void NotifyAnimationFinished(base::TimeTicks monotonic_time, - cc::TargetProperty::Type target_property, + int target_property, int group_id) override {} void NotifyAnimationAborted(base::TimeTicks monotonic_time, - cc::TargetProperty::Type target_property, + int target_property, int group_id) override {} void NotifyAnimationTakeover( base::TimeTicks monotonic_time, - cc::TargetProperty::Type target_property, - double animation_start_time, + int target_property, + base::TimeTicks animation_start_time, std::unique_ptr<cc::AnimationCurve> curve) override {} // Implementation of LayerThreadedAnimationDelegate. diff --git a/chromium/ui/compositor/layer_animator_unittest.cc b/chromium/ui/compositor/layer_animator_unittest.cc index 4b9575b4ba2..3e09d10b574 100644 --- a/chromium/ui/compositor/layer_animator_unittest.cc +++ b/chromium/ui/compositor/layer_animator_unittest.cc @@ -1694,6 +1694,178 @@ TEST(LayerAnimatorTest, ImplicitAnimationObservers) { EXPECT_FLOAT_EQ(0.0f, delegate.GetBrightnessForAnimation()); } +// Tests that caching render surface added to a scoped settings object is still +// reset when the object goes out of scope. +TEST(LayerAnimatorTest, CacheRenderSurface) { + ui::Layer layer; + scoped_refptr<LayerAnimator> animator(layer.GetAnimator()); + animator->set_disable_timer_for_test(true); + TestImplicitAnimationObserver observer(false); + + EXPECT_FALSE(observer.animations_completed()); + EXPECT_FALSE(layer.cc_layer_for_testing()->cache_render_surface()); + animator->SetOpacity(1.0f); + + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + settings.AddObserver(&observer); + animator->SetOpacity(0.0f); + } + + EXPECT_FALSE(observer.animations_completed()); + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + animator->StopAnimatingProperty(LayerAnimationElement::OPACITY); + EXPECT_TRUE(observer.animations_completed()); + EXPECT_TRUE(observer.WasAnimationCompletedForProperty( + LayerAnimationElement::OPACITY)); + EXPECT_FLOAT_EQ(0.0f, layer.opacity()); + EXPECT_FALSE(layer.cc_layer_for_testing()->cache_render_surface()); +} + +// Tests that caching render surface added to a scoped settings object will not +// crash when the layer was destroyed. +TEST(LayerAnimatorTest, CacheRenderSurfaceOnWillBeDestroyedLayer) { + // Case 1: layer is a pointer. + ui::Layer* layer1 = new Layer(); + scoped_refptr<LayerAnimator> animator(layer1->GetAnimator()); + animator->set_disable_timer_for_test(true); + TestImplicitAnimationObserver observer1(false); + + EXPECT_FALSE(observer1.animations_completed()); + animator->SetOpacity(1.0f); + + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + settings.AddObserver(&observer1); + animator->SetOpacity(0.0f); + } + + EXPECT_FALSE(observer1.animations_completed()); + delete layer1; + layer1 = nullptr; + animator->StopAnimatingProperty(LayerAnimationElement::OPACITY); + EXPECT_TRUE(observer1.animations_completed()); + + // Case 2: layer is a local variable. + TestImplicitAnimationObserver observer2(false); + { + ui::Layer layer2; + animator = layer2.GetAnimator(); + + EXPECT_FALSE(observer2.animations_completed()); + animator->SetBrightness(1.0f); + + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + settings.AddObserver(&observer2); + animator->SetBrightness(0.0f); + } + + EXPECT_FALSE(observer2.animations_completed()); + animator->StopAnimatingProperty(LayerAnimationElement::BRIGHTNESS); + EXPECT_TRUE(observer2.animations_completed()); + + // Case 3: Animation finishes before layer is destroyed. + ui::Layer layer3; + animator = layer3.GetAnimator(); + TestImplicitAnimationObserver observer3(false); + + EXPECT_FALSE(observer3.animations_completed()); + animator->SetGrayscale(1.0f); + + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + settings.AddObserver(&observer3); + animator->SetGrayscale(0.0f); + } + + EXPECT_FALSE(observer3.animations_completed()); + animator->StopAnimatingProperty(LayerAnimationElement::GRAYSCALE); + EXPECT_TRUE(observer3.animations_completed()); +} + +// Tests that caching render surface added to two scoped settings objects is +// still reset when animation finishes. +TEST(LayerAnimatorTest, CacheRenderSurfaceInTwoAnimations) { + ui::Layer layer; + scoped_refptr<LayerAnimator> animator(layer.GetAnimator()); + animator->set_disable_timer_for_test(true); + + // Case 1: the original cache status if false. + EXPECT_FALSE(layer.cc_layer_for_testing()->cache_render_surface()); + animator->SetBrightness(1.0f); + animator->SetOpacity(1.0f); + + // Start the brightness animation. + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + animator->SetBrightness(0.0f); + } + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + + // Start the opacity animation. + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + animator->SetOpacity(0.0f); + } + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + + // Finish the brightness animation. + { + animator->StopAnimatingProperty(LayerAnimationElement::BRIGHTNESS); + EXPECT_FLOAT_EQ(0.0f, layer.layer_brightness()); + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + } + + // Finish the opacity animation. + { + animator->StopAnimatingProperty(LayerAnimationElement::OPACITY); + EXPECT_FLOAT_EQ(0.0f, layer.opacity()); + EXPECT_FALSE(layer.cc_layer_for_testing()->cache_render_surface()); + } + + // Case 2: the original cache status if true. + layer.AddCacheRenderSurfaceRequest(); + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + animator->SetBrightness(1.0f); + animator->SetOpacity(1.0f); + + // Start the brightness animation. + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + animator->SetBrightness(0.0f); + } + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + + // Start the opacity animation. + { + ScopedLayerAnimationSettings settings(animator.get()); + settings.CacheRenderSurface(); + animator->SetOpacity(0.0f); + } + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + + // Finish the brightness animation. + { + animator->StopAnimatingProperty(LayerAnimationElement::BRIGHTNESS); + EXPECT_FLOAT_EQ(0.0f, layer.layer_brightness()); + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + } + + // Finish the opacity animation. + { + animator->StopAnimatingProperty(LayerAnimationElement::OPACITY); + EXPECT_FLOAT_EQ(0.0f, layer.opacity()); + EXPECT_TRUE(layer.cc_layer_for_testing()->cache_render_surface()); + } +} + // Tests that an observer added to a scoped settings object is still notified // when the object goes out of scope due to the animation being interrupted. TEST(LayerAnimatorTest, InterruptedImplicitAnimationObservers) { diff --git a/chromium/ui/compositor/layer_observer.h b/chromium/ui/compositor/layer_observer.h index fa3480bdabf..5e59deb5dab 100644 --- a/chromium/ui/compositor/layer_observer.h +++ b/chromium/ui/compositor/layer_observer.h @@ -11,8 +11,6 @@ namespace ui { class Layer; -// TODO(domlaskowski): This is only used for layer mirroring, so it should be -// removed and replaced by a private equivalent in the Layer class. class COMPOSITOR_EXPORT LayerObserver { public: virtual void LayerDestroyed(Layer* layer) {} diff --git a/chromium/ui/compositor/layer_owner_unittest.cc b/chromium/ui/compositor/layer_owner_unittest.cc index 94992e09755..3c1a65d666c 100644 --- a/chromium/ui/compositor/layer_owner_unittest.cc +++ b/chromium/ui/compositor/layer_owner_unittest.cc @@ -81,7 +81,8 @@ void LayerOwnerTestWithCompositor::SetUp() { compositor_.reset( new ui::Compositor(context_factory_private->AllocateFrameSinkId(), context_factory, context_factory_private, task_runner, - false /* enable_surface_synchronization */)); + false /* enable_surface_synchronization */, + false /* enable_pixel_canvas */)); compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); } diff --git a/chromium/ui/compositor/layer_unittest.cc b/chromium/ui/compositor/layer_unittest.cc index fbb15a8e4eb..dcb2cf9ee7d 100644 --- a/chromium/ui/compositor/layer_unittest.cc +++ b/chromium/ui/compositor/layer_unittest.cc @@ -18,15 +18,16 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" +#include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" #include "cc/animation/animation_player.h" #include "cc/layers/layer.h" -#include "cc/output/copy_output_request.h" -#include "cc/output/copy_output_result.h" #include "cc/test/pixel_test_utils.h" +#include "components/viz/common/quads/copy_output_request.h" +#include "components/viz/common/quads/copy_output_result.h" #include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_reference_factory.h" @@ -197,8 +198,8 @@ class LayerWithRealCompositorTest : public testing::Test { void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) { scoped_refptr<ReadbackHolder> holder(new ReadbackHolder); - std::unique_ptr<cc::CopyOutputRequest> request = - cc::CopyOutputRequest::CreateBitmapRequest( + std::unique_ptr<viz::CopyOutputRequest> request = + viz::CopyOutputRequest::CreateBitmapRequest( base::BindOnce(&ReadbackHolder::OutputRequestCallback, holder)); request->set_area(source_rect); @@ -245,7 +246,7 @@ class LayerWithRealCompositorTest : public testing::Test { public: ReadbackHolder() : run_loop_(new base::RunLoop) {} - void OutputRequestCallback(std::unique_ptr<cc::CopyOutputResult> result) { + void OutputRequestCallback(std::unique_ptr<viz::CopyOutputResult> result) { result_ = result->TakeBitmap(); run_loop_->Quit(); } @@ -550,7 +551,7 @@ TEST(LayerStandaloneTest, ReleaseMailboxOnDestruction) { bool callback_run = false; viz::TextureMailbox mailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), 0); layer->SetTextureMailbox(mailbox, - cc::SingleReleaseCallback::Create( + viz::SingleReleaseCallback::Create( base::Bind(ReturnMailbox, &callback_run)), gfx::Size(10, 10)); EXPECT_FALSE(callback_run); @@ -735,7 +736,7 @@ TEST_F(LayerWithDelegateTest, Cloning) { layer->SetLayerInverted(true); const float temperature = 0.8f; layer->SetLayerTemperature(temperature); - layer->SetCacheRenderSurface(true); + layer->AddCacheRenderSurfaceRequest(); auto clone = layer->Clone(); @@ -944,8 +945,9 @@ TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { bool callback1_run = false; viz::TextureMailbox mailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), 0); - l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create( - base::Bind(ReturnMailbox, &callback1_run)), + l1->SetTextureMailbox(mailbox, + viz::SingleReleaseCallback::Create( + base::Bind(ReturnMailbox, &callback1_run)), gfx::Size(10, 10)); EXPECT_NE(before_layer, l1->cc_layer_for_testing()); @@ -959,8 +961,9 @@ TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { bool callback2_run = false; mailbox = viz::TextureMailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), 0); - l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create( - base::Bind(ReturnMailbox, &callback2_run)), + l1->SetTextureMailbox(mailbox, + viz::SingleReleaseCallback::Create( + base::Bind(ReturnMailbox, &callback2_run)), gfx::Size(10, 10)); EXPECT_TRUE(callback1_run); EXPECT_FALSE(callback2_run); @@ -979,8 +982,9 @@ TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { // Back to a texture, without changing the bounds of the layer or the texture. bool callback3_run = false; mailbox = viz::TextureMailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), 0); - l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create( - base::Bind(ReturnMailbox, &callback3_run)), + l1->SetTextureMailbox(mailbox, + viz::SingleReleaseCallback::Create( + base::Bind(ReturnMailbox, &callback3_run)), gfx::Size(10, 10)); EXPECT_NE(before_layer, l1->cc_layer_for_testing()); @@ -1126,7 +1130,7 @@ TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) { // Checks that the damage rect for a TextureLayer is empty after a commit. TEST_F(LayerWithNullDelegateTest, EmptyDamagedRect) { base::RunLoop run_loop; - cc::ReleaseCallback callback = + viz::ReleaseCallback callback = base::Bind([](base::RunLoop* run_loop, const gpu::SyncToken& sync_token, bool is_lost) { run_loop->Quit(); }, base::Unretained(&run_loop)); @@ -1134,7 +1138,7 @@ TEST_F(LayerWithNullDelegateTest, EmptyDamagedRect) { std::unique_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR)); viz::TextureMailbox mailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D); - root->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(callback), + root->SetTextureMailbox(mailbox, viz::SingleReleaseCallback::Create(callback), gfx::Size(10, 10)); compositor()->SetRootLayer(root.get()); @@ -1261,9 +1265,9 @@ TEST_F(LayerWithRealCompositorTest, DrawAlphaThresholdFilterPixels) { CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size))); // Add a shape to restrict the visible part of the layer. - SkRegion shape; - shape.setRect(0, 0, viewport_size.width(), blue_height); - foreground_layer->SetAlphaShape(base::WrapUnique(new SkRegion(shape))); + auto shape = base::MakeUnique<Layer::ShapeRects>(); + shape->emplace_back(0, 0, viewport_size.width(), blue_height); + foreground_layer->SetAlphaShape(std::move(shape)); foreground_layer->SetFillsBoundsOpaquely(false); @@ -2006,7 +2010,7 @@ TEST_F(LayerWithRealCompositorTest, SwitchCCLayerCacheRenderSurface) { GetCompositor()->SetRootLayer(root.get()); root->Add(l1.get()); - l1->SetCacheRenderSurface(true); + l1->AddCacheRenderSurfaceRequest(); // Change l1's cc::Layer. l1->SwitchCCLayerForTest(); diff --git a/chromium/ui/compositor/paint_cache.cc b/chromium/ui/compositor/paint_cache.cc index 417a1798083..71b2a0e5ed3 100644 --- a/chromium/ui/compositor/paint_cache.cc +++ b/chromium/ui/compositor/paint_cache.cc @@ -10,30 +10,23 @@ namespace ui { -PaintCache::PaintCache() {} - -PaintCache::~PaintCache() { -} +PaintCache::PaintCache() = default; +PaintCache::~PaintCache() = default; bool PaintCache::UseCache(const PaintContext& context, const gfx::Size& size_in_context) { if (!paint_op_buffer_) return false; DCHECK(context.list_); - cc::PaintOpBuffer* buffer = context.list_->StartPaint(); - buffer->push<cc::DrawRecordOp>(paint_op_buffer_); + context.list_->StartPaint(); + context.list_->push<cc::DrawRecordOp>(paint_op_buffer_); gfx::Rect bounds_in_layer = context.ToLayerSpaceBounds(size_in_context); context.list_->EndPaintOfUnpaired(bounds_in_layer); return true; } -cc::PaintOpBuffer* PaintCache::ResetCache() { - paint_op_buffer_ = sk_make_sp<cc::PaintOpBuffer>(); - return paint_op_buffer_.get(); -} - -void PaintCache::FinalizeCache() { - paint_op_buffer_->ShrinkToFit(); +void PaintCache::SetPaintOpBuffer(sk_sp<cc::PaintOpBuffer> paint_op_buffer) { + paint_op_buffer_ = std::move(paint_op_buffer); } } // namespace ui diff --git a/chromium/ui/compositor/paint_cache.h b/chromium/ui/compositor/paint_cache.h index c32e96e54dd..04ae875a64e 100644 --- a/chromium/ui/compositor/paint_cache.h +++ b/chromium/ui/compositor/paint_cache.h @@ -36,12 +36,7 @@ class COMPOSITOR_EXPORT PaintCache { // Only PaintRecorder can modify these. friend PaintRecorder; - // Resets the cache to be empty, and returns a PaintOpBuffer that is the new - // empty cache. Adding PaintOps to the buffer will put them in the cache. - cc::PaintOpBuffer* ResetCache(); - - // Call when done recording into the cache's PaintOpBuffer. - void FinalizeCache(); + void SetPaintOpBuffer(sk_sp<cc::PaintOpBuffer> paint_op_buffer); // Stored in an sk_sp because PaintOpBuffer requires this to append the cached // items into it. diff --git a/chromium/ui/compositor/paint_context.cc b/chromium/ui/compositor/paint_context.cc index b2b4fac54b3..48e2e9d8f68 100644 --- a/chromium/ui/compositor/paint_context.cc +++ b/chromium/ui/compositor/paint_context.cc @@ -10,10 +10,14 @@ namespace ui { PaintContext::PaintContext(cc::DisplayItemList* list, float device_scale_factor, - const gfx::Rect& invalidation) + const gfx::Rect& invalidation, + bool is_pixel_canvas) : list_(list), device_scale_factor_(device_scale_factor), - invalidation_(invalidation) { + invalidation_(gfx::ScaleToRoundedRect( + invalidation, + is_pixel_canvas ? device_scale_factor_ : 1.f)), + is_pixel_canvas_(is_pixel_canvas) { #if DCHECK_IS_ON() root_visited_ = nullptr; inside_paint_recorder_ = false; @@ -25,7 +29,8 @@ PaintContext::PaintContext(const PaintContext& other, : list_(other.list_), device_scale_factor_(other.device_scale_factor_), invalidation_(other.invalidation_), - offset_(other.offset_ + offset) { + offset_(other.offset_ + offset), + is_pixel_canvas_(other.is_pixel_canvas_) { #if DCHECK_IS_ON() root_visited_ = other.root_visited_; inside_paint_recorder_ = other.inside_paint_recorder_; @@ -37,7 +42,8 @@ PaintContext::PaintContext(const PaintContext& other, : list_(other.list_), device_scale_factor_(other.device_scale_factor_), invalidation_(), - offset_(other.offset_) { + offset_(other.offset_), + is_pixel_canvas_(other.is_pixel_canvas_) { #if DCHECK_IS_ON() root_visited_ = other.root_visited_; inside_paint_recorder_ = other.inside_paint_recorder_; diff --git a/chromium/ui/compositor/paint_context.h b/chromium/ui/compositor/paint_context.h index bc17c50f46b..96385275c43 100644 --- a/chromium/ui/compositor/paint_context.h +++ b/chromium/ui/compositor/paint_context.h @@ -29,7 +29,8 @@ class COMPOSITOR_EXPORT PaintContext { // |invalidation|. PaintContext(cc::DisplayItemList* list, float device_scale_factor, - const gfx::Rect& invalidation); + const gfx::Rect& invalidation, + bool is_pixel_canvas); // Clone a PaintContext with an additional |offset|. PaintContext(const PaintContext& other, const gfx::Vector2d& offset); @@ -46,6 +47,13 @@ class COMPOSITOR_EXPORT PaintContext { // invalid. bool CanCheckInvalid() const { return !invalidation_.IsEmpty(); } + // The device scale of the frame being painted. + float device_scale_factor() const { return device_scale_factor_; } + + // Returns true if the paint commands are recorded at pixel size instead of + // DIP. + bool is_pixel_canvas() const { return is_pixel_canvas_; } + // When true, the |bounds| touches an invalidated area, so should be // re-painted. When false, re-painting can be skipped. Bounds should be in // the local space with offsets up to the painting root in the PaintContext. @@ -94,6 +102,8 @@ class COMPOSITOR_EXPORT PaintContext { // Offset from the PaintContext to the space of the paint root and the // |invalidation_|. gfx::Vector2d offset_; + // If enabled, the paint commands are recorded at pixel size. + const bool is_pixel_canvas_; #if DCHECK_IS_ON() // Used to verify that the |invalidation_| is only used to compare against diff --git a/chromium/ui/compositor/paint_recorder.cc b/chromium/ui/compositor/paint_recorder.cc index 8a8c4c28caf..f85d3cbdc76 100644 --- a/chromium/ui/compositor/paint_recorder.cc +++ b/chromium/ui/compositor/paint_recorder.cc @@ -21,32 +21,60 @@ namespace ui { // to the |context|'s PaintOpBuffer. PaintRecorder::PaintRecorder(const PaintContext& context, const gfx::Size& recording_size, + float recording_scale_x, + float recording_scale_y, PaintCache* cache) : context_(context), - record_canvas_(cache ? cache->ResetCache() : context_.list_->StartPaint(), + local_list_(cache ? base::MakeRefCounted<cc::DisplayItemList>( + cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + : nullptr), + record_canvas_(cache ? local_list_.get() : context_.list_, gfx::RectToSkRect(gfx::Rect(recording_size))), canvas_(&record_canvas_, context.device_scale_factor_), cache_(cache), recording_size_(recording_size) { + if (cache) { + local_list_->StartPaint(); + } else { + context_.list_->StartPaint(); + } + #if DCHECK_IS_ON() - DCHECK(!context.inside_paint_recorder_); - context.inside_paint_recorder_ = true; + DCHECK(!context_.inside_paint_recorder_); + context_.inside_paint_recorder_ = true; #endif + if (context_.is_pixel_canvas()) { + canvas()->Save(); + canvas()->Scale(recording_scale_x, recording_scale_y); + } } +// TODO(malaykeshav): The scaling of recording size needs to be handled case +// by case and the decision to perform the scale should be moved to the caller. PaintRecorder::PaintRecorder(const PaintContext& context, const gfx::Size& recording_size) - : PaintRecorder(context, recording_size, nullptr) {} + : PaintRecorder( + context, + gfx::ScaleToRoundedSize( + recording_size, + context.is_pixel_canvas() ? context.device_scale_factor_ : 1.f), + context.device_scale_factor_, + context.device_scale_factor_, + nullptr) {} PaintRecorder::~PaintRecorder() { #if DCHECK_IS_ON() context_.inside_paint_recorder_ = false; #endif + if (context_.is_pixel_canvas()) + canvas()->Restore(); // If using cache, append what we've saved there to the PaintContext. // Otherwise, the content is already stored in the PaintContext, and we can // just close it. if (cache_) { - cache_->FinalizeCache(); + local_list_->EndPaintOfUnpaired(gfx::Rect()); + local_list_->Finalize(); + cache_->SetPaintOpBuffer(local_list_->ReleaseAsRecord()); cache_->UseCache(context_, recording_size_); } else { gfx::Rect bounds_in_layer = context_.ToLayerSpaceBounds(recording_size_); diff --git a/chromium/ui/compositor/paint_recorder.h b/chromium/ui/compositor/paint_recorder.h index 3785c1bbc23..609d6f0bf42 100644 --- a/chromium/ui/compositor/paint_recorder.h +++ b/chromium/ui/compositor/paint_recorder.h @@ -8,6 +8,7 @@ #include <memory> #include "base/macros.h" +#include "cc/paint/display_item_list.h" #include "cc/paint/record_paint_canvas.h" #include "ui/compositor/compositor_export.h" #include "ui/gfx/canvas.h" @@ -31,6 +32,8 @@ class COMPOSITOR_EXPORT PaintRecorder { // PaintRecorder is in use. Canvas is bounded by |recording_size|. PaintRecorder(const PaintContext& context, const gfx::Size& recording_size, + float recording_scale_x, + float recording_scale_y, PaintCache* cache); PaintRecorder(const PaintContext& context, const gfx::Size& recording_size); ~PaintRecorder(); @@ -40,6 +43,7 @@ class COMPOSITOR_EXPORT PaintRecorder { private: const PaintContext& context_; + scoped_refptr<cc::DisplayItemList> local_list_; cc::RecordPaintCanvas record_canvas_; gfx::Canvas canvas_; PaintCache* cache_; diff --git a/chromium/ui/compositor/scoped_layer_animation_settings.cc b/chromium/ui/compositor/scoped_layer_animation_settings.cc index 71db455afb0..2ffc1250b13 100644 --- a/chromium/ui/compositor/scoped_layer_animation_settings.cc +++ b/chromium/ui/compositor/scoped_layer_animation_settings.cc @@ -10,11 +10,49 @@ #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/layer_animator.h" +#include "ui/compositor/layer_observer.h" namespace { const int kDefaultTransitionDurationMs = 200; +class CacheRenderSurfaceObserver : public ui::ImplicitAnimationObserver, + public ui::LayerObserver { + public: + CacheRenderSurfaceObserver(ui::Layer* layer) : layer_(layer) { + layer_->AddObserver(this); + layer_->AddCacheRenderSurfaceRequest(); + } + ~CacheRenderSurfaceObserver() override { + if (layer_) + layer_->RemoveObserver(this); + } + + // ui::ImplicitAnimationObserver overrides: + void OnImplicitAnimationsCompleted() override { + // If animation finishes before |layer_| is destoyed, we will reset the + // cache and remove |this| from the |layer_| observer list when deleting + // |this|. + if (layer_) + layer_->RemoveCacheRenderSurfaceRequest(); + delete this; + } + + // ui::LayerObserver overrides: + void LayerDestroyed(ui::Layer* layer) override { + // If the animation is still going past layer destruction then we want the + // layer too keep being cached until the animation has finished. We will + // defer deleting |this| until the animation finishes. + layer_->RemoveObserver(this); + layer_ = nullptr; + } + + private: + ui::Layer* layer_; + + DISALLOW_COPY_AND_ASSIGN(CacheRenderSurfaceObserver); +}; + } // namespace namespace ui { @@ -63,6 +101,11 @@ void ScopedLayerAnimationSettings::SetTransitionDuration( animator_->SetTransitionDuration(duration); } +void ScopedLayerAnimationSettings::CacheRenderSurface() { + AddObserver( + new CacheRenderSurfaceObserver(animator_->delegate()->GetLayer())); +} + void ScopedLayerAnimationSettings::LockTransitionDuration() { animator_->is_transition_duration_locked_ = true; } diff --git a/chromium/ui/compositor/scoped_layer_animation_settings.h b/chromium/ui/compositor/scoped_layer_animation_settings.h index ddc6d68499b..61867126bca 100644 --- a/chromium/ui/compositor/scoped_layer_animation_settings.h +++ b/chromium/ui/compositor/scoped_layer_animation_settings.h @@ -31,6 +31,9 @@ class COMPOSITOR_EXPORT ScopedLayerAnimationSettings { void SetAnimationMetricsReporter(AnimationMetricsReporter* reporter); void SetTransitionDuration(base::TimeDelta duration); + // This will request render surface caching on the animating layer. The cache + // request will be removed at the end of the animation. + void CacheRenderSurface(); base::TimeDelta GetTransitionDuration() const; // Locks transition duration in |animator_|. When transition duration diff --git a/chromium/ui/compositor/test/test_compositor_host_ozone.cc b/chromium/ui/compositor/test/test_compositor_host_ozone.cc index 97d33afa448..1659d9331d9 100644 --- a/chromium/ui/compositor/test/test_compositor_host_ozone.cc +++ b/chromium/ui/compositor/test/test_compositor_host_ozone.cc @@ -84,7 +84,8 @@ TestCompositorHostOzone::TestCompositorHostOzone( context_factory, context_factory_private, base::ThreadTaskRunnerHandle::Get(), - false /* enable_surface_synchronization */) {} + false /* enable_surface_synchronization */, + false /* enable_pixel_canvas */) {} TestCompositorHostOzone::~TestCompositorHostOzone() {} diff --git a/chromium/ui/compositor/transform_animation_curve_adapter_unittest.cc b/chromium/ui/compositor/transform_animation_curve_adapter_unittest.cc index b5b44e90270..7c80133bb28 100644 --- a/chromium/ui/compositor/transform_animation_curve_adapter_unittest.cc +++ b/chromium/ui/compositor/transform_animation_curve_adapter_unittest.cc @@ -7,7 +7,6 @@ #include <sstream> #include "base/time/time.h" -#include "cc/base/time_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/compositor/test/test_utils.h" @@ -39,7 +38,7 @@ TEST(InverseTransformCurveAdapterTest, InversesTransform) { static const int kSteps = 1000; double step = 1.0 / kSteps; for (int i = 0; i <= kSteps; ++i) { - base::TimeDelta time_step = cc::TimeUtil::Scale(duration, i * step); + base::TimeDelta time_step = duration * (i * step); std::ostringstream message; message << "Step " << i << " of " << kSteps; SCOPED_TRACE(message.str()); diff --git a/chromium/ui/compositor/transform_recorder.cc b/chromium/ui/compositor/transform_recorder.cc index 525de51cc98..4175f1e4fbc 100644 --- a/chromium/ui/compositor/transform_recorder.cc +++ b/chromium/ui/compositor/transform_recorder.cc @@ -17,8 +17,8 @@ TransformRecorder::~TransformRecorder() { if (!transformed_) return; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::RestoreOp>(); + context_.list_->StartPaint(); + context_.list_->push<cc::RestoreOp>(); context_.list_->EndPaintOfPairedEnd(); } @@ -27,9 +27,9 @@ void TransformRecorder::Transform(const gfx::Transform& transform) { if (transform.IsIdentity()) return; - cc::PaintOpBuffer* buffer = context_.list_->StartPaint(); - buffer->push<cc::SaveOp>(); - buffer->push<cc::ConcatOp>(static_cast<SkMatrix>(transform.matrix())); + context_.list_->StartPaint(); + context_.list_->push<cc::SaveOp>(); + context_.list_->push<cc::ConcatOp>(static_cast<SkMatrix>(transform.matrix())); context_.list_->EndPaintOfPairedBegin(); transformed_ = true; |