diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-15 02:18:36 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-15 02:18:36 +0000 |
commit | c797cd43680b525ea771dc226ca353078c5c56f1 (patch) | |
tree | a172b53773aec97a6c3dd9c4fcf93acc27d0cca2 /views/view.cc | |
parent | 8df9747bff840d1a63b9fe1309b18e5fb21e8340 (diff) | |
download | chromium_src-c797cd43680b525ea771dc226ca353078c5c56f1.zip chromium_src-c797cd43680b525ea771dc226ca353078c5c56f1.tar.gz chromium_src-c797cd43680b525ea771dc226ca353078c5c56f1.tar.bz2 |
Start working on compositor tree painting.
As a first step, maintain a skia canvas in each transformed view. Each
transformed view will acquire a texture-id for the canvas it owns. Whenever the
canvas is updated, it will trigger a refresh in the compositor tree.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6594125
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78149 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/view.cc')
-rw-r--r-- | views/view.cc | 109 |
1 files changed, 81 insertions, 28 deletions
diff --git a/views/view.cc b/views/view.cc index 0547efb7..f048892 100644 --- a/views/view.cc +++ b/views/view.cc @@ -14,6 +14,7 @@ #include "ui/base/accessibility/accessibility_types.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/gfx/canvas_skia.h" +#include "ui/gfx/compositor.h" #include "ui/gfx/path.h" #include "ui/gfx/transform.h" #include "views/background.h" @@ -33,6 +34,12 @@ #include "ui/base/gtk/scoped_handle_gtk.h" #endif +namespace { +// Whether to use accelerated compositing when necessary (e.g. when a view has a +// transformation). +bool use_acceleration_when_possible = true; +} + namespace views { // static @@ -75,6 +82,7 @@ View::View() clip_y_(0.0), needs_layout_(true), flip_canvas_on_paint_for_rtl_ui_(false), + texture_id_(0), // TODO(sadrul): 0 can be a valid texture id. accelerator_registration_delayed_(false), accelerator_focus_manager_(NULL), registered_accelerator_count_(0), @@ -423,6 +431,7 @@ void View::ConcatTranslate(float x, float y) { void View::ResetTransform() { transform_.reset(NULL); clip_x_ = clip_y_ = 0.0; + canvas_.reset(); } @@ -636,46 +645,63 @@ void View::Paint(gfx::Canvas* canvas) { if (!IsVisible()) return; - // We're going to modify the canvas, save its state first. - canvas->Save(); + 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)); - // 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_))) { + canvas = canvas_.get(); + } else { + // We're going to modify the canvas, save its state first. + canvas->Save(); + + // 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_))) { + canvas->Restore(); + 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_.get() && transform_->HasChange()) canvas->Transform(*transform_.get()); + } - // If the View we are about to paint requested the canvas to be flipped, we - // should change the transform appropriately. - canvas->Save(); - if (FlipCanvasOnPaintForRTLUI()) { - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } + // If the View we are about to paint requested the canvas to be flipped, we + // should change the transform appropriately. + canvas->Save(); + if (FlipCanvasOnPaintForRTLUI()) { + canvas->TranslateInt(width(), 0); + canvas->ScaleInt(-1, 1); + } - OnPaint(canvas); + OnPaint(canvas); - // We must undo the canvas mirroring 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. - canvas->Restore(); + // We must undo the canvas mirroring 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. + canvas->Restore(); - PaintChildren(canvas); - } + PaintChildren(canvas); - // Restore the canvas's original transform. - canvas->Restore(); + if (canvas == canvas_.get()) { + texture_id_ = canvas->GetTextureID(); + + // TODO(sadrul): Make sure the Widget's compositor tree updates itself? + } else { + // Restore the canvas's original transform. + canvas->Restore(); + } } void View::PaintNow() { @@ -693,6 +719,13 @@ ThemeProvider* View::GetThemeProvider() const { return widget ? widget->GetThemeProvider() : NULL; } +// Accelerated Painting -------------------------------------------------------- + +// static +void View::set_use_acceleration_when_possible(bool use) { + use_acceleration_when_possible = use; +} + // Input ----------------------------------------------------------------------- View* View::GetEventHandlerForPoint(const gfx::Point& point) { @@ -1069,6 +1102,23 @@ void View::OnPaintFocusBorder(gfx::Canvas* canvas) { canvas->DrawFocusRect(0, 0, width(), height()); } +// Accelerated Painting -------------------------------------------------------- + +void View::PaintComposite(ui::Compositor* compositor) { + compositor->SaveTransform(); + + // TODO(sad): Push a transform matrix for the offset and bounds of the view? + if (texture_id_) + compositor->DrawTextureWithTransform(texture_id_, GetTransform()); + + for (int i = 0, count = child_count(); i < count; ++i) { + View* child = GetChildViewAt(i); + child->PaintComposite(compositor); + } + + compositor->RestoreTransform(); +} + // Input ----------------------------------------------------------------------- bool View::HasHitTestMask() const { @@ -1274,6 +1324,9 @@ void View::VisibilityChangedImpl(View* starting_from, bool is_visible) { } void View::BoundsChanged(const gfx::Rect& previous_bounds) { + if (canvas_.get()) + canvas_.reset(gfx::Canvas::CreateCanvas(width(), height(), false)); + if (parent_) { parent_->SchedulePaintInRect(previous_bounds); parent_->SchedulePaintInRect(bounds_); |