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
|
// Copyright 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 CC_OUTPUT_OUTPUT_SURFACE_H_
#define CC_OUTPUT_OUTPUT_SURFACE_H_
#include <deque>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/output/context_provider.h"
#include "cc/output/software_output_device.h"
#include "cc/scheduler/frame_rate_controller.h"
#include "cc/scheduler/rolling_time_delta_history.h"
namespace base { class SingleThreadTaskRunner; }
namespace ui { struct LatencyInfo; }
namespace gfx {
class Rect;
class Size;
class Transform;
}
namespace cc {
class CompositorFrame;
class CompositorFrameAck;
struct ManagedMemoryPolicy;
class OutputSurfaceClient;
// Represents the output surface for a compositor. The compositor owns
// and manages its destruction. Its lifetime is:
// 1. Created on the main thread by the LayerTreeHost through its client.
// 2. Passed to the compositor thread and bound to a client via BindToClient.
// From here on, it will only be used on the compositor thread.
// 3. If the 3D context is lost, then the compositor will delete the output
// surface (on the compositor thread) and go back to step 1.
class CC_EXPORT OutputSurface : public FrameRateControllerClient {
public:
enum {
DEFAULT_MAX_FRAMES_PENDING = 2
};
explicit OutputSurface(scoped_refptr<ContextProvider> context_provider);
explicit OutputSurface(scoped_ptr<cc::SoftwareOutputDevice> software_device);
OutputSurface(scoped_refptr<ContextProvider> context_provider,
scoped_ptr<cc::SoftwareOutputDevice> software_device);
virtual ~OutputSurface();
struct Capabilities {
Capabilities()
: delegated_rendering(false),
max_frames_pending(0),
deferred_gl_initialization(false),
draw_and_swap_full_viewport_every_frame(false),
adjust_deadline_for_parent(true),
uses_default_gl_framebuffer(true) {}
bool delegated_rendering;
int max_frames_pending;
bool deferred_gl_initialization;
bool draw_and_swap_full_viewport_every_frame;
// This doesn't handle the <webview> case, but once BeginImplFrame is
// supported natively, we shouldn't need adjust_deadline_for_parent.
bool adjust_deadline_for_parent;
// Whether this output surface renders to the default OpenGL zero
// framebuffer or to an offscreen framebuffer.
bool uses_default_gl_framebuffer;
};
const Capabilities& capabilities() const {
return capabilities_;
}
virtual bool HasExternalStencilTest() const;
// Obtain the 3d context or the software device associated with this output
// surface. Either of these may return a null pointer, but not both.
// In the event of a lost context, the entire output surface should be
// recreated.
scoped_refptr<ContextProvider> context_provider() const {
return context_provider_.get();
}
SoftwareOutputDevice* software_device() const {
return software_device_.get();
}
// In the case where both the context3d and software_device are present
// (namely Android WebView), this is called to determine whether the software
// device should be used on the current frame.
virtual bool ForcedDrawToSoftwareDevice() const;
// Called by the compositor on the compositor thread. This is a place where
// thread-specific data for the output surface can be initialized, since from
// this point on the output surface will only be used on the compositor
// thread.
virtual bool BindToClient(OutputSurfaceClient* client);
void InitializeBeginImplFrameEmulation(
base::SingleThreadTaskRunner* task_runner,
bool throttle_frame_production,
base::TimeDelta interval);
void SetMaxFramesPending(int max_frames_pending);
virtual void EnsureBackbuffer();
virtual void DiscardBackbuffer();
virtual void Reshape(gfx::Size size, float scale_factor);
virtual gfx::Size SurfaceSize() const;
virtual void BindFramebuffer();
// The implementation may destroy or steal the contents of the CompositorFrame
// passed in (though it will not take ownership of the CompositorFrame
// itself).
virtual void SwapBuffers(CompositorFrame* frame);
// Notifies frame-rate smoothness preference. If true, all non-critical
// processing should be stopped, or lowered in priority.
virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}
// Requests a BeginImplFrame notification from the output surface. The
// notification will be delivered by calling
// OutputSurfaceClient::BeginImplFrame until the callback is disabled.
virtual void SetNeedsBeginImplFrame(bool enable);
bool HasClient() { return !!client_; }
// Returns an estimate of the current GPU latency. When only a software
// device is present, returns 0.
base::TimeDelta GpuLatencyEstimate();
protected:
// Synchronously initialize context3d and enter hardware mode.
// This can only supported in threaded compositing mode.
// |offscreen_context_provider| should match what is returned by
// LayerTreeClient::OffscreenContextProvider().
bool InitializeAndSetContext3d(
scoped_refptr<ContextProvider> context_provider,
scoped_refptr<ContextProvider> offscreen_context_provider);
void ReleaseGL();
void PostSwapBuffersComplete();
struct cc::OutputSurface::Capabilities capabilities_;
scoped_refptr<ContextProvider> context_provider_;
scoped_ptr<cc::SoftwareOutputDevice> software_device_;
bool has_gl_discard_backbuffer_;
bool has_swap_buffers_complete_callback_;
gfx::Size surface_size_;
float device_scale_factor_;
// The FrameRateController is deprecated.
// Platforms should move to native BeginImplFrames instead.
void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval);
virtual void FrameRateControllerTick(bool throttled,
const BeginFrameArgs& args) OVERRIDE;
scoped_ptr<FrameRateController> frame_rate_controller_;
int max_frames_pending_;
int pending_swap_buffers_;
bool needs_begin_impl_frame_;
bool client_ready_for_begin_impl_frame_;
// This stores a BeginImplFrame that we couldn't process immediately,
// but might process retroactively in the near future.
BeginFrameArgs skipped_begin_impl_frame_args_;
// Forwarded to OutputSurfaceClient but threaded through OutputSurface
// first so OutputSurface has a chance to update the FrameRateController
void SetNeedsRedrawRect(gfx::Rect damage_rect);
void BeginImplFrame(const BeginFrameArgs& args);
void DidSwapBuffers();
void OnSwapBuffersComplete();
void ReclaimResources(const CompositorFrameAck* ack);
void DidLoseOutputSurface();
void SetExternalStencilTest(bool enabled);
void SetExternalDrawConstraints(const gfx::Transform& transform,
gfx::Rect viewport,
gfx::Rect clip,
bool valid_for_tile_management);
// virtual for testing.
virtual base::TimeTicks RetroactiveBeginImplFrameDeadline();
virtual void PostCheckForRetroactiveBeginImplFrame();
void CheckForRetroactiveBeginImplFrame();
private:
OutputSurfaceClient* client_;
void SetUpContext3d();
void ResetContext3d();
void SetMemoryPolicy(const ManagedMemoryPolicy& policy);
void UpdateAndMeasureGpuLatency();
// check_for_retroactive_begin_impl_frame_pending_ is used to avoid posting
// redundant checks for a retroactive BeginImplFrame.
bool check_for_retroactive_begin_impl_frame_pending_;
bool external_stencil_test_enabled_;
base::WeakPtrFactory<OutputSurface> weak_ptr_factory_;
std::deque<unsigned> available_gpu_latency_query_ids_;
std::deque<unsigned> pending_gpu_latency_query_ids_;
RollingTimeDeltaHistory gpu_latency_history_;
DISALLOW_COPY_AND_ASSIGN(OutputSurface);
};
} // namespace cc
#endif // CC_OUTPUT_OUTPUT_SURFACE_H_
|