1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef UI_SURFACE_ACCELERATED_SURFACE_TRANSFORMER_WIN_H_
6 #define UI_SURFACE_ACCELERATED_SURFACE_TRANSFORMER_WIN_H_
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/synchronization/lock.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/win/scoped_comptr.h"
16 #include "ui/gfx/native_widget_types.h"
17 #include "ui/gfx/size.h"
18 #include "ui/surface/surface_export.h"
25 // Provides useful image filtering operations that are implemented
26 // efficiently on DirectX9-class hardware using fragment programs.
27 class SURFACE_EXPORT AcceleratedSurfaceTransformer
{
29 // Constructs an uninitialized surface transformer. Call Init() before
30 // using the resulting object.
31 AcceleratedSurfaceTransformer();
33 // Init() initializes the transformer to operate on a device. This must be
34 // called before any other method of this class, and it must be called
35 // again after ReleaseAll() or DetachAll() before the class is used.
37 // Returns true if successful.
38 bool Init(IDirect3DDevice9
* device
);
40 // ReleaseAll() releases all direct3d resource references.
43 // DetachAll() leaks all direct3d resource references. This exists in order to
44 // work around particular driver bugs, and should only be called at shutdown.
45 // TODO(ncarter): Update the leak expectations before checkin.
48 // Draw a textured quad to a surface, flipping orientation in the y direction.
50 IDirect3DTexture9
* src_texture
,
51 IDirect3DSurface9
* dst_surface
,
52 const gfx::Size
& dst_size
);
54 // Draw a textured quad to a surface.
56 IDirect3DTexture9
* src_texture
,
57 IDirect3DSurface9
* dst_surface
,
58 const gfx::Size
& dst_size
);
60 // Resize a surface using repeated bilinear interpolation.
62 IDirect3DSurface9
* src_surface
,
63 const gfx::Rect
& src_subrect
,
64 IDirect3DSurface9
* dst_surface
,
65 const gfx::Rect
& dst_subrect
);
67 // Color format conversion from RGB to planar YV12 (also known as YUV420).
69 // YV12 is effectively a twelve bit per pixel format consisting of a full-
70 // size y (luminance) plane and half-width, half-height u and v (blue and
71 // red chrominance) planes. This method will allocate three lockable surfaces,
72 // one for each plane, and return them via the arguments |dst_y|, |dst_u|,
73 // and |dst_v|. These surface will be created with an ARGB D3DFORMAT, but
74 // should be interpreted as the appropriate single-byte format when locking.
76 // The dimensions of the outputs (when interpreted as single-component data)
78 // |dst_y| : width and height exactly |dst_size|
79 // |dst_u| : width and height are each half of |dst_size|, rounded up.
80 // |dst_v| : width and height are each half of |dst_size|, rounded up.
82 // If |src_texture|'s dimensions do not match |dst_size|, the source will be
83 // bilinearly interpolated during conversion.
85 // Returns true if successful. Caller must be certain to free the buffers
86 // even if this function returns false.
87 bool TransformRGBToYV12(
88 IDirect3DTexture9
* src_texture
,
89 const gfx::Size
& dst_size
,
90 IDirect3DSurface9
** dst_y
,
91 IDirect3DSurface9
** dst_u
,
92 IDirect3DSurface9
** dst_v
);
94 // Synchronously copy from a D3D surface into a caller-allocated buffer. This
95 // will dispatch to one of a couple techniques, depending on which is
96 // determined to be the faster method for the current device.
97 bool ReadFast(IDirect3DSurface9
* gpu_surface
,
99 int dst_bytes_per_row
,
103 // Do a read using a particular technique. Which of these is faster depends on
104 // the hardware. Intended for testing; production code ought to call
106 bool ReadByLockAndCopy(IDirect3DSurface9
* gpu_surface
,
108 int dst_bytes_per_row
,
111 bool ReadByGetRenderTargetData(IDirect3DSurface9
* gpu_surface
,
113 int dst_bytes_per_row
,
118 friend class AcceleratedSurfaceTransformerTest
;
119 FRIEND_TEST_ALL_PREFIXES(AcceleratedSurfaceTransformerTest
, Init
);
123 RGB_TO_YV12_FAST__PASS_1_OF_2
,
124 RGB_TO_YV12_FAST__PASS_2_OF_2
,
125 RGB_TO_YV12_SLOW__PASS_1_OF_3
,
126 RGB_TO_YV12_SLOW__PASS_2_OF_3
,
127 RGB_TO_YV12_SLOW__PASS_3_OF_3
,
131 // Efficient RGB->YV12 in two passes, but requires a device capable of writing
132 // multiple render targets at the same time.
134 // Returns true if successful.
135 bool TransformRGBToYV12_MRT(
136 IDirect3DTexture9
* src_surface
,
137 const gfx::Size
& dst_size
,
138 const gfx::Size
& packed_y_size
,
139 const gfx::Size
& packed_uv_size
,
140 IDirect3DSurface9
* dst_y
,
141 IDirect3DSurface9
* dst_u
,
142 IDirect3DSurface9
* dst_v
);
144 // Slower, less efficient RGB->YV12; does not require the device to have
145 // multiple render target capability. Runs at about half speed of the fast
148 // Returns true if successful.
149 bool TransformRGBToYV12_WithoutMRT(
150 IDirect3DTexture9
* src_surface
,
151 const gfx::Size
& dst_size
,
152 const gfx::Size
& packed_y_size
,
153 const gfx::Size
& packed_uv_size
,
154 IDirect3DSurface9
* dst_y
,
155 IDirect3DSurface9
* dst_u
,
156 IDirect3DSurface9
* dst_v
);
158 // Helper to allocate appropriately size YUV buffers, accounting for various
159 // roundings. The sizes of the buffers (in terms of ARGB pixels) are returned
160 // as |packed_y_size| and |packed_uv_size|.
162 // Returns true if successful. Caller must be certain to free the buffers
163 // even if this function returns false.
164 bool AllocYUVBuffers(
165 const gfx::Size
& dst_size
,
166 gfx::Size
* packed_y_size
,
167 gfx::Size
* packed_uv_size
,
168 IDirect3DSurface9
** dst_y
,
169 IDirect3DSurface9
** dst_u
,
170 IDirect3DSurface9
** dst_v
);
172 bool CopyWithTextureScale(
173 IDirect3DTexture9
* src_texture
,
174 IDirect3DSurface9
* dst_surface
,
175 const gfx::Size
& dst_size
,
176 float texture_scale_x
,
177 float texture_scale_y
);
179 // Set the active vertex and pixel shader combination.
181 // Returns true if successful.
182 bool SetShaderCombo(ShaderCombo combo
);
184 // Compiles a vertex and pixel shader combination, if not already compiled.
186 // Returns true if successful.
187 bool CompileShaderCombo(ShaderCombo shader_combo_name
);
189 bool DoInit(IDirect3DDevice9
* device
);
191 void DrawScreenAlignedQuad(const gfx::Size
& dst_size
);
193 bool device_supports_multiple_render_targets() const {
194 return device_supports_multiple_render_targets_
;
197 IDirect3DDevice9
* device();
199 base::win::ScopedComPtr
<IDirect3DDevice9
> device_
;
200 base::win::ScopedComPtr
<IDirect3DVertexShader9
> vertex_shaders_
[NUM_SHADERS
];
201 base::win::ScopedComPtr
<IDirect3DPixelShader9
> pixel_shaders_
[NUM_SHADERS
];
202 bool device_supports_multiple_render_targets_
;
203 const BYTE
* vertex_shader_sources_
[NUM_SHADERS
];
204 const BYTE
* pixel_shader_sources_
[NUM_SHADERS
];
205 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceTransformer
);
208 #endif // UI_SURFACE_ACCELERATED_SURFACE_TRANSFORMER_WIN_H_