diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-07 08:24:51 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-07 08:24:51 +0000 |
commit | 7929b6c273b2cd5e1d4158c8bad301cb58312ac1 (patch) | |
tree | ae8c692404dcf8da28034321774409fe30c96d0c | |
parent | f9307cc1f95bbc9c65252abb79900e1dff4da07e (diff) | |
download | chromium_src-7929b6c273b2cd5e1d4158c8bad301cb58312ac1.zip chromium_src-7929b6c273b2cd5e1d4158c8bad301cb58312ac1.tar.gz chromium_src-7929b6c273b2cd5e1d4158c8bad301cb58312ac1.tar.bz2 |
accelerated_surface_transformer_win: Improve readback and scaling performance
by caching temporary surfaces.
This greatly improves the performance of tab capture on current-model Core i3
and Core i5 systems with Intel HD 3000/4000 graphics, and the default drivers
under Win8. On these target systems as much as 15ms was spent in the
~ScopedComPtr dtor, freeing the temporary surfaces.
Patch is intended to be as low-risk as possible while fixing the performance, since most of this code will go away soon when we do not care about non-Aura Windows.
BUG=235502
TEST=surface_gpu_tests
Review URL: https://chromiumcodereview.appspot.com/14763006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198670 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/surface/accelerated_surface_transformer_win.cc | 99 | ||||
-rw-r--r-- | ui/surface/accelerated_surface_transformer_win.h | 30 | ||||
-rw-r--r-- | ui/surface/accelerated_surface_transformer_win_unittest.cc | 34 | ||||
-rw-r--r-- | ui/surface/accelerated_surface_win.cc | 22 | ||||
-rw-r--r-- | ui/surface/d3d9_utils_win.cc | 72 | ||||
-rw-r--r-- | ui/surface/d3d9_utils_win.h | 43 |
6 files changed, 188 insertions, 112 deletions
diff --git a/ui/surface/accelerated_surface_transformer_win.cc b/ui/surface/accelerated_surface_transformer_win.cc index 9a17d1d..0706a1a 100644 --- a/ui/surface/accelerated_surface_transformer_win.cc +++ b/ui/surface/accelerated_surface_transformer_win.cc @@ -167,7 +167,7 @@ bool AcceleratedSurfaceTransformer::DoInit(IDirect3DDevice9* device) { } COMPILE_ASSERT(NUM_SHADERS == 6, must_compile_at_doinit); - base::win::ScopedComPtr<IDirect3DVertexDeclaration9> vertex_declaration; + ScopedComPtr<IDirect3DVertexDeclaration9> vertex_declaration; HRESULT hr = device_->CreateVertexDeclaration(g_vertexElements, vertex_declaration.Receive()); if (FAILED(hr)) @@ -221,6 +221,15 @@ void AcceleratedSurfaceTransformer::ReleaseAll() { vertex_shaders_[i] = NULL; pixel_shaders_[i] = NULL; } + + user_scratch_texture_ = NULL; + uv_scratch_texture_ = NULL; + y_scratch_surface_ = NULL; + u_scratch_surface_ = NULL; + v_scratch_surface_ = NULL; + for (int i = 0; i < arraysize(scaler_scratch_surfaces_); i++) + scaler_scratch_surfaces_[i] = NULL; + device_ = NULL; } void AcceleratedSurfaceTransformer::DetachAll() { @@ -228,6 +237,15 @@ void AcceleratedSurfaceTransformer::DetachAll() { vertex_shaders_[i].Detach(); pixel_shaders_[i].Detach(); } + + user_scratch_texture_.Detach(); + uv_scratch_texture_.Detach(); + y_scratch_surface_.Detach(); + u_scratch_surface_.Detach(); + v_scratch_surface_.Detach(); + for (int i = 0; i < arraysize(scaler_scratch_surfaces_); i++) + scaler_scratch_surfaces_[i].Detach(); + device_.Detach(); } @@ -314,12 +332,28 @@ void AcceleratedSurfaceTransformer::DrawScreenAlignedQuad( } +bool AcceleratedSurfaceTransformer::GetIntermediateTexture( + const gfx::Size& size, + IDirect3DTexture9** texture, + IDirect3DSurface9** texture_level_zero) { + if (!d3d_utils::CreateOrReuseRenderTargetTexture(device(), + size, + &user_scratch_texture_, + texture_level_zero)) + return false; + + *texture = ScopedComPtr<IDirect3DTexture9>(user_scratch_texture_).Detach(); + return true; +} + // Resize an RGB surface using repeated linear interpolation. bool AcceleratedSurfaceTransformer::ResizeBilinear( IDirect3DSurface9* src_surface, const gfx::Rect& src_subrect, IDirect3DSurface9* dst_surface, const gfx::Rect& dst_rect) { + COMPILE_ASSERT(arraysize(scaler_scratch_surfaces_) == 2, surface_count); + gfx::Size src_size = src_subrect.size(); gfx::Size dst_size = dst_rect.size(); @@ -329,22 +363,19 @@ bool AcceleratedSurfaceTransformer::ResizeBilinear( HRESULT hr = S_OK; // Set up intermediate buffers needed for downsampling. const int resample_count = GetResampleCount(src_subrect, dst_size); - base::win::ScopedComPtr<IDirect3DSurface9> temp_buffer[2]; const gfx::Size half_size = GetHalfSizeNoLessThan(src_subrect.size(), dst_size); if (resample_count > 1) { - TRACE_EVENT0("gpu", "CreateTemporarySurface"); - if (!d3d_utils::CreateTemporaryLockableSurface(device(), - half_size, - temp_buffer[0].Receive())) + if (!d3d_utils::CreateOrReuseLockableSurface(device(), + half_size, + &scaler_scratch_surfaces_[0])) return false; } if (resample_count > 2) { - TRACE_EVENT0("gpu", "CreateTemporarySurface"); const gfx::Size quarter_size = GetHalfSizeNoLessThan(half_size, dst_size); - if (!d3d_utils::CreateTemporaryLockableSurface(device(), - quarter_size, - temp_buffer[1].Receive())) + if (!d3d_utils::CreateOrReuseLockableSurface(device(), + quarter_size, + &scaler_scratch_surfaces_[1])) return false; } @@ -358,14 +389,14 @@ bool AcceleratedSurfaceTransformer::ResizeBilinear( for (int i = 0; i < resample_count; ++i) { TRACE_EVENT0("gpu", "StretchRect"); IDirect3DSurface9* read_buffer = - (i == 0) ? src_surface : temp_buffer[read_buffer_index]; + (i == 0) ? src_surface : scaler_scratch_surfaces_[read_buffer_index]; IDirect3DSurface9* write_buffer; RECT write_rect; if (i == resample_count - 1) { write_buffer = dst_surface; write_rect = dst_rect.ToRECT(); } else { - write_buffer = temp_buffer[write_buffer_index]; + write_buffer = scaler_scratch_surfaces_[write_buffer_index]; write_rect = gfx::Rect(write_size).ToRECT(); } @@ -468,7 +499,7 @@ bool AcceleratedSurfaceTransformer::ReadByGetRenderTargetData( int dst_num_rows, int dst_stride) { HRESULT hr = 0; - base::win::ScopedComPtr<IDirect3DSurface9> system_surface; + ScopedComPtr<IDirect3DSurface9> system_surface; gfx::Size src_size = d3d_utils::GetSize(gpu_surface); // Depending on pitch and alignment, we might be able to wrap |dst| in an @@ -525,12 +556,23 @@ bool AcceleratedSurfaceTransformer::AllocYUVBuffers( // U and V are half the size (rounded up) of Y. *uv_size = gfx::Size((y_size->width() + 1) / 2, (y_size->height() + 1) / 2); - if (!d3d_utils::CreateTemporaryLockableSurface(device(), *y_size, dst_y)) + if (!d3d_utils::CreateOrReuseLockableSurface(device(), *y_size, + &y_scratch_surface_)) { return false; - if (!d3d_utils::CreateTemporaryLockableSurface(device(), *uv_size, dst_u)) + } + if (!d3d_utils::CreateOrReuseLockableSurface(device(), *uv_size, + &u_scratch_surface_)) { return false; - if (!d3d_utils::CreateTemporaryLockableSurface(device(), *uv_size, dst_v)) + } + if (!d3d_utils::CreateOrReuseLockableSurface(device(), *uv_size, + &v_scratch_surface_)) { return false; + } + + *dst_y = ScopedComPtr<IDirect3DSurface9>(y_scratch_surface_).Detach(); + *dst_u = ScopedComPtr<IDirect3DSurface9>(u_scratch_surface_).Detach(); + *dst_v = ScopedComPtr<IDirect3DSurface9>(v_scratch_surface_).Detach(); + return true; } @@ -550,12 +592,12 @@ bool AcceleratedSurfaceTransformer::TransformRGBToYV12_MRT( // Create an intermediate surface to hold the UUVV values. This is color // target 1 for the first pass, and texture 0 for the second pass. Its // values are not read afterwards. - base::win::ScopedComPtr<IDirect3DTexture9> uv_as_texture; - base::win::ScopedComPtr<IDirect3DSurface9> uv_as_surface; - if (!d3d_utils::CreateTemporaryRenderTargetTexture(device(), - packed_y_size, - uv_as_texture.Receive(), - uv_as_surface.Receive())) { + + ScopedComPtr<IDirect3DSurface9> uv_as_surface; + if (!d3d_utils::CreateOrReuseRenderTargetTexture(device(), + packed_y_size, + &uv_scratch_texture_, + uv_as_surface.Receive())) { return false; } @@ -592,7 +634,7 @@ bool AcceleratedSurfaceTransformer::TransformRGBToYV12_MRT( device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - device()->SetTexture(0, uv_as_texture); + device()->SetTexture(0, uv_scratch_texture_); device()->SetRenderTarget(0, dst_u); device()->SetRenderTarget(1, dst_v); DrawScreenAlignedQuad(packed_y_size); @@ -614,7 +656,7 @@ bool AcceleratedSurfaceTransformer::TransformRGBToYV12_WithoutMRT( ScopedRenderTargetRestorer color0_restorer(device(), 0); - base::win::ScopedComPtr<IDirect3DTexture9> scaled_src_surface; + ScopedComPtr<IDirect3DTexture9> scaled_src_surface; // If scaling is requested, do it to a temporary texture. The MRT path // gets a scale for free, so we need to support it here too (even though @@ -622,16 +664,15 @@ bool AcceleratedSurfaceTransformer::TransformRGBToYV12_WithoutMRT( if (d3d_utils::GetSize(src_surface) == dst_size) { scaled_src_surface = src_surface; } else { - base::win::ScopedComPtr<IDirect3DSurface9> dst_level0; - if (!d3d_utils::CreateTemporaryRenderTargetTexture( - device(), dst_size, - scaled_src_surface.Receive(), dst_level0.Receive())) { + ScopedComPtr<IDirect3DSurface9> dst_level0; + if (!d3d_utils::CreateOrReuseRenderTargetTexture( + device(), dst_size, &uv_scratch_texture_, dst_level0.Receive())) { return false; } - if (!Copy(src_surface, dst_level0, dst_size)) { return false; } + scaled_src_surface = uv_scratch_texture_; } // Input texture is the same for all three passes. diff --git a/ui/surface/accelerated_surface_transformer_win.h b/ui/surface/accelerated_surface_transformer_win.h index 9e23230..b04d0ab 100644 --- a/ui/surface/accelerated_surface_transformer_win.h +++ b/ui/surface/accelerated_surface_transformer_win.h @@ -51,12 +51,21 @@ class SURFACE_EXPORT AcceleratedSurfaceTransformer { IDirect3DSurface9* dst_surface, const gfx::Size& dst_size); - // Draw a textured quad to a surface. + // Draw a textured quad to a surface. bool Copy( IDirect3DTexture9* src_texture, IDirect3DSurface9* dst_surface, const gfx::Size& dst_size); + // Get an intermediate buffer of a particular |size|, that can be used as the + // output of one transformation and the to another. The returned surface + // belongs to an internal cache, and is invalidated by a subsequent call to + // this method. + bool GetIntermediateTexture( + const gfx::Size& size, + IDirect3DTexture9** texture, + IDirect3DSurface9** texture_level_zero); + // Resize a surface using repeated bilinear interpolation. bool ResizeBilinear( IDirect3DSurface9* src_surface, @@ -82,8 +91,9 @@ class SURFACE_EXPORT AcceleratedSurfaceTransformer { // If |src_texture|'s dimensions do not match |dst_size|, the source will be // bilinearly interpolated during conversion. // - // Returns true if successful. Caller must be certain to free the buffers - // even if this function returns false. + // Returns true if successful. Caller must be certain to release the surfaces + // even if this function returns false. The returned surfaces belong to an + // internal cache, and are invalidated by a subsequent call to this method. bool TransformRGBToYV12( IDirect3DTexture9* src_texture, const gfx::Size& dst_size, @@ -159,8 +169,9 @@ class SURFACE_EXPORT AcceleratedSurfaceTransformer { // roundings. The sizes of the buffers (in terms of ARGB pixels) are returned // as |packed_y_size| and |packed_uv_size|. // - // Returns true if successful. Caller must be certain to free the buffers - // even if this function returns false. + // Returns true if successful. Caller must be certain to release the surfaces + // even if this function returns false. The returned belong to an internal + // cache. bool AllocYUVBuffers( const gfx::Size& dst_size, gfx::Size* packed_y_size, @@ -199,6 +210,15 @@ class SURFACE_EXPORT AcceleratedSurfaceTransformer { base::win::ScopedComPtr<IDirect3DDevice9> device_; base::win::ScopedComPtr<IDirect3DVertexShader9> vertex_shaders_[NUM_SHADERS]; base::win::ScopedComPtr<IDirect3DPixelShader9> pixel_shaders_[NUM_SHADERS]; + + // Temporary and scratch surfaces; cached to avoid frequent reallocation. + base::win::ScopedComPtr<IDirect3DTexture9> user_scratch_texture_; + base::win::ScopedComPtr<IDirect3DTexture9> uv_scratch_texture_; + base::win::ScopedComPtr<IDirect3DSurface9> y_scratch_surface_; + base::win::ScopedComPtr<IDirect3DSurface9> u_scratch_surface_; + base::win::ScopedComPtr<IDirect3DSurface9> v_scratch_surface_; + base::win::ScopedComPtr<IDirect3DSurface9> scaler_scratch_surfaces_[2]; + bool device_supports_multiple_render_targets_; const BYTE* vertex_shader_sources_[NUM_SHADERS]; const BYTE* pixel_shader_sources_[NUM_SHADERS]; diff --git a/ui/surface/accelerated_surface_transformer_win_unittest.cc b/ui/surface/accelerated_surface_transformer_win_unittest.cc index 1265e6e..fb19c66 100644 --- a/ui/surface/accelerated_surface_transformer_win_unittest.cc +++ b/ui/surface/accelerated_surface_transformer_win_unittest.cc @@ -349,11 +349,11 @@ bool AssertSameColor(uint8 color_a, uint8 color_b) { set_color_error_tolerance(4); base::win::ScopedComPtr<IDirect3DSurface9> src, dst; - ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface( - device(), src_size, src.Receive())) + ASSERT_TRUE(d3d_utils::CreateOrReuseLockableSurface( + device(), src_size, &src)) << "Could not create src render target"; - ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface( - device(), dst_size, dst.Receive())) + ASSERT_TRUE(d3d_utils::CreateOrReuseLockableSurface( + device(), dst_size, &dst)) << "Could not create dst render target"; FillSymmetricRandomCheckerboard(src, src_size, checkerboard_size); @@ -367,12 +367,12 @@ bool AssertSameColor(uint8 color_a, uint8 color_b) { void CreateRandomCheckerboardTexture( const gfx::Size& size, int checkerboard_size, - IDirect3DSurface9** reference_surface, - IDirect3DTexture9** result) { + base::win::ScopedComPtr<IDirect3DSurface9>* reference_surface, + base::win::ScopedComPtr<IDirect3DTexture9>* result) { base::win::ScopedComPtr<IDirect3DSurface9> dst; - ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(device(), size, + ASSERT_TRUE(d3d_utils::CreateOrReuseLockableSurface(device(), size, reference_surface)); - ASSERT_TRUE(d3d_utils::CreateTemporaryRenderTargetTexture(device(), size, + ASSERT_TRUE(d3d_utils::CreateOrReuseRenderTargetTexture(device(), size, result, dst.Receive())); FillRandomCheckerboard(*reference_surface, size, checkerboard_size); ASSERT_HRESULT_SUCCEEDED( @@ -411,8 +411,7 @@ bool AssertSameColor(uint8 color_a, uint8 color_b) { base::win::ScopedComPtr<IDirect3DSurface9> dst, reference_pattern; base::win::ScopedComPtr<IDirect3DTexture9> src; - CreateRandomCheckerboardTexture(size, 1, reference_pattern.Receive(), - src.Receive()); + CreateRandomCheckerboardTexture(size, 1, &reference_pattern, &src); // Alloc a slightly larger image 75% of the time, to test that the // viewport is set properly. @@ -420,8 +419,8 @@ bool AssertSameColor(uint8 color_a, uint8 color_b) { gfx::Size alloc_size((size.width() + kAlign - 1) / kAlign * kAlign, (size.height() + kAlign - 1) / kAlign * kAlign); - ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(device(), alloc_size, - dst.Receive())) << "Could not create dst render target."; + ASSERT_TRUE(d3d_utils::CreateOrReuseLockableSurface(device(), alloc_size, + &dst)) << "Could not create dst render target."; ASSERT_TRUE(gpu_ops->CopyInverted(src, dst, size)); AssertIsInvertedCopy(size, reference_pattern, dst); @@ -479,8 +478,8 @@ bool AssertSameColor(uint8 color_a, uint8 color_b) { // (or maybe more pixels = more test trials). Results are usually to an // error of 1, but we must use a tolerance of 3. set_color_error_tolerance(3); - CreateRandomCheckerboardTexture( - src_size, checkerboard_size, reference.Receive(), src.Receive()); + CreateRandomCheckerboardTexture(src_size, checkerboard_size, &reference, + &src); gfx::Size packed_y_size, packed_uv_size; @@ -523,10 +522,9 @@ bool AssertSameColor(uint8 color_a, uint8 color_b) { // We'll call Copy to do the bilinear scaling if needed. base::win::ScopedComPtr<IDirect3DSurface9> reference_scaled; ASSERT_TRUE( - d3d_utils::CreateTemporaryLockableSurface( - device(), dst_size, reference_scaled.Receive())); - ASSERT_TRUE( - gpu_ops->Copy(src, reference_scaled, dst_size)); + d3d_utils::CreateOrReuseLockableSurface( + device(), dst_size, &reference_scaled)); + ASSERT_TRUE(gpu_ops->Copy(src, reference_scaled, dst_size)); BeforeLockWorkaround(); reference_rgb_scaled = ToSkBitmap(reference_scaled, false); } diff --git a/ui/surface/accelerated_surface_win.cc b/ui/surface/accelerated_surface_win.cc index 1223616..03d4880 100644 --- a/ui/surface/accelerated_surface_win.cc +++ b/ui/surface/accelerated_surface_win.cc @@ -456,10 +456,9 @@ bool AcceleratedPresenter::DoCopyToARGB(const gfx::Rect& requested_src_subrect, src_subrect.Intersect(gfx::Rect(back_buffer_size)); base::win::ScopedComPtr<IDirect3DSurface9> final_surface; { - TRACE_EVENT0("gpu", "CreateTemporaryLockableSurface"); - if (!d3d_utils::CreateTemporaryLockableSurface(present_thread_->device(), - dst_size, - final_surface.Receive())) { + if (!d3d_utils::CreateOrReuseLockableSurface(present_thread_->device(), + dst_size, + &final_surface)) { LOG(ERROR) << "Failed to create temporary lockable surface"; return false; } @@ -527,17 +526,12 @@ bool AcceleratedPresenter::DoCopyToYUV( gfx::Rect src_subrect = requested_src_subrect; src_subrect.Intersect(gfx::Rect(back_buffer_size)); - base::win::ScopedComPtr<IDirect3DTexture9> resized_as_texture; base::win::ScopedComPtr<IDirect3DSurface9> resized; - { - TRACE_EVENT0("gpu", "CreateTemporaryRenderTargetTexture"); - if (!d3d_utils::CreateTemporaryRenderTargetTexture( - present_thread_->device(), - dst_size, - resized_as_texture.Receive(), - resized.Receive())) { - return false; - } + base::win::ScopedComPtr<IDirect3DTexture9> resized_as_texture; + if (!gpu_ops->GetIntermediateTexture(dst_size, + resized_as_texture.Receive(), + resized.Receive())) { + return false; } // Shrink the source to fit entirely in the destination while preserving diff --git a/ui/surface/d3d9_utils_win.cc b/ui/surface/d3d9_utils_win.cc index b4d210b..a95ffb6 100644 --- a/ui/surface/d3d9_utils_win.cc +++ b/ui/surface/d3d9_utils_win.cc @@ -4,6 +4,7 @@ #include "ui/surface/d3d9_utils_win.h" +#include "base/debug/trace_event.h" #include "base/files/file_path.h" #include "base/scoped_native_library.h" #include "base/win/scoped_comptr.h" @@ -71,6 +72,7 @@ bool OpenSharedTexture(IDirect3DDevice9* device, int64 surface_handle, const gfx::Size& size, IDirect3DTexture9** opened_texture) { + TRACE_EVENT0("gpu", "OpenSharedTexture"); HANDLE handle = reinterpret_cast<HANDLE>(surface_handle); HRESULT hr = device->CreateTexture(size.width(), size.height(), @@ -83,37 +85,49 @@ bool OpenSharedTexture(IDirect3DDevice9* device, 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 CreateOrReuseLockableSurface( + IDirect3DDevice9* device, + const gfx::Size& size, + base::win::ScopedComPtr<IDirect3DSurface9>* surface) { + if (!*surface || GetSize(*surface) != size) { + TRACE_EVENT0("gpu", "CreateRenderTarget"); + surface->Release(); + HRESULT hr = device->CreateRenderTarget( + size.width(), + size.height(), + D3DFMT_A8R8G8B8, + D3DMULTISAMPLE_NONE, + 0, + TRUE, + surface->Receive(), + NULL); + if (FAILED(hr)) + return false; + } + return true; } -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); +bool CreateOrReuseRenderTargetTexture( + IDirect3DDevice9* device, + const gfx::Size& size, + base::win::ScopedComPtr<IDirect3DTexture9>* texture, + IDirect3DSurface9** render_target) { + if (!*texture || GetSize(*texture) != size) { + TRACE_EVENT0("gpu", "CreateTexture"); + texture->Release(); + HRESULT hr = device->CreateTexture( + size.width(), + size.height(), + 1, // Levels + D3DUSAGE_RENDERTARGET, + D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, + texture->Receive(), + NULL); + if (!SUCCEEDED(hr)) + return false; + } + HRESULT hr = (*texture)->GetSurfaceLevel(0, render_target); return SUCCEEDED(hr); } diff --git a/ui/surface/d3d9_utils_win.h b/ui/surface/d3d9_utils_win.h index 4f11a3a..58d1918 100644 --- a/ui/surface/d3d9_utils_win.h +++ b/ui/surface/d3d9_utils_win.h @@ -11,6 +11,7 @@ #include <d3d9.h> #include "base/basictypes.h" +#include "base/win/scoped_comptr.h" #include "ui/surface/surface_export.h" namespace base { @@ -35,10 +36,11 @@ bool CreateDevice(const base::ScopedNativeLibrary& d3d_module, uint32 presentation_interval, IDirect3DDevice9Ex** device); -// Calls the Vista+ (WDDM1.0) variant of CreateTexture that semantically -// opens a texture allocated (possibly in another process) as shared. The -// shared texture is identified by its surface handle. The resulting texture -// is written into |opened_texture|. +// Calls the Vista+ (WDDM1.0) variant of CreateTexture that semantically opens a +// texture allocated as shared. In this way textures allocated by another +// process can be used by a D3D context in this process. The shared texture is +// identified by its surface handle. The resulting texture is written into +// |opened_texture|. // // Returns true on success. SURFACE_EXPORT @@ -47,24 +49,31 @@ bool OpenSharedTexture(IDirect3DDevice9* device, const gfx::Size& size, IDirect3DTexture9** opened_texture); -// Create a one-off lockable surface of a specified size. +// Ensures that |surface| is a lockable surface of a specified |size|. If +// |*surface| is non-null and has dimensions that match |size|, it is reused. +// Otherwise, a new resource is created and the old one (if any) is freed. // // Returns true on success. SURFACE_EXPORT -bool CreateTemporaryLockableSurface(IDirect3DDevice9* device, - const gfx::Size& size, - IDirect3DSurface9** surface); - -// Create a one-off renderable texture of a specified size. The texture object -// as well as the surface object for the texture's level 0 is returned (callers -// almost always need to use both). +bool CreateOrReuseLockableSurface( + IDirect3DDevice9* device, + const gfx::Size& size, + base::win::ScopedComPtr<IDirect3DSurface9>* surface); + +// Ensures that |texture| is a render target texture of a specified |size|. If +// |*texture| is non-null and has dimensions that match |size|, it is reused. +// Otherwise, a new resource is created and the old one (if any) is freed. +// +// A reference to level 0 of the resulting texture is placed into +// |render_target|. // // Returns true on success. SURFACE_EXPORT -bool CreateTemporaryRenderTargetTexture(IDirect3DDevice9* device, - const gfx::Size& size, - IDirect3DTexture9** texture, - IDirect3DSurface9** render_target); +bool CreateOrReuseRenderTargetTexture( + IDirect3DDevice9* device, + const gfx::Size& size, + base::win::ScopedComPtr<IDirect3DTexture9>* texture, + IDirect3DSurface9** render_target); SURFACE_EXPORT gfx::Size GetSize(IDirect3DTexture9* texture); @@ -74,4 +83,4 @@ gfx::Size GetSize(IDirect3DSurface9* surface); } // namespace ui_surface_d3d9_utils -#endif // UI_SURFACE_D3D9_UTILS_WIN_H_
\ No newline at end of file +#endif // UI_SURFACE_D3D9_UTILS_WIN_H_ |