summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-13 16:47:57 +0000
committervollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-13 16:47:57 +0000
commit30e3f575b5255afb37615ff66677556e9974c56d (patch)
treee3286e98757a6587a5ce696b242a7dcb4bdf83f2
parentb71a804937563c9bdae9ae15611d423639963b6a (diff)
downloadchromium_src-30e3f575b5255afb37615ff66677556e9974c56d.zip
chromium_src-30e3f575b5255afb37615ff66677556e9974c56d.tar.gz
chromium_src-30e3f575b5255afb37615ff66677556e9974c56d.tar.bz2
Force clear when root view is animating.
If the root view is animating, or it's bounds do not fill the client area, compositing should clear first to clean up any ghosts. BUG=None TEST=None Review URL: http://codereview.chromium.org/7778045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@100927 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--aura/desktop.cc4
-rw-r--r--ui/gfx/compositor/compositor.cc4
-rw-r--r--ui/gfx/compositor/compositor.h7
-rw-r--r--ui/gfx/compositor/compositor_gl.cc18
-rw-r--r--ui/gfx/compositor/compositor_gl.h2
-rw-r--r--ui/gfx/compositor/compositor_win.cc6
-rw-r--r--views/widget/widget.cc28
7 files changed, 53 insertions, 16 deletions
diff --git a/aura/desktop.cc b/aura/desktop.cc
index 171da3c..3d3d81c 100644
--- a/aura/desktop.cc
+++ b/aura/desktop.cc
@@ -47,7 +47,9 @@ void Desktop::Run() {
}
void Desktop::Draw() {
- compositor_->NotifyStart();
+ // Second pass renders the layers.
+ const bool force_clear = false;
+ compositor_->NotifyStart(force_clear);
window_->DrawTree();
compositor_->NotifyEnd();
}
diff --git a/ui/gfx/compositor/compositor.cc b/ui/gfx/compositor/compositor.cc
index eca0c70..0bfe870 100644
--- a/ui/gfx/compositor/compositor.cc
+++ b/ui/gfx/compositor/compositor.cc
@@ -15,8 +15,8 @@ Compositor::Compositor(CompositorDelegate* delegate, const gfx::Size& size)
Compositor::~Compositor() {
}
-void Compositor::NotifyStart() {
- OnNotifyStart();
+void Compositor::NotifyStart(bool clear) {
+ OnNotifyStart(clear);
}
void Compositor::NotifyEnd() {
diff --git a/ui/gfx/compositor/compositor.h b/ui/gfx/compositor/compositor.h
index fd462f8..f0c370a 100644
--- a/ui/gfx/compositor/compositor.h
+++ b/ui/gfx/compositor/compositor.h
@@ -88,8 +88,9 @@ class COMPOSITOR_EXPORT Compositor : public base::RefCounted<Compositor> {
// Creates a new texture. The caller owns the returned object.
virtual Texture* CreateTexture() = 0;
- // Notifies the compositor that compositing is about to start.
- void NotifyStart();
+ // Notifies the compositor that compositing is about to start. If |clear| is
+ // true, this will cause the compositor to clear before compositing.
+ void NotifyStart(bool clear);
// Notifies the compositor that compositing is complete.
void NotifyEnd();
@@ -122,7 +123,7 @@ class COMPOSITOR_EXPORT Compositor : public base::RefCounted<Compositor> {
virtual ~Compositor();
// Notifies the compositor that compositing is about to start.
- virtual void OnNotifyStart() = 0;
+ virtual void OnNotifyStart(bool clear) = 0;
// Notifies the compositor that compositing is complete.
virtual void OnNotifyEnd() = 0;
diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc
index c3775c2..920e2a6 100644
--- a/ui/gfx/compositor/compositor_gl.cc
+++ b/ui/gfx/compositor/compositor_gl.cc
@@ -470,18 +470,24 @@ Texture* CompositorGL::CreateTexture() {
return texture;
}
-void CompositorGL::OnNotifyStart() {
+void CompositorGL::OnNotifyStart(bool clear) {
started_ = true;
gl_context_->MakeCurrent(gl_surface_.get());
glViewport(0, 0, size().width(), size().height());
glColorMask(true, true, true, true);
-#if defined(DEBUG)
- // Clear to 'psychedelic' purple to make it easy to spot un-rendered regions.
- glClearColor(223.0 / 255, 0, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
+ if (clear) {
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+#if !defined(NDEBUG)
+ else {
+ // In debug mode, when we're not forcing a clear, clear to 'psychedelic'
+ // purple to make it easy to spot un-rendered regions.
+ glClearColor(223.0 / 255, 0, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
#endif
- // Do not clear in release: root layer is responsible for drawing every pixel.
}
void CompositorGL::OnNotifyEnd() {
diff --git a/ui/gfx/compositor/compositor_gl.h b/ui/gfx/compositor/compositor_gl.h
index dc7ac8c..6fc3b1d 100644
--- a/ui/gfx/compositor/compositor_gl.h
+++ b/ui/gfx/compositor/compositor_gl.h
@@ -107,7 +107,7 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor {
private:
// Overridden from Compositor.
virtual Texture* CreateTexture() OVERRIDE;
- virtual void OnNotifyStart() OVERRIDE;
+ virtual void OnNotifyStart(bool clear) OVERRIDE;
virtual void OnNotifyEnd() OVERRIDE;
virtual void Blur(const gfx::Rect& bounds) OVERRIDE;
diff --git a/ui/gfx/compositor/compositor_win.cc b/ui/gfx/compositor/compositor_win.cc
index e07744a..3051213 100644
--- a/ui/gfx/compositor/compositor_win.cc
+++ b/ui/gfx/compositor/compositor_win.cc
@@ -102,10 +102,11 @@ class CompositorWin : public Compositor {
// Compositor:
virtual Texture* CreateTexture() OVERRIDE;
+
virtual void Blur(const gfx::Rect& bounds) OVERRIDE;
protected:
- virtual void OnNotifyStart() OVERRIDE;
+ virtual void OnNotifyStart(bool clear) OVERRIDE;
virtual void OnNotifyEnd() OVERRIDE;
virtual void OnWidgetSizeChanged() OVERRIDE;
@@ -387,11 +388,12 @@ Texture* CompositorWin::CreateTexture() {
return new ViewTexture(this, device_.get(), fx_.get());
}
-void CompositorWin::OnNotifyStart() {
+void CompositorWin::OnNotifyStart(bool clear) {
ID3D10RenderTargetView* target_view = main_render_target_view_.get();
device_->OMSetRenderTargets(1, &target_view, depth_stencil_view_.get());
// Clear the background and stencil view.
+ // TODO(vollick) see if |clear| can be used to avoid unnecessary clearing.
device_->ClearRenderTargetView(target_view,
D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
device_->ClearDepthStencilView(
diff --git a/views/widget/widget.cc b/views/widget/widget.cc
index 4bb880e..065e633 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -10,6 +10,7 @@
#include "ui/base/l10n/l10n_font_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/compositor/compositor.h"
+#include "ui/gfx/compositor/layer.h"
#include "views/controls/menu/menu_controller.h"
#include "views/focus/focus_manager_factory.h"
#include "views/focus/view_storage.h"
@@ -920,7 +921,32 @@ bool Widget::OnNativeWidgetPaintAccelerated(const gfx::Rect& dirty_region) {
if (!compositor)
return false;
- compositor->NotifyStart();
+ // If the root view is animating, it is likely that it does not cover the same
+ // set of pixels it did at the last frame, so we must clear when compositing
+ // to avoid leaving ghosts.
+ bool should_force_clear = false;
+ if (GetRootView()->layer()) {
+ const ui::Transform& layer_transform = GetRootView()->layer()->transform();
+ if (layer_transform != GetRootView()->GetTransform()) {
+ // The layer has not caught up to the view (i.e., the layer is still
+ // animating), and so a clear is required.
+ should_force_clear = true;
+ } else {
+ // Determine if the layer fills the client area.
+ gfx::Rect layer_bounds = GetRootView()->layer()->bounds();
+ layer_transform.TransformRect(&layer_bounds);
+ gfx::Rect client_bounds = GetClientAreaScreenBounds();
+ // Translate bounds to origin (client area bounds are offset to account
+ // for buttons, etc).
+ client_bounds.set_origin(gfx::Point(0, 0));
+ if (!layer_bounds.Contains(client_bounds)) {
+ // It doesn't, and so a clear is required.
+ should_force_clear = true;
+ }
+ }
+ }
+
+ compositor->NotifyStart(should_force_clear);
GetRootView()->PaintToLayer(dirty_region);
GetRootView()->PaintComposite();
compositor->NotifyEnd();