1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
// 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.
#ifndef UI_SURFACE_ACCELERATED_SURFACE_WIN_H_
#define UI_SURFACE_ACCELERATED_SURFACE_WIN_H_
#include <d3d9.h>
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "base/win/scoped_comptr.h"
#include "ui/events/latency_info.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
#include "ui/surface/surface_export.h"
class PresentThread;
namespace gfx {
class Rect;
}
namespace media {
class VideoFrame;
}
class SURFACE_EXPORT AcceleratedPresenter
: public base::RefCountedThreadSafe<AcceleratedPresenter> {
public:
typedef base::Callback<void(
bool,
base::TimeTicks,
base::TimeDelta,
const std::vector<ui::LatencyInfo>&)> CompletionTask;
explicit AcceleratedPresenter(gfx::PluginWindowHandle window);
static void SetAdapterLUID(uint64 adapter_luid);
// Returns a thread safe reference to the presenter for the given window or
// null is no such presenter exists. The thread safe refptr ensures the
// presenter will not be destroyed. This can be called on any thread.
static scoped_refptr<AcceleratedPresenter> GetForWindow(
gfx::PluginWindowHandle window);
// Schedule a frame to be presented. The completion callback will be invoked
// when it is safe to write to the surface on another thread. The lock for
// this surface will be held while the completion callback runs. This can be
// called on any thread.
void AsyncPresentAndAcknowledge(
const gfx::Size& size,
int64 surface_handle,
const std::vector<ui::LatencyInfo>& latency_info,
const CompletionTask& completion_task);
// Returns true if the swap chain has been created and initialized. This can
// be called on any thread.
bool IsSwapChainInitialized() const;
// Schedule the presenter to free all its resources. This can be called on any
// thread.
void Suspend();
// Indicates that the presenter has become invisible.
void WasHidden();
// Called when the Windows session is locked or unlocked.
void SetIsSessionLocked(bool locked);
// Schedule the presenter to release its reference to the shared surface.
void ReleaseSurface();
// The public member functions are called on the main thread.
void Present(HDC dc);
void AsyncCopyTo(const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback);
void AsyncCopyToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback);
void Invalidate();
// Destroy any D3D resources owned by the given present thread. Called on
// the given present thread.
void ResetPresentThread(PresentThread* present_thread);
private:
friend class base::RefCountedThreadSafe<AcceleratedPresenter>;
~AcceleratedPresenter();
// These member functions are called on the PresentThread with which the
// presenter has affinity.
void DoPresentAndAcknowledge(
const gfx::Size& size,
int64 surface_handle,
const std::vector<ui::LatencyInfo>& latency_info,
const CompletionTask& completion_task);
void DoSuspend();
void DoPresent(const base::Closure& composite_task);
void DoReleaseSurface();
void DoCopyToAndAcknowledge(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
const base::Callback<void(bool, const SkBitmap&)>& callback);
void DoCopyToVideoFrameAndAcknowledge(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const scoped_refptr<base::SingleThreadTaskRunner>& callback_runner,
const base::Callback<void(bool)>& callback);
bool DoCopyToYUV(const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& frame);
bool DoCopyToARGB(const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
SkBitmap* bitmap);
void PresentWithGDI(HDC dc);
gfx::Size GetWindowSize();
// This function tries to guess whether Direct3D will be able to reliably
// present to the window. When the window is resizing, presenting with
// Direct3D causes other regions of the window rendered with GDI to
// flicker transparent / non-transparent.
bool CheckDirect3DWillWork();
// The thread with which this presenter has affinity.
PresentThread* const present_thread_;
// The window that is presented to.
gfx::PluginWindowHandle window_;
// UI thread can wait on this event to ensure a present is finished.
base::WaitableEvent event_;
// The current size of the swap chain. This is only accessed on the thread
// with which the surface has affinity. The swap chain size is rounded up and
// is not necessarily the same as the window size.
gfx::Size quantized_size_;
// The size of the window on the last present. This is used to trigger the
// compositor instead of presenting the last frame in the case where the
// window has been resized.
gfx::Size present_size_;
// This is a shared texture that is being presented from.
base::win::ScopedComPtr<IDirect3DTexture9> source_texture_;
// The swap chain is presented to the child window. Copy semantics
// are used so it is possible to represent it to quickly validate the window.
base::win::ScopedComPtr<IDirect3DSwapChain9> swap_chain_;
// Whether the window is hidden or has not been presented to since it was
// last hidden.
bool hidden_;
// Set to true if the first present after the tab is unhidden needs to be done
// with GDI.
bool do_present_with_GDI_;
// Set to true when the Windows session is locked.
bool is_session_locked_;
// These are used to detect when the window is resizing. For some reason,
// presenting with D3D while the window resizes causes those parts not
// drawn with D3D (e.g. with GDI) to flicker visible / invisible.
// http://crbug.com/120904
gfx::Size last_window_size_;
base::Time last_window_resize_time_;
std::vector<ui::LatencyInfo> latency_info_;
DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenter);
};
class SURFACE_EXPORT AcceleratedSurface {
public:
AcceleratedSurface(gfx::PluginWindowHandle window);
~AcceleratedSurface();
// Synchronously present a frame with no acknowledgement.
void Present(HDC dc);
// Returns true if the surface is fully initialized and has been presented to
// at least once.
bool IsReadyForCopy() const;
// Transfer the contents of the surface to an SkBitmap, and invoke a callback
// with the result.
void AsyncCopyTo(const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback);
// Transfer the contents of the surface to an already-allocated YV12
// VideoFrame, and invoke a callback to indicate success or failure.
void AsyncCopyToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback);
// Temporarily release resources until a new surface is asynchronously
// presented. Present will not be able to represent the last surface after
// calling this and will return false.
void Suspend();
// Indicates that the surface has become invisible.
void WasHidden();
// Called when the Windows session in locked or unlocked.
void SetIsSessionLocked(bool locked);
private:
const scoped_refptr<AcceleratedPresenter> presenter_;
DISALLOW_COPY_AND_ASSIGN(AcceleratedSurface);
};
#endif // UI_SURFACE_ACCELERATED_SURFACE_WIN_H_
|