diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-26 05:15:42 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-26 05:15:42 +0000 |
commit | 7c4ea146bc033d89c1a0d527ae3d43b587a23cab (patch) | |
tree | 293c4da0b8fa44e5d4939c410434c51c8ffb872c /chrome/browser/renderer_host | |
parent | 877cbee0688984a2a00ce074f981bdfb1e42abfa (diff) | |
download | chromium_src-7c4ea146bc033d89c1a0d527ae3d43b587a23cab.zip chromium_src-7c4ea146bc033d89c1a0d527ae3d43b587a23cab.tar.gz chromium_src-7c4ea146bc033d89c1a0d527ae3d43b587a23cab.tar.bz2 |
Create initial GPU backing store in the GPU process for X windows applications.
This gets the window from the RenderWidgetHostViewGtk and just does OpenGL
calls directly into it. There are a lot of bugs, especially around expose
events, which aren't really processed at all, and also tab teardown and
reparenting.
The new backing store defaults to off.
This does some refactoring of the existing Windows GPU process backing store
implementation to make some of it sharable by this Linux verion.
This removes some previously defunct in-process GL backing store code and moves
it to the GPU process.
This patch does some refactoring around how child processes are created using
zygoes or not. I found there were many places where a command line would be
checked with special logic to know whether to enable zygote code or not. I
tried to unify this so it could be computed once for each process type. This is
what most of the changed files in chrome/browser are related to.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/548112
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37088 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
8 files changed, 39 insertions, 412 deletions
diff --git a/chrome/browser/renderer_host/backing_store_gl.cc b/chrome/browser/renderer_host/backing_store_gl.cc deleted file mode 100644 index 414f071..0000000 --- a/chrome/browser/renderer_host/backing_store_gl.cc +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2009 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 "chrome/browser/renderer_host/backing_store.h" - -#include <GL/gl.h> - -#include "base/scoped_ptr.h" -#include "chrome/browser/renderer_host/backing_store_manager.h" -#include "chrome/browser/renderer_host/backing_store_manager_glx.h" -#include "chrome/browser/renderer_host/render_widget_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/common/transport_dib.h" -#include "chrome/common/x11_util.h" -#include "skia/ext/platform_canvas.h" -#include "third_party/skia/include/core/SkBitmap.h" - -BackingStore::BackingStore(RenderWidgetHost* widget, - const gfx::Size& size, - void* visual, - int depth) - : render_widget_host_(widget), - size_(size), - display_(x11_util::GetXDisplay()), - root_window_(x11_util::GetX11RootWindow()), - texture_id_(0) { - XID id = x11_util::GetX11WindowFromGtkWidget(widget->view()->GetNativeView()); - BackingStoreManager::GetGlManager()->BindContext(id); - - glGenTextures(1, &texture_id_); - glBindTexture(GL_TEXTURE_2D, texture_id_); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - DCHECK(glGetError() == GL_NO_ERROR); -} - -BackingStore::BackingStore(RenderWidgetHost* widget, const gfx::Size& size) - : render_widget_host_(widget), - size_(size), - display_(NULL), - root_window_(0), - texture_id_(0) { -} - -BackingStore::~BackingStore() { - if (texture_id_) - glDeleteTextures(1, &texture_id_); -} - -void BackingStore::ShowRect(const gfx::Rect& damage, XID target) { - DCHECK(texture_id_ > 0); - - // TODO(brettw) is this necessray? - XID id = x11_util::GetX11WindowFromGtkWidget( - render_widget_host_->view()->GetNativeView()); - BackingStoreManager::GetGlManager()->BindContext(id); - - glViewport(0, 0, size_.width(), size_.height()); - - // TODO(brettw) only repaint the damaged area. This currently erases and - // repaints the entire screen. - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture_id_); - - // TODO(brettw) use vertex buffers. - // TODO(brettw) make this so we use the texture size rather than the whole - // area size so we don't stretch bitmaps. - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); - glVertex2f(-1.0, 1.0); - - glTexCoord2f(0.0f, 1.0f); - glVertex2f(-1.0, -1.0); - - glTexCoord2f(1.0f, 1.0f); - glVertex2f(1.0, -1.0); - - glTexCoord2f(1.0f, 0.0f); - glVertex2f(1.0, 1.0); - glEnd(); - DCHECK(glGetError() == GL_NO_ERROR); - - // TODO(brettw) when we no longer stretch non-fitting bitmaps, we should - // paint white over any unpainted area here. - - glXSwapBuffers(display_, id); -} - -SkBitmap BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { - NOTIMPLEMENTED(); - return SkBitmap(); -} - -#if defined(TOOLKIT_GTK) -void BackingStore::PaintToRect(const gfx::Rect& rect, GdkDrawable* target) { - NOTIMPLEMENTED(); -} -#endif - -// Paint the given transport DIB into our backing store. -void BackingStore::PaintRect(base::ProcessHandle process, - TransportDIB* bitmap, - const gfx::Rect& bitmap_rect, - const gfx::Rect& copy_rect) { - if (!display_) - return; - - if (bitmap_rect.IsEmpty() || copy_rect.IsEmpty()) - return; - - scoped_ptr<skia::PlatformCanvas> canvas( - bitmap->GetPlatformCanvas(bitmap_rect.width(), bitmap_rect.height())); - const SkBitmap& transport_bitmap = - canvas->getTopPlatformDevice().accessBitmap(false); - - // Make a bitmap referring to the correct subset of the input bitmap. - SkBitmap copy_bitmap; - if (copy_rect.x() == 0 && - copy_rect.y() == 0 && - copy_rect.width() == bitmap_rect.width() && - copy_rect.height() == bitmap_rect.height()) { - // The subregion we're being asked to copy is the full bitmap. We don't - // have to do any extra work to make the bitmap, we can just refer to the - // original data (bitmap assignments are just refs to the original). - copy_bitmap = transport_bitmap; - } else { - // Make a rect referring to the subset into the original (copy_rect and - // bitmap_rect are both in global coords) and make a copy of that data to - // give to OpenGL later. - // - // TODO(brettw) on desktop GL (not ES) we can do a trick here using - // GL_UNPACK_ROW_WIDTH, GL_UNPACK_SKIP_PIXELS and GL_UNPACK_SKIP_ROWS to - // avoid this copy. - // - // On ES, it may be better to actually call subimage for each row of - // the updated bitmap to avoid the copy. We will have to benchmark that - // approach against making the copy here to see if it performs better on - // the systems we're targeting. - SkIRect subset; - subset.fLeft = copy_rect.x() - bitmap_rect.x(); - subset.fTop = copy_rect.y() - bitmap_rect.y(); - subset.fRight = subset.fLeft + copy_rect.width(); - subset.fBottom = subset.fTop + copy_rect.height(); - SkIRect sk_copy_rect = { copy_rect.x() - bitmap_rect.x(), - copy_rect.y() - bitmap_rect.y(), - copy_rect.right(), copy_rect.bottom() }; - - // extractSubset will not acutually make a copy, and Skia will refer to the - // original data which is not what we want, since rows won't be contiguous. - // However, since this is very cheap, we can do it and *then* make a copy. - SkBitmap non_copied_subset; - transport_bitmap.extractSubset(&non_copied_subset, sk_copy_rect); - non_copied_subset.copyTo(©_bitmap, SkBitmap::kARGB_8888_Config); - CHECK(!copy_bitmap.isNull()); - } - - glBindTexture(GL_TEXTURE_2D, texture_id_); - - SkAutoLockPixels lock(copy_bitmap); - if (copy_rect.size() == size_ && copy_rect.size() != texture_size_) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, copy_rect.width(), - copy_rect.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, - copy_bitmap.getAddr32(0, 0)); - texture_size_ = copy_rect.size(); - DCHECK(glGetError() == GL_NO_ERROR); - } else { - /* Debugging code for why the below call may fail. - int existing_width = 0, existing_height = 0; - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, - &existing_width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, - &existing_height); - */ - glTexSubImage2D(GL_TEXTURE_2D, 0, copy_rect.x(), copy_rect.y(), - copy_rect.width(), copy_rect.height(), - GL_BGRA, GL_UNSIGNED_BYTE, - copy_bitmap.getAddr32(0, 0)); - DCHECK(glGetError() == GL_NO_ERROR); - /* Enable if you're having problems with TexSubImage failing. - int err = glGetError(); - DCHECK(err == GL_NO_ERROR) << "Error " << err << - " copying (" << copy_rect.x() << "," << copy_rect.y() << - ")," << copy_rect.width() << "x" << copy_rect.height() << - " for bitmap " << texture_size_.width() << "x" << - texture_size_.height() << - " real size " << existing_width << "x" << existing_height << - " for " << this; - */ - } -} - -void BackingStore::ScrollRect(base::ProcessHandle process, - TransportDIB* bitmap, - const gfx::Rect& bitmap_rect, - int dx, int dy, - const gfx::Rect& clip_rect, - const gfx::Size& view_size) { - NOTIMPLEMENTED(); -} - -size_t BackingStore::MemorySize() { - return texture_size_.GetArea() * 4; -} diff --git a/chrome/browser/renderer_host/backing_store_glx.h b/chrome/browser/renderer_host/backing_store_glx.h deleted file mode 100644 index 534c052..0000000 --- a/chrome/browser/renderer_host/backing_store_glx.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2010 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 CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_GLX_H_ -#define CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_GLX_H_ - -#include "base/basictypes.h" -#include "build/build_config.h" -#include "chrome/browser/renderer_host/backing_store.h" -#include "chrome/common/x11_util.h" - -class BackingStoreGLX : public BackingStore { - public: - // Create a backing store on the X server. The visual is an Xlib Visual - // describing the format of the target window and the depth is the color - // depth of the X window which will be drawn into. - BackingStoreGLX(RenderWidgetHost* widget, - const gfx::Size& size, - void* visual, - int depth); - - // This is for unittesting only. An object constructed using this constructor - // will silently ignore all paints - BackingStoreGLX(RenderWidgetHost* widget, const gfx::Size& size); - - virtual ~BackingStoreGLX(); - - Display* display() const { return display_; } - XID root_window() const { return root_window_; } - - // Copy from the server-side backing store to the target window - // display: the display of the backing store and target window - // damage: the area to copy - // target: the X id of the target window - void ShowRect(const gfx::Rect& damage, XID target); - - // Paints the server-side backing store data to a SkBitmap. On failure, the - // return bitmap will be isNull(). - SkBitmap PaintRectToBitmap(const gfx::Rect& rect); - -#if defined(TOOLKIT_GTK) - // Paint the backing store into the target's |dest_rect|. - void PaintToRect(const gfx::Rect& dest_rect, GdkDrawable* target); -#endif - - // BackingStore implementation. - virtual size_t MemorySize(); - virtual void PaintRect(base::ProcessHandle process, - TransportDIB* bitmap, - const gfx::Rect& bitmap_rect, - const gfx::Rect& copy_rect); - virtual void ScrollRect(int dx, int dy, - const gfx::Rect& clip_rect, - const gfx::Size& view_size); - - private: - Display* const display_; - - // The parent window for this backing store. - const XID root_window_; - - unsigned int texture_id_; // 0 when uninitialized. - - // The size of the texture loaded into GL. This is 0x0 when there is no - // texture loaded. This may be different than the size of the backing store - // because we could have been resized without yet getting the updated - // bitmap. - gfx::Size texture_size_; - - DISALLOW_COPY_AND_ASSIGN(BackingStoreGLX); -}; - -#endif // CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_GLX_H_ diff --git a/chrome/browser/renderer_host/backing_store_manager_glx.cc b/chrome/browser/renderer_host/backing_store_manager_glx.cc deleted file mode 100644 index d220bb2..0000000 --- a/chrome/browser/renderer_host/backing_store_manager_glx.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2009 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 "chrome/browser/renderer_host/backing_store_manager_glx.h" - -#include <GL/gl.h> -#include <X11/Xutil.h> - -#include "base/scoped_ptr.h" -#include "chrome/common/x11_util.h" - -namespace { - -// scoped_ptr functor for XFree(). -class ScopedPtrXFree { - public: - inline void operator()(void* x) const { - ::XFree(x); - } -}; - -} // namespace - -BackingStoreManagerGlx::BackingStoreManagerGlx() - : display_(x11_util::GetXDisplay()), - tried_to_init_(false), - context_(NULL), - previous_window_id_(0) { -} - -BackingStoreManagerGlx::~BackingStoreManagerGlx() { - if (context_) - glXDestroyContext(display_, context_); -} - -GLXContext BackingStoreManagerGlx::BindContext(XID window_id) { - if (tried_to_init_) { - if (!context_) - return NULL; - if (!previous_window_id_ || previous_window_id_ != window_id) - ::glXMakeCurrent(display_, window_id, context_); - previous_window_id_ = window_id; - return context_; - } - tried_to_init_ = true; - - int attrib_list[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; - scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info( - ::glXChooseVisual(display_, 0, attrib_list)); - if (!visual_info.get()) - return NULL; - - context_ = ::glXCreateContext(display_, visual_info.get(), NULL, True); - ::glXMakeCurrent(display_, window_id, context_); - return context_; -} diff --git a/chrome/browser/renderer_host/backing_store_manager_glx.h b/chrome/browser/renderer_host/backing_store_manager_glx.h deleted file mode 100644 index cf6bbe2..0000000 --- a/chrome/browser/renderer_host/backing_store_manager_glx.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2009 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 CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_MANAGER_GLX_H_ -#define CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_MANAGER_GLX_H_ - -#include <GL/glx.h> -#include <X11/Xlib.h> - -#include "base/basictypes.h" - -class BackingStoreManagerGlx { - public: - BackingStoreManagerGlx(); - ~BackingStoreManagerGlx(); - - Display* display() const { return display_; } - - // Returns the context, creating it if necessary, and binding it to the given - // display and window identified by the XID. This will avoid duplicate calls - // to MakeCurrent if the display/XID hasn't changed from the last call. - // Returns NULL on failure. - GLXContext BindContext(XID window_id); - - private: - Display* display_; - - // Set to true when we've tried to create the context. This prevents us from - // trying to initialize the OpenGL context over and over in the failure case. - bool tried_to_init_; - - // The OpenGL context. Non-NULL when initialized. - GLXContext context_; - - // The last window we've bound our context to. This allows us to avoid - // duplicate "MakeCurrent" calls which are expensive. - XID previous_window_id_; - - DISALLOW_COPY_AND_ASSIGN(BackingStoreManagerGlx); -}; - -#endif // CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_MANAGER_GLX_H_ diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 3ca726c..b4e57df 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -271,9 +271,19 @@ bool BrowserRenderProcessHost::Init(bool is_extensions_process, widget_helper_, request_context); + std::wstring renderer_prefix; +#if defined(OS_POSIX) + // A command prefix is something prepended to the command line of the spawned + // process. It is supported only on POSIX systems. + const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); + renderer_prefix = + browser_command_line.GetSwitchValue(switches::kRendererCmdPrefix); +#endif // defined(OS_POSIX) + // Find the renderer before creating the channel so if this fails early we // return without creating the channel. - FilePath renderer_path = ChildProcessHost::GetChildPath(); + FilePath renderer_path = ChildProcessHost::GetChildPath( + renderer_prefix.empty()); if (renderer_path.empty()) return false; @@ -315,15 +325,20 @@ bool BrowserRenderProcessHost::Init(bool is_extensions_process, // Build command line for renderer. We call AppendRendererCommandLine() // first so the process type argument will appear first. CommandLine* cmd_line = new CommandLine(renderer_path); + if (!renderer_prefix.empty()) + cmd_line->PrependWrapper(renderer_prefix); AppendRendererCommandLine(cmd_line); cmd_line->AppendSwitchWithValue(switches::kProcessChannelID, ASCIIToWide(channel_id)); // Spawn the child process asynchronously to avoid blocking the UI thread. + // As long as there's no renderer prefix, we can use the zygote process + // at this stage. child_process_.reset(new ChildProcessLauncher( #if defined(OS_WIN) FilePath(), #elif defined(POSIX) + renderer_prefix.empty(), base::environment_vector(), channel_->GetClientFileDescriptor(), #endif @@ -453,17 +468,6 @@ void BrowserRenderProcessHost::AppendRendererCommandLine( field_trial_states); } - // A command prefix is something prepended to the command line of the spawned - // process. It is supported only on POSIX systems. -#if defined(OS_POSIX) - if (browser_command_line.HasSwitch(switches::kRendererCmdPrefix)) { - // launch the renderer child with some prefix (usually "gdb --args") - const std::wstring prefix = - browser_command_line.GetSwitchValue(switches::kRendererCmdPrefix); - command_line->PrependWrapper(prefix); - } -#endif // defined(OS_POSIX) - ChildProcessHost::SetCrashReporterCommandLine(command_line); const std::string user_data_dir = diff --git a/chrome/browser/renderer_host/gpu_view_host.cc b/chrome/browser/renderer_host/gpu_view_host.cc index 5addbc0..9b9404a 100644 --- a/chrome/browser/renderer_host/gpu_view_host.cc +++ b/chrome/browser/renderer_host/gpu_view_host.cc @@ -8,7 +8,7 @@ #include "chrome/browser/renderer_host/backing_store_proxy.h" #include "chrome/common/gpu_messages.h" -GpuViewHost::GpuViewHost(RenderWidgetHost* widget, gfx::NativeView parent) +GpuViewHost::GpuViewHost(RenderWidgetHost* widget, GpuNativeWindowHandle parent) : widget_(widget), process_(GpuProcessHost::Get()), routing_id_(0) { @@ -16,8 +16,7 @@ GpuViewHost::GpuViewHost(RenderWidgetHost* widget, gfx::NativeView parent) // TODO(brettw) handle error. return; } - routing_id_ = process_->NewRenderWidgetHostView( - gfx::IdFromNativeView(parent)); + routing_id_ = process_->NewRenderWidgetHostView(parent); } GpuViewHost::~GpuViewHost() { diff --git a/chrome/browser/renderer_host/gpu_view_host.h b/chrome/browser/renderer_host/gpu_view_host.h index 11f417a..adafbf7 100644 --- a/chrome/browser/renderer_host/gpu_view_host.h +++ b/chrome/browser/renderer_host/gpu_view_host.h @@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_RENDERER_HOST_GPU_VIEW_HOST_H_ #define CHROME_BROWSER_RENDERER_HOST_GPU_VIEW_HOST_H_ -#include "app/gfx/native_widget_types.h" #include "base/basictypes.h" +#include "chrome/common/gpu_native_window_handle.h" class BackingStore; class GpuProcessHost; @@ -19,7 +19,7 @@ class Size; // A proxy for the GPU process' window for rendering pages. class GpuViewHost { public: - GpuViewHost(RenderWidgetHost* widget, gfx::NativeView parent); + GpuViewHost(RenderWidgetHost* widget, GpuNativeWindowHandle parent); ~GpuViewHost(); // Creates a new backing store in the GPU process and returns ownership of diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index d7a7ff2..ced2f16 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -39,6 +39,10 @@ static const int kMaxWindowWidth = 4000; static const int kMaxWindowHeight = 4000; +// True if we're doing out-of-process painting via the GPU process. +// TODO(brettw) make this a command line option. +static const bool kUseGPURendering = false; + using WebKit::WebInputEventFactory; // This class is a simple convenience wrapper for Gtk functions. It has only @@ -334,9 +338,6 @@ void RenderWidgetHostViewGtk::InitAsChild() { key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get())); plugin_container_manager_.set_host_widget(view_.get()); gtk_widget_show(view_.get()); - - // Uncomment this line to use out-of-process painting. - // gpu_view_host_.reset(new GpuViewHost(host_, GetNativeView())); } void RenderWidgetHostViewGtk::InitAsPopup( @@ -608,8 +609,19 @@ void RenderWidgetHostViewGtk::AppendInputMethodsContextMenu(MenuGtk* menu) { BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( const gfx::Size& size) { - if (gpu_view_host_.get()) + if (kUseGPURendering) { + // Use a special GPU accelerated backing store. + if (!gpu_view_host_.get()) { + // Here we lazily make the GpuViewHost. This must be allocated when we + // have a native view realized, which happens sometime after creation + // when our owner puts us in the parent window. + DCHECK(GetNativeView()); + XID window_xid = x11_util::GetX11WindowFromGtkWidget(GetNativeView()); + gpu_view_host_.reset(new GpuViewHost(host_, window_xid)); + } return gpu_view_host_->CreateBackingStore(size); + } + return new BackingStoreX(host_, size, x11_util::GetVisualFromGtkWidget(view_.get()), gtk_widget_get_visual(view_.get())->depth); @@ -621,17 +633,13 @@ void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) { } void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { - GdkWindow* window = view_.get()->window; - - if (gpu_view_host_.get()) { + if (kUseGPURendering) { // When we're proxying painting, we don't actually display the web page - // ourselves. We clear it white in case the proxy window isn't visible - // yet we won't show gibberish. - if (window) - gdk_window_clear(window); + // ourselves. return; } + GdkWindow* window = view_.get()->window; DCHECK(!about_to_validate_and_paint_); invalid_rect_ = damage_rect; |