summaryrefslogtreecommitdiff
path: root/chromium/ui/views/view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/view.cc')
-rw-r--r--chromium/ui/views/view.cc245
1 files changed, 153 insertions, 92 deletions
diff --git a/chromium/ui/views/view.cc b/chromium/ui/views/view.cc
index 19b9a6d98a5..db50dc0720c 100644
--- a/chromium/ui/views/view.cc
+++ b/chromium/ui/views/view.cc
@@ -642,19 +642,6 @@ void View::SetLayoutManager(LayoutManager* layout_manager) {
layout_manager_->Installed(this);
}
-void View::SnapLayerToPixelBoundary() {
- if (!layer())
- return;
-
- if (snap_layer_to_pixel_boundary_ && layer()->parent() &&
- layer()->GetCompositor()) {
- ui::SnapLayerToPhysicalPixelBoundary(layer()->parent(), layer());
- } else {
- // Reset the offset.
- layer()->SetSubpixelPositionOffset(gfx::Vector2dF());
- }
-}
-
// Attributes ------------------------------------------------------------------
const char* View::GetClassName() const {
@@ -845,36 +832,46 @@ void View::SchedulePaintInRect(const gfx::Rect& rect) {
}
}
-void View::Paint(const ui::PaintContext& parent_context) {
+void View::Paint(const PaintInfo& parent_paint_info) {
if (!ShouldPaint())
return;
- ui::PaintContext context(parent_context, GetPaintContextOffset());
+ const gfx::Rect& parent_bounds = !parent()
+ ? GetPaintRecordingBounds()
+ : parent()->GetPaintRecordingBounds();
+
+ PaintInfo paint_info = PaintInfo::CreateChildPaintInfo(
+ parent_paint_info, GetPaintRecordingBounds(), parent_bounds.size(),
+ GetPaintScaleType());
+ const ui::PaintContext& context = paint_info.context();
bool is_invalidated = true;
- if (context.CanCheckInvalid()) {
+ if (paint_info.context().CanCheckInvalid()) {
#if DCHECK_IS_ON()
- gfx::Vector2d offset;
- context.Visited(this);
- View* view = this;
- while (view->parent() && !view->layer()) {
- DCHECK(view->GetTransform().IsIdentity());
- offset += view->GetMirroredPosition().OffsetFromOrigin();
- view = view->parent();
+ if (!context.is_pixel_canvas()) {
+ gfx::Vector2d offset;
+ context.Visited(this);
+ View* view = this;
+ while (view->parent() && !view->layer()) {
+ DCHECK(view->GetTransform().IsIdentity());
+ offset += view->GetMirroredPosition().OffsetFromOrigin();
+ view = view->parent();
+ }
+ // The offset in the PaintContext should be the offset up to the paint
+ // root, which we compute and verify here.
+ DCHECK_EQ(context.PaintOffset().x(), offset.x());
+ DCHECK_EQ(context.PaintOffset().y(), offset.y());
+ // The above loop will stop when |view| is the paint root, which should be
+ // the root of the current paint walk, as verified by storing the root in
+ // the PaintContext.
+ DCHECK_EQ(context.RootVisited(), view);
}
- // The offset in the PaintContext should be the offset up to the paint root,
- // which we compute and verify here.
- DCHECK_EQ(context.PaintOffset().x(), offset.x());
- DCHECK_EQ(context.PaintOffset().y(), offset.y());
- // The above loop will stop when |view| is the paint root, which should be
- // the root of the current paint walk, as verified by storing the root in
- // the PaintContext.
- DCHECK_EQ(context.RootVisited(), view);
#endif
// If the View wasn't invalidated, don't waste time painting it, the output
// would be culled.
- is_invalidated = context.IsRectInvalid(GetLocalBounds());
+ is_invalidated =
+ context.IsRectInvalid(gfx::Rect(paint_info.paint_recording_size()));
}
TRACE_EVENT1("views", "View::Paint", "class", GetClassName());
@@ -883,29 +880,44 @@ void View::Paint(const ui::PaintContext& parent_context) {
// rather than relative to its parent.
// TODO(danakj): Rework clip and transform recorder usage here to use
// std::optional once we can do so.
- ui::ClipRecorder clip_recorder(parent_context);
+ ui::ClipRecorder clip_recorder(parent_paint_info.context());
if (!layer()) {
// Set the clip rect to the bounds of this View, or |clip_path_| if it's
// been set. Note that the X (or left) position we pass to ClipRect takes
// into consideration whether or not the View uses a right-to-left layout so
// that we paint the View in its mirrored position if need be.
if (clip_path_.isEmpty()) {
- clip_recorder.ClipRect(GetMirroredBounds());
+ clip_recorder.ClipRect(gfx::Rect(paint_info.paint_recording_size()) +
+ paint_info.offset_from_parent());
} else {
gfx::Path clip_path_in_parent = clip_path_;
- clip_path_in_parent.offset(GetMirroredX(), y());
+
+ // Transform |clip_path_| from local space to parent recording space.
+ gfx::Transform to_parent_recording_space;
+
+ to_parent_recording_space.Translate(paint_info.offset_from_parent());
+ to_parent_recording_space.Scale(
+ SkFloatToScalar(paint_info.paint_recording_scale_x()),
+ SkFloatToScalar(paint_info.paint_recording_scale_y()));
+
+ clip_path_in_parent.transform(to_parent_recording_space.matrix());
clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent);
}
}
ui::TransformRecorder transform_recorder(context);
- SetupTransformRecorderForPainting(&transform_recorder);
+ SetupTransformRecorderForPainting(paint_info.offset_from_parent(),
+ &transform_recorder);
// Note that the cache is not aware of the offset of the view
// relative to the parent since painting is always done relative to
// the top left of the individual view.
- if (is_invalidated || !paint_cache_.UseCache(context, size())) {
- ui::PaintRecorder recorder(context, size(), &paint_cache_);
+ if (is_invalidated ||
+ !paint_cache_.UseCache(context, paint_info.paint_recording_size())) {
+ ui::PaintRecorder recorder(context, paint_info.paint_recording_size(),
+ paint_info.paint_recording_scale_x(),
+ paint_info.paint_recording_scale_y(),
+ &paint_cache_);
gfx::Canvas* canvas = recorder.canvas();
gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(),
flip_canvas_on_paint_for_rtl_ui_);
@@ -915,7 +927,7 @@ void View::Paint(const ui::PaintContext& parent_context) {
}
// View::Paint() recursion over the subtree.
- PaintChildren(context);
+ PaintChildren(paint_info);
}
void View::SetBackground(std::unique_ptr<Background> b) {
@@ -1543,9 +1555,9 @@ void View::RemovedFromWidget() {}
// Painting --------------------------------------------------------------------
-void View::PaintChildren(const ui::PaintContext& context) {
+void View::PaintChildren(const PaintInfo& paint_info) {
TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName());
- RecursivePaintHelper(&View::Paint, context);
+ RecursivePaintHelper(&View::Paint, paint_info);
}
void View::OnPaint(gfx::Canvas* canvas) {
@@ -1570,18 +1582,20 @@ void View::OnPaintBorder(gfx::Canvas* canvas) {
// Accelerated Painting --------------------------------------------------------
-gfx::Vector2d View::CalculateOffsetToAncestorWithLayer(
+View::LayerOffsetData View::CalculateOffsetToAncestorWithLayer(
ui::Layer** layer_parent) {
if (layer()) {
if (layer_parent)
*layer_parent = layer();
- return gfx::Vector2d();
+ return LayerOffsetData(layer()->device_scale_factor());
}
if (!parent_)
- return gfx::Vector2d();
+ return LayerOffsetData();
- return gfx::Vector2d(GetMirroredX(), y()) +
+ LayerOffsetData offset_data =
parent_->CalculateOffsetToAncestorWithLayer(layer_parent);
+
+ return offset_data + GetMirroredPosition().OffsetFromOrigin();
}
void View::UpdateParentLayer() {
@@ -1591,25 +1605,27 @@ void View::UpdateParentLayer() {
ui::Layer* parent_layer = NULL;
gfx::Vector2d offset(GetMirroredX(), y());
- if (parent_)
- offset += parent_->CalculateOffsetToAncestorWithLayer(&parent_layer);
+ if (parent_) {
+ offset +=
+ parent_->CalculateOffsetToAncestorWithLayer(&parent_layer).offset();
+ }
ReparentLayer(offset, parent_layer);
}
void View::MoveLayerToParent(ui::Layer* parent_layer,
- const gfx::Point& point) {
- gfx::Point local_point(point);
+ const LayerOffsetData& offset_data) {
+ LayerOffsetData local_offset_data(offset_data);
if (parent_layer != layer())
- local_point.Offset(GetMirroredX(), y());
+ local_offset_data += GetMirroredPosition().OffsetFromOrigin();
+
if (layer() && parent_layer != layer()) {
parent_layer->Add(layer());
- SetLayerBounds(gfx::Rect(local_point.x(), local_point.y(),
- width(), height()));
+ SetLayerBounds(size(), local_offset_data);
} else {
internal::ScopedChildrenLock lock(this);
for (auto* child : children_)
- child->MoveLayerToParent(parent_layer, local_point);
+ child->MoveLayerToParent(parent_layer, local_offset_data);
}
}
@@ -1674,14 +1690,14 @@ void View::NotifyParentsOfLayerChange() {
}
}
-void View::UpdateChildLayerBounds(const gfx::Vector2d& offset) {
+void View::UpdateChildLayerBounds(const LayerOffsetData& offset_data) {
if (layer()) {
- SetLayerBounds(GetLocalBounds() + offset);
+ SetLayerBounds(size(), offset_data);
} else {
internal::ScopedChildrenLock lock(this);
for (auto* child : children_) {
child->UpdateChildLayerBounds(
- offset + gfx::Vector2d(child->GetMirroredX(), child->y()));
+ offset_data + child->GetMirroredPosition().OffsetFromOrigin());
}
}
}
@@ -1697,8 +1713,23 @@ void View::OnDelegatedFrameDamage(
void View::OnDeviceScaleFactorChanged(float device_scale_factor) {
snap_layer_to_pixel_boundary_ =
(device_scale_factor - std::floor(device_scale_factor)) != 0.0f;
- SnapLayerToPixelBoundary();
- // Repainting with new scale factor will paint the content at the right scale.
+
+ if (!layer())
+ return;
+
+ // There can be no subpixel offset if the layer has no parent.
+ if (!parent() || !layer()->parent())
+ return;
+
+ if (layer()->parent() && layer()->GetCompositor() &&
+ layer()->GetCompositor()->is_pixel_canvas()) {
+ LayerOffsetData offset_data(
+ parent()->CalculateOffsetToAncestorWithLayer(nullptr));
+ offset_data += GetMirroredPosition().OffsetFromOrigin();
+ SnapLayerToPixelBoundary(offset_data);
+ } else {
+ SnapLayerToPixelBoundary(LayerOffsetData());
+ }
}
void View::ReorderLayers() {
@@ -1817,6 +1848,10 @@ int View::GetVerticalDragThreshold() {
return kDefaultVerticalDragThreshold;
}
+PaintInfo::ScaleType View::GetPaintScaleType() const {
+ return PaintInfo::ScaleType::kScaleWithEdgeSnapping;
+}
+
// Debugging -------------------------------------------------------------------
#if !defined(NDEBUG)
@@ -1969,14 +2004,16 @@ bool View::ShouldPaint() const {
return visible_ && !size().IsEmpty();
}
-gfx::Vector2d View::GetPaintContextOffset() const {
- // If the View has a layer() then it is a paint root. Otherwise, we need to
- // add the offset from the parent into the total offset from the paint root.
+gfx::Rect View::GetPaintRecordingBounds() const {
+ // If the View has a layer() then it is a paint root and no offset information
+ // is needed. Otherwise, we need bounds that includes an offset from the
+ // parent to add to the total offset from the paint root.
DCHECK(layer() || parent() || origin() == gfx::Point());
- return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin();
+ return layer() ? GetLocalBounds() : GetMirroredBounds();
}
void View::SetupTransformRecorderForPainting(
+ const gfx::Vector2d& offset_from_parent,
ui::TransformRecorder* recorder) const {
// If the view is backed by a layer, it should paint with itself as the origin
// rather than relative to its parent.
@@ -1986,42 +2023,54 @@ void View::SetupTransformRecorderForPainting(
// Translate the graphics such that 0,0 corresponds to where this View is
// located relative to its parent.
gfx::Transform transform_from_parent;
- gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin();
transform_from_parent.Translate(offset_from_parent.x(),
offset_from_parent.y());
- transform_from_parent.PreconcatTransform(GetTransform());
recorder->Transform(transform_from_parent);
}
-void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&),
- const ui::PaintContext& context) {
+void View::RecursivePaintHelper(void (View::*func)(const PaintInfo&),
+ const PaintInfo& info) {
View::Views children = GetChildrenInZOrder();
DCHECK_EQ(child_count(), static_cast<int>(children.size()));
for (auto* child : children) {
if (!child->layer())
- (child->*func)(context);
+ (child->*func)(info);
}
}
void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) {
- Paint(parent_context);
+ PaintInfo paint_info = PaintInfo::CreateRootPaintInfo(
+ parent_context, layer() ? layer()->size() : size());
+ Paint(paint_info);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDrawViewBoundsRects))
- PaintDebugRects(parent_context);
+ PaintDebugRects(paint_info);
}
-void View::PaintDebugRects(const ui::PaintContext& parent_context) {
+void View::PaintDebugRects(const PaintInfo& parent_paint_info) {
if (!ShouldPaint())
return;
- ui::PaintContext context(parent_context, GetPaintContextOffset());
+ const gfx::Rect& parent_bounds = (layer() || !parent())
+ ? GetPaintRecordingBounds()
+ : parent()->GetPaintRecordingBounds();
+ PaintInfo paint_info = PaintInfo::CreateChildPaintInfo(
+ parent_paint_info, GetPaintRecordingBounds(), parent_bounds.size(),
+ GetPaintScaleType());
+
+ const ui::PaintContext& context = paint_info.context();
+
ui::TransformRecorder transform_recorder(context);
- SetupTransformRecorderForPainting(&transform_recorder);
+ SetupTransformRecorderForPainting(paint_info.offset_from_parent(),
+ &transform_recorder);
- RecursivePaintHelper(&View::PaintDebugRects, context);
+ RecursivePaintHelper(&View::PaintDebugRects, paint_info);
// Draw outline rects for debugging.
- ui::PaintRecorder recorder(context, size());
+ ui::PaintRecorder recorder(context, paint_info.paint_recording_size(),
+ paint_info.paint_recording_scale_x(),
+ paint_info.paint_recording_scale_y(),
+ &paint_cache_);
gfx::Canvas* canvas = recorder.canvas();
const float scale = canvas->UndoDeviceScaleFactor();
gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale));
@@ -2180,6 +2229,23 @@ void View::VisibilityChangedImpl(View* starting_from, bool is_visible) {
VisibilityChanged(starting_from, is_visible);
}
+void View::SnapLayerToPixelBoundary(const LayerOffsetData& offset_data) {
+ if (!layer())
+ return;
+
+ if (snap_layer_to_pixel_boundary_ && layer()->parent() &&
+ layer()->GetCompositor()) {
+ if (layer()->GetCompositor()->is_pixel_canvas()) {
+ layer()->SetSubpixelPositionOffset(offset_data.GetSubpixelOffset());
+ } else {
+ ui::SnapLayerToPhysicalPixelBoundary(layer()->parent(), layer());
+ }
+ } else {
+ // Reset the offset.
+ layer()->SetSubpixelPositionOffset(gfx::Vector2dF());
+ }
+}
+
void View::BoundsChanged(const gfx::Rect& previous_bounds) {
if (visible_) {
// Paint the new bounds.
@@ -2190,11 +2256,13 @@ void View::BoundsChanged(const gfx::Rect& previous_bounds) {
if (layer()) {
if (parent_) {
- SetLayerBounds(GetLocalBounds() +
- gfx::Vector2d(GetMirroredX(), y()) +
- parent_->CalculateOffsetToAncestorWithLayer(NULL));
+ LayerOffsetData offset_data(
+ parent_->CalculateOffsetToAncestorWithLayer(nullptr));
+ offset_data += GetMirroredPosition().OffsetFromOrigin();
+ SetLayerBounds(size(), offset_data);
} else {
- SetLayerBounds(bounds_);
+ SetLayerBounds(bounds_.size(),
+ LayerOffsetData() + bounds_.OffsetFromOrigin());
}
// In RTL mode, if our width has changed, our children's mirrored bounds
@@ -2204,7 +2272,8 @@ void View::BoundsChanged(const gfx::Rect& previous_bounds) {
for (int i = 0; i < child_count(); ++i) {
View* child = child_at(i);
child->UpdateChildLayerBounds(
- gfx::Vector2d(child->GetMirroredX(), child->y()));
+ LayerOffsetData(layer()->device_scale_factor(),
+ child->GetMirroredPosition().OffsetFromOrigin()));
}
}
} else {
@@ -2284,9 +2353,10 @@ void View::RemoveDescendantToNotify(View* view) {
descendants_to_notify_.reset();
}
-void View::SetLayerBounds(const gfx::Rect& bounds) {
- layer()->SetBounds(bounds);
- SnapLayerToPixelBoundary();
+void View::SetLayerBounds(const gfx::Size& size,
+ const LayerOffsetData& offset_data) {
+ layer()->SetBounds(gfx::Rect(size) + offset_data.offset());
+ SnapLayerToPixelBoundary(offset_data);
}
// Transformations -------------------------------------------------------------
@@ -2423,7 +2493,7 @@ void View::ReparentLayer(const gfx::Vector2d& offset, ui::Layer* parent_layer) {
if (parent_layer)
parent_layer->Add(layer());
layer()->SchedulePaint(GetLocalBounds());
- MoveLayerToParent(layer(), gfx::Point());
+ MoveLayerToParent(layer(), LayerOffsetData(layer()->device_scale_factor()));
}
// Input -----------------------------------------------------------------------
@@ -2620,15 +2690,6 @@ void View::PropagateThemeChanged() {
OnThemeChanged();
}
-void View::PropagateLocaleChanged() {
- {
- internal::ScopedChildrenLock lock(this);
- for (auto* child : base::Reversed(children_))
- child->PropagateLocaleChanged();
- }
- OnLocaleChanged();
-}
-
void View::PropagateDeviceScaleFactorChanged(float device_scale_factor) {
{
internal::ScopedChildrenLock lock(this);