diff options
Diffstat (limited to 'chromium/cc/layers')
27 files changed, 243 insertions, 471 deletions
diff --git a/chromium/cc/layers/deadline_policy.h b/chromium/cc/layers/deadline_policy.h index 6c3b0063046..6a461e3c235 100644 --- a/chromium/cc/layers/deadline_policy.h +++ b/chromium/cc/layers/deadline_policy.h @@ -7,7 +7,7 @@ #include <cstdint> -#include "base/logging.h" +#include "base/check.h" #include "base/optional.h" #include "cc/cc_export.h" diff --git a/chromium/cc/layers/draw_properties.h b/chromium/cc/layers/draw_properties.h index b241728724c..d5a0a7d84a4 100644 --- a/chromium/cc/layers/draw_properties.h +++ b/chromium/cc/layers/draw_properties.h @@ -53,9 +53,9 @@ struct CC_EXPORT DrawProperties { // the layer's coordinate space. gfx::Rect visible_layer_rect; - // In target surface space, the rect that encloses the clipped, drawable - // content of the layer. - gfx::Rect drawable_content_rect; + // In target surface space, the rect that encloses the clipped, visible, + // and drawable content of the layer. + gfx::Rect visible_drawable_content_rect; // In target surface space, the original rect that clipped this layer. This // value is used to avoid unnecessarily changing GL scissor state. diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc index 6851763975f..b539a5da7c7 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl.cc @@ -10,6 +10,7 @@ #include <algorithm> #include <vector> +#include "base/logging.h" #include "base/memory/shared_memory_mapping.h" #include "base/numerics/safe_conversions.h" #include "base/optional.h" @@ -19,6 +20,7 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" #include "cc/debug/debug_colors.h" +#include "cc/metrics/dropped_frame_counter.h" #include "cc/paint/display_item_list.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" @@ -27,7 +29,6 @@ #include "cc/paint/skia_paint_canvas.h" #include "cc/raster/scoped_gpu_raster.h" #include "cc/resources/memory_history.h" -#include "cc/trees/frame_rate_counter.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" @@ -88,27 +89,9 @@ class DummyImageProvider : public ImageProvider { } // namespace -HeadsUpDisplayLayerImpl::Graph::Graph(double indicator_value, - double start_upper_bound) - : value(0.0), - min(0.0), - max(0.0), - current_upper_bound(start_upper_bound), - default_upper_bound(start_upper_bound), - indicator(indicator_value) {} - -double HeadsUpDisplayLayerImpl::Graph::UpdateUpperBound() { - double target_upper_bound = std::max(max, default_upper_bound); - current_upper_bound += (target_upper_bound - current_upper_bound) * 0.5; - return current_upper_bound; -} - HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl, int id) - : LayerImpl(tree_impl, id), - internal_contents_scale_(1.f), - fps_graph_(60.0, 80.0), - paint_time_graph_(16.0, 48.0) {} + : LayerImpl(tree_impl, id) {} HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() { ReleaseResources(); @@ -550,18 +533,8 @@ void HeadsUpDisplayLayerImpl::UpdateHudContents() { time_of_last_graph_update_ = now; if (debug_state.show_fps_counter) { - FrameRateCounter* fps_counter = layer_tree_impl()->frame_rate_counter(); - fps_graph_.value = fps_counter->GetAverageFPS(); - fps_counter->GetMinAndMaxFPS(&fps_graph_.min, &fps_graph_.max); - current_throughput_ = layer_tree_impl()->current_universal_throughput(); - if (current_throughput_.has_value()) { - if (!max_throughput.has_value() || - current_throughput_.value() > max_throughput.value()) - max_throughput = current_throughput_; - if (!min_throughput.has_value() || - current_throughput_.value() < min_throughput.value()) - min_throughput = current_throughput_; - } + throughput_value_ = + layer_tree_impl()->dropped_frame_counter()->GetAverageThroughput(); } if (debug_state.ShowMemoryStats()) { @@ -572,9 +545,6 @@ void HeadsUpDisplayLayerImpl::UpdateHudContents() { memory_entry_ = MemoryHistory::Entry(); } } - - fps_graph_.UpdateUpperBound(); - paint_time_graph_.UpdateUpperBound(); } void HeadsUpDisplayLayerImpl::DrawHudContents(PaintCanvas* canvas) { @@ -597,8 +567,8 @@ void HeadsUpDisplayLayerImpl::DrawHudContents(PaintCanvas* canvas) { return; } - SkRect area = - DrawFPSDisplay(canvas, layer_tree_impl()->frame_rate_counter(), 0, 0); + SkRect area = DrawFrameThroughputDisplay( + canvas, layer_tree_impl()->dropped_frame_counter(), 0, 0); area = DrawGpuRasterizationStatus(canvas, 0, area.bottom(), std::max<SkScalar>(area.width(), 150)); @@ -652,30 +622,18 @@ void HeadsUpDisplayLayerImpl::DrawGraphBackground(PaintCanvas* canvas, void HeadsUpDisplayLayerImpl::DrawGraphLines(PaintCanvas* canvas, PaintFlags* flags, - const SkRect& bounds, - const Graph& graph) const { + const SkRect& bounds) const { // Draw top and bottom line. flags->setColor(DebugColors::HUDSeparatorLineColor()); canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top() - 1, *flags); canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), bounds.bottom(), *flags); - - // Draw indicator line (additive blend mode to increase contrast when drawn on - // top of graph). - flags->setColor(DebugColors::HUDIndicatorLineColor()); - flags->setBlendMode(SkBlendMode::kPlus); - const double indicator_top = - bounds.height() * (1.0 - graph.indicator / graph.current_upper_bound) - - 1.0; - canvas->drawLine(bounds.left(), bounds.top() + indicator_top, bounds.right(), - bounds.top() + indicator_top, *flags); - flags->setBlendMode(SkBlendMode::kSrcOver); } -SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay( +SkRect HeadsUpDisplayLayerImpl::DrawFrameThroughputDisplay( PaintCanvas* canvas, - const FrameRateCounter* fps_counter, + const DroppedFrameCounter* dropped_frame_counter, int right, int top) const { const int kPadding = 4; @@ -685,39 +643,35 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay( const int kFontHeight = 12; const int kGraphWidth = - base::saturated_cast<int>(fps_counter->time_stamp_history_size()) - 2; + base::saturated_cast<int>(dropped_frame_counter->frame_history_size()); const int kGraphHeight = 40; - const int kHistogramWidth = 37; - - int width = kGraphWidth + kHistogramWidth + 4 * kPadding; - int height = - 2 * kTitleFontHeight + 2 * kFontHeight + kGraphHeight + 10 * kPadding + 2; + int width = kGraphWidth + 4 * kPadding; + int height = kTitleFontHeight + kFontHeight + kGraphHeight + 6 * kPadding + 2; int left = 0; SkRect area = SkRect::MakeXYWH(left, top, width, height); PaintFlags flags; DrawGraphBackground(canvas, &flags, area); - SkRect title_bounds = SkRect::MakeXYWH( - left + kPadding, top + kPadding, kGraphWidth + kHistogramWidth + kGap + 2, - kTitleFontHeight); + SkRect title_bounds = + SkRect::MakeXYWH(left + kPadding, top + kPadding, kGraphWidth + kGap + 2, + kTitleFontHeight); SkRect text_bounds = SkRect::MakeXYWH(left + kPadding, title_bounds.bottom() + 2 * kPadding, - kGraphWidth + kHistogramWidth + kGap + 2, kFontHeight); + kGraphWidth + kGap + 2, kFontHeight); SkRect graph_bounds = SkRect::MakeXYWH(left + kPadding, text_bounds.bottom() + 2 * kPadding, kGraphWidth, kGraphHeight); - SkRect histogram_bounds = - SkRect::MakeXYWH(graph_bounds.right() + kGap, graph_bounds.top(), - kHistogramWidth, kGraphHeight); // Draw the fps meter. - const std::string title("Frame Rate"); - const std::string value_text = - base::StringPrintf("%5.1f fps", fps_graph_.value); - const std::string min_max_text = - base::StringPrintf("%.0f-%.0f", fps_graph_.min, fps_graph_.max); + const std::string title("Frames"); + const std::string value_text = base::StringPrintf("%d %%", throughput_value_); + const std::string dropped_frames_text = + base::StringPrintf("%zu (%zu m) dropped of %zu", + dropped_frame_counter->total_compositor_dropped(), + dropped_frame_counter->total_main_dropped(), + dropped_frame_counter->total_frames()); VLOG(1) << value_text; @@ -728,105 +682,40 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay( flags.setColor(DebugColors::FPSDisplayTextAndGraphColor()); DrawText(canvas, flags, value_text, TextAlign::kLeft, kFontHeight, text_bounds.left(), text_bounds.bottom()); - DrawText(canvas, flags, min_max_text, TextAlign::kRight, kFontHeight, + DrawText(canvas, flags, dropped_frames_text, TextAlign::kRight, kFontHeight, text_bounds.right(), text_bounds.bottom()); - DrawGraphLines(canvas, &flags, graph_bounds, fps_graph_); - - // Draw the throughput meter. - int current_top = histogram_bounds.bottom() + kPadding; - const std::string throughput_title("Throughput"); - const std::string throughput_value_text = - current_throughput_.has_value() - ? base::StringPrintf("%d %%", current_throughput_.value()) - : base::StringPrintf("n/a"); - - VLOG(1) << throughput_value_text; - - flags.setColor(DebugColors::HUDTitleColor()); - DrawText(canvas, flags, throughput_title, TextAlign::kLeft, kTitleFontHeight, - title_bounds.left(), title_bounds.bottom() + current_top); - - flags.setColor(DebugColors::FPSDisplayTextAndGraphColor()); - DrawText(canvas, flags, throughput_value_text, TextAlign::kLeft, kFontHeight, - text_bounds.left(), text_bounds.bottom() + current_top); - if (min_throughput.has_value()) { - const std::string throughput_min_max_text = base::StringPrintf( - "%d-%d", min_throughput.value(), max_throughput.value()); - DrawText(canvas, flags, throughput_min_max_text, TextAlign::kRight, - kFontHeight, text_bounds.right(), - text_bounds.bottom() + current_top); - } - - // Collect fps graph and histogram data. - SkPath path; - - const int kHistogramSize = 20; - double histogram[kHistogramSize] = {1.0}; - double max_bucket_value = 1.0; - - for (FrameRateCounter::RingBufferType::Iterator it = --fps_counter->end(); it; - --it) { - base::TimeDelta delta = fps_counter->RecentFrameInterval(it.index() + 1); - - // Skip this particular instantaneous frame rate if it is not likely to have - // been valid. - if (!fps_counter->IsBadFrameInterval(delta)) { - double fps = 1.0 / delta.InSecondsF(); - - // Clamp the FPS to the range we want to plot visually. - double p = fps / fps_graph_.current_upper_bound; - if (p > 1.0) - p = 1.0; - - // Plot this data point. - SkPoint cur = - SkPoint::Make(graph_bounds.left() + it.index(), - graph_bounds.bottom() - p * graph_bounds.height()); - if (path.isEmpty()) - path.moveTo(cur); - else - path.lineTo(cur); - - // Use the fps value to find the right bucket in the histogram. - int bucket_index = floor(p * (kHistogramSize - 1)); - - // Add the delta time to take the time spent at that fps rate into - // account. - histogram[bucket_index] += delta.InSecondsF(); - max_bucket_value = std::max(histogram[bucket_index], max_bucket_value); - } - } - - // Draw FPS histogram. - flags.setColor(DebugColors::HUDSeparatorLineColor()); - canvas->drawLine(histogram_bounds.left() - 1, histogram_bounds.top() - 1, - histogram_bounds.left() - 1, histogram_bounds.bottom() + 1, - flags); - canvas->drawLine(histogram_bounds.right() + 1, histogram_bounds.top() - 1, - histogram_bounds.right() + 1, histogram_bounds.bottom() + 1, - flags); - - flags.setColor(DebugColors::FPSDisplayTextAndGraphColor()); - const double bar_height = histogram_bounds.height() / kHistogramSize; - - for (int i = kHistogramSize - 1; i >= 0; --i) { - if (histogram[i] > 0) { - double bar_width = - histogram[i] / max_bucket_value * histogram_bounds.width(); - canvas->drawRect( - SkRect::MakeXYWH(histogram_bounds.left(), - histogram_bounds.bottom() - (i + 1) * bar_height, - bar_width, 1), - flags); - } + DrawGraphLines(canvas, &flags, graph_bounds); + + // Collect the frames graph data. + SkPath good_path; + SkPath dropped_path; + SkPath partial_path; + for (auto it = --dropped_frame_counter->end(); it; --it) { + const auto state = **it; + int x = graph_bounds.left() + it.index(); + SkPath& path = state == DroppedFrameCounter::kFrameStateDropped + ? dropped_path + : state == DroppedFrameCounter::kFrameStateComplete + ? good_path + : partial_path; + path.moveTo(x, graph_bounds.top()); + path.lineTo(x, graph_bounds.bottom()); } // Draw FPS graph. flags.setAntiAlias(true); flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(1); - canvas->drawPath(path, flags); + + flags.setColor(SkColorSetA(SK_ColorGREEN, 128)); + canvas->drawPath(good_path, flags); + + flags.setColor(SkColorSetA(SK_ColorRED, 128)); + canvas->drawPath(dropped_path, flags); + + flags.setColor(SkColorSetA(SK_ColorYELLOW, 255)); + canvas->drawPath(partial_path, flags); return area; } diff --git a/chromium/cc/layers/heads_up_display_layer_impl.h b/chromium/cc/layers/heads_up_display_layer_impl.h index 323da1fff87..417d5a0d9b8 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.h +++ b/chromium/cc/layers/heads_up_display_layer_impl.h @@ -26,7 +26,7 @@ class ClientResourceProvider; } namespace cc { -class FrameRateCounter; +class DroppedFrameCounter; class LayerTreeFrameSink; class PaintCanvas; class PaintFlags; @@ -76,24 +76,6 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { void PushPropertiesTo(LayerImpl* layer) override; private: - class Graph { - public: - Graph(double indicator_value, double start_upper_bound); - - // Eases the upper bound, which limits what is currently visible in the - // graph, so that the graph always scales to either it's max or - // default_upper_bound. - double UpdateUpperBound(); - - double value; - double min; - double max; - - double current_upper_bound; - const double default_upper_bound; - const double indicator; - }; - HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl, int id); const char* LayerTypeAsString() const override; @@ -120,13 +102,13 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { const SkRect& bounds) const; void DrawGraphLines(PaintCanvas* canvas, PaintFlags* flags, - const SkRect& bounds, - const Graph& graph) const; + const SkRect& bounds) const; - SkRect DrawFPSDisplay(PaintCanvas* canvas, - const FrameRateCounter* fps_counter, - int right, - int top) const; + SkRect DrawFrameThroughputDisplay( + PaintCanvas* canvas, + const DroppedFrameCounter* dropped_frame_counter, + int right, + int top) const; SkRect DrawMemoryDisplay(PaintCanvas* canvas, int top, int right, @@ -154,21 +136,15 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { sk_sp<SkTypeface> typeface_; std::vector<gfx::Rect> layout_shift_rects_; - float internal_contents_scale_; + float internal_contents_scale_ = 1.0f; gfx::Size internal_content_bounds_; - Graph fps_graph_; - Graph paint_time_graph_; + uint32_t throughput_value_ = 0.0f; MemoryHistory::Entry memory_entry_; int paint_rects_fade_step_ = 0; int layout_shift_rects_fade_step_ = 0; std::vector<DebugRect> paint_rects_; std::vector<DebugRect> layout_shift_debug_rects_; - base::Optional<int> current_throughput_; - // The worst and best throughput we have seen so far, they either both have no - // value, or both have value. - base::Optional<int> min_throughput; - base::Optional<int> max_throughput; base::TimeTicks time_of_last_graph_update_; }; diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc index c354081f17b..7b74ae2da3c 100644 --- a/chromium/cc/layers/layer.cc +++ b/chromium/cc/layers/layer.cc @@ -78,6 +78,7 @@ Layer::Inputs::Inputs(int layer_id) : layer_id(layer_id), hit_testable(false), contents_opaque(false), + contents_opaque_for_text(false), is_drawable(false), double_sided(true), has_will_change_transform_hint(false), @@ -804,11 +805,21 @@ void Layer::SetContentsOpaque(bool opaque) { if (inputs_.contents_opaque == opaque) return; inputs_.contents_opaque = opaque; + inputs_.contents_opaque_for_text = opaque; SetNeedsCommit(); SetSubtreePropertyChanged(); SetPropertyTreesNeedRebuild(); } +void Layer::SetContentsOpaqueForText(bool opaque) { + DCHECK(IsPropertyChangeAllowed()); + if (inputs_.contents_opaque_for_text == opaque) + return; + DCHECK(!contents_opaque() || opaque); + inputs_.contents_opaque_for_text = opaque; + SetNeedsCommit(); +} + void Layer::SetPosition(const gfx::PointF& position) { DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists()); @@ -1321,6 +1332,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetWheelEventHandlerRegion(Region()); } layer->SetContentsOpaque(inputs_.contents_opaque); + layer->SetContentsOpaqueForText(inputs_.contents_opaque_for_text); layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility_); layer->UpdateScrollable(); diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h index 43debb199e8..a2da20587d1 100644 --- a/chromium/cc/layers/layer.h +++ b/chromium/cc/layers/layer.h @@ -333,9 +333,24 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { // must be opaque or visual errors can occur. This applies only to this layer // and not to children, and does not imply the layer should be composited // opaquely, as effects may be applied such as opacity() or filters(). + // Note that this also calls SetContentsOpaqueForText(opaque) internally. + // To override a different contents_opaque_for_text, the client should call + // SetContentsOpaqueForText() after SetContentsOpaque(). void SetContentsOpaque(bool opaque); bool contents_opaque() const { return inputs_.contents_opaque; } + // Whether the contents area containing text is known to be opaque. + // For example, blink will SetContentsOpaque(false) but + // SetContentsOpaqueForText(true) for the following case: + // <div style="overflow: hidden; border-radius: 10px; background: white"> + // TEXT + // </div> + // See also the note for SetContentsOpaque(). + void SetContentsOpaqueForText(bool opaque); + bool contents_opaque_for_text() const { + return inputs_.contents_opaque_for_text; + } + // Set or get whether this layer should be a hit test target void SetHitTestable(bool should_hit_test); virtual bool HitTestable() const; @@ -829,6 +844,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool hit_testable : 1; bool contents_opaque : 1; + bool contents_opaque_for_text : 1; bool is_drawable : 1; bool double_sided : 1; diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc index bb1c93f2538..318c2cbc1ee 100644 --- a/chromium/cc/layers/layer_impl.cc +++ b/chromium/cc/layers/layer_impl.cc @@ -55,6 +55,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, layer_property_changed_from_property_trees_(false), may_contain_video_(false), contents_opaque_(false), + contents_opaque_for_text_(false), should_check_backface_visibility_(false), draws_content_(false), contributes_to_drawn_render_surface_(false), @@ -374,6 +375,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->has_transform_node_ = has_transform_node_; layer->offset_to_transform_parent_ = offset_to_transform_parent_; layer->contents_opaque_ = contents_opaque_; + layer->contents_opaque_for_text_ = contents_opaque_for_text_; layer->may_contain_video_ = may_contain_video_; layer->should_check_backface_visibility_ = should_check_backface_visibility_; layer->draws_content_ = draws_content_; @@ -571,6 +573,12 @@ SkColor LayerImpl::SafeOpaqueBackgroundColor() const { void LayerImpl::SetContentsOpaque(bool opaque) { contents_opaque_ = opaque; + contents_opaque_for_text_ = opaque; +} + +void LayerImpl::SetContentsOpaqueForText(bool opaque) { + DCHECK(!contents_opaque_ || opaque); + contents_opaque_for_text_ = opaque; } float LayerImpl::Opacity() const { diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h index 95eb4828df8..006057b5b12 100644 --- a/chromium/cc/layers/layer_impl.h +++ b/chromium/cc/layers/layer_impl.h @@ -14,7 +14,7 @@ #include <string> #include <vector> -#include "base/logging.h" +#include "base/check.h" #include "base/memory/ptr_util.h" #include "cc/base/region.h" #include "cc/base/synced_property.h" @@ -165,8 +165,12 @@ class CC_EXPORT LayerImpl { // non-opaque color. Tries to return background_color(), if possible. SkColor SafeOpaqueBackgroundColor() const; + // See Layer::SetContentsOpaque() and SetContentsOpaqueForText() for the + // relationship between the two flags. void SetContentsOpaque(bool opaque); bool contents_opaque() const { return contents_opaque_; } + void SetContentsOpaqueForText(bool opaque); + bool contents_opaque_for_text() const { return contents_opaque_for_text_; } float Opacity() const; @@ -221,8 +225,8 @@ class CC_EXPORT LayerImpl { return draw_properties_.screen_space_transform_is_animating; } gfx::Rect clip_rect() const { return draw_properties_.clip_rect; } - gfx::Rect drawable_content_rect() const { - return draw_properties_.drawable_content_rect; + gfx::Rect visible_drawable_content_rect() const { + return draw_properties_.visible_drawable_content_rect; } gfx::Rect visible_layer_rect() const { return draw_properties_.visible_layer_rect; @@ -475,6 +479,7 @@ class CC_EXPORT LayerImpl { bool may_contain_video_ : 1; bool contents_opaque_ : 1; + bool contents_opaque_for_text_ : 1; bool should_check_backface_visibility_ : 1; bool draws_content_ : 1; bool contributes_to_drawn_render_surface_ : 1; diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc index c49c99b106f..1d975284495 100644 --- a/chromium/cc/layers/layer_unittest.cc +++ b/chromium/cc/layers/layer_unittest.cc @@ -17,6 +17,7 @@ #include "cc/layers/picture_layer.h" #include "cc/layers/solid_color_scrollbar_layer.h" #include "cc/test/animation_test_common.h" +#include "cc/test/cc_test_suite.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host.h" @@ -1388,15 +1389,23 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP, base::BindOnce(&ReceiveCopyOutputResult, &result_count)); layer->RequestCopyOfOutput(std::move(request)); + // Because RequestCopyOfOutput could run as a PostTask to return results + // RunUntilIdle() to ensure that the result is not returned yet. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(0, result_count); request = std::make_unique<viz::CopyOutputRequest>( viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP, base::BindOnce(&ReceiveCopyOutputResult, &result_count)); layer->RequestCopyOfOutput(std::move(request)); + // Because RequestCopyOfOutput could run as a PostTask to return results + // RunUntilIdle() to ensure that the result is not returned yet. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(0, result_count); // When the layer is destroyed, expect both requests to be aborted. layer = nullptr; + // Wait for any posted tasks to run so the results will be returned. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(2, result_count); layer = Layer::Create(); @@ -1412,6 +1421,9 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { &did_receive_first_result_from_this_source)); request->set_source(kArbitrarySourceId1); layer->RequestCopyOfOutput(std::move(request)); + // Because RequestCopyOfOutput could run as a PostTask to return results + // RunUntilIdle() to ensure that the result is not returned yet. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(0, did_receive_first_result_from_this_source); // Make a request from a different source. int did_receive_result_from_different_source = 0; @@ -1421,6 +1433,9 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { &did_receive_result_from_different_source)); request->set_source(kArbitrarySourceId2); layer->RequestCopyOfOutput(std::move(request)); + // Because RequestCopyOfOutput could run as a PostTask to return results + // RunUntilIdle() to ensure that the result is not returned yet. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(0, did_receive_result_from_different_source); // Make a request without specifying the source. int did_receive_result_from_anonymous_source = 0; @@ -1429,6 +1444,9 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { base::BindOnce(&ReceiveCopyOutputResult, &did_receive_result_from_anonymous_source)); layer->RequestCopyOfOutput(std::move(request)); + // Because RequestCopyOfOutput could run as a PostTask to return results + // RunUntilIdle() to ensure that the result is not returned yet. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(0, did_receive_result_from_anonymous_source); // Make the second request from |kArbitrarySourceId1|. int did_receive_second_result_from_this_source = 0; @@ -1439,6 +1457,8 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { request->set_source(kArbitrarySourceId1); layer->RequestCopyOfOutput( std::move(request)); // First request to be aborted. + // Wait for any posted tasks to run so the results will be returned. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(1, did_receive_first_result_from_this_source); EXPECT_EQ(0, did_receive_result_from_different_source); EXPECT_EQ(0, did_receive_result_from_anonymous_source); @@ -1446,6 +1466,8 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { // When the layer is destroyed, the other three requests should be aborted. layer = nullptr; + // Wait for any posted tasks to run so the results will be returned. + CCTestSuite::RunUntilIdle(); EXPECT_EQ(1, did_receive_first_result_from_this_source); EXPECT_EQ(1, did_receive_result_from_different_source); EXPECT_EQ(1, did_receive_result_from_anonymous_source); @@ -1507,7 +1529,7 @@ TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) { // Expect additional calls due to has-animation check and initialization // of keyframes. - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(7); + EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(3); scoped_refptr<AnimationTimeline> timeline = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); animation_host_->AddAnimationTimeline(timeline); @@ -1526,6 +1548,19 @@ TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) { EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id)); } +// Triggering a commit to push animation counts and raf presence to the +// compositor is expensive and updated counts can wait until the next +// commit to be pushed. See https://crbug.com/1083244. +TEST_F(LayerTest, PushAnimationCountsLazily) { + EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); + animation_host_->SetAnimationCounts(0, /* current_frame_had_raf = */ true, + /* next_frame_has_pending_raf = */ true); + EXPECT_FALSE(host_impl_.animation_host()->CurrentFrameHadRAF()); + EXPECT_FALSE(animation_host_->needs_push_properties()); + animation_host_->PushPropertiesTo(host_impl_.animation_host()); + EXPECT_TRUE(host_impl_.animation_host()->CurrentFrameHadRAF()); +} + TEST_F(LayerTest, SetElementIdNotUsingLayerLists) { scoped_refptr<Layer> test_layer = Layer::Create(); test_layer->SetLayerTreeHost(layer_tree_host_.get()); diff --git a/chromium/cc/layers/mirror_layer_impl.cc b/chromium/cc/layers/mirror_layer_impl.cc index 7a916bf5d69..5751ccb53b2 100644 --- a/chromium/cc/layers/mirror_layer_impl.cc +++ b/chromium/cc/layers/mirror_layer_impl.cc @@ -56,8 +56,7 @@ void MirrorLayerImpl::AppendQuads(viz::RenderPass* render_pass, quad->SetNew(shared_quad_state, content_rect, unoccluded_content_rect, mirrored_layer_id_, mask_resource_id, mask_uv_rect, mask_texture_size, mirrored_effect_node->surface_contents_scale, - mirrored_effect_node->filters_origin, - gfx::RectF(gfx::Rect(content_rect.size())), + gfx::PointF(), gfx::RectF(gfx::Rect(content_rect.size())), !layer_tree_impl()->settings().enable_edge_anti_aliasing, 0.f); } diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc index 84f6b872302..2be635c50e2 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.cc +++ b/chromium/cc/layers/painted_scrollbar_layer.cc @@ -40,6 +40,7 @@ PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_refptr<Scrollbar> scrollbar) internal_contents_scale_(1.f), painted_opacity_(scrollbar_->Opacity()), has_thumb_(scrollbar_->HasThumb()), + jump_on_track_click_(scrollbar_->JumpOnTrackClick()), supports_drag_snap_back_(scrollbar_->SupportsDragSnapBack()), is_overlay_(scrollbar_->IsOverlay()) {} @@ -58,6 +59,7 @@ void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { scrollbar_layer->set_internal_contents_scale_and_bounds( internal_contents_scale_, internal_content_bounds_); + scrollbar_layer->SetJumpOnTrackClick(jump_on_track_click_); scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_); scrollbar_layer->SetBackButtonRect(back_button_rect_); scrollbar_layer->SetForwardButtonRect(forward_button_rect_); @@ -112,6 +114,7 @@ void PaintedScrollbarLayer::UpdateThumbAndTrackGeometry() { DCHECK_EQ(is_overlay_, scrollbar_->IsOverlay()); DCHECK_EQ(orientation(), scrollbar_->Orientation()); + UpdateProperty(scrollbar_->JumpOnTrackClick(), &jump_on_track_click_); UpdateProperty(scrollbar_->TrackRect(), &track_rect_); UpdateProperty(scrollbar_->BackButtonRect(), &back_button_rect_); UpdateProperty(scrollbar_->ForwardButtonRect(), &forward_button_rect_); diff --git a/chromium/cc/layers/painted_scrollbar_layer.h b/chromium/cc/layers/painted_scrollbar_layer.h index 191c37d8e5a..930c614071e 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.h +++ b/chromium/cc/layers/painted_scrollbar_layer.h @@ -86,6 +86,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase { gfx::Rect forward_button_rect_; float painted_opacity_; bool has_thumb_; + bool jump_on_track_click_; const bool supports_drag_snap_back_; const bool is_overlay_; diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc index 70da5b1be8f..6d36154b803 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc @@ -43,6 +43,7 @@ PaintedScrollbarLayerImpl::PaintedScrollbarLayerImpl( thumb_ui_resource_id_(0), painted_opacity_(1.f), internal_contents_scale_(1.f), + jump_on_track_click_(false), supports_drag_snap_back_(false), thumb_thickness_(0), thumb_length_(0) {} @@ -65,6 +66,7 @@ void PaintedScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { scrollbar_layer->set_internal_contents_scale_and_bounds( internal_contents_scale_, internal_content_bounds_); + scrollbar_layer->SetJumpOnTrackClick(jump_on_track_click_); scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_); scrollbar_layer->SetThumbThickness(thumb_thickness_); scrollbar_layer->SetThumbLength(thumb_length_); @@ -162,6 +164,17 @@ gfx::Rect PaintedScrollbarLayerImpl::GetEnclosingRectInTargetSpace() const { return GetScaledEnclosingRectInTargetSpace(internal_contents_scale_); } +void PaintedScrollbarLayerImpl::SetJumpOnTrackClick(bool jump_on_track_click) { + if (jump_on_track_click_ == jump_on_track_click) + return; + jump_on_track_click_ = jump_on_track_click; + NoteLayerPropertyChanged(); +} + +bool PaintedScrollbarLayerImpl::JumpOnTrackClick() const { + return jump_on_track_click_; +} + void PaintedScrollbarLayerImpl::SetSupportsDragSnapBack( bool supports_drag_snap_back) { if (supports_drag_snap_back_ == supports_drag_snap_back) diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.h b/chromium/cc/layers/painted_scrollbar_layer_impl.h index e5035e1dc3b..eecf7c9aefd 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.h +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.h @@ -38,6 +38,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { AppendQuadsData* append_quads_data) override; gfx::Rect GetEnclosingRectInTargetSpace() const override; + void SetJumpOnTrackClick(bool jump_on_track_click); void SetSupportsDragSnapBack(bool supports_drag_snap_back); void SetBackButtonRect(gfx::Rect back_button_rect); void SetForwardButtonRect(gfx::Rect forward_button_rect); @@ -63,6 +64,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { internal_content_bounds_ = content_bounds; } + bool JumpOnTrackClick() const override; bool SupportsDragSnapBack() const override; gfx::Rect BackButtonRect() const override; gfx::Rect ForwardButtonRect() const override; @@ -98,6 +100,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { float internal_contents_scale_; gfx::Size internal_content_bounds_; + bool jump_on_track_click_; bool supports_drag_snap_back_; int thumb_thickness_; int thumb_length_; diff --git a/chromium/cc/layers/picture_image_layer.cc b/chromium/cc/layers/picture_image_layer.cc deleted file mode 100644 index 2208b11c6a1..00000000000 --- a/chromium/cc/layers/picture_image_layer.cc +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2010 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/layers/picture_image_layer.h" - -#include <stddef.h> - -#include "cc/base/math_util.h" -#include "cc/layers/picture_layer_impl.h" -#include "cc/paint/paint_op_buffer.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_settings.h" - -namespace cc { - -scoped_refptr<PictureImageLayer> PictureImageLayer::Create() { - return base::WrapRefCounted(new PictureImageLayer()); -} - -PictureImageLayer::PictureImageLayer() : PictureLayer(this) {} - -PictureImageLayer::~PictureImageLayer() { - ClearClient(); -} - -bool PictureImageLayer::HasDrawableContent() const { - return image_ && PictureLayer::HasDrawableContent(); -} - -void PictureImageLayer::SetImage(PaintImage image, - const SkMatrix& matrix, - bool uses_width_as_height) { - // SetImage() currently gets called whenever there is any - // style change that affects the layer even if that change doesn't - // affect the actual contents of the image (e.g. a CSS animation). - // With this check in place we avoid unecessary texture uploads. - if (image_ == image && matrix_ == matrix && - uses_width_as_height_ == uses_width_as_height) { - return; - } - - image_ = std::move(image); - matrix_ = matrix; - uses_width_as_height_ = uses_width_as_height; - - int width = uses_width_as_height_ ? image_.height() : image_.width(); - int height = uses_width_as_height_ ? image_.width() : image_.height(); - picture_layer_inputs_.directly_composited_image_size = - gfx::Size(width, height); - - UpdateDrawsContent(HasDrawableContent()); - SetNeedsDisplay(); -} - -gfx::Rect PictureImageLayer::PaintableRegion() { - return gfx::Rect(bounds()); -} - -scoped_refptr<DisplayItemList> PictureImageLayer::PaintContentsToDisplayList( - ContentLayerClient::PaintingControlSetting painting_control) { - DCHECK(image_); - DCHECK_GT(image_.width(), 0); - DCHECK_GT(image_.height(), 0); - DCHECK(layer_tree_host()); - - gfx::Size image_size = - picture_layer_inputs_.directly_composited_image_size.value(); - float content_to_layer_scale_x = - static_cast<float>(bounds().width()) / image_size.width(); - float content_to_layer_scale_y = - static_cast<float>(bounds().height()) / image_size.height(); - - bool has_scale = !MathUtil::IsWithinEpsilon(content_to_layer_scale_x, 1.f) || - !MathUtil::IsWithinEpsilon(content_to_layer_scale_y, 1.f); - DCHECK(!has_scale); - bool needs_save = has_scale || !matrix_.isIdentity(); - - auto display_list = base::MakeRefCounted<DisplayItemList>(); - - display_list->StartPaint(); - - if (needs_save) - display_list->push<SaveOp>(); - - if (has_scale) { - display_list->push<ScaleOp>(content_to_layer_scale_x, - content_to_layer_scale_y); - } - - if (!matrix_.isIdentity()) - display_list->push<ConcatOp>(matrix_); - - // Because Android WebView resourceless software draw mode rasters directly - // to the root canvas, this draw must use the SkBlendMode::kSrcOver so that - // transparent images blend correctly. - display_list->push<DrawImageOp>(image_, 0.f, 0.f, nullptr); - - if (needs_save) - display_list->push<RestoreOp>(); - - display_list->EndPaintOfUnpaired(PaintableRegion()); - display_list->Finalize(); - - return display_list; -} - -bool PictureImageLayer::FillsBoundsCompletely() const { - return false; -} - -size_t PictureImageLayer::GetApproximateUnsharedMemoryUsage() const { - return 0; -} - -} // namespace cc diff --git a/chromium/cc/layers/picture_image_layer.h b/chromium/cc/layers/picture_image_layer.h deleted file mode 100644 index 92fddfad360..00000000000 --- a/chromium/cc/layers/picture_image_layer.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2010 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_LAYERS_PICTURE_IMAGE_LAYER_H_ -#define CC_LAYERS_PICTURE_IMAGE_LAYER_H_ - -#include <stddef.h> - -#include "cc/cc_export.h" -#include "cc/layers/content_layer_client.h" -#include "cc/layers/picture_layer.h" -#include "cc/paint/paint_image.h" -#include "third_party/skia/include/core/SkRefCnt.h" -#include "ui/gfx/geometry/size.h" - -namespace cc { - -class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient { - public: - static scoped_refptr<PictureImageLayer> Create(); - - PictureImageLayer(const PictureImageLayer&) = delete; - PictureImageLayer& operator=(const PictureImageLayer&) = delete; - - void SetImage(PaintImage image, - const SkMatrix& matrix, - bool uses_width_as_height); - - gfx::Rect PaintableRegion() override; - - // ContentLayerClient implementation. - scoped_refptr<DisplayItemList> PaintContentsToDisplayList( - ContentLayerClient::PaintingControlSetting painting_control) override; - bool FillsBoundsCompletely() const override; - size_t GetApproximateUnsharedMemoryUsage() const override; - - protected: - bool HasDrawableContent() const override; - - private: - PictureImageLayer(); - ~PictureImageLayer() override; - - PaintImage image_; - SkMatrix matrix_; - bool uses_width_as_height_; -}; - -} // namespace cc - -#endif // CC_LAYERS_PICTURE_IMAGE_LAYER_H_ diff --git a/chromium/cc/layers/picture_image_layer_unittest.cc b/chromium/cc/layers/picture_image_layer_unittest.cc deleted file mode 100644 index f02c127aa37..00000000000 --- a/chromium/cc/layers/picture_image_layer_unittest.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2015 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/layers/picture_image_layer.h" - -#include "cc/animation/animation_host.h" -#include "cc/paint/paint_image_builder.h" -#include "cc/test/fake_layer_tree_host.h" -#include "cc/test/skia_common.h" -#include "cc/test/test_task_graph_runner.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/core/SkImage.h" -#include "third_party/skia/include/core/SkSurface.h" - -namespace cc { -namespace { - -TEST(PictureImageLayerTest, PaintContentsToDisplayList) { - scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create(); - FakeLayerTreeHostClient client; - TestTaskGraphRunner task_graph_runner; - auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( - &client, &task_graph_runner, animation_host.get()); - layer->SetLayerTreeHost(host.get()); - gfx::Rect layer_rect(200, 200); - - unsigned char image_pixels[4 * 200 * 200] = {0}; - SkImageInfo info = - SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height()); - sk_sp<SkSurface> image_surface = - SkSurface::MakeRasterDirect(info, image_pixels, info.minRowBytes()); - SkCanvas* image_canvas = image_surface->getCanvas(); - image_canvas->clear(SK_ColorRED); - SkPaint blue_paint; - blue_paint.setColor(SK_ColorBLUE); - image_canvas->drawRect(SkRect::MakeWH(100, 100), blue_paint); - image_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), blue_paint); - - layer->SetImage(PaintImageBuilder::WithDefault() - .set_id(PaintImage::GetNextId()) - .set_image(image_surface->makeImageSnapshot(), - PaintImage::GetNextContentId()) - .TakePaintImage(), - SkMatrix::I(), false); - layer->SetBounds(gfx::Size(layer_rect.width(), layer_rect.height())); - - scoped_refptr<DisplayItemList> display_list = - layer->PaintContentsToDisplayList( - ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); - unsigned char actual_pixels[4 * 200 * 200] = {0}; - DrawDisplayList(actual_pixels, layer_rect, display_list); - - EXPECT_EQ(0, memcmp(actual_pixels, image_pixels, 4 * 200 * 200)); - - layer->SetLayerTreeHost(nullptr); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc index b7244152c31..0baee75a961 100644 --- a/chromium/cc/layers/picture_layer.cc +++ b/chromium/cc/layers/picture_layer.cc @@ -137,9 +137,17 @@ bool PictureLayer::Update() { &last_updated_invalidation_, layer_size, recorded_viewport); if (updated) { - picture_layer_inputs_.display_list = - picture_layer_inputs_.client->PaintContentsToDisplayList( - ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); + { + auto old_display_list = std::move(picture_layer_inputs_.display_list); + picture_layer_inputs_.display_list = + picture_layer_inputs_.client->PaintContentsToDisplayList( + ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); + if (old_display_list && + picture_layer_inputs_.display_list + ->NeedsAdditionalInvalidationForLCDText(*old_display_list)) { + last_updated_invalidation_ = gfx::Rect(bounds()); + } + } // Clear out previous directly composited image state - if the layer // qualifies we'll set up the state below. @@ -282,14 +290,6 @@ bool PictureLayer::ShouldUseTransformedRasterization() const { if (!picture_layer_inputs_.transformed_rasterization_allowed) return false; - // Background color overfill is undesirable with transformed rasterization. - // However, without background overfill, the tiles will be non-opaque on - // external edges, and layer opaque region can't be computed in layer space - // due to rounding under extreme scaling. This defeats many opaque layer - // optimization. Prefer optimization over quality for this particular case. - if (contents_opaque()) - return false; - const TransformTree& transform_tree = layer_tree_host()->property_trees()->transform_tree; DCHECK(!transform_tree.needs_update()); diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc index 00e845e2b3f..0f030bd4ff3 100644 --- a/chromium/cc/layers/picture_layer_impl.cc +++ b/chromium/cc/layers/picture_layer_impl.cc @@ -258,12 +258,16 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, // |PictureLayerTiling::EnclosingContentsRectFromLayer()| will // create a tiling that, when scaled by |max_contents_scale| above, is // larger than the layer bounds by a fraction of a pixel. - gfx::Rect clip_rect = draw_properties().drawable_content_rect; + gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( + draw_properties().target_space_transform, gfx::Rect(bounds())); + if (is_clipped()) + bounds_in_target_space.Intersect(draw_properties().clip_rect); + if (shared_quad_state->is_clipped) - clip_rect.Intersect(shared_quad_state->clip_rect); + bounds_in_target_space.Intersect(shared_quad_state->clip_rect); shared_quad_state->is_clipped = true; - shared_quad_state->clip_rect = clip_rect; + shared_quad_state->clip_rect = bounds_in_target_space; #if DCHECK_IS_ON() // Validate that the tile and bounds size are always within one pixel. @@ -836,22 +840,24 @@ LCDTextDisallowedReason PictureLayerImpl::ComputeLCDTextDisallowedReason() return LCDTextDisallowedReason::kNone; if (!layer_tree_impl()->settings().can_use_lcd_text) return LCDTextDisallowedReason::kSetting; - if (!contents_opaque()) { + if (!contents_opaque_for_text()) { if (SkColorGetA(background_color()) != SK_AlphaOPAQUE) return LCDTextDisallowedReason::kBackgroundColorNotOpaque; return LCDTextDisallowedReason::kContentsNotOpaque; } - if (!GetTransformTree() - .Node(transform_tree_index()) - ->node_and_ancestors_have_only_integer_translation) - return LCDTextDisallowedReason::kNonIntegralTranslation; - if (static_cast<int>(offset_to_transform_parent().x()) != - offset_to_transform_parent().x()) - return LCDTextDisallowedReason::kNonIntegralXOffset; - if (static_cast<int>(offset_to_transform_parent().y()) != - offset_to_transform_parent().y()) - return LCDTextDisallowedReason::kNonIntegralYOffset; + if (!use_transformed_rasterization_) { + if (!GetTransformTree() + .Node(transform_tree_index()) + ->node_and_ancestors_have_only_integer_translation) + return LCDTextDisallowedReason::kNonIntegralTranslation; + if (static_cast<int>(offset_to_transform_parent().x()) != + offset_to_transform_parent().x()) + return LCDTextDisallowedReason::kNonIntegralXOffset; + if (static_cast<int>(offset_to_transform_parent().y()) != + offset_to_transform_parent().y()) + return LCDTextDisallowedReason::kNonIntegralYOffset; + } if (has_will_change_transform_hint()) return LCDTextDisallowedReason::kWillChangeTransform; @@ -1066,6 +1072,11 @@ void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) { } void PictureLayerImpl::SetUseTransformedRasterization(bool use) { + // With transformed rasterization, the pixels along the edge of the layer may + // become translucent, so clear contents_opaque. + if (use) + SetContentsOpaque(false); + if (use_transformed_rasterization_ == use) return; @@ -1561,6 +1572,8 @@ gfx::Vector2dF PictureLayerImpl::CalculateRasterTranslation( if (!use_transformed_rasterization_) return gfx::Vector2dF(); + DCHECK(!contents_opaque()); + gfx::Transform draw_transform = DrawTransform(); // TODO(enne): for performance reasons, we should only have a raster // translation when the screen space transform is not animating. We try to diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc index 25fff7cb2ae..38609980105 100644 --- a/chromium/cc/layers/picture_layer_impl_unittest.cc +++ b/chromium/cc/layers/picture_layer_impl_unittest.cc @@ -5981,5 +5981,33 @@ TEST_F(LegacySWPictureLayerImplTest, NoTilingsUsesScaleOne) { EXPECT_RECT_EQ(gfx::Rect(1000, 10000), shared_quad_state->quad_layer_rect); EXPECT_TRUE(shared_quad_state->quad_to_target_transform.IsIdentity()); } + +TEST_F(LegacySWPictureLayerImplTest, + TransformedRasterizationAndContentsOpaqueAndLCDText) { + SetupDefaultTreesWithInvalidation(gfx::Size(200, 200), Region()); + + pending_layer()->SetBackgroundColor(SK_ColorWHITE); + pending_layer()->SetContentsOpaque(true); + pending_layer()->SetOffsetToTransformParent(gfx::Vector2dF(0.2, 0.3)); + EXPECT_TRUE(pending_layer()->contents_opaque()); + EXPECT_TRUE(pending_layer()->contents_opaque_for_text()); + EXPECT_EQ(LCDTextDisallowedReason::kNonIntegralXOffset, + pending_layer()->ComputeLCDTextDisallowedReasonForTesting()); + + pending_layer()->SetUseTransformedRasterization(true); + EXPECT_FALSE(pending_layer()->contents_opaque()); + EXPECT_FALSE(pending_layer()->contents_opaque_for_text()); + EXPECT_EQ(LCDTextDisallowedReason::kContentsNotOpaque, + pending_layer()->ComputeLCDTextDisallowedReasonForTesting()); + + // Simulate another push from main-thread with the same values. + pending_layer()->SetContentsOpaque(true); + pending_layer()->SetUseTransformedRasterization(true); + EXPECT_FALSE(pending_layer()->contents_opaque()); + EXPECT_FALSE(pending_layer()->contents_opaque_for_text()); + EXPECT_EQ(LCDTextDisallowedReason::kContentsNotOpaque, + pending_layer()->ComputeLCDTextDisallowedReasonForTesting()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc index 3d60067a835..f3cd766fdd5 100644 --- a/chromium/cc/layers/render_surface_impl.cc +++ b/chromium/cc/layers/render_surface_impl.cc @@ -134,10 +134,6 @@ const FilterOperations& RenderSurfaceImpl::Filters() const { return OwningEffectNode()->filters; } -gfx::PointF RenderSurfaceImpl::FiltersOrigin() const { - return OwningEffectNode()->filters_origin; -} - gfx::Transform RenderSurfaceImpl::SurfaceScale() const { gfx::Transform surface_scale; surface_scale.Scale(OwningEffectNode()->surface_contents_scale.x(), @@ -303,7 +299,7 @@ void RenderSurfaceImpl::AccumulateContentRectFromContributingLayer( if (render_target() == this) return; - accumulated_content_rect_.Union(layer->drawable_content_rect()); + accumulated_content_rect_.Union(layer->visible_drawable_content_rect()); } void RenderSurfaceImpl::AccumulateContentRectFromContributingRenderSurface( @@ -456,7 +452,7 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode, auto* quad = render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetAll(shared_quad_state, content_rect(), unoccluded_content_rect, /*needs_blending=*/true, id(), mask_resource_id, mask_uv_rect, - mask_texture_size, surface_contents_scale, FiltersOrigin(), + mask_texture_size, surface_contents_scale, gfx::PointF(), tex_coord_rect, !layer_tree_impl_->settings().enable_edge_anti_aliasing, OwningEffectNode()->backdrop_filter_quality, diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h index 72587093ba7..fac0274a79d 100644 --- a/chromium/cc/layers/render_surface_impl.h +++ b/chromium/cc/layers/render_surface_impl.h @@ -168,7 +168,6 @@ class CC_EXPORT RenderSurfaceImpl { const FilterOperations& BackdropFilters() const; base::Optional<gfx::RRectF> BackdropFilterBounds() const; LayerImpl* BackdropMaskLayer() const; - gfx::PointF FiltersOrigin() const; gfx::Transform SurfaceScale() const; bool TrilinearFiltering() const; diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.cc b/chromium/cc/layers/scrollbar_layer_impl_base.cc index 2d9e885c030..787f339fb49 100644 --- a/chromium/cc/layers/scrollbar_layer_impl_base.cc +++ b/chromium/cc/layers/scrollbar_layer_impl_base.cc @@ -291,6 +291,10 @@ bool ScrollbarLayerImplBase::SupportsDragSnapBack() const { return false; } +bool ScrollbarLayerImplBase::JumpOnTrackClick() const { + return false; +} + gfx::Rect ScrollbarLayerImplBase::BackButtonRect() const { return gfx::Rect(0, 0); } diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.h b/chromium/cc/layers/scrollbar_layer_impl_base.h index 3b508f3c17a..a887ab47ed2 100644 --- a/chromium/cc/layers/scrollbar_layer_impl_base.h +++ b/chromium/cc/layers/scrollbar_layer_impl_base.h @@ -72,6 +72,7 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { virtual gfx::Rect BackTrackRect() const; virtual gfx::Rect ForwardTrackRect() const; virtual bool SupportsDragSnapBack() const; + virtual bool JumpOnTrackClick() const; virtual ScrollbarPart IdentifyScrollbarPart( const gfx::PointF position_in_widget) const; // Only PaintedOverlayScrollbar(Aura Overlay Scrollbar) need to know diff --git a/chromium/cc/layers/solid_color_layer_impl.cc b/chromium/cc/layers/solid_color_layer_impl.cc index 48c728cfde6..242f76415f9 100644 --- a/chromium/cc/layers/solid_color_layer_impl.cc +++ b/chromium/cc/layers/solid_color_layer_impl.cc @@ -53,6 +53,9 @@ void SolidColorLayerImpl::AppendSolidQuads( gfx::Rect visible_quad_rect = occlusion_in_layer_space.GetUnoccludedContentRect(visible_layer_rect); + if (visible_quad_rect.IsEmpty()) + return; + auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); quad->SetNew(shared_quad_state, visible_layer_rect, visible_quad_rect, color, force_anti_aliasing_off); diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc index 5b4229280eb..544676a563b 100644 --- a/chromium/cc/layers/texture_layer_impl.cc +++ b/chromium/cc/layers/texture_layer_impl.cc @@ -9,6 +9,7 @@ #include <vector> +#include "base/logging.h" #include "base/strings/stringprintf.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_impl.h" diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc index 8a22f392e56..06197477989 100644 --- a/chromium/cc/layers/video_layer_impl_unittest.cc +++ b/chromium/cc/layers/video_layer_impl_unittest.cc @@ -395,8 +395,7 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { gfx::Size(10, 10), gfx::Rect(10, 10), gfx::Size(10, 10), base::TimeDelta()); ASSERT_TRUE(video_frame); - video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, - true); + video_frame->metadata()->allow_overlay = true; FakeVideoFrameProvider provider; provider.set_frame(video_frame); @@ -439,8 +438,7 @@ TEST(VideoLayerImplTest, NativeARGBFrameGeneratesTextureQuad) { media::PIXEL_FORMAT_ARGB, mailbox_holders, base::DoNothing(), resource_size, gfx::Rect(10, 10), resource_size, base::TimeDelta()); ASSERT_TRUE(video_frame); - video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, - true); + video_frame->metadata()->allow_overlay = true; FakeVideoFrameProvider provider; provider.set_frame(video_frame); |