summaryrefslogtreecommitdiffstats
path: root/views/view.cc
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-10 18:26:25 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-10 18:26:25 +0000
commitc36b0bfba80a88ce3776739575a1103235c409d1 (patch)
treed37790e560bff4136f3c723c95c645abec7caf76 /views/view.cc
parent5b37cb72a5bfbcc1daa57249319a8235d0d4874a (diff)
downloadchromium_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.cc131
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) {