Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first. | 5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first. |
| 6 | 6 |
| 7 #include "ui/views/view.h" | 7 #include "ui/views/view.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 831 } else if (parent_) { | 831 } else if (parent_) { |
| 832 // Translate the requested paint rect to the parent's coordinate system | 832 // Translate the requested paint rect to the parent's coordinate system |
| 833 // then pass this notification up to the parent. | 833 // then pass this notification up to the parent. |
| 834 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); | 834 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); |
| 835 } | 835 } |
| 836 } | 836 } |
| 837 | 837 |
| 838 void View::Paint(const ui::PaintContext& parent_context) { | 838 void View::Paint(const ui::PaintContext& parent_context) { |
| 839 if (!ShouldPaint()) | 839 if (!ShouldPaint()) |
| 840 return; | 840 return; |
| 841 | 841 ui::PaintContext context(parent_context, GetPaintContextBounds(), |
| 842 ui::PaintContext context(parent_context, GetPaintContextOffset()); | 842 GetContextScaleType()); |
| 843 | 843 |
| 844 bool is_invalidated = true; | 844 bool is_invalidated = true; |
| 845 if (context.CanCheckInvalid()) { | 845 if (context.CanCheckRepaint()) { |
| 846 #if DCHECK_IS_ON() | 846 #if DCHECK_IS_ON() |
| 847 gfx::Vector2d offset; | 847 if (!context.IsPixelCanvas()) { |
| 848 context.Visited(this); | 848 gfx::Vector2d offset; |
| 849 View* view = this; | 849 context.Visited(this); |
| 850 while (view->parent() && !view->layer()) { | 850 View* view = this; |
| 851 DCHECK(view->GetTransform().IsIdentity()); | 851 while (view->parent() && !view->layer()) { |
| 852 offset += view->GetMirroredPosition().OffsetFromOrigin(); | 852 DCHECK(view->GetTransform().IsIdentity()); |
| 853 view = view->parent(); | 853 offset += view->GetMirroredPosition().OffsetFromOrigin(); |
| 854 view = view->parent(); | |
| 855 } | |
| 856 // The offset in the PaintContext should be the offset up to the paint | |
| 857 // root, which we compute and verify here. | |
| 858 DCHECK_EQ(context.PaintOffset().x(), offset.x()); | |
| 859 DCHECK_EQ(context.PaintOffset().y(), offset.y()); | |
| 860 // The above loop will stop when |view| is the paint root, which should be | |
| 861 // the root of the current paint walk, as verified by storing the root in | |
| 862 // the PaintContext. | |
| 863 DCHECK_EQ(context.RootVisited(), view); | |
| 854 } | 864 } |
| 855 // The offset in the PaintContext should be the offset up to the paint root, | |
| 856 // which we compute and verify here. | |
| 857 DCHECK_EQ(context.PaintOffset().x(), offset.x()); | |
| 858 DCHECK_EQ(context.PaintOffset().y(), offset.y()); | |
| 859 // The above loop will stop when |view| is the paint root, which should be | |
| 860 // the root of the current paint walk, as verified by storing the root in | |
| 861 // the PaintContext. | |
| 862 DCHECK_EQ(context.RootVisited(), view); | |
| 863 #endif | 865 #endif |
| 864 | 866 |
| 865 // If the View wasn't invalidated, don't waste time painting it, the output | 867 // If the View wasn't invalidated, don't waste time painting it, the output |
| 866 // would be culled. | 868 // would be culled. |
| 867 is_invalidated = context.IsRectInvalid(GetLocalBounds()); | 869 is_invalidated = context.ShouldRepaint(); |
| 868 } | 870 } |
| 869 | 871 |
| 870 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); | 872 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
| 871 | 873 |
| 872 // If the view is backed by a layer, it should paint with itself as the origin | 874 // If the view is backed by a layer, it should paint with itself as the origin |
| 873 // rather than relative to its parent. | 875 // rather than relative to its parent. |
| 874 // TODO(danakj): Rework clip and transform recorder usage here to use | 876 // TODO(danakj): Rework clip and transform recorder usage here to use |
| 875 // std::optional once we can do so. | 877 // std::optional once we can do so. |
| 876 ui::ClipRecorder clip_recorder(parent_context); | 878 ui::ClipRecorder clip_recorder(parent_context); |
| 877 if (!layer()) { | 879 if (!layer()) { |
| 878 // Set the clip rect to the bounds of this View, or |clip_path_| if it's | 880 // Set the clip rect to the bounds of this View, or |clip_path_| if it's |
| 879 // been set. Note that the X (or left) position we pass to ClipRect takes | 881 // been set. Note that the X (or left) position we pass to ClipRect takes |
| 880 // into consideration whether or not the View uses a right-to-left layout so | 882 // into consideration whether or not the View uses a right-to-left layout so |
| 881 // that we paint the View in its mirrored position if need be. | 883 // that we paint the View in its mirrored position if need be. |
| 882 if (clip_path_.isEmpty()) { | 884 if (clip_path_.isEmpty()) { |
| 883 clip_recorder.ClipRect(GetMirroredBounds()); | 885 clip_recorder.ClipRect(context.pixel_bounds()); |
| 884 } else { | 886 } else { |
| 885 gfx::Path clip_path_in_parent = clip_path_; | 887 gfx::Path clip_path_in_parent = clip_path_; |
| 886 clip_path_in_parent.offset(GetMirroredX(), y()); | 888 clip_path_in_parent.transform(SkMatrix::MakeScale( |
| 889 SkFloatToScalar(context.effective_scale_factor_x()), | |
| 890 SkFloatToScalar(context.effective_scale_factor_y()))); | |
| 891 clip_path_in_parent.offset(context.pixel_bounds().OffsetFromOrigin().x(), | |
| 892 context.pixel_bounds().OffsetFromOrigin().y()); | |
|
oshima
2017/06/22 15:24:11
can we move the clipping function to context as we
malaykeshav
2017/06/22 21:02:53
Done
| |
| 887 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); | 893 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); |
| 888 } | 894 } |
| 889 } | 895 } |
| 890 | 896 |
| 891 ui::TransformRecorder transform_recorder(context); | 897 ui::TransformRecorder transform_recorder(context); |
| 892 SetupTransformRecorderForPainting(&transform_recorder); | 898 SetupTransformRecorderForPainting(&transform_recorder, context); |
| 893 | 899 |
| 894 // Note that the cache is not aware of the offset of the view | 900 // Note that the cache is not aware of the offset of the view |
| 895 // relative to the parent since painting is always done relative to | 901 // relative to the parent since painting is always done relative to |
| 896 // the top left of the individual view. | 902 // the top left of the individual view. |
| 897 if (is_invalidated || !paint_cache_.UseCache(context, size())) { | 903 if (is_invalidated || !paint_cache_.UseCache(context, context.pixel_size())) { |
| 898 ui::PaintRecorder recorder(context, size(), &paint_cache_); | 904 ui::PaintRecorder recorder(context, context.pixel_size(), &paint_cache_); |
|
oshima
2017/06/22 15:24:11
same here. I'm still not convinced that extra argu
malaykeshav
2017/06/22 21:02:53
A lot of files are calling the PaintRecorder's sec
oshima
2017/06/23 18:42:32
You can keep the second ctr.
There are only 3~4
malaykeshav
2017/06/23 18:53:21
The second constructor needs this constructor to h
| |
| 899 gfx::Canvas* canvas = recorder.canvas(); | 905 gfx::Canvas* canvas = recorder.canvas(); |
| 900 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), | 906 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), |
| 901 flip_canvas_on_paint_for_rtl_ui_); | 907 flip_canvas_on_paint_for_rtl_ui_); |
| 902 | 908 |
| 903 // Delegate painting the contents of the View to the virtual OnPaint method. | 909 // Delegate painting the contents of the View to the virtual OnPaint method. |
| 904 OnPaint(canvas); | 910 OnPaint(canvas); |
| 905 } | 911 } |
| 906 | 912 |
| 907 // View::Paint() recursion over the subtree. | 913 // View::Paint() recursion over the subtree. |
| 908 PaintChildren(context); | 914 PaintChildren(context); |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1800 // and for different display density. | 1806 // and for different display density. |
| 1801 return kDefaultHorizontalDragThreshold; | 1807 return kDefaultHorizontalDragThreshold; |
| 1802 } | 1808 } |
| 1803 | 1809 |
| 1804 int View::GetVerticalDragThreshold() { | 1810 int View::GetVerticalDragThreshold() { |
| 1805 // TODO(jennyz): This value may need to be adjusted for different platforms | 1811 // TODO(jennyz): This value may need to be adjusted for different platforms |
| 1806 // and for different display density. | 1812 // and for different display density. |
| 1807 return kDefaultVerticalDragThreshold; | 1813 return kDefaultVerticalDragThreshold; |
| 1808 } | 1814 } |
| 1809 | 1815 |
| 1816 int View::GetContextScaleType() const { | |
| 1817 return ui::PaintContext::SCALE_TO_FIT; | |
| 1818 } | |
| 1819 | |
| 1810 // Debugging ------------------------------------------------------------------- | 1820 // Debugging ------------------------------------------------------------------- |
| 1811 | 1821 |
| 1812 #if !defined(NDEBUG) | 1822 #if !defined(NDEBUG) |
| 1813 | 1823 |
| 1814 std::string View::PrintViewGraph(bool first) { | 1824 std::string View::PrintViewGraph(bool first) { |
| 1815 return DoPrintViewGraph(first, this); | 1825 return DoPrintViewGraph(first, this); |
| 1816 } | 1826 } |
| 1817 | 1827 |
| 1818 std::string View::DoPrintViewGraph(bool first, View* view_with_children) { | 1828 std::string View::DoPrintViewGraph(bool first, View* view_with_children) { |
| 1819 // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19. | 1829 // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1952 // Translate the requested paint rect to the parent's coordinate system | 1962 // Translate the requested paint rect to the parent's coordinate system |
| 1953 // then pass this notification up to the parent. | 1963 // then pass this notification up to the parent. |
| 1954 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); | 1964 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); |
| 1955 } | 1965 } |
| 1956 } | 1966 } |
| 1957 | 1967 |
| 1958 bool View::ShouldPaint() const { | 1968 bool View::ShouldPaint() const { |
| 1959 return visible_ && !size().IsEmpty(); | 1969 return visible_ && !size().IsEmpty(); |
| 1960 } | 1970 } |
| 1961 | 1971 |
| 1962 gfx::Vector2d View::GetPaintContextOffset() const { | 1972 gfx::Rect View::GetPaintContextBounds() const { |
| 1963 // If the View has a layer() then it is a paint root. Otherwise, we need to | 1973 // If the View has a layer() then it is a paint root. Otherwise, we need to |
| 1964 // add the offset from the parent into the total offset from the paint root. | 1974 // add the offset from the parent into the total offset from the paint root. |
| 1965 DCHECK(layer() || parent() || origin() == gfx::Point()); | 1975 DCHECK(layer() || parent() || origin() == gfx::Point()); |
| 1966 return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin(); | 1976 return layer() ? GetLocalBounds() : GetMirroredBounds(); |
| 1967 } | 1977 } |
| 1968 | 1978 |
| 1969 void View::SetupTransformRecorderForPainting( | 1979 void View::SetupTransformRecorderForPainting( |
| 1970 ui::TransformRecorder* recorder) const { | 1980 ui::TransformRecorder* recorder, |
| 1981 const ui::PaintContext& context) const { | |
| 1971 // If the view is backed by a layer, it should paint with itself as the origin | 1982 // If the view is backed by a layer, it should paint with itself as the origin |
| 1972 // rather than relative to its parent. | 1983 // rather than relative to its parent. |
| 1973 if (layer()) | 1984 if (layer()) |
| 1974 return; | 1985 return; |
| 1975 | 1986 |
| 1976 // Translate the graphics such that 0,0 corresponds to where this View is | 1987 // Translate the graphics such that 0,0 corresponds to where this View is |
| 1977 // located relative to its parent. | 1988 // located relative to its parent. |
| 1978 gfx::Transform transform_from_parent; | 1989 gfx::Transform transform_from_parent; |
| 1979 gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin(); | 1990 gfx::Vector2d offset_from_parent = context.pixel_bounds().OffsetFromOrigin(); |
| 1980 transform_from_parent.Translate(offset_from_parent.x(), | 1991 transform_from_parent.Translate(offset_from_parent.x(), |
| 1981 offset_from_parent.y()); | 1992 offset_from_parent.y()); |
| 1982 transform_from_parent.PreconcatTransform(GetTransform()); | |
| 1983 recorder->Transform(transform_from_parent); | 1993 recorder->Transform(transform_from_parent); |
| 1984 } | 1994 } |
| 1985 | 1995 |
| 1986 void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), | 1996 void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), |
| 1987 const ui::PaintContext& context) { | 1997 const ui::PaintContext& context) { |
| 1988 View::Views children = GetChildrenInZOrder(); | 1998 View::Views children = GetChildrenInZOrder(); |
| 1989 DCHECK_EQ(child_count(), static_cast<int>(children.size())); | 1999 DCHECK_EQ(child_count(), static_cast<int>(children.size())); |
| 1990 for (auto* child : children) { | 2000 for (auto* child : children) { |
| 1991 if (!child->layer()) | 2001 if (!child->layer()) |
| 1992 (child->*func)(context); | 2002 (child->*func)(context); |
| 1993 } | 2003 } |
| 1994 } | 2004 } |
| 1995 | 2005 |
| 1996 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { | 2006 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { |
| 1997 Paint(parent_context); | 2007 Paint(parent_context); |
| 1998 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 2008 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1999 switches::kDrawViewBoundsRects)) | 2009 switches::kDrawViewBoundsRects)) |
| 2000 PaintDebugRects(parent_context); | 2010 PaintDebugRects(parent_context); |
| 2001 } | 2011 } |
| 2002 | 2012 |
| 2003 void View::PaintDebugRects(const ui::PaintContext& parent_context) { | 2013 void View::PaintDebugRects(const ui::PaintContext& parent_context) { |
| 2004 if (!ShouldPaint()) | 2014 if (!ShouldPaint()) |
| 2005 return; | 2015 return; |
| 2006 | 2016 |
| 2007 ui::PaintContext context(parent_context, GetPaintContextOffset()); | 2017 ui::PaintContext context(parent_context, GetPaintContextBounds(), |
| 2018 GetContextScaleType()); | |
| 2008 ui::TransformRecorder transform_recorder(context); | 2019 ui::TransformRecorder transform_recorder(context); |
| 2009 SetupTransformRecorderForPainting(&transform_recorder); | 2020 SetupTransformRecorderForPainting(&transform_recorder, context); |
| 2010 | 2021 |
| 2011 RecursivePaintHelper(&View::PaintDebugRects, context); | 2022 RecursivePaintHelper(&View::PaintDebugRects, context); |
| 2012 | 2023 |
| 2013 // Draw outline rects for debugging. | 2024 // Draw outline rects for debugging. |
| 2014 ui::PaintRecorder recorder(context, size()); | 2025 ui::PaintRecorder recorder(context, context.pixel_size(), &paint_cache_); |
| 2015 gfx::Canvas* canvas = recorder.canvas(); | 2026 gfx::Canvas* canvas = recorder.canvas(); |
| 2016 const float scale = canvas->UndoDeviceScaleFactor(); | 2027 const float scale = canvas->UndoDeviceScaleFactor(); |
| 2017 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); | 2028 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); |
| 2018 outline_rect.Inset(0.5f, 0.5f); | 2029 outline_rect.Inset(0.5f, 0.5f); |
| 2019 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); | 2030 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); |
| 2020 canvas->DrawRect(outline_rect, color); | 2031 canvas->DrawRect(outline_rect, color); |
| 2021 } | 2032 } |
| 2022 | 2033 |
| 2023 // Tree operations ------------------------------------------------------------- | 2034 // Tree operations ------------------------------------------------------------- |
| 2024 | 2035 |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2668 // Message the RootView to do the drag and drop. That way if we're removed | 2679 // Message the RootView to do the drag and drop. That way if we're removed |
| 2669 // the RootView can detect it and avoid calling us back. | 2680 // the RootView can detect it and avoid calling us back. |
| 2670 gfx::Point widget_location(event.location()); | 2681 gfx::Point widget_location(event.location()); |
| 2671 ConvertPointToWidget(this, &widget_location); | 2682 ConvertPointToWidget(this, &widget_location); |
| 2672 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2683 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
| 2673 // WARNING: we may have been deleted. | 2684 // WARNING: we may have been deleted. |
| 2674 return true; | 2685 return true; |
| 2675 } | 2686 } |
| 2676 | 2687 |
| 2677 } // namespace views | 2688 } // namespace views |
| OLD | NEW |