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 | |
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
-rw-r--r-- | chrome/chrome_dll.gypi | 1 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor.gyp | 22 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor.h | 57 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.cc | 53 | ||||
-rw-r--r-- | views/view.cc | 131 | ||||
-rw-r--r-- | views/view.h | 44 | ||||
-rw-r--r-- | views/views.gyp | 1 | ||||
-rw-r--r-- | views/widget/native_widget_delegate.h | 5 | ||||
-rw-r--r-- | views/widget/root_view.cc | 12 | ||||
-rw-r--r-- | views/widget/root_view.h | 3 | ||||
-rw-r--r-- | views/widget/widget.cc | 40 | ||||
-rw-r--r-- | views/widget/widget.h | 14 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 21 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 18 |
14 files changed, 381 insertions, 41 deletions
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 8381331..930acae 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -119,6 +119,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', + '<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_chromium_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_resources.rc', diff --git a/ui/gfx/compositor/compositor.gyp b/ui/gfx/compositor/compositor.gyp index f739b93..98adcf8 100644 --- a/ui/gfx/compositor/compositor.gyp +++ b/ui/gfx/compositor/compositor.gyp @@ -3,6 +3,19 @@ # found in the LICENSE file. { + 'target_defaults': { + 'sources/': [ + ['exclude', '_(gl|win)\\.(cc?)$'], + ], + 'conditions': [ + ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {'sources/': [ + ['include', '_(gl)\\.cc$'], + ]}], + ['OS=="win"', {'sources/': [ + ['include', '_(win)\\.cc$'], + ]}], + ], + }, 'targets': [ { 'target_name': 'compositor', @@ -10,25 +23,22 @@ 'msvs_guid': '21CEE0E3-6F4E-4F01-B8C9-F7751CC21AA9', 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/ui/gfx/gl/gl.gyp:gl', '<(DEPTH)/ui/ui.gyp:ui_gfx', ], 'sources': [ 'compositor.cc', - 'compositor_gl.cc', 'compositor.h', + 'compositor_gl.cc', ], 'conditions': [ ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', { 'sources!': [ 'compositor.cc', ], - }, { - 'sources!': [ - 'compositor_gl.cc', - ] }], ], }, ], -}
\ No newline at end of file +} diff --git a/ui/gfx/compositor/compositor.h b/ui/gfx/compositor/compositor.h index 7d19598..9b35eb1 100644 --- a/ui/gfx/compositor/compositor.h +++ b/ui/gfx/compositor/compositor.h @@ -9,9 +9,16 @@ #include "base/memory/ref_counted.h" #include "ui/gfx/native_widget_types.h" +class SkBitmap; +namespace gfx { +class Point; +class Size; +} + namespace ui { class Transform; +#if !defined(COMPOSITOR_2) typedef unsigned int TextureID; // Compositor object to take care of GPU painting. @@ -48,6 +55,56 @@ class Compositor : public base::RefCounted<Compositor> { friend class base::RefCounted<Compositor>; }; +#else +// Textures are created by a Compositor for managing an accelerated view. +// Any time a View with a texture needs to redraw itself it invokes SetBitmap(). +// When the view is ready to be drawn Draw() is invoked. +// +// Texture is really a proxy to the gpu. Texture does not itself keep a copy of +// the bitmap. +// +// Views own the Texture. +class Texture { + public: + virtual ~Texture() {} + + // Sets the bitmap of this texture. The bitmaps origin is at |origin|. + // |overall_size| gives the total size of texture. + virtual void SetBitmap(const SkBitmap& bitmap, + const gfx::Point& origin, + const gfx::Size& overall_size) = 0; + + // Draws the texture. + virtual void Draw(const ui::Transform& transform) = 0; +}; + +// Compositor object to take care of GPU painting. +// A Browser compositor object is responsible for generating the final +// displayable form of pixels comprising a single widget's contents. It draws an +// appropriately transformed texture for each transformed view in the widget's +// view hierarchy. +class Compositor : public base::RefCounted<Compositor> { + public: + // Create a compositor from the provided handle. + static Compositor* Create(gfx::AcceleratedWidget widget); + + // Creates a new texture. The caller owns the returned object. + virtual Texture* CreateTexture() = 0; + + // Notifies the compositor that compositing is about to start. + virtual void NotifyStart() = 0; + + // Notifies the compositor that compositing is complete. + virtual void NotifyEnd() = 0; + + protected: + virtual ~Compositor() {} + + private: + friend class base::RefCounted<Compositor>; +}; + +#endif // COMPOSITOR_2 } // namespace ui #endif // UI_GFX_COMPOSITOR_COMPOSITOR_H_ diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc index f152ffc..4beb65c 100644 --- a/ui/gfx/compositor/compositor_gl.cc +++ b/ui/gfx/compositor/compositor_gl.cc @@ -15,6 +15,57 @@ namespace ui { +#if defined COMPOSITOR_2 +namespace { + +class CompositorGL : public Compositor { + public: + explicit CompositorGL(gfx::AcceleratedWidget widget); + + private: + // Overridden from Compositor. + virtual Texture* CreateTexture() OVERRIDE; + virtual void NotifyStart() OVERRIDE; + virtual void NotifyEnd() OVERRIDE; + + // The GL context used for compositing. + scoped_ptr<gfx::GLContext> gl_context_; + + // Keep track of whether compositing has started or not. + bool started_; + + DISALLOW_COPY_AND_ASSIGN(CompositorGL); +}; + +CompositorGL::CompositorGL(gfx::AcceleratedWidget widget) + : gl_context_(gfx::GLContext::CreateViewGLContext(widget, false)), + started_(false) { +} + +Texture* CompositorGL::CreateTexture() { + return NULL; +} + +void CompositorGL::NotifyStart() { + started_ = true; + gl_context_->MakeCurrent(); +} + +void CompositorGL::NotifyEnd() { + DCHECK(started_); + gl_context_->SwapBuffers(); + started_ = false; +} + +} // namespace + +// static +Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { + if (gfx::GetGLImplementation() != gfx::kGLImplementationNone) + return new CompositorGL(widget); + return NULL; +} +#else class CompositorGL : public Compositor { public: explicit CompositorGL(gfx::AcceleratedWidget widget); @@ -77,5 +128,5 @@ Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { return new CompositorGL(widget); return NULL; } - +#endif } // namespace ui 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) { diff --git a/views/view.h b/views/view.h index a2a6156..98337a5 100644 --- a/views/view.h +++ b/views/view.h @@ -25,7 +25,6 @@ using ui::OSExchangeData; - namespace gfx { class Canvas; class Insets; @@ -35,6 +34,7 @@ class Path; namespace ui { struct AccessibleViewState; class Compositor; +class Texture; class ThemeProvider; class Transform; @@ -1040,8 +1040,29 @@ class View : public AcceleratorTarget { // Accelerated painting ------------------------------------------------------ +#if !defined(COMPOSITOR_2) // Performs accelerated painting using the compositor. virtual void PaintComposite(ui::Compositor* compositor); +#else + // If our texture is out of date invokes Paint() with a canvas that is then + // copied to the texture. If the texture is not out of date recursively + // descends in case any children needed their textures updated. + // + // This is invoked internally by Widget and painting code. + void PaintToTexture(const gfx::Rect& dirty_rect); + + // Instructs the compositor to show our texture and all children textures. + // + // This is invoked internally by Widget and painting code. + void PaintComposite(); +#endif + + // Returns true if this view should paint using a texture. + virtual bool ShouldPaintToTexture() const; + + // Returns the Compositor. + virtual const ui::Compositor* GetCompositor() const; + virtual ui::Compositor* GetCompositor(); // Input --------------------------------------------------------------------- @@ -1216,6 +1237,10 @@ class View : public AcceleratorTarget { // Initialize the transform matrix when necessary. void InitTransform(); + // Returns in |transform| the transform to get from root view coordinates to + // this views coordinates. + void GetTransformRelativeToRoot(ui::Transform* transform); + // Coordinate conversion ----------------------------------------------------- // This is the actual implementation for ConvertPointToView() @@ -1238,6 +1263,11 @@ class View : public AcceleratorTarget { // coordinate system. bool ConvertPointFromAncestor(const View* ancestor, gfx::Point* point) const; + // Accelerated painting ------------------------------------------------------ + + // Releases the texture of this and recurses through all children. + void ResetTexture(); + // Input --------------------------------------------------------------------- // RootView invokes these. These in turn invoke the appropriate OnMouseXXX @@ -1372,6 +1402,7 @@ class View : public AcceleratorTarget { // Accelerated painting ------------------------------------------------------ +#if !defined(COMPOSITOR_2) // Each transformed view will maintain its own canvas. scoped_ptr<gfx::Canvas> canvas_; @@ -1379,6 +1410,17 @@ class View : public AcceleratorTarget { // TODO(sadrul): This will eventually be replaced by an abstract texture // object. ui::TextureID texture_id_; +#else + scoped_ptr<ui::Texture> texture_; + + // If not empty and Paint() is invoked, the canvas is created with the + // specified size. + // TODO(sky): this should be passed in. + gfx::Rect texture_clip_rect_; +#endif + + // Is the texture out of date? + bool texture_needs_updating_; // Accelerators -------------------------------------------------------------- diff --git a/views/views.gyp b/views/views.gyp index 6489d87..3c4bf77 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -603,6 +603,7 @@ 'test/test_views_delegate.cc', 'test/test_views_delegate.h', '<(SHARED_INTERMEDIATE_DIR)/app/app_resources/app_resources.rc', + '<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc', ], 'conditions': [ ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', { diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h index 0ac5e09..036bb48 100644 --- a/views/widget/native_widget_delegate.h +++ b/views/widget/native_widget_delegate.h @@ -37,6 +37,11 @@ class NativeWidgetDelegate { // Returns true if the delegate has a FocusManager. virtual bool HasFocusManager() const = 0; + // Paints the widget using acceleration. If the widget is not using + // accelerated painting this returns false and does nothing. + virtual bool OnNativeWidgetPaintAccelerated( + const gfx::Rect& dirty_region) = 0; + // Paints the rootview in the canvas. This will also refresh the compositor // tree if necessary when accelerated painting is enabled. virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) = 0; diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index bea5b58..6942d3d 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -451,6 +451,18 @@ void RootView::OnPaint(gfx::Canvas* canvas) { canvas->AsCanvasSkia()->drawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); } +bool RootView::ShouldPaintToTexture() const { + return widget_->compositor() != NULL; +} + +const ui::Compositor* RootView::GetCompositor() const { + return widget_->compositor(); +} + +ui::Compositor* RootView::GetCompositor() { + return widget_->compositor(); +} + //////////////////////////////////////////////////////////////////////////////// // RootView, private: diff --git a/views/widget/root_view.h b/views/widget/root_view.h index 12212e0..fc8b632 100644 --- a/views/widget/root_view.h +++ b/views/widget/root_view.h @@ -128,6 +128,9 @@ class RootView : public View, virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child) OVERRIDE; virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual bool ShouldPaintToTexture() const OVERRIDE; + virtual const ui::Compositor* GetCompositor() const OVERRIDE; + virtual ui::Compositor* GetCompositor() OVERRIDE; private: friend class View; diff --git a/views/widget/widget.cc b/views/widget/widget.cc index 71cd85f..a7c03d9 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -314,6 +314,7 @@ void Widget::OnNativeWidgetCreated() { // manager. focus_manager_.reset(new FocusManager(this)); } + EnsureCompositor(); } void Widget::OnSizeChanged(const gfx::Size& new_size) { @@ -324,9 +325,30 @@ bool Widget::HasFocusManager() const { return !!focus_manager_.get(); } +bool Widget::OnNativeWidgetPaintAccelerated(const gfx::Rect& dirty_region) { +#if !defined(COMPOSITOR_2) + return false; +#else + if (!compositor_.get()) + return false; + + compositor_->NotifyStart(); + GetRootView()->PaintToTexture(dirty_region); + GetRootView()->PaintComposite(); + compositor_->NotifyEnd(); + return true; +#endif +} + void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) { GetRootView()->Paint(canvas); - RefreshCompositeTree(); +#if !defined(COMPOSITOR_2) + if (compositor_.get()) { + compositor_->NotifyStart(); + root_view_->PaintComposite(compositor_.get()); + compositor_->NotifyEnd(); + } +#endif } bool Widget::OnKeyEvent(const KeyEvent& event) { @@ -435,26 +457,14 @@ void Widget::ReplaceFocusManager(FocusManager* focus_manager) { //////////////////////////////////////////////////////////////////////////////// // Widget, private: -void Widget::RefreshCompositeTree() { - if (!EnsureCompositor()) - return; - - compositor_->NotifyStart(); - root_view_->PaintComposite(compositor_.get()); - compositor_->NotifyEnd(); -} - -bool Widget::EnsureCompositor() { - if (compositor_.get()) - return true; +void Widget::EnsureCompositor() { + DCHECK(!compositor_.get()); // TODO(sad): If there is a parent Widget, then use the same compositor // instead of creating a new one here. gfx::AcceleratedWidget widget = native_widget_->GetAcceleratedWidget(); if (widget != gfx::kNullAcceleratedWidget) compositor_ = ui::Compositor::Create(widget); - - return compositor_.get() != NULL; } bool Widget::ShouldReleaseCaptureOnMouseReleased() const { diff --git a/views/widget/widget.h b/views/widget/widget.h index ae77851..110ee20 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -271,6 +271,9 @@ class Widget : public internal::NativeWidgetDelegate, void SetFocusTraversableParent(FocusTraversable* parent); void SetFocusTraversableParentView(View* parent_view); + const ui::Compositor* compositor() const { return compositor_.get(); } + ui::Compositor* compositor() { return compositor_.get(); } + // Notifies assistive technology that an accessibility event has // occurred on |view|, such as when the view is focused or when its // value changes. Pass true for |send_native_event| except for rare @@ -290,6 +293,8 @@ class Widget : public internal::NativeWidgetDelegate, virtual void OnNativeWidgetCreated() OVERRIDE; virtual void OnSizeChanged(const gfx::Size& new_size) OVERRIDE; virtual bool HasFocusManager() const OVERRIDE; + virtual bool OnNativeWidgetPaintAccelerated( + const gfx::Rect& dirty_region) OVERRIDE; virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE; virtual bool OnKeyEvent(const KeyEvent& event) OVERRIDE; virtual bool OnMouseEvent(const MouseEvent& event) OVERRIDE; @@ -332,13 +337,8 @@ class Widget : public internal::NativeWidgetDelegate, gfx::Point last_mouse_event_position_; private: - // Refresh the compositor tree. This is called by a View whenever its texture - // is updated. - void RefreshCompositeTree(); - - // Try to create a compositor if one hasn't been created yet. Returns false if - // a compositor couldn't be created. - bool EnsureCompositor(); + // Try to create a compositor if one hasn't been created yet. + void EnsureCompositor(); // Returns whether capture should be released on mouse release. virtual bool ShouldReleaseCaptureOnMouseReleased() const; diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 6f63876..b506dac 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -21,6 +21,7 @@ #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/dragdrop/os_exchange_data_provider_gtk.h" #include "ui/base/gtk/gtk_windowing.h" +#include "ui/base/gtk/scoped_handle_gtk.h" #include "ui/base/x/x11_util.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/path.h" @@ -1061,10 +1062,17 @@ gboolean WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { XSync(ui::GetXDisplay(), false /* don't discard events */); } - gfx::CanvasSkiaPaint canvas(event); - if (!canvas.is_empty()) { - canvas.set_composite_alpha(is_transparent()); - delegate_->OnNativeWidgetPaint(&canvas); + ui::ScopedRegion region(gdk_region_copy(event->region)); + if (!gdk_region_empty(region.Get())) { + GdkRectangle clip_bounds; + gdk_region_get_clipbox(region.Get(), &clip_bounds); + if (!delegate_->OnNativeWidgetPaintAccelerated(gfx::Rect(clip_bounds))) { + gfx::CanvasSkiaPaint canvas(event); + if (!canvas.is_empty()) { + canvas.set_composite_alpha(is_transparent()); + delegate_->OnNativeWidgetPaint(&canvas); + } + } } if (!painted_) { @@ -1559,6 +1567,11 @@ void WidgetGtk::CreateGtkWidget(const InitParams& params) { if (ignore_events_) ConfigureWidgetForIgnoreEvents(); + // Realize the window_contents_ so that we can always get a handle for + // acceleration. Without this we need to check every time paint is + // invoked. + gtk_widget_realize(window_contents_); + SetAlwaysOnTop(always_on_top_); // UpdateFreezeUpdatesProperty will realize the widget and handlers like // size-allocate will function properly. diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 4fb0802..a5d2044 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -845,9 +845,19 @@ LRESULT WidgetWin::OnNotify(int w_param, NMHDR* l_param) { } void WidgetWin::OnPaint(HDC dc) { - scoped_ptr<gfx::CanvasPaint> canvas( - gfx::CanvasPaint::CreateCanvasPaint(hwnd())); - delegate_->OnNativeWidgetPaint(canvas->AsCanvas()); + RECT dirty_rect; + // Try to paint accelerated first. + if (GetUpdateRect(hwnd(), &dirty_rect, FALSE) && + !IsRectEmpty(&dirty_rect)) { + if (delegate_->OnNativeWidgetPaintAccelerated( + gfx::Rect(dirty_rect))) { + ValidateRect(hwnd(), NULL); + } else { + scoped_ptr<gfx::CanvasPaint> canvas( + gfx::CanvasPaint::CreateCanvasPaint(hwnd())); + delegate_->OnNativeWidgetPaint(canvas->AsCanvas()); + } + } } LRESULT WidgetWin::OnPowerBroadcast(DWORD power_event, DWORD data) { @@ -1111,7 +1121,7 @@ void WidgetWin::ClientAreaSizeChanged() { } gfx::AcceleratedWidget WidgetWin::GetAcceleratedWidget() { - // TODO(beng): + // TODO(sky): return gfx::kNullAcceleratedWidget; } |