diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-21 03:20:31 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-21 03:20:31 +0000 |
commit | 2966d38b0a79d0f7ef6ce41f0dc19d74acf2d058 (patch) | |
tree | 0b35f5f3cb3595707377b46e98569b547ff047f1 /ui/surface/d3d9_utils_win.cc | |
parent | 79d3a6b1916276ad8b7a392ef34c56cbefdc412f (diff) | |
download | chromium_src-2966d38b0a79d0f7ef6ce41f0dc19d74acf2d058.zip chromium_src-2966d38b0a79d0f7ef6ce41f0dc19d74acf2d058.tar.gz chromium_src-2966d38b0a79d0f7ef6ce41f0dc19d74acf2d058.tar.bz2 |
[ui/surface] Separate image processing logic from presentation logic.
The D3D image processing code from AcceleratedPresenter moves to its own class, "ui/surface/accelerated_surface_transformer_win.h". This split allows the image processing code to be tested independently of the present-scheduling system, and so we add unit tests doing exactly that. Utility functions (loading d3d, creating temp surfaces) doing things commonly required by test, transform, and present code -- these functions are moved to a third location, "ui/surface/d3d9_utils_win.h"
The new unit tests -- which live in the ui_unittests binary -- make extensive use of pseudorandom image content, which I think is kind of neat. The tests use D3D HAL devices; I tried to use REF, but it didn't work, as StretchRect+LINEAR is not supported by refrast. So as a result we may have a GPU vendor dependency in these results.
BUG=161537
TEST=new ui_unittests
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=174028
Review URL: https://chromiumcodereview.appspot.com/11464017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174338 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/surface/d3d9_utils_win.cc')
-rw-r--r-- | ui/surface/d3d9_utils_win.cc | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/ui/surface/d3d9_utils_win.cc b/ui/surface/d3d9_utils_win.cc new file mode 100644 index 0000000..85dc668 --- /dev/null +++ b/ui/surface/d3d9_utils_win.cc @@ -0,0 +1,119 @@ +// Copyright (c) 2012 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 "ui/surface/d3d9_utils_win.h" + +#include "base/file_path.h" +#include "base/scoped_native_library.h" +#include "base/win/scoped_comptr.h" +#include "ui/gfx/size.h" + +namespace { + +const wchar_t kD3D9ModuleName[] = L"d3d9.dll"; +const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex"; +typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version, + IDirect3D9Ex **d3d); +} // namespace + +namespace ui_surface_d3d9_utils { + +bool LoadD3D9(base::ScopedNativeLibrary* storage) { + storage->Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); + return storage->is_valid(); +} + +bool CreateDevice(const base::ScopedNativeLibrary& d3d_module, + D3DDEVTYPE device_type, + uint32 presentation_interval, + IDirect3DDevice9Ex** device) { + + Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>( + d3d_module.GetFunctionPointer(kCreate3D9DeviceExName)); + if (!create_func) + return false; + + base::win::ScopedComPtr<IDirect3D9Ex> d3d; + HRESULT hr = create_func(D3D_SDK_VERSION, d3d.Receive()); + if (FAILED(hr)) + return false; + + // Any old window will do to create the device. In practice the window to + // present to is an argument to IDirect3DDevice9::Present. + HWND window = GetShellWindow(); + + D3DPRESENT_PARAMETERS parameters = { 0 }; + parameters.BackBufferWidth = 1; + parameters.BackBufferHeight = 1; + parameters.BackBufferCount = 1; + parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + parameters.hDeviceWindow = window; + parameters.Windowed = TRUE; + parameters.Flags = 0; + parameters.PresentationInterval = presentation_interval; + parameters.SwapEffect = D3DSWAPEFFECT_COPY; + + hr = d3d->CreateDeviceEx( + D3DADAPTER_DEFAULT, + device_type, + window, + D3DCREATE_FPU_PRESERVE | D3DCREATE_SOFTWARE_VERTEXPROCESSING | + D3DCREATE_DISABLE_PSGP_THREADING | D3DCREATE_MULTITHREADED, + ¶meters, + NULL, + device); + return SUCCEEDED(hr); +} + +bool OpenSharedTexture(IDirect3DDevice9* device, + int64 surface_handle, + const gfx::Size& size, + IDirect3DTexture9** opened_texture) { + HANDLE handle = reinterpret_cast<HANDLE>(surface_handle); + HRESULT hr = device->CreateTexture(size.width(), + size.height(), + 1, + D3DUSAGE_RENDERTARGET, + D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, + opened_texture, + &handle); + return SUCCEEDED(hr); +} + +bool CreateTemporaryLockableSurface(IDirect3DDevice9* device, + const gfx::Size& size, + IDirect3DSurface9** surface) { + HRESULT hr = device->CreateRenderTarget( + size.width(), + size.height(), + D3DFMT_A8R8G8B8, + D3DMULTISAMPLE_NONE, + 0, + TRUE, + surface, + NULL); + return SUCCEEDED(hr); +} + +bool CreateTemporaryRenderTargetTexture(IDirect3DDevice9* device, + const gfx::Size& size, + IDirect3DTexture9** texture, + IDirect3DSurface9** render_target) { + HRESULT hr = device->CreateTexture( + size.width(), + size.height(), + 1, // Levels + D3DUSAGE_RENDERTARGET, + D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, + texture, + NULL); + if (!SUCCEEDED(hr)) + return false; + hr = (*texture)->GetSurfaceLevel(0, render_target); + return SUCCEEDED(hr); +} + +} // namespace ui_surface_d3d9_utils |