| 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..698f5fcd3d3dbb53c5c241514b1bb8c9de93187c 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,
|
| + 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() {
|
|
|