Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(817)

Side by Side Diff: views/view.cc

Issue 7845033: Rework View Layer Draw() to use the Layer::DrawTree() method and the LayerDelegate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "views/view.h" 5 #include "views/view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } 363 }
364 364
365 int View::GetHeightForWidth(int w) { 365 int View::GetHeightForWidth(int w) {
366 if (layout_manager_.get()) 366 if (layout_manager_.get())
367 return layout_manager_->GetPreferredHeightForWidth(this, w); 367 return layout_manager_->GetPreferredHeightForWidth(this, w);
368 return GetPreferredSize().height(); 368 return GetPreferredSize().height();
369 } 369 }
370 370
371 void View::SetVisible(bool visible) { 371 void View::SetVisible(bool visible) {
372 if (visible != visible_) { 372 if (visible != visible_) {
373 // If the tab is currently visible, schedule paint to refresh parent. 373 // If the View is currently visible, schedule paint to refresh parent.
374 if (visible_) 374 if (visible_)
375 SchedulePaint(); 375 SchedulePaint();
376 376
377 visible_ = visible; 377 visible_ = visible;
378 378
379 if (visible_) 379 if (visible_)
380 CreateLayerIfNecessary(); 380 CreateLayerIfNecessary();
381 else 381 else
382 // Destroy layer if tab is invisible as invisible tabs never paint 382 // Destroy layer if the View is invisible as invisible Views never paint.
383 DestroyLayerRecurse(); 383 DestroyLayerRecurse();
384 384
385 // This notifies all sub-views recursively. 385 // This notifies all sub-views recursively.
386 PropagateVisibilityNotifications(this, visible_); 386 PropagateVisibilityNotifications(this, visible_);
387 387
388 // If we are newly visible, schedule paint. 388 // If we are newly visible, schedule paint.
389 if (visible_) 389 if (visible_)
390 SchedulePaint(); 390 SchedulePaint();
391 } 391 }
392 } 392 }
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 x_rect = v->ConvertRectToParent(x_rect); 674 x_rect = v->ConvertRectToParent(x_rect);
675 return x_rect; 675 return x_rect;
676 } 676 }
677 677
678 // Painting -------------------------------------------------------------------- 678 // Painting --------------------------------------------------------------------
679 679
680 void View::SchedulePaint() { 680 void View::SchedulePaint() {
681 SchedulePaintInRect(GetLocalBounds()); 681 SchedulePaintInRect(GetLocalBounds());
682 } 682 }
683 683
684 void View::SchedulePaintInRect(const gfx::Rect& rect) { 684 void View::SchedulePaintInRect(const gfx::Rect& rect) {
sky 2011/09/13 17:47:06 All the scheduling paint code (SchedulePaintInRect
685 if (!IsVisible() || !painting_enabled_) 685 if (!IsVisible() || !painting_enabled_)
686 return; 686 return;
687 687
688 MarkLayerDirty(); 688 MarkLayerDirty();
689 SchedulePaintInternal(rect); 689 SchedulePaintInternal(rect);
690 } 690 }
691 691
692 void View::Paint(gfx::Canvas* canvas) { 692 void View::Paint(gfx::Canvas* canvas) {
693 TRACE_EVENT0("View", "Paint"); 693 TRACE_EVENT0("View", "Paint");
694 if (!IsVisible() || !painting_enabled_) 694
695 ScopedCanvas scoped_canvas(canvas);
696
697 // Paint this View and its children, setting the clip rect to the bounds
698 // of this View and translating the origin to the local bounds' top left
699 // point.
700 //
701 // Note that the X (or left) position we pass to ClipRectInt takes into
702 // consideration whether or not the view uses a right-to-left layout so that
703 // we paint our view in its mirrored position if need be.
704 if (!canvas->ClipRectInt(GetMirroredX(), y(),
705 width() - static_cast<int>(clip_x_),
706 height() - static_cast<int>(clip_y_))) {
695 return; 707 return;
708 }
709 // Non-empty clip, translate the graphics such that 0,0 corresponds to
710 // where this view is located (related to its parent).
711 canvas->TranslateInt(GetMirroredX(), y());
696 712
697 ScopedCanvas scoped_canvas(NULL); 713 if (transform())
698 scoped_ptr<gfx::Canvas> layer_canvas; 714 canvas->Transform(*transform());
699 gfx::Rect layer_rect;
700 715
701 if (layer()) { 716 PaintCommon(canvas);
702 gfx::Rect dirty_rect;
703 if (!layer_helper_->clip_rect().IsEmpty()) {
704 dirty_rect = layer_helper_->clip_rect();
705 } else {
706 // TODO: clip against dirty rect of canvas (if canvas is non-null).
707 dirty_rect = gfx::Rect(0, 0, width(), height());
708 }
709 if (dirty_rect.IsEmpty())
710 return;
711
712 if (!layer_helper_->bitmap_needs_updating()) {
713 // We don't need to be painted. Iterate over descendants in case one of
714 // them is dirty.
715 PaintToLayer(dirty_rect);
716 return;
717 }
718
719 layer_canvas.reset(gfx::Canvas::CreateCanvas(dirty_rect.width(),
720 dirty_rect.height(), false));
721 layer_canvas->AsCanvasSkia()->drawColor(
722 SK_ColorBLACK, SkXfermode::kClear_Mode);
723 layer_canvas->TranslateInt(-dirty_rect.x(), -dirty_rect.y());
724 canvas = layer_canvas.get();
725 layer_rect = dirty_rect;
726 } else {
727 // We're going to modify the canvas, save its state first.
728 scoped_canvas.SetCanvas(canvas);
729
730 // Paint this View and its children, setting the clip rect to the bounds
731 // of this View and translating the origin to the local bounds' top left
732 // point.
733 //
734 // Note that the X (or left) position we pass to ClipRectInt takes into
735 // consideration whether or not the view uses a right-to-left layout so that
736 // we paint our view in its mirrored position if need be.
737 if (!canvas->ClipRectInt(GetMirroredX(), y(),
738 width() - static_cast<int>(clip_x_),
739 height() - static_cast<int>(clip_y_))) {
740 return;
741 }
742 // Non-empty clip, translate the graphics such that 0,0 corresponds to
743 // where this view is located (related to its parent).
744 canvas->TranslateInt(GetMirroredX(), y());
745
746 if (transform())
747 canvas->Transform(*transform());
748 }
749
750 {
751 // If the View we are about to paint requested the canvas to be flipped, we
752 // should change the transform appropriately.
753 // The canvas mirroring is undone once the View is done painting so that we
754 // don't pass the canvas with the mirrored transform to Views that didn't
755 // request the canvas to be flipped.
756
757 ScopedCanvas scoped(canvas);
758 if (FlipCanvasOnPaintForRTLUI()) {
759 canvas->TranslateInt(width(), 0);
760 canvas->ScaleInt(-1, 1);
761 }
762
763 OnPaint(canvas);
764 }
765
766 PaintChildren(canvas);
767
768 if (layer_canvas.get()) {
769 layer()->SetCanvas(*layer_canvas->AsCanvasSkia(), layer_rect.origin());
770 layer_helper_->set_bitmap_needs_updating(false);
771 }
772 } 717 }
773 718
774 ThemeProvider* View::GetThemeProvider() const { 719 ThemeProvider* View::GetThemeProvider() const {
775 const Widget* widget = GetWidget(); 720 const Widget* widget = GetWidget();
776 return widget ? widget->GetThemeProvider() : NULL; 721 return widget ? widget->GetThemeProvider() : NULL;
777 } 722 }
778 723
779 // Accelerated Painting -------------------------------------------------------- 724 // Accelerated Painting --------------------------------------------------------
780 725
781 // static 726 // static
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 border_->Paint(*this, canvas); 1095 border_->Paint(*this, canvas);
1151 } 1096 }
1152 1097
1153 void View::OnPaintFocusBorder(gfx::Canvas* canvas) { 1098 void View::OnPaintFocusBorder(gfx::Canvas* canvas) {
1154 if ((IsFocusable() || IsAccessibilityFocusableInRootView()) && HasFocus()) 1099 if ((IsFocusable() || IsAccessibilityFocusableInRootView()) && HasFocus())
1155 canvas->DrawFocusRect(0, 0, width(), height()); 1100 canvas->DrawFocusRect(0, 0, width(), height());
1156 } 1101 }
1157 1102
1158 // Accelerated Painting -------------------------------------------------------- 1103 // Accelerated Painting --------------------------------------------------------
1159 1104
1160 void View::PaintComposite() {
1161 if (!IsVisible())
1162 return;
1163
1164 if (layer()) {
1165 OnWillCompositeLayer();
1166 layer()->Draw();
1167 }
1168
1169 for (int i = 0, count = child_count(); i < count; ++i)
1170 child_at(i)->PaintComposite();
1171 }
1172
1173 void View::SchedulePaintInternal(const gfx::Rect& rect) { 1105 void View::SchedulePaintInternal(const gfx::Rect& rect) {
1174 if (parent_ && parent_->IsVisible() && painting_enabled_) { 1106 if (parent_ && parent_->IsVisible() && painting_enabled_) {
1175 // Translate the requested paint rect to the parent's coordinate system 1107 // Translate the requested paint rect to the parent's coordinate system
1176 // then pass this notification up to the parent. 1108 // then pass this notification up to the parent.
1177 parent_->SchedulePaintInternal(ConvertRectToParent(rect)); 1109 parent_->SchedulePaintInternal(ConvertRectToParent(rect));
1178 } 1110 }
1179 } 1111 }
1180 1112
1181 void View::PaintToLayer(const gfx::Rect& dirty_region) {
1182 if (!IsVisible())
1183 return;
1184
1185 if (layer() && layer_helper_->bitmap_needs_updating()) {
1186 if (!layer_helper_->needs_paint_all())
1187 layer_helper_->set_clip_rect(dirty_region);
1188 else
1189 layer_helper_->set_needs_paint_all(false);
1190 Paint(NULL);
1191 layer_helper_->set_clip_rect(gfx::Rect());
1192 } else {
1193 // Forward to all children as a descendant may be dirty and have a layer.
1194 for (int i = child_count() - 1; i >= 0; --i) {
1195 View* child_view = child_at(i);
1196
1197 gfx::Rect child_dirty_rect = dirty_region;
1198 child_dirty_rect.Offset(-child_view->GetMirroredX(), -child_view->y());
1199 child_view->GetTransform().TransformRectReverse(&child_dirty_rect);
1200 child_dirty_rect = gfx::Rect(gfx::Point(), child_view->size()).Intersect(
1201 child_dirty_rect);
1202
1203 if (!child_dirty_rect.IsEmpty())
1204 child_at(i)->PaintToLayer(child_dirty_rect);
1205 }
1206 }
1207 }
1208
1209 void View::OnWillCompositeLayer() {
1210 }
1211
1212 void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { 1113 void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
1213 if (!layer_helper_.get()) 1114 if (!layer_helper_.get())
1214 layer_helper_.reset(new internal::LayerHelper()); 1115 layer_helper_.reset(new internal::LayerHelper());
1215 1116
1216 layer_helper_->set_fills_bounds_opaquely(fills_bounds_opaquely); 1117 layer_helper_->set_fills_bounds_opaquely(fills_bounds_opaquely);
1217 1118
1218 if (layer()) 1119 if (layer())
1219 layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely); 1120 layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely);
1220 } 1121 }
1221 1122
(...skipping 13 matching lines...) Expand all
1235 return false; 1136 return false;
1236 1137
1237 // Child views must not paint into the external texture. So make sure each 1138 // Child views must not paint into the external texture. So make sure each
1238 // child view has its own layer to paint into. 1139 // child view has its own layer to paint into.
1239 if (use_external) { 1140 if (use_external) {
1240 for (Views::iterator i = children_.begin(); i != children_.end(); ++i) 1141 for (Views::iterator i = children_.begin(); i != children_.end(); ++i)
1241 (*i)->SetPaintToLayer(true); 1142 (*i)->SetPaintToLayer(true);
1242 } 1143 }
1243 1144
1244 layer_helper_->set_layer_updated_externally(use_external); 1145 layer_helper_->set_layer_updated_externally(use_external);
1245 layer_helper_->set_bitmap_needs_updating(!use_external);
1246 if (layer()) 1146 if (layer())
1247 layer()->SetTexture(texture); 1147 layer()->SetTexture(texture);
1248 1148
1249 if (IsVisible()) 1149 if (IsVisible())
1250 SchedulePaintInternal(GetLocalBounds()); 1150 SchedulePaintInternal(GetLocalBounds());
1251 1151
1252 return true; 1152 return true;
1253 } 1153 }
1254 1154
1255 const ui::Compositor* View::GetCompositor() const { 1155 const ui::Compositor* View::GetCompositor() const {
1256 return parent_ ? parent_->GetCompositor() : NULL; 1156 return parent_ ? parent_->GetCompositor() : NULL;
1257 } 1157 }
1258 1158
1259 ui::Compositor* View::GetCompositor() { 1159 ui::Compositor* View::GetCompositor() {
1260 return parent_ ? parent_->GetCompositor() : NULL; 1160 return parent_ ? parent_->GetCompositor() : NULL;
1261 } 1161 }
1262 1162
1263 void View::MarkLayerDirty() { 1163 void View::MarkLayerDirty() {
1264 if (!use_acceleration_when_possible) 1164 if (!use_acceleration_when_possible)
1265 return; 1165 return;
1266 1166
1267 if (ShouldPaintToLayer()) { 1167 if (ShouldPaintToLayer())
1268 if (!layer_helper_->layer_updated_externally())
1269 layer_helper_->set_bitmap_needs_updating(true);
1270 return; 1168 return;
1271 }
1272 if (parent_) 1169 if (parent_)
1273 parent_->MarkLayerDirty(); 1170 parent_->MarkLayerDirty();
1274 } 1171 }
1275 1172
1276 void View::CalculateOffsetToAncestorWithLayer(gfx::Point* offset, 1173 void View::CalculateOffsetToAncestorWithLayer(gfx::Point* offset,
1277 View** ancestor) { 1174 ui::Layer** layer_parent) {
1278 if (layer()) { 1175 if (layer()) {
1279 if (ancestor) 1176 if (layer_parent)
1280 *ancestor = this; 1177 *layer_parent = layer();
1281 return; 1178 return;
1282 } 1179 }
1283 if (!parent_) 1180 if (!parent_)
1284 return; 1181 return;
1285 1182
1286 offset->Offset(x(), y()); 1183 offset->Offset(x(), y());
1287 parent_->CalculateOffsetToAncestorWithLayer(offset, ancestor); 1184 parent_->CalculateOffsetToAncestorWithLayer(offset, layer_parent);
1288 } 1185 }
1289 1186
1290 void View::CreateLayerIfNecessary() { 1187 void View::CreateLayerIfNecessary() {
1291 if (ShouldPaintToLayer()) 1188 if (ShouldPaintToLayer())
1292 CreateLayer(); 1189 CreateLayer();
1293 1190
1294 for (int i = 0, count = child_count(); i < count; ++i) 1191 for (int i = 0, count = child_count(); i < count; ++i)
1295 child_at(i)->CreateLayerIfNecessary(); 1192 child_at(i)->CreateLayerIfNecessary();
1296 } 1193 }
1297 1194
(...skipping 23 matching lines...) Expand all
1321 layer_helper_->property_setter()->SetBounds( 1218 layer_helper_->property_setter()->SetBounds(
1322 layer(), 1219 layer(),
1323 gfx::Rect(offset.x() + x(), offset.y() + y(), width(), height())); 1220 gfx::Rect(offset.x() + x(), offset.y() + y(), width(), height()));
1324 } else { 1221 } else {
1325 gfx::Point new_offset(offset.x() + x(), offset.y() + y()); 1222 gfx::Point new_offset(offset.x() + x(), offset.y() + y());
1326 for (int i = 0, count = child_count(); i < count; ++i) 1223 for (int i = 0, count = child_count(); i < count; ++i)
1327 child_at(i)->UpdateLayerBounds(new_offset); 1224 child_at(i)->UpdateLayerBounds(new_offset);
1328 } 1225 }
1329 } 1226 }
1330 1227
1228 void View::OnPaintLayer(gfx::Canvas* canvas) {
1229 canvas->AsCanvasSkia()->drawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
sky 2011/09/13 17:47:06 We should ignore this if layer_helper_->layer_upda
1230 PaintCommon(canvas);
1231 }
1232
1331 // Input ----------------------------------------------------------------------- 1233 // Input -----------------------------------------------------------------------
1332 1234
1333 bool View::HasHitTestMask() const { 1235 bool View::HasHitTestMask() const {
1334 return false; 1236 return false;
1335 } 1237 }
1336 1238
1337 void View::GetHitTestMask(gfx::Path* mask) const { 1239 void View::GetHitTestMask(gfx::Path* mask) const {
1338 DCHECK(mask); 1240 DCHECK(mask);
1339 } 1241 }
1340 1242
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1434 // If only the positions changes and we have a layer, we don't need to mark 1336 // If only the positions changes and we have a layer, we don't need to mark
1435 // the layer as dirty (which SchedulePaint does), only paint the bounds. 1337 // the layer as dirty (which SchedulePaint does), only paint the bounds.
1436 SchedulePaintInternal(gfx::Rect(0, 0, width(), height())); 1338 SchedulePaintInternal(gfx::Rect(0, 0, width(), height()));
1437 } else { 1339 } else {
1438 // If the size changes, or we don't have a layer then we need to use 1340 // If the size changes, or we don't have a layer then we need to use
1439 // SchedulePaint to make sure the layer is marked as dirty. 1341 // SchedulePaint to make sure the layer is marked as dirty.
1440 SchedulePaint(); 1342 SchedulePaint();
1441 } 1343 }
1442 } 1344 }
1443 1345
1346 void View::PaintCommon(gfx::Canvas* canvas) {
1347 if (!IsVisible() || !painting_enabled_)
1348 return;
1349
1350 {
1351 // If the View we are about to paint requested the canvas to be flipped, we
1352 // should change the transform appropriately.
1353 // The canvas mirroring is undone once the View is done painting so that we
1354 // don't pass the canvas with the mirrored transform to Views that didn't
1355 // request the canvas to be flipped.
1356 ScopedCanvas scoped(canvas);
1357 if (FlipCanvasOnPaintForRTLUI()) {
1358 canvas->TranslateInt(width(), 0);
1359 canvas->ScaleInt(-1, 1);
1360 }
1361
1362 OnPaint(canvas);
1363 }
1364
1365 PaintChildren(canvas);
1366 }
1367
1444 // Tree operations ------------------------------------------------------------- 1368 // Tree operations -------------------------------------------------------------
1445 1369
1446 void View::DoRemoveChildView(View* view, 1370 void View::DoRemoveChildView(View* view,
1447 bool update_focus_cycle, 1371 bool update_focus_cycle,
1448 bool update_tool_tip, 1372 bool update_tool_tip,
1449 bool delete_removed_view) { 1373 bool delete_removed_view) {
1450 DCHECK(view); 1374 DCHECK(view);
1451 const Views::iterator i(std::find(children_.begin(), children_.end(), view)); 1375 const Views::iterator i(std::find(children_.begin(), children_.end(), view));
1452 scoped_ptr<View> view_to_be_deleted; 1376 scoped_ptr<View> view_to_be_deleted;
1453 if (i != children_.end()) { 1377 if (i != children_.end()) {
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 void View::CreateLayer() { 1675 void View::CreateLayer() {
1752 if (!ShouldPaintToLayer() || layer()) 1676 if (!ShouldPaintToLayer() || layer())
1753 return; 1677 return;
1754 1678
1755 ui::Compositor* compositor = GetCompositor(); 1679 ui::Compositor* compositor = GetCompositor();
1756 if (!compositor) 1680 if (!compositor)
1757 return; 1681 return;
1758 1682
1759 DCHECK(layer_helper_.get()); 1683 DCHECK(layer_helper_.get());
1760 1684
1761 View* ancestor_with_layer = NULL; 1685 ui::Layer* layer_parent = NULL;
1762 gfx::Point offset; 1686 gfx::Point offset;
1763 CalculateOffsetToAncestorWithLayer(&offset, &ancestor_with_layer); 1687 CalculateOffsetToAncestorWithLayer(&offset, &layer_parent);
1764 1688
1765 DCHECK(ancestor_with_layer || parent_ == NULL); 1689 DCHECK(layer_parent || parent_ == NULL);
1766 1690
1767 layer_helper_->SetLayer(new ui::Layer(compositor)); 1691 layer_helper_->SetLayer(new ui::Layer(compositor));
1692 layer()->set_delegate(this);
1768 layer()->SetFillsBoundsOpaquely(layer_helper_->fills_bounds_opaquely()); 1693 layer()->SetFillsBoundsOpaquely(layer_helper_->fills_bounds_opaquely());
1769 layer()->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height())); 1694 layer()->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
1770 layer()->SetTransform(GetTransform()); 1695 layer()->SetTransform(GetTransform());
1771 if (ancestor_with_layer) 1696 if (layer_parent)
1772 ancestor_with_layer->layer()->Add(layer()); 1697 layer_parent->Add(layer());
1773 layer_helper_->set_bitmap_needs_updating(true);
1774 layer_helper_->set_needs_paint_all(true); 1698 layer_helper_->set_needs_paint_all(true);
sky 2011/09/13 17:47:06 It seems like this should somehow be combined with
1775 1699
1776 MoveLayerToParent(layer(), gfx::Point()); 1700 MoveLayerToParent(layer(), gfx::Point());
1777 } 1701 }
1778 1702
1779 void View::DestroyLayerAndReparent() { 1703 void View::DestroyLayerAndReparent() {
1780 if (!layer()) 1704 if (!layer())
1781 return; 1705 return;
1782 1706
1783 ui::Layer* new_parent = layer()->parent(); 1707 ui::Layer* new_parent = layer()->parent();
1784 std::vector<ui::Layer*> children = layer()->children(); 1708 std::vector<ui::Layer*> children = layer()->children();
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 result.append(child_at(i)->PrintViewGraph(false)); 1990 result.append(child_at(i)->PrintViewGraph(false));
2067 1991
2068 if (first) 1992 if (first)
2069 result.append("}\n"); 1993 result.append("}\n");
2070 1994
2071 return result; 1995 return result;
2072 } 1996 }
2073 #endif 1997 #endif
2074 1998
2075 } // namespace views 1999 } // namespace views
OLDNEW
« ui/gfx/compositor/layer.cc ('K') | « views/view.h ('k') | views/view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698