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 | |
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
-rw-r--r-- | ui/gfx/canvas.h | 5 | ||||
-rw-r--r-- | ui/gfx/canvas_direct2d.cc | 5 | ||||
-rw-r--r-- | ui/gfx/canvas_direct2d.h | 1 | ||||
-rw-r--r-- | ui/gfx/canvas_skia.h | 1 | ||||
-rw-r--r-- | ui/gfx/canvas_skia_linux.cc | 5 | ||||
-rw-r--r-- | ui/gfx/canvas_skia_mac.mm | 5 | ||||
-rw-r--r-- | ui/gfx/canvas_skia_win.cc | 5 | ||||
-rw-r--r-- | ui/gfx/compositor.cc | 14 | ||||
-rw-r--r-- | ui/gfx/compositor.h | 53 | ||||
-rw-r--r-- | ui/gfx/compositor_gl.cc | 80 | ||||
-rw-r--r-- | ui/gfx/gfx.gyp | 15 | ||||
-rw-r--r-- | ui/gfx/native_widget_types.h | 12 | ||||
-rw-r--r-- | views/view.cc | 109 | ||||
-rw-r--r-- | views/view.h | 23 | ||||
-rw-r--r-- | views/widget/native_widget.h | 4 | ||||
-rw-r--r-- | views/widget/native_widget_delegate.h | 5 | ||||
-rw-r--r-- | views/widget/root_view.h | 1 | ||||
-rw-r--r-- | views/widget/widget.cc | 31 | ||||
-rw-r--r-- | views/widget/widget.h | 15 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 7 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 6 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 7 | ||||
-rw-r--r-- | views/widget/widget_win.h | 3 |
23 files changed, 381 insertions, 31 deletions
diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h index 0149486..e4ce7ad 100644 --- a/ui/gfx/canvas.h +++ b/ui/gfx/canvas.h @@ -15,6 +15,8 @@ namespace ui { class Transform; + +typedef unsigned int TextureID; } namespace gfx { @@ -215,6 +217,9 @@ class Canvas { // Apply transformation on the canvas. virtual void Transform(const ui::Transform& transform) = 0; + // Create a texture ID that can be used for accelerated drawing. + virtual ui::TextureID GetTextureID() = 0; + // TODO(beng): remove this once we don't need to use any skia-specific methods // through this interface. // A quick and dirty way to obtain the underlying SkCanvas. diff --git a/ui/gfx/canvas_direct2d.cc b/ui/gfx/canvas_direct2d.cc index 63e9bb9..38ed18aa 100644 --- a/ui/gfx/canvas_direct2d.cc +++ b/ui/gfx/canvas_direct2d.cc @@ -345,6 +345,11 @@ void CanvasDirect2D::Transform(const ui::Transform& transform) { NOTIMPLEMENTED(); } +ui::TextureID CanvasDirect2D::GetTextureID() { + NOTIMPLEMENTED(); + return 0; +} + CanvasSkia* CanvasDirect2D::AsCanvasSkia() { return NULL; } diff --git a/ui/gfx/canvas_direct2d.h b/ui/gfx/canvas_direct2d.h index 45452f5..88ab8bf 100644 --- a/ui/gfx/canvas_direct2d.h +++ b/ui/gfx/canvas_direct2d.h @@ -78,6 +78,7 @@ class CanvasDirect2D : public Canvas { virtual gfx::NativeDrawingContext BeginPlatformPaint(); virtual void EndPlatformPaint(); virtual void Transform(const ui::Transform& transform); + virtual ui::TextureID GetTextureID(); virtual CanvasSkia* AsCanvasSkia(); virtual const CanvasSkia* AsCanvasSkia() const; diff --git a/ui/gfx/canvas_skia.h b/ui/gfx/canvas_skia.h index 854ce84..9516e8a3 100644 --- a/ui/gfx/canvas_skia.h +++ b/ui/gfx/canvas_skia.h @@ -140,6 +140,7 @@ class CanvasSkia : public skia::PlatformCanvas, virtual gfx::NativeDrawingContext BeginPlatformPaint(); virtual void EndPlatformPaint(); virtual void Transform(const ui::Transform& transform); + virtual ui::TextureID GetTextureID(); virtual CanvasSkia* AsCanvasSkia(); virtual const CanvasSkia* AsCanvasSkia() const; diff --git a/ui/gfx/canvas_skia_linux.cc b/ui/gfx/canvas_skia_linux.cc index d418626..fa9d1a4 100644 --- a/ui/gfx/canvas_skia_linux.cc +++ b/ui/gfx/canvas_skia_linux.cc @@ -384,4 +384,9 @@ void CanvasSkia::DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y) { cairo_paint(cr); } +ui::TextureID CanvasSkia::GetTextureID() { + // TODO(wjmaclean) + return 0; +} + } // namespace gfx diff --git a/ui/gfx/canvas_skia_mac.mm b/ui/gfx/canvas_skia_mac.mm index c6fb031..aacf100 100644 --- a/ui/gfx/canvas_skia_mac.mm +++ b/ui/gfx/canvas_skia_mac.mm @@ -86,4 +86,9 @@ void CanvasSkia::DrawStringInt(const string16& text, endPlatformPaint(); } +ui::TextureID CanvasSkia::GetTextureID() { + // TODO(wjmaclean) + return 0; +} + } // namespace gfx diff --git a/ui/gfx/canvas_skia_win.cc b/ui/gfx/canvas_skia_win.cc index 1e108b3..b343234 100644 --- a/ui/gfx/canvas_skia_win.cc +++ b/ui/gfx/canvas_skia_win.cc @@ -298,4 +298,9 @@ void CanvasSkia::DrawStringWithHalo(const string16& text, DrawBitmapInt(text_bitmap, x - 1, y - 1); } +ui::TextureID CanvasSkia::GetTextureID() { + // TODO(wjmaclean) + return 0; +} + } // namespace gfx diff --git a/ui/gfx/compositor.cc b/ui/gfx/compositor.cc new file mode 100644 index 0000000..f9c6487 --- /dev/null +++ b/ui/gfx/compositor.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/compositor.h" + +namespace ui { + +// static +Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { + return NULL; +} + +} // namespace ui diff --git a/ui/gfx/compositor.h b/ui/gfx/compositor.h new file mode 100644 index 0000000..2c33942 --- /dev/null +++ b/ui/gfx/compositor.h @@ -0,0 +1,53 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_COMPOSITOR_H_ +#define UI_GFX_COMPOSITOR_H_ +#pragma once + +#include "base/ref_counted.h" +#include "ui/gfx/native_widget_types.h" + +namespace ui { +class Transform; + +typedef unsigned int TextureID; + +// 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. The initial implementation uses GL for this purpose. +// Future CLs will adapt this to ongoing Skia development. +class Compositor : public base::RefCounted<Compositor> { + public: + // Create a compositor from the provided handle. + static Compositor* Create(gfx::AcceleratedWidget widget); + + // Notifies the compositor that compositing is about to start. + virtual void NotifyStart() = 0; + + // Notifies the compositor that compositing is complete. + virtual void NotifyEnd() = 0; + + // Draws the given texture with the given transform. + virtual void DrawTextureWithTransform(TextureID txt, + const ui::Transform& transform) = 0; + + // Save the current transformation that can be restored with RestoreTransform. + virtual void SaveTransform() = 0; + + // Restore a previously saved transformation using SaveTransform. + virtual void RestoreTransform() = 0; + + protected: + virtual ~Compositor() {} + + private: + friend class base::RefCounted<Compositor>; +}; + +} // namespace ui + +#endif // UI_GFX_COMPOSITOR_H_ diff --git a/ui/gfx/compositor_gl.cc b/ui/gfx/compositor_gl.cc new file mode 100644 index 0000000..39a57a1 --- /dev/null +++ b/ui/gfx/compositor_gl.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/compositor.h" + +#include <GL/gl.h> + +#include "app/gfx/gl/gl_context.h" +#include "app/gfx/gl/gl_implementation.h" +#include "base/scoped_ptr.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "ui/gfx/transform.h" + +namespace ui { + +class CompositorGL : public Compositor { + public: + CompositorGL(gfx::AcceleratedWidget widget); + + private: + // Overridden from Compositor. + void NotifyStart() OVERRIDE; + void NotifyEnd() OVERRIDE; + void DrawTextureWithTransform(TextureID txt, + const ui::Transform& transform) OVERRIDE; + void SaveTransform() OVERRIDE; + void RestoreTransform() 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) { +} + +void CompositorGL::NotifyStart() { + started_ = true; + gl_context_->MakeCurrent(); +} + +void CompositorGL::NotifyEnd() { + DCHECK(started_); + gl_context_->SwapBuffers(); + started_ = false; +} + +void CompositorGL::DrawTextureWithTransform(TextureID txt, + const ui::Transform& transform) { + DCHECK(started_); + + // TODO(wjmaclean): + NOTIMPLEMENTED(); +} + +void CompositorGL::SaveTransform() { + glPushMatrix(); +} + +void CompositorGL::RestoreTransform() { + glPopMatrix(); +} + +// static +Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { + if (gfx::GetGLImplementation() != gfx::kGLImplementationNone) + return new CompositorGL(widget); + return NULL; +} + +} // namespace ui diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp index c6906ac..b8e0cad 100644 --- a/ui/gfx/gfx.gyp +++ b/ui/gfx/gfx.gyp @@ -106,6 +106,9 @@ 'codec/png_codec.h', 'color_utils.cc', 'color_utils.h', + 'compositor.cc', + 'compositor_gl.cc', + 'compositor.h', 'favicon_size.h', 'font.h', 'font.cc', @@ -175,6 +178,14 @@ '../../build/linux/system.gyp:fontconfig', '../../build/linux/system.gyp:gtk', ], + 'link_settings': { + 'libraries': [ + '-lGL', + ], + }, + 'sources!': [ + 'compositor.cc', + ], 'sources': [ 'gtk_native_view_id_manager.cc', 'gtk_native_view_id_manager.h', @@ -186,6 +197,10 @@ 'native_theme_linux.h', 'native_widget_types_gtk.cc', ], + }, { + 'sources!': [ + 'compositor_gl.cc', + ] }], ], }, diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index bc60777..ba530d9 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h @@ -171,6 +171,18 @@ NativeViewId IdFromNativeView(NativeView view); const PluginWindowHandle kNullPluginWindow = 0; #endif +// AcceleratedWidget provides a surface to compositors to paint pixels. +#if defined(OS_WIN) +typedef HWND AcceleratedWidget; +const AcceleratedWidget kNullAcceleratedWidget = NULL; +#elif defined(USE_X11) +typedef unsigned long AcceleratedWidget; +const AcceleratedWidget kNullAcceleratedWidget = 0; +#else +typedef void* AcceleratedWidget; +const AcceleratedWidget kNullAcceleratedWidget = NULL; +#endif + } // namespace gfx #endif // UI_GFX_NATIVE_WIDGET_TYPES_H_ 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_); diff --git a/views/view.h b/views/view.h index 8117ab2..e09f0bee 100644 --- a/views/view.h +++ b/views/view.h @@ -34,8 +34,11 @@ class Path; namespace ui { struct AccessibleViewState; +class Compositor; class ThemeProvider; class Transform; + +typedef unsigned int TextureID; } using ui::ThemeProvider; @@ -562,6 +565,11 @@ class View : public AcceleratorTarget { flip_canvas_on_paint_for_rtl_ui_ = enable; } + // Accelerated painting ------------------------------------------------------ + + // Enable/Disable accelerated compositing. + static void set_use_acceleration_when_possible(bool use); + // Input --------------------------------------------------------------------- // The points (and mouse locations) in the following functions are in the // view's coordinates, except for a RootView. @@ -1016,6 +1024,11 @@ class View : public AcceleratorTarget { // relevant contents. virtual void OnPaintFocusBorder(gfx::Canvas* canvas); + // Accelerated painting ------------------------------------------------------ + + // Performs accelerated painting using the compositor. + virtual void PaintComposite(ui::Compositor* compositor); + // Input --------------------------------------------------------------------- // Called by HitTest to see if this View has a custom hit test mask. If the @@ -1333,6 +1346,16 @@ class View : public AcceleratorTarget { // right-to-left locales for this View. bool flip_canvas_on_paint_for_rtl_ui_; + // Accelerated painting ------------------------------------------------------ + + // Each transformed view will maintain its own canvas. + scoped_ptr<gfx::Canvas> canvas_; + + // Texture ID used for accelerated painting. + // TODO(sadrul): This will eventually be replaced by an abstract texture + // object. + ui::TextureID texture_id_; + // Accelerators -------------------------------------------------------------- // true if when we were added to hierarchy we were without focus manager diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index 26dbd9b..a833664 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -72,6 +72,10 @@ class NativeWidget { protected: friend class Widget; + // Returns a handle for the underlying native widget that can be used for + // accelerated drawing. + virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; + // Widget pass-thrus, private to Views. -------------------------------------- // See method documentation in Widget. virtual gfx::Rect GetWindowScreenBounds() const = 0; diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h index e14e32b..b21cd10 100644 --- a/views/widget/native_widget_delegate.h +++ b/views/widget/native_widget_delegate.h @@ -7,6 +7,7 @@ #pragma once namespace gfx { +class Canvas; class Size; } @@ -35,6 +36,10 @@ class NativeWidgetDelegate { // Returns true if the delegate has a FocusManager. virtual bool HasFocusManager() const = 0; + + // Paints the rootview in the canvas. This will also refresh the compositor + // tree if necessary when accelerated painting is enabled. + virtual void OnPaint(gfx::Canvas* canvas) = 0; }; } // namespace internal diff --git a/views/widget/root_view.h b/views/widget/root_view.h index 3eac199..6658fe0 100644 --- a/views/widget/root_view.h +++ b/views/widget/root_view.h @@ -124,6 +124,7 @@ class RootView : public View, private: friend class View; + friend class Widget; #if defined(TOUCH_UI) // Required so the GestureManager can call the Process* entry points diff --git a/views/widget/widget.cc b/views/widget/widget.cc index 4a58b32..88c7bf3 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/message_loop.h" +#include "ui/gfx/compositor.h" #include "views/focus/view_storage.h" #include "views/widget/default_theme_provider.h" #include "views/widget/root_view.h" @@ -264,6 +265,11 @@ bool Widget::HasFocusManager() const { return !!focus_manager_.get(); } +void Widget::OnPaint(gfx::Canvas* canvas) { + GetRootView()->Paint(canvas); + RefreshCompositeTree(); +} + //////////////////////////////////////////////////////////////////////////////// // Widget, FocusTraversable implementation: @@ -311,4 +317,29 @@ void Widget::ReplaceFocusManager(FocusManager* focus_manager) { focus_manager_.reset(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; + + // 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; +} + } // namespace views diff --git a/views/widget/widget.h b/views/widget/widget.h index 684cade..21f4f48 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -8,6 +8,7 @@ #include <vector> +#include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "ui/base/accessibility/accessibility_types.h" #include "ui/gfx/native_widget_types.h" @@ -15,6 +16,7 @@ #include "views/widget/native_widget_delegate.h" namespace gfx { +class Canvas; class Path; class Point; class Rect; @@ -22,6 +24,7 @@ class Rect; namespace ui { class Accelerator; +class Compositor; class OSExchangeData; class ThemeProvider; } @@ -272,6 +275,7 @@ class Widget : public internal::NativeWidgetDelegate, virtual void OnNativeWidgetCreated() OVERRIDE; virtual void OnSizeChanged(const gfx::Size& new_size) OVERRIDE; virtual bool HasFocusManager() const OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; // Overridden from FocusTraversable: virtual FocusSearch* GetFocusSearch() OVERRIDE; @@ -299,6 +303,14 @@ class Widget : public internal::NativeWidgetDelegate, void ReplaceFocusManager(FocusManager* focus_manager); 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(); + NativeWidget* native_widget_; // Non-owned pointer to the Widget's delegate. May be NULL if no delegate is @@ -323,6 +335,9 @@ class Widget : public internal::NativeWidgetDelegate, // started from. View* dragged_view_; + // The compositor for accelerated drawing. + scoped_refptr<ui::Compositor> compositor_; + DISALLOW_COPY_AND_ASSIGN(Widget); }; diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 3ebd950..0a89fee 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -955,7 +955,7 @@ gboolean WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { gfx::CanvasSkiaPaint canvas(event); if (!canvas.is_empty()) { canvas.set_composite_alpha(is_transparent()); - GetRootView()->Paint(&canvas); + delegate_->OnPaint(&canvas); } return false; // False indicates other widgets should get the event as well. } @@ -1270,6 +1270,11 @@ RootView* WidgetGtk::CreateRootView() { return new RootView(this); } +gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { + DCHECK(window_contents_ && window_contents_->window); + return GDK_WINDOW_XID(window_contents_->window); +} + gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { // Clear the background to be totally transparent. We don't need to // paint the root view here as that is done by OnPaint. diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 142f2cd..370e9cf 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -287,7 +287,11 @@ class WidgetGtk : public Widget, class DropObserver; friend class DropObserver; - virtual RootView* CreateRootView(); + // Overridden from Widget + virtual RootView* CreateRootView() OVERRIDE; + + // Overridden from NativeWidget + virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnWindowPaint, GdkEventExpose*); diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 657ece9..823f7d4 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -820,7 +820,7 @@ LRESULT WidgetWin::OnNotify(int w_param, NMHDR* l_param) { void WidgetWin::OnPaint(HDC dc) { scoped_ptr<gfx::CanvasPaint> canvas( gfx::CanvasPaint::CreateCanvasPaint(hwnd())); - GetRootView()->Paint(canvas->AsCanvas()); + delegate_->OnPaint(canvas->AsCanvas()); } LRESULT WidgetWin::OnPowerBroadcast(DWORD power_event, DWORD data) { @@ -1123,6 +1123,11 @@ void WidgetWin::ClientAreaSizeChanged() { } } +gfx::AcceleratedWidget WidgetWin::GetAcceleratedWidget() { + NOTIMPLEMENTED(); + return gfx::kNullAcceleratedWidget; +} + //////////////////////////////////////////////////////////////////////////////// // Widget, public: diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index ba78268..9779bd8 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -456,6 +456,9 @@ class WidgetWin : public ui::WindowImpl, // or subsequently. void ClientAreaSizeChanged(); + // Overridden from NativeWidget. + virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; + // A delegate implementation that handles events received here. internal::NativeWidgetDelegate* delegate_; |