Chromium Code Reviews| Index: ui/surface/accelerated_surface_win.cc |
| diff --git a/ui/surface/accelerated_surface_win.cc b/ui/surface/accelerated_surface_win.cc |
| index 51e2d6125329add171b02b40f32764bea7cfeedf..f57a50a428057a94fa0802b3070f6f0309e24026 100644 |
| --- a/ui/surface/accelerated_surface_win.cc |
| +++ b/ui/surface/accelerated_surface_win.cc |
| @@ -25,6 +25,7 @@ |
| #include "base/tracked_objects.h" |
| #include "base/win/wrapped_window_proc.h" |
| #include "ui/base/win/hwnd_util.h" |
| +#include "ui/gfx/rect.h" |
| #include "ui/gl/gl_switches.h" |
| namespace { |
| @@ -117,19 +118,27 @@ UINT GetPresentationInterval() { |
| return D3DPRESENT_INTERVAL_ONE; |
| } |
| -// Calculate the number necessary to transform |source_size| into |dest_size| |
| -// by repeating downsampling of the image of |source_size| by a factor no more |
| +// Calculate the number necessary to transform |src_subrect| into |dst_size| |
| +// by repeating downsampling of the image of |src_subrect| by a factor no more |
| // than 2. |
| -int GetResampleCount(const gfx::Size& source_size, const gfx::Size& dest_size) { |
| +int GetResampleCount(const gfx::Rect src_subrect, |
|
apatrick_chromium
2012/07/27 18:28:19
Did you mean to make this const gfx::Rect& ?
mazda
2012/07/27 19:29:10
Done. Thanks.
|
| + const gfx::Size& dst_size, |
| + const gfx::Size& back_buffer_size) { |
| + if (src_subrect.size() == dst_size) { |
| + // Even when the size of |src_subrect| is equal to |dst_size|, it is |
| + // necessary to resample pixels at least once unless |src_subrect| exactly |
| + // covers the back buffer. |
| + return (src_subrect == gfx::Rect(back_buffer_size)) ? 0 : 1; |
| + } |
| int width_count = 0; |
| - int width = source_size.width(); |
| - while (width > dest_size.width()) { |
| + int width = src_subrect.width(); |
| + while (width > dst_size.width()) { |
| ++width_count; |
| width >>= 1; |
| } |
| int height_count = 0; |
| - int height = source_size.height(); |
| - while (height > dest_size.height()) { |
| + int height = src_subrect.height(); |
| + while (height > dst_size.height()) { |
| ++height_count; |
| height >>= 1; |
| } |
| @@ -506,7 +515,9 @@ bool AcceleratedPresenter::DoRealPresent(HDC dc) |
| return true; |
| } |
| -bool AcceleratedPresenter::CopyTo(const gfx::Size& size, void* buf) { |
| +bool AcceleratedPresenter::CopyTo(const gfx::Rect& src_subrect, |
| + const gfx::Size& dst_size, |
| + void* buf) { |
| base::AutoLock locked(lock_); |
| if (!swap_chain_) |
| @@ -530,18 +541,19 @@ bool AcceleratedPresenter::CopyTo(const gfx::Size& size, void* buf) { |
| // Set up intermediate buffers needed for downsampling. |
| const int resample_count = |
| - GetResampleCount(gfx::Size(desc.Width, desc.Height), size); |
| + GetResampleCount(src_subrect, dst_size, back_buffer_size); |
| base::win::ScopedComPtr<IDirect3DSurface9> final_surface; |
| base::win::ScopedComPtr<IDirect3DSurface9> temp_buffer[2]; |
| if (resample_count == 0) |
| final_surface = back_buffer; |
| if (resample_count > 0) { |
| if (!CreateTemporarySurface(present_thread_->device(), |
| - size, |
| + dst_size, |
| final_surface.Receive())) |
| return false; |
| } |
| - const gfx::Size half_size = GetHalfSizeNoLessThan(back_buffer_size, size); |
| + const gfx::Size half_size = |
| + GetHalfSizeNoLessThan(src_subrect.size(), dst_size); |
| if (resample_count > 1) { |
| if (!CreateTemporarySurface(present_thread_->device(), |
| half_size, |
| @@ -549,17 +561,18 @@ bool AcceleratedPresenter::CopyTo(const gfx::Size& size, void* buf) { |
| return false; |
| } |
| if (resample_count > 2) { |
| - const gfx::Size quarter_size = GetHalfSizeNoLessThan(half_size, size); |
| + const gfx::Size quarter_size = GetHalfSizeNoLessThan(half_size, dst_size); |
| if (!CreateTemporarySurface(present_thread_->device(), |
| quarter_size, |
| temp_buffer[1].Receive())) |
| return false; |
| } |
| + |
| // Repeat downsampling the surface until its size becomes identical to |
| - // |size|. We keep the factor of each downsampling no more than two because |
| - // using a factor more than two can introduce aliasing. |
| - gfx::Size read_size = back_buffer_size; |
| + // |dst_size|. We keep the factor of each downsampling no more than two |
| + // because using a factor more than two can introduce aliasing. |
| + RECT read_rect = src_subrect.ToRECT(); |
| gfx::Size write_size = half_size; |
| int read_buffer_index = 1; |
| int write_buffer_index = 0; |
| @@ -569,8 +582,7 @@ bool AcceleratedPresenter::CopyTo(const gfx::Size& size, void* buf) { |
| base::win::ScopedComPtr<IDirect3DSurface9> write_buffer = |
| (i == resample_count - 1) ? final_surface : |
| temp_buffer[write_buffer_index]; |
| - RECT read_rect = {0, 0, read_size.width(), read_size.height()}; |
| - RECT write_rect = {0, 0, write_size.width(), write_size.height()}; |
| + RECT write_rect = gfx::Rect(write_size).ToRECT(); |
| hr = present_thread_->device()->StretchRect(read_buffer, |
| &read_rect, |
| write_buffer, |
| @@ -578,18 +590,16 @@ bool AcceleratedPresenter::CopyTo(const gfx::Size& size, void* buf) { |
| D3DTEXF_LINEAR); |
| if (FAILED(hr)) |
| return false; |
| - read_size = write_size; |
| - write_size = GetHalfSizeNoLessThan(write_size, size); |
| + read_rect = write_rect; |
| + write_size = GetHalfSizeNoLessThan(write_size, dst_size); |
| std::swap(read_buffer_index, write_buffer_index); |
| } |
| - DCHECK(size == read_size); |
| - |
| base::win::ScopedComPtr<IDirect3DSurface9> temp_surface; |
| HANDLE handle = reinterpret_cast<HANDLE>(buf); |
| hr = present_thread_->device()->CreateOffscreenPlainSurface( |
| - size.width(), |
| - size.height(), |
| + dst_size.width(), |
| + dst_size.height(), |
| D3DFMT_A8R8G8B8, |
| D3DPOOL_SYSTEMMEM, |
| temp_surface.Receive(), |
| @@ -847,8 +857,10 @@ bool AcceleratedSurface::Present(HDC dc) { |
| return presenter_->Present(dc); |
| } |
| -bool AcceleratedSurface::CopyTo(const gfx::Size& size, void* buf) { |
| - return presenter_->CopyTo(size, buf); |
| +bool AcceleratedSurface::CopyTo(const gfx::Rect& src_subrect, |
| + const gfx::Size& dst_size, |
| + void* buf) { |
| + return presenter_->CopyTo(src_subrect, dst_size, buf); |
| } |
| void AcceleratedSurface::Suspend() { |