Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Unified Diff: ui/gfx/surface/accelerated_surface_win.cc

Issue 9582003: Support browser side thumbnailing for GPU composited pages on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix test compilation Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/gfx/surface/accelerated_surface_win.cc
diff --git a/ui/gfx/surface/accelerated_surface_win.cc b/ui/gfx/surface/accelerated_surface_win.cc
index 4edc1ee332eb367f6d45813fd488653e42889933..005d6749d156482fe4ca55e139a9858d1fc24a65 100644
--- a/ui/gfx/surface/accelerated_surface_win.cc
+++ b/ui/gfx/surface/accelerated_surface_win.cc
@@ -5,6 +5,7 @@
#include "ui/gfx/surface/accelerated_surface_win.h"
#include <windows.h>
+#include <algorithm>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -145,6 +146,82 @@ void PresentThread::ResetDevice() {
}
}
+bool AcceleratedPresenter::CopyTo(const gfx::Size& size,
+ std::vector<unsigned char>* buf) {
+ base::AutoLock locked(lock_);
+
+ base::win::ScopedComPtr<IDirect3DSurface9> temp_buffer[2];
+ HRESULT hr = swap_chain_->GetBackBuffer(0,
apatrick_chromium 2012/03/08 20:15:47 swap_chain_ will be null if either no surface has
mazda 2012/03/10 07:51:37 Done.
+ D3DBACKBUFFER_TYPE_MONO,
+ temp_buffer[0].Receive());
+ if (FAILED(hr))
+ return false;
+
+ D3DSURFACE_DESC desc;
+ hr = temp_buffer[0]->GetDesc(&desc);
+ if (FAILED(hr) || (desc.Width == 0) || (desc.Height == 0))
+ 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.
+ int buffer_width = desc.Width;
+ int buffer_height = desc.Height;
+ int read_buffer = 0;
+ int write_buffer = 1;
+ do {
apatrick_chromium 2012/03/08 20:15:47 I believe it is possible to call GetRenderTargetDa
mazda 2012/03/10 07:51:37 Done.
+ buffer_width = std::max(buffer_width / 2, size.width());
+ buffer_height = std::max(buffer_height / 2, size.height());
+ temp_buffer[write_buffer].Release();
+ hr = present_thread_->device()->CreateRenderTarget(
vangelis 2012/03/08 17:34:35 Can we avoid creating render targets for all inter
mazda 2012/03/10 07:51:37 Done.
+ buffer_width,
+ buffer_height,
+ D3DFMT_A8R8G8B8,
+ D3DMULTISAMPLE_NONE,
+ 0,
+ TRUE,
+ temp_buffer[write_buffer].Receive(),
+ NULL);
+ if (FAILED(hr))
+ return false;
+
+ hr = present_thread_->device()->StretchRect(temp_buffer[read_buffer],
+ NULL,
+ temp_buffer[write_buffer],
+ NULL,
+ D3DTEXF_LINEAR);
+ if (FAILED(hr))
+ return false;
+
+ std::swap(read_buffer, write_buffer);
+ } while (size != gfx::Size(buffer_width, buffer_height));
+
+ const size_t buf_size = static_cast<size_t>(4 * size.GetArea());
+ if (buf->size() < buf_size) {
+ buf->resize(buf_size);
+ }
+
+ base::win::ScopedComPtr<IDirect3DSurface9> temp_surface;
+ HANDLE handle = reinterpret_cast<HANDLE>(&(*buf)[0]);
+ hr = present_thread_->device()->CreateOffscreenPlainSurface(
+ size.width(),
+ size.height(),
+ D3DFMT_A8R8G8B8,
+ D3DPOOL_SYSTEMMEM,
+ temp_surface.Receive(),
+ &handle);
+ if (FAILED(hr))
+ return false;
+
+ // Copy the data in the temporary buffer to the surface backed by |buf|.
+ hr = present_thread_->device()->GetRenderTargetData(
+ temp_buffer[read_buffer], temp_surface);
+ if (FAILED(hr))
+ return false;
+
+ return true;
+}
+
void PresentThread::Init() {
TRACE_EVENT0("surface", "PresentThread::Init");
d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL));
@@ -431,8 +508,12 @@ bool AcceleratedSurface::Present(HWND window) {
return false;
}
+bool AcceleratedSurface::CopyTo(const gfx::Size& size,
+ std::vector<unsigned char>* buf) {
+ return presenter_->CopyTo(size, buf);
+}
+
void AcceleratedSurface::Suspend() {
if (presenter_)
presenter_->Suspend();
}
-

Powered by Google App Engine
This is Rietveld 408576698