diff options
author | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-06 17:27:55 +0000 |
---|---|---|
committer | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-06 17:27:55 +0000 |
commit | d9884f501247498d6687ea762afbbab13e4045c9 (patch) | |
tree | e5d160659742028bc1ee7c30fd3117bfbc2bf4ef | |
parent | 964bd398fa49519c9afa19c66d4de56d842e884d (diff) | |
download | chromium_src-d9884f501247498d6687ea762afbbab13e4045c9.zip chromium_src-d9884f501247498d6687ea762afbbab13e4045c9.tar.gz chromium_src-d9884f501247498d6687ea762afbbab13e4045c9.tar.bz2 |
Push (not pull) window geometry for the compositor.
The previous implementation used to poll the environment for the window size every drawing cycle. On Linux this is an expensive operation because it requires a round trip to the X server. This CL pushes window size change to the compositor.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/7212028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91572 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/gfx/compositor/compositor.cc | 3 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor.h | 7 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.cc | 20 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.h | 3 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_win.cc | 88 | ||||
-rw-r--r-- | views/view_unittest.cc | 1 | ||||
-rw-r--r-- | views/widget/native_widget_gtk.cc | 14 | ||||
-rw-r--r-- | views/widget/native_widget_win.cc | 13 |
8 files changed, 87 insertions, 62 deletions
diff --git a/ui/gfx/compositor/compositor.cc b/ui/gfx/compositor/compositor.cc index e5d5ce64..1d68ffc 100644 --- a/ui/gfx/compositor/compositor.cc +++ b/ui/gfx/compositor/compositor.cc @@ -7,7 +7,8 @@ namespace ui { // static -Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { +Compositor* Compositor::Create(gfx::AcceleratedWidget widget, + const gfx::Size& size) { return NULL; } diff --git a/ui/gfx/compositor/compositor.h b/ui/gfx/compositor/compositor.h index bc7b1e1..08b8b38 100644 --- a/ui/gfx/compositor/compositor.h +++ b/ui/gfx/compositor/compositor.h @@ -53,7 +53,8 @@ class Texture : public base::RefCounted<Texture> { class Compositor : public base::RefCounted<Compositor> { public: // Create a compositor from the provided handle. - static Compositor* Create(gfx::AcceleratedWidget widget); + static Compositor* Create(gfx::AcceleratedWidget widget, + const gfx::Size& size); // Creates a new texture. The caller owns the returned object. virtual Texture* CreateTexture() = 0; @@ -70,6 +71,10 @@ class Compositor : public base::RefCounted<Compositor> { // Schedules a paint on the widget this Compositor was created for. virtual void SchedulePaint() = 0; + // Notifies the compositor that the size of the widget that it is + // drawing to has changed. + virtual void OnWidgetSizeChanged(const gfx::Size& size) = 0; + protected: virtual ~Compositor() {} diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc index 8b9a43b..707402d 100644 --- a/ui/gfx/compositor/compositor_gl.cc +++ b/ui/gfx/compositor/compositor_gl.cc @@ -315,8 +315,10 @@ void TextureGL::DrawInternal(const ui::TextureProgramGL& program, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } -CompositorGL::CompositorGL(gfx::AcceleratedWidget widget) - : started_(false) { +CompositorGL::CompositorGL(gfx::AcceleratedWidget widget, + const gfx::Size& size) + : started_(false), + size_(size) { gl_surface_ = gfx::GLSurface::CreateViewGLSurface(widget); gl_context_ = gfx::GLContext::CreateGLContext(NULL, gl_surface_.get()); gl_context_->MakeCurrent(gl_surface_.get()); @@ -336,7 +338,7 @@ void CompositorGL::MakeCurrent() { } gfx::Size CompositorGL::GetSize() { - return gl_surface_->GetSize(); + return size_; } TextureProgramGL* CompositorGL::program_no_swizzle() { @@ -355,8 +357,7 @@ Texture* CompositorGL::CreateTexture() { void CompositorGL::NotifyStart() { started_ = true; gl_context_->MakeCurrent(gl_surface_.get()); - glViewport(0, 0, - gl_surface_->GetSize().width(), gl_surface_->GetSize().height()); + glViewport(0, 0, size_.width(), size_.height()); #if defined(DEBUG) // Clear to 'psychedelic' purple to make it easy to spot un-rendered regions. @@ -386,6 +387,10 @@ void CompositorGL::SchedulePaint() { NOTIMPLEMENTED(); } +void CompositorGL::OnWidgetSizeChanged(const gfx::Size& size) { + size_ = size; +} + bool CompositorGL::InitShaders() { scoped_ptr<TextureProgramGL> temp_program(new TextureProgramNoSwizzleGL()); if (!temp_program->Initialize()) @@ -403,14 +408,15 @@ bool CompositorGL::InitShaders() { } // static -Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { +Compositor* Compositor::Create(gfx::AcceleratedWidget widget, + const gfx::Size& size) { // The following line of code exists soley to disable IO restrictions // on this thread long enough to perform the GL bindings. // TODO(wjmaclean) Remove this when GL initialisation cleaned up. base::ThreadRestrictions::ScopedAllowIO allow_io; if (gfx::GLSurface::InitializeOneOff() && gfx::GetGLImplementation() != gfx::kGLImplementationNone) - return new CompositorGL(widget); + return new CompositorGL(widget, size); return NULL; } diff --git a/ui/gfx/compositor/compositor_gl.h b/ui/gfx/compositor/compositor_gl.h index cb3c49a..7ea0b12 100644 --- a/ui/gfx/compositor/compositor_gl.h +++ b/ui/gfx/compositor/compositor_gl.h @@ -50,7 +50,7 @@ class TextureGL : public Texture { class CompositorGL : public Compositor { public: - explicit CompositorGL(gfx::AcceleratedWidget widget); + CompositorGL(gfx::AcceleratedWidget widget, const gfx::Size& size); virtual ~CompositorGL(); void MakeCurrent(); @@ -66,6 +66,7 @@ class CompositorGL : public Compositor { virtual void NotifyEnd() OVERRIDE; virtual void Blur(const gfx::Rect& bounds) OVERRIDE; virtual void SchedulePaint() OVERRIDE; + virtual void OnWidgetSizeChanged(const gfx::Size& size) OVERRIDE; // Specific to CompositorGL. bool InitShaders(); diff --git a/ui/gfx/compositor/compositor_win.cc b/ui/gfx/compositor/compositor_win.cc index e3ca2a2..19b91b5 100644 --- a/ui/gfx/compositor/compositor_win.cc +++ b/ui/gfx/compositor/compositor_win.cc @@ -84,7 +84,8 @@ class ViewTexture : public Texture { // D3D 10 Compositor implementation. class CompositorWin : public Compositor { public: - explicit CompositorWin(gfx::AcceleratedWidget widget); + CompositorWin(gfx::AcceleratedWidget widget, + const gfx::Size& size); void Init(); @@ -105,6 +106,7 @@ class CompositorWin : public Compositor { virtual void NotifyEnd() OVERRIDE; virtual void Blur(const gfx::Rect& bounds) OVERRIDE; virtual void SchedulePaint() OVERRIDE; + virtual void OnWidgetSizeChanged(const gfx::Size& size) OVERRIDE; private: enum Direction { @@ -116,16 +118,13 @@ class CompositorWin : public Compositor { void Errored(HRESULT error_code); - // Returns the bounds of the hosting window. - gfx::Rect HostBounds(); - void CreateDevice(); void LoadEffects(); void InitVertexLayout(); - void Resize(const gfx::Rect& bounds); + void Resize(const gfx::Size& size); // Updates the kernel used for blurring. Size is the size of the texture // being drawn to along the appropriate axis. @@ -149,8 +148,8 @@ class CompositorWin : public Compositor { gfx::AcceleratedWidget host_; - // Bounds the device was last created at. - gfx::Rect last_bounds_; + // Size the device was last created at. + gfx::Size last_size_; ScopedComPtr<ID3D10Device> device_; ScopedComPtr<IDXGISwapChain> swap_chain_; @@ -322,15 +321,17 @@ void ViewTexture::CreateVertexBuffer(const gfx::Size& size) { vertex_buffer_.Receive())); } -CompositorWin::CompositorWin(gfx::AcceleratedWidget widget) +CompositorWin::CompositorWin(gfx::AcceleratedWidget widget, + const gfx::Size& size) : host_(widget), - technique_(NULL) { + technique_(NULL), + last_size_(size) { } void CompositorWin::Init() { CreateDevice(); LoadEffects(); - Resize(last_bounds_); + Resize(last_size_); InitVertexLayout(); CreateVertexBuffer(); CreateIndexBuffer(); @@ -358,8 +359,8 @@ void CompositorWin::UpdatePerspective(const ui::Transform& transform, D3DXMATRIX scale_matrix; D3DXMatrixScaling( &scale_matrix, - 2.0f / static_cast<float>(last_bounds_.width()), - 2.0f / static_cast<float>(last_bounds_.height()), + 2.0f / static_cast<float>(last_size_.width()), + 2.0f / static_cast<float>(last_size_.height()), 1.0f); // Translate so x and y are from -1,-1 to 1,1. @@ -383,7 +384,7 @@ void CompositorWin::UpdatePerspective(const ui::Transform& transform, } const gfx::Size& CompositorWin::GetHostSize() { - return last_bounds_.size(); + return last_size_; } ID3D10Buffer* CompositorWin::GetTextureIndexBuffer() { @@ -395,10 +396,6 @@ Texture* CompositorWin::CreateTexture() { } void CompositorWin::NotifyStart() { - gfx::Rect bounds = HostBounds(); - if (bounds != last_bounds_) - Resize(bounds); - ID3D10RenderTargetView* target_view = main_render_target_view_.get(); device_->OMSetRenderTargets(1, &target_view, depth_stencil_view_.get()); @@ -468,7 +465,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) { D3DXMatrixIdentity(&identity_matrix); // Horizontal blur from the main texture to blur texture. - UpdateBlurKernel(HORIZONTAL, last_bounds_.width()); + UpdateBlurKernel(HORIZONTAL, last_size_.width()); ID3D10RenderTargetView* target_view = blur_render_target_view_.get(); device_->OMSetRenderTargets(1, &target_view, NULL); RETURN_IF_FAILED( @@ -494,7 +491,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) { RETURN_IF_FAILED( blur_fx_->GetVariableByName("textureMap")->AsShaderResource()-> SetResource(blur_texture_shader_view_.get())); - UpdateBlurKernel(VERTICAL, last_bounds_.height()); + UpdateBlurKernel(VERTICAL, last_size_.height()); target_view = main_render_target_view_.get(); device_->OMSetRenderTargets(1, &target_view, NULL); for(UINT p = 0; p < tech_desc.Passes; ++p) @@ -517,6 +514,10 @@ void CompositorWin::SchedulePaint() { InvalidateRect(host_, &bounds, FALSE); } +void CompositorWin::OnWidgetSizeChanged(const gfx::Size& size) { + Resize(size); +} + CompositorWin::~CompositorWin() { } @@ -525,18 +526,10 @@ void CompositorWin::Errored(HRESULT error_code) { DCHECK(false); } -gfx::Rect CompositorWin::HostBounds() { - RECT client_rect; - GetClientRect(host_, &client_rect); - return gfx::Rect(client_rect); -} - void CompositorWin::CreateDevice() { - last_bounds_ = HostBounds(); - DXGI_SWAP_CHAIN_DESC sd; - sd.BufferDesc.Width = last_bounds_.width(); - sd.BufferDesc.Height = last_bounds_.height(); + sd.BufferDesc.Width = last_size_.width(); + sd.BufferDesc.Height = last_size_.height(); sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -619,8 +612,8 @@ void CompositorWin::InitVertexLayout() { vertex_layout_.Receive())); } -void CompositorWin::Resize(const gfx::Rect& bounds) { - last_bounds_ = bounds; +void CompositorWin::Resize(const gfx::Size& size) { + last_size_ = size; dest_render_target_view_ = NULL; depth_stencil_buffer_ = NULL; @@ -634,17 +627,17 @@ void CompositorWin::Resize(const gfx::Rect& bounds) { blur_texture_ = NULL; blur_texture_shader_view_ = NULL; - CreateTexture(bounds.size(), main_texture_.Receive(), + CreateTexture(size, main_texture_.Receive(), main_render_target_view_.Receive(), main_texture_shader_view_.Receive()); - CreateTexture(bounds.size(), blur_texture_.Receive(), + CreateTexture(size, blur_texture_.Receive(), blur_render_target_view_.Receive(), blur_texture_shader_view_.Receive()); // Resize the swap chain and recreate the render target view. RETURN_IF_FAILED(swap_chain_->ResizeBuffers( - 1, bounds.width(), bounds.height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0)); + 1, size.width(), size.height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0)); ScopedComPtr<ID3D10Texture2D> back_buffer; RETURN_IF_FAILED(swap_chain_->GetBuffer( 0, __uuidof(ID3D10Texture2D), @@ -655,8 +648,8 @@ void CompositorWin::Resize(const gfx::Rect& bounds) { // Create the depth/stencil buffer and view. D3D10_TEXTURE2D_DESC depth_stencil_desc; - depth_stencil_desc.Width = bounds.width(); - depth_stencil_desc.Height = bounds.height(); + depth_stencil_desc.Width = size.width(); + depth_stencil_desc.Height = size.height(); depth_stencil_desc.MipLevels = 1; depth_stencil_desc.ArraySize = 1; depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; @@ -676,10 +669,10 @@ void CompositorWin::Resize(const gfx::Rect& bounds) { // Set the viewport transform. D3D10_VIEWPORT vp; - vp.TopLeftX = bounds.x(); - vp.TopLeftY = bounds.y(); - vp.Width = bounds.width(); - vp.Height = bounds.height(); + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = size.width(); + vp.Height = size.height(); vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; @@ -776,14 +769,14 @@ void CompositorWin::CreateIndexBuffer() { ID3D10Buffer* CompositorWin::CreateVertexBufferForRegion( const gfx::Rect& bounds) { float x = static_cast<float>(bounds.x()) / - static_cast<float>(last_bounds_.width()) * 2.0f - 1.0f; + static_cast<float>(last_size_.width()) * 2.0f - 1.0f; float max_x = - x + bounds.width() / static_cast<float>(last_bounds_.width()) * 2.0f; + x + bounds.width() / static_cast<float>(last_size_.width()) * 2.0f; float y = - static_cast<float>(last_bounds_.height() - bounds.y() - bounds.height()) / - static_cast<float>(last_bounds_.height()) * 2.0f - 1.0f; + static_cast<float>(last_size_.height() - bounds.y() - bounds.height()) / + static_cast<float>(last_size_.height()) * 2.0f - 1.0f; float max_y = - y + bounds.height() / static_cast<float>(last_bounds_.height()) * 2.0f; + y + bounds.height() / static_cast<float>(last_size_.height()) * 2.0f; float tex_x = x / 2.0f + .5f; float max_tex_x = max_x / 2.0f + .5f; float tex_y = 1.0f - (max_y + 1.0f) / 2.0f; @@ -818,8 +811,9 @@ ID3D10Buffer* CompositorWin::CreateVertexBufferForRegion( } // namespace // static -Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { - CompositorWin* compositor = new CompositorWin(widget); +Compositor* Compositor::Create(gfx::AcceleratedWidget widget, + const gfx::Size& size) { + CompositorWin* compositor = new CompositorWin(widget, size); compositor->Init(); return compositor; } diff --git a/views/view_unittest.cc b/views/view_unittest.cc index 6d8a35c..c01fd72 100644 --- a/views/view_unittest.cc +++ b/views/view_unittest.cc @@ -2337,6 +2337,7 @@ class TestCompositor : public ui::Compositor { virtual void NotifyEnd() OVERRIDE {} virtual void Blur(const gfx::Rect& bounds) OVERRIDE {} virtual void SchedulePaint() OVERRIDE {} + virtual void OnWidgetSizeChanged(const gfx::Size& size) OVERRIDE {} private: DISALLOW_COPY_AND_ASSIGN(TestCompositor); diff --git a/views/widget/native_widget_gtk.cc b/views/widget/native_widget_gtk.cc index 777755d..fabacc5 100644 --- a/views/widget/native_widget_gtk.cc +++ b/views/widget/native_widget_gtk.cc @@ -686,9 +686,15 @@ void NativeWidgetGtk::InitNativeWidget(const Widget::InitParams& params) { CreateGtkWidget(modified_params); if (View::get_use_acceleration_when_possible()) { - compositor_ = Widget::compositor_factory() ? - (*Widget::compositor_factory())() : - ui::Compositor::Create(GDK_WINDOW_XID(window_contents_->window)); + if (Widget::compositor_factory()) { + compositor_ = (*Widget::compositor_factory())(); + } else { + gint width, height; + gdk_drawable_get_size(window_contents_->window, &width, &height); + compositor_ = ui::Compositor::Create( + GDK_WINDOW_XID(window_contents_->window), + gfx::Size(width, height)); + } if (compositor_.get()) delegate_->AsWidget()->GetRootView()->SetPaintToLayer(true); } @@ -1290,6 +1296,8 @@ void NativeWidgetGtk::OnSizeAllocate(GtkWidget* widget, if (new_size == size_) return; size_ = new_size; + if (compositor_.get()) + compositor_->OnWidgetSizeChanged(size_); delegate_->OnNativeWidgetSizeChanged(size_); if (GetWidget()->non_client_view()) { diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc index 8802ceca..a694ad4 100644 --- a/views/widget/native_widget_win.cc +++ b/views/widget/native_widget_win.cc @@ -1233,8 +1233,15 @@ LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) { #if defined(VIEWS_COMPOSITOR) if (View::get_use_acceleration_when_possible()) { - compositor_ = Widget::compositor_factory() ? - (*Widget::compositor_factory())() : ui::Compositor::Create(hwnd()); + if (Widget::compositor_factory()) { + compositor_ = (*Widget::compositor_factory())(); + } else { + CRect window_rect; + GetClientRect(&window_rect); + compositor_ = ui::Compositor::Create( + hwnd(), + gfx::Size(window_rect.Width(), window_rect.Height())); + } if (compositor_.get()) delegate_->AsWidget()->GetRootView()->SetPaintToLayer(true); } @@ -2293,6 +2300,8 @@ void NativeWidgetWin::ClientAreaSizeChanged() { GetWindowRect(&r); gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)), std::max(0, static_cast<int>(r.bottom - r.top))); + if (compositor_.get()) + compositor_->OnWidgetSizeChanged(s); delegate_->OnNativeWidgetSizeChanged(s); if (use_layered_buffer_) { layered_window_contents_.reset( |