Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: cc/output/output_surface.cc

Issue 16833003: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/output/output_surface.h" 5 #include "cc/output/output_surface.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/message_loop.h" 14 #include "base/message_loop.h"
14 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
16 #include "cc/output/compositor_frame.h" 17 #include "cc/output/compositor_frame.h"
17 #include "cc/output/output_surface_client.h" 18 #include "cc/output/output_surface_client.h"
19 #include "cc/scheduler/delay_based_time_source.h"
18 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 20 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
19 #include "third_party/khronos/GLES2/gl2.h" 21 #include "third_party/khronos/GLES2/gl2.h"
20 #include "third_party/khronos/GLES2/gl2ext.h" 22 #include "third_party/khronos/GLES2/gl2ext.h"
21 #include "ui/gfx/rect.h" 23 #include "ui/gfx/rect.h"
22 #include "ui/gfx/size.h" 24 #include "ui/gfx/size.h"
23 25
24 using std::set; 26 using std::set;
25 using std::string; 27 using std::string;
26 using std::vector; 28 using std::vector;
27 29
28 namespace cc { 30 namespace cc {
29 31
30 class OutputSurfaceCallbacks 32 class OutputSurfaceCallbacks
31 : public WebKit::WebGraphicsContext3D:: 33 : public WebKit::WebGraphicsContext3D::
32 WebGraphicsSwapBuffersCompleteCallbackCHROMIUM, 34 WebGraphicsSwapBuffersCompleteCallbackCHROMIUM,
33 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { 35 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
34 public: 36 public:
35 explicit OutputSurfaceCallbacks(OutputSurfaceClient* client) 37 explicit OutputSurfaceCallbacks(OutputSurface* client)
36 : client_(client) { 38 : client_(client) {
37 DCHECK(client_); 39 DCHECK(client_);
38 } 40 }
39 41
40 // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation. 42 // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation.
41 virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(NULL); } 43 virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(NULL); }
42 44
43 // WK:WGC3D::WGContextLostCallback implementation. 45 // WK:WGC3D::WGContextLostCallback implementation.
44 virtual void onContextLost() { client_->DidLoseOutputSurface(); } 46 virtual void onContextLost() { client_->DidLoseOutputSurface(); }
45 47
46 private: 48 private:
47 OutputSurfaceClient* client_; 49 OutputSurface* client_;
48 }; 50 };
49 51
50 OutputSurface::OutputSurface( 52 OutputSurface::OutputSurface(
51 scoped_ptr<WebKit::WebGraphicsContext3D> context3d) 53 scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
52 : client_(NULL), 54 : context3d_(context3d.Pass()),
53 context3d_(context3d.Pass()),
54 has_gl_discard_backbuffer_(false), 55 has_gl_discard_backbuffer_(false),
55 has_swap_buffers_complete_callback_(false), 56 has_swap_buffers_complete_callback_(false),
56 device_scale_factor_(-1), 57 device_scale_factor_(-1),
57 weak_ptr_factory_(this) { 58 weak_ptr_factory_(this),
59 max_frames_pending_(0),
60 pending_swap_buffers_(0),
61 begin_frame_pending_(false),
62 client_(NULL) {
58 } 63 }
59 64
60 OutputSurface::OutputSurface( 65 OutputSurface::OutputSurface(
61 scoped_ptr<cc::SoftwareOutputDevice> software_device) 66 scoped_ptr<cc::SoftwareOutputDevice> software_device)
62 : client_(NULL), 67 : software_device_(software_device.Pass()),
63 software_device_(software_device.Pass()),
64 has_gl_discard_backbuffer_(false), 68 has_gl_discard_backbuffer_(false),
65 has_swap_buffers_complete_callback_(false), 69 has_swap_buffers_complete_callback_(false),
66 device_scale_factor_(-1), 70 device_scale_factor_(-1),
67 weak_ptr_factory_(this) { 71 weak_ptr_factory_(this),
72 max_frames_pending_(0),
73 pending_swap_buffers_(0),
74 begin_frame_pending_(false),
75 client_(NULL) {
68 } 76 }
69 77
70 OutputSurface::OutputSurface( 78 OutputSurface::OutputSurface(
71 scoped_ptr<WebKit::WebGraphicsContext3D> context3d, 79 scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
72 scoped_ptr<cc::SoftwareOutputDevice> software_device) 80 scoped_ptr<cc::SoftwareOutputDevice> software_device)
73 : client_(NULL), 81 : context3d_(context3d.Pass()),
74 context3d_(context3d.Pass()),
75 software_device_(software_device.Pass()), 82 software_device_(software_device.Pass()),
76 has_gl_discard_backbuffer_(false), 83 has_gl_discard_backbuffer_(false),
77 has_swap_buffers_complete_callback_(false), 84 has_swap_buffers_complete_callback_(false),
78 device_scale_factor_(-1), 85 device_scale_factor_(-1),
79 weak_ptr_factory_(this) { 86 weak_ptr_factory_(this),
87 max_frames_pending_(0),
88 pending_swap_buffers_(0),
89 begin_frame_pending_(false),
90 client_(NULL) {
91 }
92
93 void OutputSurface::InitializeBeginFrameEmulation(
94 Thread* thread,
95 bool throttle_frame_production,
96 base::TimeDelta interval) {
97 if (throttle_frame_production){
98 frame_rate_controller_.reset(
99 new FrameRateController(
100 DelayBasedTimeSource::Create(interval, thread)));
101 } else {
102 frame_rate_controller_.reset(new FrameRateController(thread));
103 }
104
105 frame_rate_controller_->SetClient(this);
106 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending_);
107
108 // The new frame rate controller will consume the swap acks of the old
109 // frame rate controller, so we set that expectation up here.
110 for (int i = 0; i < pending_swap_buffers_; i++)
111 frame_rate_controller_->DidSwapBuffers();
112 }
113
114 void OutputSurface::SetMaxFramesPending(int max_frames_pending) {
115 if (frame_rate_controller_)
116 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending);
117 max_frames_pending_ = max_frames_pending;
118 }
119
120 void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase,
121 base::TimeDelta interval) {
122 TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged",
123 "timebase", (timebase - base::TimeTicks()).InSecondsF(),
124 "interval", interval.InSecondsF());
125 if (frame_rate_controller_)
126 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
127 }
128
129 void OutputSurface::FrameRateControllerTick(bool throttled) {
130 DCHECK(frame_rate_controller_);
131 if (!throttled)
132 BeginFrame(frame_rate_controller_->LastTickTime());
133 }
134
135 // Forwarded to OutputSurfaceClient
136 void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) {
137 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
138 client_->SetNeedsRedrawRect(damage_rect);
139 }
140
141 void OutputSurface::SetNeedsBeginFrame(bool enable) {
142 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
143 begin_frame_pending_ = false;
144 if (frame_rate_controller_)
145 frame_rate_controller_->SetActive(enable);
146 }
147
148 void OutputSurface::BeginFrame(base::TimeTicks frame_time) {
149 if (begin_frame_pending_ ||
150 (pending_swap_buffers_ >= max_frames_pending_ && max_frames_pending_ > 0))
151 return;
152 TRACE_EVENT1("cc", "OutputSurface::BeginFrame",
153 "pending_swap_buffers_", pending_swap_buffers_);
154 begin_frame_pending_ = true;
155 client_->BeginFrame(frame_time);
156 }
157
158 void OutputSurface::DidSwapBuffers() {
159 begin_frame_pending_ = false;
160 pending_swap_buffers_++;
161 TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers",
162 "pending_swap_buffers_", pending_swap_buffers_);
163 if (frame_rate_controller_)
164 frame_rate_controller_->DidSwapBuffers();
165 }
166
167 void OutputSurface::OnSwapBuffersComplete(const CompositorFrameAck* ack) {
168 pending_swap_buffers_--;
169 TRACE_EVENT1("cc", "OutputSurface::OnSwapBuffersComplete",
170 "pending_swap_buffers_", pending_swap_buffers_);
171 client_->OnSwapBuffersComplete(ack);
172 if (frame_rate_controller_)
173 frame_rate_controller_->DidSwapBuffersComplete();
174 }
175
176 void OutputSurface::DidLoseOutputSurface() {
177 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
178 begin_frame_pending_ = false;
179 pending_swap_buffers_ = 0;
180 client_->DidLoseOutputSurface();
181 }
182
183 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
184 gfx::Rect viewport) {
185 client_->SetExternalDrawConstraints(transform, viewport);
80 } 186 }
81 187
82 OutputSurface::~OutputSurface() { 188 OutputSurface::~OutputSurface() {
189 if (frame_rate_controller_)
190 frame_rate_controller_->SetActive(false);
83 } 191 }
84 192
85 bool OutputSurface::ForcedDrawToSoftwareDevice() const { 193 bool OutputSurface::ForcedDrawToSoftwareDevice() const {
86 return false; 194 return false;
87 } 195 }
88 196
89 bool OutputSurface::BindToClient( 197 bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) {
90 cc::OutputSurfaceClient* client) {
91 DCHECK(client); 198 DCHECK(client);
92 client_ = client; 199 client_ = client;
93 bool success = true; 200 bool success = true;
94 201
95 if (context3d_) { 202 if (context3d_) {
96 success = context3d_->makeContextCurrent(); 203 success = context3d_->makeContextCurrent();
97 if (success) 204 if (success)
98 SetContext3D(context3d_.Pass()); 205 SetContext3D(context3d_.Pass());
99 } 206 }
100 207
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 vector<string> extensions_list; 243 vector<string> extensions_list;
137 base::SplitString(extensions_string, ' ', &extensions_list); 244 base::SplitString(extensions_string, ' ', &extensions_list);
138 set<string> extensions(extensions_list.begin(), extensions_list.end()); 245 set<string> extensions(extensions_list.begin(), extensions_list.end());
139 has_gl_discard_backbuffer_ = 246 has_gl_discard_backbuffer_ =
140 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0; 247 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0;
141 has_swap_buffers_complete_callback_ = 248 has_swap_buffers_complete_callback_ =
142 extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0; 249 extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0;
143 250
144 251
145 context3d_ = context3d.Pass(); 252 context3d_ = context3d.Pass();
146 callbacks_.reset(new OutputSurfaceCallbacks(client_)); 253 callbacks_.reset(new OutputSurfaceCallbacks(this));
147 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get()); 254 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get());
148 context3d_->setContextLostCallback(callbacks_.get()); 255 context3d_->setContextLostCallback(callbacks_.get());
149 } 256 }
150 257
151 void OutputSurface::EnsureBackbuffer() { 258 void OutputSurface::EnsureBackbuffer() {
152 DCHECK(context3d_); 259 DCHECK(context3d_);
153 if (has_gl_discard_backbuffer_) 260 if (has_gl_discard_backbuffer_)
154 context3d_->ensureBackbufferCHROMIUM(); 261 context3d_->ensureBackbufferCHROMIUM();
155 } 262 }
156 263
(...skipping 22 matching lines...) Expand all
179 } 286 }
180 287
181 void OutputSurface::BindFramebuffer() { 288 void OutputSurface::BindFramebuffer() {
182 DCHECK(context3d_); 289 DCHECK(context3d_);
183 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0); 290 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0);
184 } 291 }
185 292
186 void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) { 293 void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
187 if (frame->software_frame_data) { 294 if (frame->software_frame_data) {
188 PostSwapBuffersComplete(); 295 PostSwapBuffersComplete();
296 DidSwapBuffers();
189 return; 297 return;
190 } 298 }
191 299
192 DCHECK(context3d_); 300 DCHECK(context3d_);
193 DCHECK(frame->gl_frame_data); 301 DCHECK(frame->gl_frame_data);
194 302
195 if (frame->gl_frame_data->partial_swap_allowed) { 303 if (frame->gl_frame_data->partial_swap_allowed) {
196 gfx::Rect sub_buffer_rect = frame->gl_frame_data->sub_buffer_rect; 304 gfx::Rect sub_buffer_rect = frame->gl_frame_data->sub_buffer_rect;
197 context3d()->postSubBufferCHROMIUM(sub_buffer_rect.x(), 305 context3d()->postSubBufferCHROMIUM(sub_buffer_rect.x(),
198 sub_buffer_rect.y(), 306 sub_buffer_rect.y(),
199 sub_buffer_rect.width(), 307 sub_buffer_rect.width(),
200 sub_buffer_rect.height()); 308 sub_buffer_rect.height());
201 } else { 309 } else {
202 // Note that currently this has the same effect as SwapBuffers; we should 310 // Note that currently this has the same effect as SwapBuffers; we should
203 // consider exposing a different entry point on WebGraphicsContext3D. 311 // consider exposing a different entry point on WebGraphicsContext3D.
204 context3d()->prepareTexture(); 312 context3d()->prepareTexture();
205 } 313 }
206 314
207 if (!has_swap_buffers_complete_callback_) 315 if (!has_swap_buffers_complete_callback_)
208 PostSwapBuffersComplete(); 316 PostSwapBuffersComplete();
317
318 DidSwapBuffers();
209 } 319 }
210 320
211 void OutputSurface::PostSwapBuffersComplete() { 321 void OutputSurface::PostSwapBuffersComplete() {
212 base::MessageLoop::current()->PostTask( 322 base::MessageLoop::current()->PostTask(
213 FROM_HERE, 323 FROM_HERE,
214 base::Bind(&OutputSurface::SwapBuffersComplete, 324 base::Bind(&OutputSurface::OnSwapBuffersComplete,
215 weak_ptr_factory_.GetWeakPtr())); 325 weak_ptr_factory_.GetWeakPtr(),
216 } 326 static_cast<CompositorFrameAck*>(NULL)));
217
218 void OutputSurface::SwapBuffersComplete() {
219 if (!client_)
220 return;
221
222 client_->OnSwapBuffersComplete(NULL);
223 } 327 }
224 328
225 } // namespace cc 329 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698