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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 16845005: Don't use a sleep in the browser's main thread to throttle swapbuffers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Resolve against head 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 | Annotate | Revision Log
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 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 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 "content/browser/renderer_host/render_widget_host_view_mac.h" 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
6 6
7 #include <QuartzCore/QuartzCore.h> 7 #include <QuartzCore/QuartzCore.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 about_to_validate_and_paint_(false), 370 about_to_validate_and_paint_(false),
371 call_set_needs_display_in_rect_pending_(false), 371 call_set_needs_display_in_rect_pending_(false),
372 last_frame_was_accelerated_(false), 372 last_frame_was_accelerated_(false),
373 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), 373 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
374 can_compose_inline_(true), 374 can_compose_inline_(true),
375 allow_overlapping_views_(false), 375 allow_overlapping_views_(false),
376 use_core_animation_(false), 376 use_core_animation_(false),
377 is_loading_(false), 377 is_loading_(false),
378 is_hidden_(false), 378 is_hidden_(false),
379 weak_factory_(this), 379 weak_factory_(this),
380 fullscreen_parent_host_view_(NULL) { 380 fullscreen_parent_host_view_(NULL),
381 pending_swap_buffers_acks_weak_factory_(this),
382 next_swap_ack_time_(base::Time::Now()) {
381 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| 383 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_|
382 // goes away. Since we autorelease it, our caller must put 384 // goes away. Since we autorelease it, our caller must put
383 // |GetNativeView()| into the view hierarchy right after calling us. 385 // |GetNativeView()| into the view hierarchy right after calling us.
384 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] 386 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc]
385 initWithRenderWidgetHostViewMac:this] autorelease]; 387 initWithRenderWidgetHostViewMac:this] autorelease];
386 388
387 if (GetCoreAnimationStatus() == CORE_ANIMATION_ENABLED_ALWAYS) { 389 if (GetCoreAnimationStatus() == CORE_ANIMATION_ENABLED_ALWAYS) {
388 EnableCoreAnimation(); 390 EnableCoreAnimation();
389 } 391 }
390 392
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 } else { 1257 } else {
1256 compositing_iosurface_->DrawIOSurface(this); 1258 compositing_iosurface_->DrawIOSurface(this);
1257 } 1259 }
1258 } 1260 }
1259 1261
1260 if (should_post_notification && [[cocoa_view_ delegate] 1262 if (should_post_notification && [[cocoa_view_ delegate]
1261 respondsToSelector:@selector(compositingIOSurfaceCreated)]) { 1263 respondsToSelector:@selector(compositingIOSurfaceCreated)]) {
1262 [[cocoa_view_ delegate] compositingIOSurfaceCreated]; 1264 [[cocoa_view_ delegate] compositingIOSurfaceCreated];
1263 } 1265 }
1264 1266
1265 // Don't ack the new frame until it is drawn.
1266 if (use_core_animation_)
1267 return false;
1268
1269 return true; 1267 return true;
1270 } 1268 }
1271 1269
1272 void RenderWidgetHostViewMac::AckPendingSwapBuffers() { 1270 void RenderWidgetHostViewMac::AckPendingSwapBuffers() {
1273 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::AckPendingSwapBuffers"); 1271 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::AckPendingSwapBuffers");
1272
1273 // Cancel any outstanding delayed calls to this function.
1274 pending_swap_buffers_acks_weak_factory_.InvalidateWeakPtrs();
1275
1274 while (!pending_swap_buffers_acks_.empty()) { 1276 while (!pending_swap_buffers_acks_.empty()) {
1275 if (pending_swap_buffers_acks_.front().first != 0) { 1277 if (pending_swap_buffers_acks_.front().first != 0) {
1276 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; 1278 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
1277 ack_params.sync_point = 0; 1279 ack_params.sync_point = 0;
1278 if (compositing_iosurface_) 1280 if (compositing_iosurface_)
1279 ack_params.renderer_id = compositing_iosurface_->GetRendererID(); 1281 ack_params.renderer_id = compositing_iosurface_->GetRendererID();
1280 RenderWidgetHostImpl::AcknowledgeBufferPresent( 1282 RenderWidgetHostImpl::AcknowledgeBufferPresent(
1281 pending_swap_buffers_acks_.front().first, 1283 pending_swap_buffers_acks_.front().first,
1282 pending_swap_buffers_acks_.front().second, 1284 pending_swap_buffers_acks_.front().second,
1283 ack_params); 1285 ack_params);
1284 if (render_widget_host_) { 1286 if (render_widget_host_) {
1285 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); 1287 render_widget_host_->AcknowledgeSwapBuffersToRenderer();
1286
1287 // Send VSync parameters to compositor thread.
1288 if (compositing_iosurface_) {
1289 base::TimeTicks timebase;
1290 uint32 numerator = 0, denominator = 0;
1291 compositing_iosurface_->GetVSyncParameters(&timebase,
1292 &numerator,
1293 &denominator);
1294 if (numerator > 0 && denominator > 0) {
1295 int64 interval_micros =
1296 1000000 * static_cast<int64>(numerator) / denominator;
1297 render_widget_host_->UpdateVSyncParameters(
1298 timebase, base::TimeDelta::FromMicroseconds(interval_micros));
1299 } else {
1300 // Pass reasonable default values if unable to get the actual ones
1301 // (e.g. CVDisplayLink failed to return them because the display is
1302 // in sleep mode).
1303 static const int64 kOneOverSixtyMicroseconds = 16669;
1304 render_widget_host_->UpdateVSyncParameters(
1305 base::TimeTicks::Now(),
1306 base::TimeDelta::FromMicroseconds(kOneOverSixtyMicroseconds));
1307 }
1308 }
1309 } 1288 }
1310 } 1289 }
1311 pending_swap_buffers_acks_.erase(pending_swap_buffers_acks_.begin()); 1290 pending_swap_buffers_acks_.erase(pending_swap_buffers_acks_.begin());
1312 } 1291 }
1313 } 1292 }
1314 1293
1294 void RenderWidgetHostViewMac::ThrottledAckPendingSwapBuffers() {
1295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1296
1297 // Send VSync parameters to the renderer's compositor thread.
1298 base::TimeTicks vsync_timebase;
1299 base::TimeDelta vsync_interval;
1300 GetVSyncParameters(&vsync_timebase, &vsync_interval);
1301 if (render_widget_host_ && compositing_iosurface_)
1302 render_widget_host_->UpdateVSyncParameters(vsync_timebase, vsync_interval);
1303
1304 // If the render widget host is responsible for throttling swaps to vsync rate
1305 // then don't ack the swapbuffers until a full vsync has passed since the last
1306 // ack was sent.
1307 bool throttle_swap_ack =
1308 render_widget_host_ &&
1309 !render_widget_host_->is_threaded_compositing_enabled() &&
1310 compositing_iosurface_ &&
1311 !compositing_iosurface_->is_vsync_disabled();
1312 base::Time now = base::Time::Now();
1313 if (throttle_swap_ack && next_swap_ack_time_ > now) {
1314 base::TimeDelta next_swap_ack_delay = next_swap_ack_time_ - now;
1315 next_swap_ack_time_ += vsync_interval;
1316 base::MessageLoop::current()->PostDelayedTask(
1317 FROM_HERE,
1318 base::Bind(&RenderWidgetHostViewMac::AckPendingSwapBuffers,
1319 pending_swap_buffers_acks_weak_factory_.GetWeakPtr()),
1320 next_swap_ack_delay);
1321 } else {
1322 next_swap_ack_time_ = now + vsync_interval;
1323 AckPendingSwapBuffers();
1324 }
1325 }
1326
1327 void RenderWidgetHostViewMac::GetVSyncParameters(
1328 base::TimeTicks* timebase, base::TimeDelta* interval) {
1329 if (compositing_iosurface_) {
1330 uint32 numerator = 0;
1331 uint32 denominator = 0;
1332 compositing_iosurface_->GetVSyncParameters(
1333 timebase, &numerator, &denominator);
1334 if (numerator > 0 && denominator > 0) {
1335 int64 interval_micros =
1336 1000000 * static_cast<int64>(numerator) / denominator;
1337 *interval = base::TimeDelta::FromMicroseconds(interval_micros);
1338 return;
1339 }
1340 }
1341
1342 // Pass reasonable default values if unable to get the actual ones
1343 // (e.g. CVDisplayLink failed to return them because the display is
1344 // in sleep mode).
1345 static const int64 kOneOverSixtyMicroseconds = 16669;
1346 *timebase = base::TimeTicks::Now(),
1347 *interval = base::TimeDelta::FromMicroseconds(kOneOverSixtyMicroseconds);
1348 }
1349
1315 bool RenderWidgetHostViewMac::GetLineBreakIndex( 1350 bool RenderWidgetHostViewMac::GetLineBreakIndex(
1316 const std::vector<gfx::Rect>& bounds, 1351 const std::vector<gfx::Rect>& bounds,
1317 const ui::Range& range, 1352 const ui::Range& range,
1318 size_t* line_break_point) { 1353 size_t* line_break_point) {
1319 DCHECK(line_break_point); 1354 DCHECK(line_break_point);
1320 if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty()) 1355 if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty())
1321 return false; 1356 return false;
1322 1357
1323 // We can't check line breaking completely from only rectangle array. Thus we 1358 // We can't check line breaking completely from only rectangle array. Thus we
1324 // assume the line breaking as the next character's y offset is larger than 1359 // assume the line breaking as the next character's y offset is larger than
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 TRACE_EVENT0("browser", 1478 TRACE_EVENT0("browser",
1444 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); 1479 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped");
1445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1446 1481
1447 pending_swap_buffers_acks_.push_back(std::make_pair(params.route_id, 1482 pending_swap_buffers_acks_.push_back(std::make_pair(params.route_id,
1448 gpu_host_id)); 1483 gpu_host_id));
1449 1484
1450 if (CompositorSwapBuffers(params.surface_handle, 1485 if (CompositorSwapBuffers(params.surface_handle,
1451 params.size, 1486 params.size,
1452 params.scale_factor, 1487 params.scale_factor,
1453 params.latency_info)) 1488 params.latency_info)) {
1454 AckPendingSwapBuffers(); 1489 if (!use_core_animation_)
1490 ThrottledAckPendingSwapBuffers();
1491 }
1455 } 1492 }
1456 1493
1457 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( 1494 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer(
1458 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, 1495 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
1459 int gpu_host_id) { 1496 int gpu_host_id) {
1460 TRACE_EVENT0("browser", 1497 TRACE_EVENT0("browser",
1461 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); 1498 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer");
1462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1463 1500
1464 pending_swap_buffers_acks_.push_back(std::make_pair(params.route_id, 1501 pending_swap_buffers_acks_.push_back(std::make_pair(params.route_id,
1465 gpu_host_id)); 1502 gpu_host_id));
1466 1503
1467 if (CompositorSwapBuffers(params.surface_handle, 1504 if (CompositorSwapBuffers(params.surface_handle,
1468 params.surface_size, 1505 params.surface_size,
1469 params.surface_scale_factor, 1506 params.surface_scale_factor,
1470 params.latency_info)) 1507 params.latency_info)) {
1471 AckPendingSwapBuffers(); 1508 if (!use_core_animation_)
1509 ThrottledAckPendingSwapBuffers();
1510 }
1472 } 1511 }
1473 1512
1474 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { 1513 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() {
1475 if (compositing_iosurface_) 1514 if (compositing_iosurface_)
1476 compositing_iosurface_->UnrefIOSurface(); 1515 compositing_iosurface_->UnrefIOSurface();
1477 } 1516 }
1478 1517
1479 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { 1518 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() {
1480 DestroyCompositedIOSurfaceAndLayer(); 1519 DestroyCompositedIOSurfaceAndLayer();
1481 } 1520 }
(...skipping 2155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 return YES; 3676 return YES;
3638 } 3677 }
3639 3678
3640 - (BOOL)isOpaque { 3679 - (BOOL)isOpaque {
3641 if (renderWidgetHostView_->use_core_animation_) 3680 if (renderWidgetHostView_->use_core_animation_)
3642 return YES; 3681 return YES;
3643 return [super isOpaque]; 3682 return [super isOpaque];
3644 } 3683 }
3645 3684
3646 @end 3685 @end
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698