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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « views/view.h ('k') | views/view_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: views/view.cc
===================================================================
--- views/view.cc (revision 100773)
+++ views/view.cc (working copy)
@@ -186,8 +186,6 @@
if (layout_manager_.get())
layout_manager_->ViewAdded(this, view);
-
- view->MarkLayerDirty();
}
void View::ReorderChildView(View* view, int index) {
@@ -370,7 +368,7 @@
void View::SetVisible(bool visible) {
if (visible != visible_) {
- // If the tab is currently visible, schedule paint to refresh parent.
+ // If the View is currently visible, schedule paint to refresh parent.
if (visible_)
SchedulePaint();
@@ -379,7 +377,7 @@
if (visible_)
CreateLayerIfNecessary();
else
- // Destroy layer if tab is invisible as invisible tabs never paint
+ // Destroy layer if the View is invisible as invisible Views never paint.
DestroyLayerRecurse();
// This notifies all sub-views recursively.
@@ -434,11 +432,6 @@
SchedulePaint();
} else {
- // Make sure if the view didn't have its own texture and was painting onto
- // something else, that gets refreshed too.
- if (!ShouldPaintToLayer())
- MarkLayerDirty();
-
if (!layer_helper_.get())
layer_helper_.reset(new internal::LayerHelper());
layer_helper_->SetTransform(transform);
@@ -685,90 +678,40 @@
if (!IsVisible() || !painting_enabled_)
return;
- MarkLayerDirty();
- SchedulePaintInternal(rect);
+ if (layer()) {
+ layer()->SchedulePaint(rect);
+ } else if (parent_) {
+ // Translate the requested paint rect to the parent's coordinate system
+ // then pass this notification up to the parent.
+ parent_->SchedulePaintInRect(ConvertRectToParent(rect));
+ }
}
void View::Paint(gfx::Canvas* canvas) {
TRACE_EVENT0("View", "Paint");
- if (!IsVisible() || !painting_enabled_)
- return;
- ScopedCanvas scoped_canvas(NULL);
- scoped_ptr<gfx::Canvas> layer_canvas;
- gfx::Rect layer_rect;
+ ScopedCanvas scoped_canvas(canvas);
- if (layer()) {
- gfx::Rect dirty_rect;
- if (!layer_helper_->clip_rect().IsEmpty()) {
- dirty_rect = layer_helper_->clip_rect();
- } else {
- // TODO: clip against dirty rect of canvas (if canvas is non-null).
- dirty_rect = gfx::Rect(0, 0, width(), height());
- }
- if (dirty_rect.IsEmpty())
- return;
-
- if (!layer_helper_->bitmap_needs_updating()) {
- // We don't need to be painted. Iterate over descendants in case one of
- // them is dirty.
- PaintToLayer(dirty_rect);
- return;
- }
-
- layer_canvas.reset(gfx::Canvas::CreateCanvas(dirty_rect.width(),
- dirty_rect.height(), false));
- layer_canvas->AsCanvasSkia()->drawColor(
- SK_ColorBLACK, SkXfermode::kClear_Mode);
- layer_canvas->TranslateInt(-dirty_rect.x(), -dirty_rect.y());
- canvas = layer_canvas.get();
- layer_rect = dirty_rect;
- } else {
- // We're going to modify the canvas, save its state first.
- scoped_canvas.SetCanvas(canvas);
-
- // Paint this View and its children, setting the clip rect to the bounds
- // of this View and translating the origin to the local bounds' top left
- // point.
- //
- // Note that the X (or left) position we pass to ClipRectInt takes into
- // consideration whether or not the view uses a right-to-left layout so that
- // we paint our view in its mirrored position if need be.
- if (!canvas->ClipRectInt(GetMirroredX(), y(),
- width() - static_cast<int>(clip_x_),
- height() - static_cast<int>(clip_y_))) {
- return;
- }
- // Non-empty clip, translate the graphics such that 0,0 corresponds to
- // where this view is located (related to its parent).
- canvas->TranslateInt(GetMirroredX(), y());
-
- if (transform())
- canvas->Transform(*transform());
+ // Paint this View and its children, setting the clip rect to the bounds
+ // of this View and translating the origin to the local bounds' top left
+ // point.
+ //
+ // Note that the X (or left) position we pass to ClipRectInt takes into
+ // consideration whether or not the view uses a right-to-left layout so that
+ // we paint our view in its mirrored position if need be.
+ if (!canvas->ClipRectInt(GetMirroredX(), y(),
+ width() - static_cast<int>(clip_x_),
+ height() - static_cast<int>(clip_y_))) {
+ return;
}
+ // Non-empty clip, translate the graphics such that 0,0 corresponds to
+ // where this view is located (related to its parent).
+ canvas->TranslateInt(GetMirroredX(), y());
- {
- // If the View we are about to paint requested the canvas to be flipped, we
- // should change the transform appropriately.
- // The canvas mirroring is undone once the View is done painting so that we
- // don't pass the canvas with the mirrored transform to Views that didn't
- // request the canvas to be flipped.
+ if (transform())
+ canvas->Transform(*transform());
- ScopedCanvas scoped(canvas);
- if (FlipCanvasOnPaintForRTLUI()) {
- canvas->TranslateInt(width(), 0);
- canvas->ScaleInt(-1, 1);
- }
-
- OnPaint(canvas);
- }
-
- PaintChildren(canvas);
-
- if (layer_canvas.get()) {
- layer()->SetCanvas(*layer_canvas->AsCanvasSkia(), layer_rect.origin());
- layer_helper_->set_bitmap_needs_updating(false);
- }
+ PaintCommon(canvas);
}
ThemeProvider* View::GetThemeProvider() const {
@@ -1157,58 +1100,6 @@
// Accelerated Painting --------------------------------------------------------
-void View::PaintComposite() {
- if (!IsVisible())
- return;
-
- if (layer()) {
- OnWillCompositeLayer();
- layer()->Draw();
- }
-
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->PaintComposite();
-}
-
-void View::SchedulePaintInternal(const gfx::Rect& rect) {
- if (parent_ && parent_->IsVisible() && painting_enabled_) {
- // Translate the requested paint rect to the parent's coordinate system
- // then pass this notification up to the parent.
- parent_->SchedulePaintInternal(ConvertRectToParent(rect));
- }
-}
-
-void View::PaintToLayer(const gfx::Rect& dirty_region) {
- if (!IsVisible())
- return;
-
- if (layer() && layer_helper_->bitmap_needs_updating()) {
- if (!layer_helper_->needs_paint_all())
- layer_helper_->set_clip_rect(dirty_region);
- else
- layer_helper_->set_needs_paint_all(false);
- Paint(NULL);
- layer_helper_->set_clip_rect(gfx::Rect());
- } else {
- // Forward to all children as a descendant may be dirty and have a layer.
- for (int i = child_count() - 1; i >= 0; --i) {
- View* child_view = child_at(i);
-
- gfx::Rect child_dirty_rect = dirty_region;
- child_dirty_rect.Offset(-child_view->GetMirroredX(), -child_view->y());
- child_view->GetTransform().TransformRectReverse(&child_dirty_rect);
- child_dirty_rect = gfx::Rect(gfx::Point(), child_view->size()).Intersect(
- child_dirty_rect);
-
- if (!child_dirty_rect.IsEmpty())
- child_at(i)->PaintToLayer(child_dirty_rect);
- }
- }
-}
-
-void View::OnWillCompositeLayer() {
-}
-
void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
if (!layer_helper_.get())
layer_helper_.reset(new internal::LayerHelper());
@@ -1242,12 +1133,10 @@
}
layer_helper_->set_layer_updated_externally(use_external);
- layer_helper_->set_bitmap_needs_updating(!use_external);
if (layer())
layer()->SetTexture(texture);
- if (IsVisible())
- SchedulePaintInternal(GetLocalBounds());
+ SchedulePaintInRect(GetLocalBounds());
return true;
}
@@ -1260,31 +1149,18 @@
return parent_ ? parent_->GetCompositor() : NULL;
}
-void View::MarkLayerDirty() {
- if (!use_acceleration_when_possible)
- return;
-
- if (ShouldPaintToLayer()) {
- if (!layer_helper_->layer_updated_externally())
- layer_helper_->set_bitmap_needs_updating(true);
- return;
- }
- if (parent_)
- parent_->MarkLayerDirty();
-}
-
void View::CalculateOffsetToAncestorWithLayer(gfx::Point* offset,
- View** ancestor) {
+ ui::Layer** layer_parent) {
if (layer()) {
- if (ancestor)
- *ancestor = this;
+ if (layer_parent)
+ *layer_parent = layer();
return;
}
if (!parent_)
return;
offset->Offset(x(), y());
- parent_->CalculateOffsetToAncestorWithLayer(offset, ancestor);
+ parent_->CalculateOffsetToAncestorWithLayer(offset, layer_parent);
}
void View::CreateLayerIfNecessary() {
@@ -1328,6 +1204,15 @@
}
}
+void View::OnPaintLayer(gfx::Canvas* canvas) {
+ // If someone else is directly providing our Layer's texture, we should not
+ // do any rendering.
+ if (layer_helper_->layer_updated_externally())
+ return;
+ canvas->AsCanvasSkia()->drawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
+ PaintCommon(canvas);
+}
+
// Input -----------------------------------------------------------------------
bool View::HasHitTestMask() const {
@@ -1430,17 +1315,38 @@
// Painting --------------------------------------------------------------------
void View::SchedulePaintBoundsChanged(SchedulePaintType type) {
- if (layer() && type == SCHEDULE_PAINT_SIZE_SAME) {
- // If only the positions changes and we have a layer, we don't need to mark
- // the layer as dirty (which SchedulePaint does), only paint the bounds.
- SchedulePaintInternal(gfx::Rect(0, 0, width(), height()));
- } else {
- // If the size changes, or we don't have a layer then we need to use
- // SchedulePaint to make sure the layer is marked as dirty.
+ // If we have a layer and the View's size did not change, we do not need to
+ // schedule any paints since the layer will be redrawn at its new location
+ // during the next Draw() cycle in the compositor.
+ if (!layer() || type == SCHEDULE_PAINT_SIZE_CHANGED) {
+ // Otherwise, if the size changes or we don't have a layer then we need to
+ // use SchedulePaint to invalidate the area occupied by the View.
SchedulePaint();
}
}
+void View::PaintCommon(gfx::Canvas* canvas) {
+ if (!IsVisible() || !painting_enabled_)
+ return;
+
+ {
+ // If the View we are about to paint requested the canvas to be flipped, we
+ // should change the transform appropriately.
+ // The canvas mirroring is undone once the View is done painting so that we
+ // don't pass the canvas with the mirrored transform to Views that didn't
+ // request the canvas to be flipped.
+ ScopedCanvas scoped(canvas);
+ if (FlipCanvasOnPaintForRTLUI()) {
+ canvas->TranslateInt(width(), 0);
+ canvas->ScaleInt(-1, 1);
+ }
+
+ OnPaint(canvas);
+ }
+
+ PaintChildren(canvas);
+}
+
// Tree operations -------------------------------------------------------------
void View::DoRemoveChildView(View* view,
@@ -1567,7 +1473,7 @@
!layer_helper_->layer_updated_externally()) {
// If our bounds have changed then we need to update the complete
// texture.
- layer_helper_->set_needs_paint_all(true);
+ layer()->SchedulePaint(GetLocalBounds());
}
} else if (GetCompositor()) {
// If our bounds have changed, then any descendant layer bounds may
@@ -1758,20 +1664,20 @@
DCHECK(layer_helper_.get());
- View* ancestor_with_layer = NULL;
+ ui::Layer* layer_parent = NULL;
gfx::Point offset;
- CalculateOffsetToAncestorWithLayer(&offset, &ancestor_with_layer);
+ CalculateOffsetToAncestorWithLayer(&offset, &layer_parent);
- DCHECK(ancestor_with_layer || parent_ == NULL);
+ DCHECK(layer_parent || parent_ == NULL);
layer_helper_->SetLayer(new ui::Layer(compositor));
+ layer()->set_delegate(this);
layer()->SetFillsBoundsOpaquely(layer_helper_->fills_bounds_opaquely());
layer()->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
layer()->SetTransform(GetTransform());
- if (ancestor_with_layer)
- ancestor_with_layer->layer()->Add(layer());
- layer_helper_->set_bitmap_needs_updating(true);
- layer_helper_->set_needs_paint_all(true);
+ if (layer_parent)
+ layer_parent->Add(layer());
+ layer()->SchedulePaint(GetLocalBounds());
MoveLayerToParent(layer(), gfx::Point());
}
« no previous file with comments | « views/view.h ('k') | views/view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698