Replace the deprecated __attribute__((no_address_safety_analysis))
[chromium-blink-merge.git] / ui / surface / accelerated_surface_transformer_win.h
blobb04d0ab6977b0cf37c004f5be12e29c331395a50
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_
8 #include <d3d9.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"
20 namespace gfx {
21 class Size;
22 class Rect;
23 } // namespace gfx
25 // Provides useful image filtering operations that are implemented
26 // efficiently on DirectX9-class hardware using fragment programs.
27 class SURFACE_EXPORT AcceleratedSurfaceTransformer {
28 public:
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.
41 void ReleaseAll();
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.
46 void DetachAll();
48 // Draw a textured quad to a surface, flipping orientation in the y direction.
49 bool CopyInverted(
50 IDirect3DTexture9* src_texture,
51 IDirect3DSurface9* dst_surface,
52 const gfx::Size& dst_size);
54 // Draw a textured quad to a surface.
55 bool Copy(
56 IDirect3DTexture9* src_texture,
57 IDirect3DSurface9* dst_surface,
58 const gfx::Size& dst_size);
60 // Get an intermediate buffer of a particular |size|, that can be used as the
61 // output of one transformation and the to another. The returned surface
62 // belongs to an internal cache, and is invalidated by a subsequent call to
63 // this method.
64 bool GetIntermediateTexture(
65 const gfx::Size& size,
66 IDirect3DTexture9** texture,
67 IDirect3DSurface9** texture_level_zero);
69 // Resize a surface using repeated bilinear interpolation.
70 bool ResizeBilinear(
71 IDirect3DSurface9* src_surface,
72 const gfx::Rect& src_subrect,
73 IDirect3DSurface9* dst_surface,
74 const gfx::Rect& dst_subrect);
76 // Color format conversion from RGB to planar YV12 (also known as YUV420).
78 // YV12 is effectively a twelve bit per pixel format consisting of a full-
79 // size y (luminance) plane and half-width, half-height u and v (blue and
80 // red chrominance) planes. This method will allocate three lockable surfaces,
81 // one for each plane, and return them via the arguments |dst_y|, |dst_u|,
82 // and |dst_v|. These surface will be created with an ARGB D3DFORMAT, but
83 // should be interpreted as the appropriate single-byte format when locking.
85 // The dimensions of the outputs (when interpreted as single-component data)
86 // are as follows:
87 // |dst_y| : width and height exactly |dst_size|
88 // |dst_u| : width and height are each half of |dst_size|, rounded up.
89 // |dst_v| : width and height are each half of |dst_size|, rounded up.
91 // If |src_texture|'s dimensions do not match |dst_size|, the source will be
92 // bilinearly interpolated during conversion.
94 // Returns true if successful. Caller must be certain to release the surfaces
95 // even if this function returns false. The returned surfaces belong to an
96 // internal cache, and are invalidated by a subsequent call to this method.
97 bool TransformRGBToYV12(
98 IDirect3DTexture9* src_texture,
99 const gfx::Size& dst_size,
100 IDirect3DSurface9** dst_y,
101 IDirect3DSurface9** dst_u,
102 IDirect3DSurface9** dst_v);
104 // Synchronously copy from a D3D surface into a caller-allocated buffer. This
105 // will dispatch to one of a couple techniques, depending on which is
106 // determined to be the faster method for the current device.
107 bool ReadFast(IDirect3DSurface9* gpu_surface,
108 uint8* dst,
109 int dst_bytes_per_row,
110 int dst_num_rows,
111 int dst_stride);
113 // Do a read using a particular technique. Which of these is faster depends on
114 // the hardware. Intended for testing; production code ought to call
115 // ReadFast().
116 bool ReadByLockAndCopy(IDirect3DSurface9* gpu_surface,
117 uint8* dst,
118 int dst_bytes_per_row,
119 int dst_num_rows,
120 int dst_stride);
121 bool ReadByGetRenderTargetData(IDirect3DSurface9* gpu_surface,
122 uint8* dst,
123 int dst_bytes_per_row,
124 int dst_num_rows,
125 int dst_stride);
127 private:
128 friend class AcceleratedSurfaceTransformerTest;
129 FRIEND_TEST_ALL_PREFIXES(AcceleratedSurfaceTransformerTest, Init);
131 enum ShaderCombo {
132 ONE_TEXTURE,
133 RGB_TO_YV12_FAST__PASS_1_OF_2,
134 RGB_TO_YV12_FAST__PASS_2_OF_2,
135 RGB_TO_YV12_SLOW__PASS_1_OF_3,
136 RGB_TO_YV12_SLOW__PASS_2_OF_3,
137 RGB_TO_YV12_SLOW__PASS_3_OF_3,
138 NUM_SHADERS
141 // Efficient RGB->YV12 in two passes, but requires a device capable of writing
142 // multiple render targets at the same time.
144 // Returns true if successful.
145 bool TransformRGBToYV12_MRT(
146 IDirect3DTexture9* src_surface,
147 const gfx::Size& dst_size,
148 const gfx::Size& packed_y_size,
149 const gfx::Size& packed_uv_size,
150 IDirect3DSurface9* dst_y,
151 IDirect3DSurface9* dst_u,
152 IDirect3DSurface9* dst_v);
154 // Slower, less efficient RGB->YV12; does not require the device to have
155 // multiple render target capability. Runs at about half speed of the fast
156 // path.
158 // Returns true if successful.
159 bool TransformRGBToYV12_WithoutMRT(
160 IDirect3DTexture9* src_surface,
161 const gfx::Size& dst_size,
162 const gfx::Size& packed_y_size,
163 const gfx::Size& packed_uv_size,
164 IDirect3DSurface9* dst_y,
165 IDirect3DSurface9* dst_u,
166 IDirect3DSurface9* dst_v);
168 // Helper to allocate appropriately size YUV buffers, accounting for various
169 // roundings. The sizes of the buffers (in terms of ARGB pixels) are returned
170 // as |packed_y_size| and |packed_uv_size|.
172 // Returns true if successful. Caller must be certain to release the surfaces
173 // even if this function returns false. The returned belong to an internal
174 // cache.
175 bool AllocYUVBuffers(
176 const gfx::Size& dst_size,
177 gfx::Size* packed_y_size,
178 gfx::Size* packed_uv_size,
179 IDirect3DSurface9** dst_y,
180 IDirect3DSurface9** dst_u,
181 IDirect3DSurface9** dst_v);
183 bool CopyWithTextureScale(
184 IDirect3DTexture9* src_texture,
185 IDirect3DSurface9* dst_surface,
186 const gfx::Size& dst_size,
187 float texture_scale_x,
188 float texture_scale_y);
190 // Set the active vertex and pixel shader combination.
192 // Returns true if successful.
193 bool SetShaderCombo(ShaderCombo combo);
195 // Compiles a vertex and pixel shader combination, if not already compiled.
197 // Returns true if successful.
198 bool CompileShaderCombo(ShaderCombo shader_combo_name);
200 bool DoInit(IDirect3DDevice9* device);
202 void DrawScreenAlignedQuad(const gfx::Size& dst_size);
204 bool device_supports_multiple_render_targets() const {
205 return device_supports_multiple_render_targets_;
208 IDirect3DDevice9* device();
210 base::win::ScopedComPtr<IDirect3DDevice9> device_;
211 base::win::ScopedComPtr<IDirect3DVertexShader9> vertex_shaders_[NUM_SHADERS];
212 base::win::ScopedComPtr<IDirect3DPixelShader9> pixel_shaders_[NUM_SHADERS];
214 // Temporary and scratch surfaces; cached to avoid frequent reallocation.
215 base::win::ScopedComPtr<IDirect3DTexture9> user_scratch_texture_;
216 base::win::ScopedComPtr<IDirect3DTexture9> uv_scratch_texture_;
217 base::win::ScopedComPtr<IDirect3DSurface9> y_scratch_surface_;
218 base::win::ScopedComPtr<IDirect3DSurface9> u_scratch_surface_;
219 base::win::ScopedComPtr<IDirect3DSurface9> v_scratch_surface_;
220 base::win::ScopedComPtr<IDirect3DSurface9> scaler_scratch_surfaces_[2];
222 bool device_supports_multiple_render_targets_;
223 const BYTE* vertex_shader_sources_[NUM_SHADERS];
224 const BYTE* pixel_shader_sources_[NUM_SHADERS];
225 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceTransformer);
228 #endif // UI_SURFACE_ACCELERATED_SURFACE_TRANSFORMER_WIN_H_