diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-10 18:26:25 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-10 18:26:25 +0000 |
commit | c36b0bfba80a88ce3776739575a1103235c409d1 (patch) | |
tree | d37790e560bff4136f3c723c95c645abec7caf76 /views/view.cc | |
parent | 5b37cb72a5bfbcc1daa57249319a8235d0d4874a (diff) | |
download | chromium_src-c36b0bfba80a88ce3776739575a1103235c409d1.zip chromium_src-c36b0bfba80a88ce3776739575a1103235c409d1.tar.gz chromium_src-c36b0bfba80a88ce3776739575a1103235c409d1.tar.bz2 |
Tweaks Compositor API. To make it possible to land this I've ifdef'd
the code in a couple of places.
BUG=none
TEST=none
R=ben@chromium.org,wjmaclean@chromium.org,rjkroege@chromium.org
Review URL: http://codereview.chromium.org/6999005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84823 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/view.cc')
-rw-r--r-- | views/view.cc | 131 |
1 files changed, 128 insertions, 3 deletions
diff --git a/views/view.cc b/views/view.cc index 12fbf45..52234d7 100644 --- a/views/view.cc +++ b/views/view.cc @@ -107,7 +107,10 @@ View::View() clip_y_(0.0), needs_layout_(true), flip_canvas_on_paint_for_rtl_ui_(false), +#if !defined(COMPOSITOR_2) texture_id_(0), // TODO(sadrul): 0 can be a valid texture id. +#endif + texture_needs_updating_(true), accelerator_registration_delayed_(false), accelerator_focus_manager_(NULL), registered_accelerator_count_(0), @@ -363,6 +366,8 @@ void View::SetVisible(bool flag) { // refresh parent if (IsVisible()) SchedulePaint(); + else + ResetTexture(); is_visible_ = flag; @@ -456,7 +461,11 @@ void View::ConcatTranslate(float x, float y) { void View::ResetTransform() { transform_.reset(NULL); clip_x_ = clip_y_ = 0.0; +#if !defined(COMPOSITOR_2) canvas_.reset(); +#else + texture_.reset(); +#endif } @@ -671,13 +680,43 @@ void View::Paint(gfx::Canvas* canvas) { return; ScopedCanvas scoped_canvas(NULL); + scoped_ptr<gfx::Canvas> texture_canvas; + gfx::Rect texture_rect; + +#if !defined(COMPOSITOR_2) if (use_acceleration_when_possible && transform_.get() && transform_->HasChange()) { // This view has a transformation. So this maintains its own canvas. if (!canvas_.get()) canvas_.reset(gfx::Canvas::CreateCanvas(width(), height(), false)); +#else + if (ShouldPaintToTexture()) { + gfx::Rect dirty_rect; + if (!texture_clip_rect_.IsEmpty()) { + dirty_rect = texture_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 (!texture_.get()) + texture_.reset(GetCompositor()->CreateTexture()); + + if (!texture_needs_updating_) { + // We don't need to be painted. Iterate over descendants in case one of + // them is dirty. + PaintToTexture(dirty_rect); + return; + } - canvas = canvas_.get(); + texture_canvas.reset(gfx::Canvas::CreateCanvas(dirty_rect.width(), + dirty_rect.height(), false)); + texture_canvas->TranslateInt(-dirty_rect.x(), -dirty_rect.y()); + canvas = texture_canvas.get(); + // TODO: set texture_needs_updating_ to false. +#endif } else { // We're going to modify the canvas, save its state first. scoped_canvas.SetCanvas(canvas); @@ -690,8 +729,8 @@ void View::Paint(gfx::Canvas* canvas) { // 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_))) { + 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 @@ -720,11 +759,20 @@ void View::Paint(gfx::Canvas* canvas) { PaintChildren(canvas); +#if !defined(COMPOSITOR_2) if (canvas == canvas_.get()) { texture_id_ = canvas->GetTextureID(); // TODO(sadrul): Make sure the Widget's compositor tree updates itself? } +#else + if (texture_canvas.get()) { + texture_->SetBitmap( + texture_canvas->AsCanvasSkia()->getDevice()->accessBitmap(false), + texture_rect.origin(), + size()); + } +#endif } ThemeProvider* View::GetThemeProvider() const { @@ -1133,6 +1181,7 @@ void View::OnPaintFocusBorder(gfx::Canvas* canvas) { // Accelerated Painting -------------------------------------------------------- +#if !defined(COMPOSITOR_2) void View::PaintComposite(ui::Compositor* compositor) { compositor->SaveTransform(); @@ -1147,6 +1196,56 @@ void View::PaintComposite(ui::Compositor* compositor) { compositor->RestoreTransform(); } +#else +void View::PaintComposite() { + if (!IsVisible()) + return; + + if (texture_.get()) { + // TODO: if dirty_region doesn't itersect bounds, return. + scoped_ptr<ui::Transform> transform(ui::Transform::Create()); + GetTransformRelativeToRoot(transform.get()); + texture_->Draw(*transform); + } + + for (int i = 0, count = child_count(); i < count; ++i) + GetChildViewAt(i)->PaintComposite(); +} + +void View::PaintToTexture(const gfx::Rect& dirty_region) { + if (!IsVisible()) + return; + + if (ShouldPaintToTexture() && texture_needs_updating_) { + texture_clip_rect_ = dirty_region; + Paint(NULL); + texture_clip_rect_.SetRect(0, 0, 0, 0); + } else { + // Forward to all children as a descendant may be dirty and have a texture. + for (int i = child_count() - 1; i >= 0; --i) { + View* child_view = GetChildViewAt(i); + gfx::Rect child_dirty_rect(child_view->bounds().Intersect(dirty_region)); + if (!child_dirty_rect.IsEmpty()) { + child_dirty_rect.Offset(-child_view->x(), -child_view->y()); + GetChildViewAt(i)->PaintToTexture(child_dirty_rect); + } + } + } +} +#endif + +bool View::ShouldPaintToTexture() const { + return use_acceleration_when_possible && transform_.get() && + transform_->HasChange() && GetCompositor(); +} + +const ui::Compositor* View::GetCompositor() const { + return parent_ ? parent_->GetCompositor() : NULL; +} + +ui::Compositor* View::GetCompositor() { + return parent_ ? parent_->GetCompositor() : NULL; +} // Input ----------------------------------------------------------------------- @@ -1266,6 +1365,7 @@ void View::DoRemoveChildView(View* view, if (GetWidget()) UnregisterChildrenForVisibleBoundsNotification(view); + view->ResetTexture(); view->PropagateRemoveNotifications(this); view->SetParent(NULL); @@ -1353,8 +1453,10 @@ void View::VisibilityChangedImpl(View* starting_from, bool is_visible) { } void View::BoundsChanged(const gfx::Rect& previous_bounds) { +#if !defined(COMPOSITOR_2) if (canvas_.get()) canvas_.reset(gfx::Canvas::CreateCanvas(width(), height(), false)); +#endif if (IsVisible()) { if (parent_) { @@ -1461,6 +1563,19 @@ void View::InitTransform() { transform_.reset(ui::Transform::Create()); } +void View::GetTransformRelativeToRoot(ui::Transform* transform) { + // TODO: the direction of transformation is likely wrong here. + if (parent_) { + parent_->GetTransformRelativeToRoot(transform); + } else if (transform_.get()) { + transform->Copy(*transform_); + } + transform->ConcatTranslate(static_cast<float>(GetMirroredX()), + static_cast<float>(y())); + if (transform_.get()) + transform->ConcatTransform(*transform_); +} + // Coordinate conversion ------------------------------------------------------- // static @@ -1535,6 +1650,16 @@ bool View::ConvertPointFromAncestor(const View* ancestor, return v == ancestor; } +// Accelerated painting -------------------------------------------------------- + +void View::ResetTexture() { +#if defined(COMPOSITOR_2) + texture_.reset(); + for (int i = child_count() - 1; i >= 0; --i) + GetChildViewAt(i)->ResetTexture(); +#endif +} + // Input ----------------------------------------------------------------------- bool View::ProcessMousePressed(const MouseEvent& event, DragInfo* drag_info) { |