| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |