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

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

Issue 20185002: ContextProvider in OutputSurface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: contextprovider: don't access Context3d() in OutputSurface contructors, it's not bound yet Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_unittest.cc » ('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/debug/trace_event.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "cc/output/compositor_frame.h" 17 #include "cc/output/compositor_frame.h"
18 #include "cc/output/managed_memory_policy.h" 18 #include "cc/output/managed_memory_policy.h"
19 #include "cc/output/output_surface_client.h" 19 #include "cc/output/output_surface_client.h"
20 #include "cc/scheduler/delay_based_time_source.h" 20 #include "cc/scheduler/delay_based_time_source.h"
21 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 21 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
22 #include "third_party/WebKit/public/platform/WebGraphicsMemoryAllocation.h"
23 #include "third_party/khronos/GLES2/gl2.h" 22 #include "third_party/khronos/GLES2/gl2.h"
24 #include "third_party/khronos/GLES2/gl2ext.h" 23 #include "third_party/khronos/GLES2/gl2ext.h"
25 #include "ui/gfx/rect.h" 24 #include "ui/gfx/rect.h"
26 #include "ui/gfx/size.h" 25 #include "ui/gfx/size.h"
27 26
28 using std::set; 27 using std::set;
29 using std::string; 28 using std::string;
30 using std::vector; 29 using std::vector;
31 30
32 namespace cc { 31 namespace cc {
33 namespace {
34
35 ManagedMemoryPolicy::PriorityCutoff ConvertPriorityCutoff(
36 WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff) {
37 // This is simple a 1:1 map, the names differ only because the WebKit names
38 // should be to match the cc names.
39 switch (priority_cutoff) {
40 case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowNothing:
41 return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
42 case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleOnly:
43 return ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY;
44 case WebKit::WebGraphicsMemoryAllocation::
45 PriorityCutoffAllowVisibleAndNearby:
46 return ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE;
47 case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything:
48 return ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING;
49 }
50 NOTREACHED();
51 return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
52 }
53
54 } // anonymous namespace
55
56 class OutputSurfaceCallbacks
57 : public WebKit::WebGraphicsContext3D::
58 WebGraphicsSwapBuffersCompleteCallbackCHROMIUM,
59 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback,
60 public WebKit::WebGraphicsContext3D::
61 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM {
62 public:
63 explicit OutputSurfaceCallbacks(OutputSurface* client)
64 : client_(client) {
65 DCHECK(client_);
66 }
67
68 // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation.
69 virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(NULL); }
70
71 // WK:WGC3D::WGContextLostCallback implementation.
72 virtual void onContextLost() { client_->DidLoseOutputSurface(); }
73
74 // WK:WGC3D::WGMemoryAllocationChangedCallbackCHROMIUM implementation.
75 virtual void onMemoryAllocationChanged(
76 WebKit::WebGraphicsMemoryAllocation allocation) {
77 ManagedMemoryPolicy policy(
78 allocation.bytesLimitWhenVisible,
79 ConvertPriorityCutoff(allocation.priorityCutoffWhenVisible),
80 allocation.bytesLimitWhenNotVisible,
81 ConvertPriorityCutoff(allocation.priorityCutoffWhenNotVisible),
82 ManagedMemoryPolicy::kDefaultNumResourcesLimit);
83 bool discard_backbuffer = !allocation.suggestHaveBackbuffer;
84 client_->SetMemoryPolicy(policy, discard_backbuffer);
85 }
86
87 private:
88 OutputSurface* client_;
89 };
90 32
91 OutputSurface::OutputSurface( 33 OutputSurface::OutputSurface(
92 scoped_ptr<WebKit::WebGraphicsContext3D> context3d) 34 scoped_refptr<ContextProvider> context_provider)
93 : context3d_(context3d.Pass()), 35 : context_provider_(context_provider),
94 has_gl_discard_backbuffer_(false), 36 has_gl_discard_backbuffer_(false),
95 has_swap_buffers_complete_callback_(false), 37 has_swap_buffers_complete_callback_(false),
96 device_scale_factor_(-1), 38 device_scale_factor_(-1),
97 weak_ptr_factory_(this), 39 weak_ptr_factory_(this),
98 max_frames_pending_(0), 40 max_frames_pending_(0),
99 pending_swap_buffers_(0), 41 pending_swap_buffers_(0),
100 needs_begin_frame_(false), 42 needs_begin_frame_(false),
101 begin_frame_pending_(false), 43 begin_frame_pending_(false),
102 client_(NULL), 44 client_(NULL),
103 check_for_retroactive_begin_frame_pending_(false) { 45 check_for_retroactive_begin_frame_pending_(false) {
104 } 46 }
105 47
106 OutputSurface::OutputSurface( 48 OutputSurface::OutputSurface(
107 scoped_ptr<cc::SoftwareOutputDevice> software_device) 49 scoped_ptr<cc::SoftwareOutputDevice> software_device)
108 : software_device_(software_device.Pass()), 50 : software_device_(software_device.Pass()),
109 has_gl_discard_backbuffer_(false), 51 has_gl_discard_backbuffer_(false),
110 has_swap_buffers_complete_callback_(false), 52 has_swap_buffers_complete_callback_(false),
111 device_scale_factor_(-1), 53 device_scale_factor_(-1),
112 weak_ptr_factory_(this), 54 weak_ptr_factory_(this),
113 max_frames_pending_(0), 55 max_frames_pending_(0),
114 pending_swap_buffers_(0), 56 pending_swap_buffers_(0),
115 needs_begin_frame_(false), 57 needs_begin_frame_(false),
116 begin_frame_pending_(false), 58 begin_frame_pending_(false),
117 client_(NULL), 59 client_(NULL),
118 check_for_retroactive_begin_frame_pending_(false) { 60 check_for_retroactive_begin_frame_pending_(false) {
119 } 61 }
120 62
121 OutputSurface::OutputSurface( 63 OutputSurface::OutputSurface(
122 scoped_ptr<WebKit::WebGraphicsContext3D> context3d, 64 scoped_refptr<ContextProvider> context_provider,
123 scoped_ptr<cc::SoftwareOutputDevice> software_device) 65 scoped_ptr<cc::SoftwareOutputDevice> software_device)
124 : context3d_(context3d.Pass()), 66 : context_provider_(context_provider),
125 software_device_(software_device.Pass()), 67 software_device_(software_device.Pass()),
126 has_gl_discard_backbuffer_(false), 68 has_gl_discard_backbuffer_(false),
127 has_swap_buffers_complete_callback_(false), 69 has_swap_buffers_complete_callback_(false),
128 device_scale_factor_(-1), 70 device_scale_factor_(-1),
129 weak_ptr_factory_(this), 71 weak_ptr_factory_(this),
130 max_frames_pending_(0), 72 max_frames_pending_(0),
131 pending_swap_buffers_(0), 73 pending_swap_buffers_(0),
132 needs_begin_frame_(false), 74 needs_begin_frame_(false),
133 begin_frame_pending_(false), 75 begin_frame_pending_(false),
134 client_(NULL), 76 client_(NULL),
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 } 224 }
283 225
284 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform, 226 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
285 gfx::Rect viewport) { 227 gfx::Rect viewport) {
286 client_->SetExternalDrawConstraints(transform, viewport); 228 client_->SetExternalDrawConstraints(transform, viewport);
287 } 229 }
288 230
289 OutputSurface::~OutputSurface() { 231 OutputSurface::~OutputSurface() {
290 if (frame_rate_controller_) 232 if (frame_rate_controller_)
291 frame_rate_controller_->SetActive(false); 233 frame_rate_controller_->SetActive(false);
292 234 ResetContext3d();
293 if (context3d_) {
294 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(NULL);
295 context3d_->setContextLostCallback(NULL);
296 context3d_->setMemoryAllocationChangedCallbackCHROMIUM(NULL);
297 }
298 } 235 }
299 236
300 bool OutputSurface::ForcedDrawToSoftwareDevice() const { 237 bool OutputSurface::ForcedDrawToSoftwareDevice() const {
301 return false; 238 return false;
302 } 239 }
303 240
304 bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) { 241 bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) {
305 DCHECK(client); 242 DCHECK(client);
306 client_ = client; 243 client_ = client;
307 bool success = true; 244 bool success = true;
308 245
309 if (context3d_) { 246 if (context_provider_) {
310 success = context3d_->makeContextCurrent(); 247 success = context_provider_->BindToCurrentThread();
311 if (success) 248 if (success)
312 SetContext3D(context3d_.Pass()); 249 SetUpContext3d();
313 } 250 }
314 251
315 if (!success) 252 if (!success)
316 client_ = NULL; 253 client_ = NULL;
317 254
318 return success; 255 return success;
319 } 256 }
320 257
321 bool OutputSurface::InitializeAndSetContext3D( 258 bool OutputSurface::InitializeAndSetContext3d(
322 scoped_ptr<WebKit::WebGraphicsContext3D> context3d, 259 scoped_refptr<ContextProvider> context_provider,
323 scoped_refptr<ContextProvider> offscreen_context_provider) { 260 scoped_refptr<ContextProvider> offscreen_context_provider) {
324 DCHECK(!context3d_); 261 DCHECK(!context_provider_);
325 DCHECK(context3d); 262 DCHECK(context_provider);
326 DCHECK(client_); 263 DCHECK(client_);
327 264
328 bool success = false; 265 bool success = false;
329 if (context3d->makeContextCurrent()) { 266 if (context_provider->BindToCurrentThread()) {
330 SetContext3D(context3d.Pass()); 267 context_provider_ = context_provider;
268 SetUpContext3d();
331 if (client_->DeferredInitialize(offscreen_context_provider)) 269 if (client_->DeferredInitialize(offscreen_context_provider))
332 success = true; 270 success = true;
333 } 271 }
334 272
335 if (!success) 273 if (!success)
336 ResetContext3D(); 274 ResetContext3d();
337 275
338 return success; 276 return success;
339 } 277 }
340 278
341 void OutputSurface::ReleaseGL() { 279 void OutputSurface::ReleaseGL() {
342 DCHECK(client_); 280 DCHECK(client_);
343 DCHECK(context3d_); 281 DCHECK(context_provider_);
344 client_->ReleaseGL(); 282 client_->ReleaseGL();
345 ResetContext3D(); 283 ResetContext3d();
346 } 284 }
347 285
348 void OutputSurface::SetContext3D( 286 void OutputSurface::SetUpContext3d() {
349 scoped_ptr<WebKit::WebGraphicsContext3D> context3d) { 287 DCHECK(context_provider_);
350 DCHECK(!context3d_);
351 DCHECK(context3d);
352 DCHECK(client_); 288 DCHECK(client_);
353 289
354 string extensions_string = UTF16ToASCII(context3d->getString(GL_EXTENSIONS)); 290 WebKit::WebGraphicsContext3D* context3d = context_provider_->Context3d();
291
292 string extensions_string =
293 UTF16ToASCII(context3d->getString(GL_EXTENSIONS));
355 vector<string> extensions_list; 294 vector<string> extensions_list;
356 base::SplitString(extensions_string, ' ', &extensions_list); 295 base::SplitString(extensions_string, ' ', &extensions_list);
357 set<string> extensions(extensions_list.begin(), extensions_list.end()); 296 set<string> extensions(extensions_list.begin(), extensions_list.end());
358 has_gl_discard_backbuffer_ = 297 has_gl_discard_backbuffer_ =
359 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0; 298 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0;
360 has_swap_buffers_complete_callback_ = 299 has_swap_buffers_complete_callback_ =
361 extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0; 300 extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0;
362 301
363 302 context_provider_->SetLostContextCallback(
364 context3d_ = context3d.Pass(); 303 base::Bind(&OutputSurface::DidLoseOutputSurface,
365 callbacks_.reset(new OutputSurfaceCallbacks(this)); 304 base::Unretained(this)));
366 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get()); 305 context_provider_->SetSwapBuffersCompleteCallback(
367 context3d_->setContextLostCallback(callbacks_.get()); 306 base::Bind(&OutputSurface::OnSwapBuffersComplete,
368 context3d_->setMemoryAllocationChangedCallbackCHROMIUM(callbacks_.get()); 307 base::Unretained(this),
308 static_cast<CompositorFrameAck*>(NULL)));
309 context_provider_->SetMemoryPolicyChangedCallback(
310 base::Bind(&OutputSurface::SetMemoryPolicy,
311 base::Unretained(this)));
369 } 312 }
370 313
371 void OutputSurface::ResetContext3D() { 314 void OutputSurface::ResetContext3d() {
372 context3d_.reset(); 315 if (context_provider_.get()) {
373 callbacks_.reset(); 316 context_provider_->SetLostContextCallback(
317 ContextProvider::LostContextCallback());
318 context_provider_->SetSwapBuffersCompleteCallback(
319 ContextProvider::SwapBuffersCompleteCallback());
320 context_provider_->SetMemoryPolicyChangedCallback(
321 ContextProvider::MemoryPolicyChangedCallback());
322 }
323 context_provider_ = NULL;
374 } 324 }
375 325
376 void OutputSurface::EnsureBackbuffer() { 326 void OutputSurface::EnsureBackbuffer() {
377 DCHECK(context3d_); 327 DCHECK(context_provider_);
378 if (has_gl_discard_backbuffer_) 328 if (has_gl_discard_backbuffer_)
379 context3d_->ensureBackbufferCHROMIUM(); 329 context_provider_->Context3d()->ensureBackbufferCHROMIUM();
380 } 330 }
381 331
382 void OutputSurface::DiscardBackbuffer() { 332 void OutputSurface::DiscardBackbuffer() {
383 DCHECK(context3d_); 333 DCHECK(context_provider_);
384 if (has_gl_discard_backbuffer_) 334 if (has_gl_discard_backbuffer_)
385 context3d_->discardBackbufferCHROMIUM(); 335 context_provider_->Context3d()->discardBackbufferCHROMIUM();
386 } 336 }
387 337
388 void OutputSurface::Reshape(gfx::Size size, float scale_factor) { 338 void OutputSurface::Reshape(gfx::Size size, float scale_factor) {
389 if (size == surface_size_ && scale_factor == device_scale_factor_) 339 if (size == surface_size_ && scale_factor == device_scale_factor_)
390 return; 340 return;
391 341
392 surface_size_ = size; 342 surface_size_ = size;
393 device_scale_factor_ = scale_factor; 343 device_scale_factor_ = scale_factor;
394 if (context3d_) { 344 if (context_provider_) {
395 context3d_->reshapeWithScaleFactor( 345 context_provider_->Context3d()->reshapeWithScaleFactor(
396 size.width(), size.height(), scale_factor); 346 size.width(), size.height(), scale_factor);
397 } 347 }
398 if (software_device_) 348 if (software_device_)
399 software_device_->Resize(size); 349 software_device_->Resize(size);
400 } 350 }
401 351
402 gfx::Size OutputSurface::SurfaceSize() const { 352 gfx::Size OutputSurface::SurfaceSize() const {
403 return surface_size_; 353 return surface_size_;
404 } 354 }
405 355
406 void OutputSurface::BindFramebuffer() { 356 void OutputSurface::BindFramebuffer() {
407 DCHECK(context3d_); 357 DCHECK(context_provider_);
408 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0); 358 context_provider_->Context3d()->bindFramebuffer(GL_FRAMEBUFFER, 0);
409 } 359 }
410 360
411 void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) { 361 void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
412 if (frame->software_frame_data) { 362 if (frame->software_frame_data) {
413 PostSwapBuffersComplete(); 363 PostSwapBuffersComplete();
414 DidSwapBuffers(); 364 DidSwapBuffers();
415 return; 365 return;
416 } 366 }
417 367
418 DCHECK(context3d_); 368 DCHECK(context_provider_);
419 DCHECK(frame->gl_frame_data); 369 DCHECK(frame->gl_frame_data);
420 370
421 if (frame->gl_frame_data->sub_buffer_rect == 371 if (frame->gl_frame_data->sub_buffer_rect ==
422 gfx::Rect(frame->gl_frame_data->size)) { 372 gfx::Rect(frame->gl_frame_data->size)) {
423 // Note that currently this has the same effect as SwapBuffers; we should 373 // Note that currently this has the same effect as SwapBuffers; we should
424 // consider exposing a different entry point on WebGraphicsContext3D. 374 // consider exposing a different entry point on WebGraphicsContext3D.
425 context3d()->prepareTexture(); 375 context_provider_->Context3d()->prepareTexture();
426 } else { 376 } else {
427 gfx::Rect sub_buffer_rect = frame->gl_frame_data->sub_buffer_rect; 377 gfx::Rect sub_buffer_rect = frame->gl_frame_data->sub_buffer_rect;
428 context3d()->postSubBufferCHROMIUM(sub_buffer_rect.x(), 378 context_provider_->Context3d()->postSubBufferCHROMIUM(
429 sub_buffer_rect.y(), 379 sub_buffer_rect.x(),
430 sub_buffer_rect.width(), 380 sub_buffer_rect.y(),
431 sub_buffer_rect.height()); 381 sub_buffer_rect.width(),
382 sub_buffer_rect.height());
432 } 383 }
433 384
434 if (!has_swap_buffers_complete_callback_) 385 if (!has_swap_buffers_complete_callback_)
435 PostSwapBuffersComplete(); 386 PostSwapBuffersComplete();
436 387
437 DidSwapBuffers(); 388 DidSwapBuffers();
438 } 389 }
439 390
440 void OutputSurface::PostSwapBuffersComplete() { 391 void OutputSurface::PostSwapBuffersComplete() {
441 base::MessageLoop::current()->PostTask( 392 base::MessageLoop::current()->PostTask(
(...skipping 10 matching lines...) Expand all
452 "discard_backbuffer", discard_backbuffer); 403 "discard_backbuffer", discard_backbuffer);
453 // Just ignore the memory manager when it says to set the limit to zero 404 // Just ignore the memory manager when it says to set the limit to zero
454 // bytes. This will happen when the memory manager thinks that the renderer 405 // bytes. This will happen when the memory manager thinks that the renderer
455 // is not visible (which the renderer knows better). 406 // is not visible (which the renderer knows better).
456 if (policy.bytes_limit_when_visible) 407 if (policy.bytes_limit_when_visible)
457 client_->SetMemoryPolicy(policy); 408 client_->SetMemoryPolicy(policy);
458 client_->SetDiscardBackBufferWhenNotVisible(discard_backbuffer); 409 client_->SetDiscardBackBufferWhenNotVisible(discard_backbuffer);
459 } 410 }
460 411
461 } // namespace cc 412 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698