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 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
8 #include <QuartzCore/QuartzCore.h> | 8 #include <QuartzCore/QuartzCore.h> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 } | 600 } |
601 | 601 |
602 return true; | 602 return true; |
603 } | 603 } |
604 | 604 |
605 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { | 605 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { |
606 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); | 606 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); |
607 if (software_layer_ || !use_core_animation_) | 607 if (software_layer_ || !use_core_animation_) |
608 return; | 608 return; |
609 | 609 |
610 software_layer_.reset([[SoftwareLayer alloc] | 610 software_layer_.reset([[SoftwareLayer alloc] init]); |
611 initWithRenderWidgetHostViewMac:this]); | |
612 DCHECK(software_layer_); | 611 DCHECK(software_layer_); |
613 | 612 |
614 // Disable the fade-in animation as the layer is added. | 613 // Disable the fade-in animation as the layer is added. |
615 ScopedCAActionDisabler disabler; | 614 ScopedCAActionDisabler disabler; |
616 [background_layer_ addSublayer:software_layer_]; | 615 [background_layer_ addSublayer:software_layer_]; |
617 } | 616 } |
618 | 617 |
619 void RenderWidgetHostViewMac::DestroySoftwareLayer() { | 618 void RenderWidgetHostViewMac::DestroySoftwareLayer() { |
620 if (!software_layer_) | 619 if (!software_layer_) |
621 return; | 620 return; |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 | 860 |
862 if (web_contents_switch_paint_time_.is_null()) | 861 if (web_contents_switch_paint_time_.is_null()) |
863 web_contents_switch_paint_time_ = base::TimeTicks::Now(); | 862 web_contents_switch_paint_time_ = base::TimeTicks::Now(); |
864 render_widget_host_->WasShown(); | 863 render_widget_host_->WasShown(); |
865 software_frame_manager_->SetVisibility(true); | 864 software_frame_manager_->SetVisibility(true); |
866 if (delegated_frame_host_) | 865 if (delegated_frame_host_) |
867 delegated_frame_host_->WasShown(); | 866 delegated_frame_host_->WasShown(); |
868 | 867 |
869 // Call setNeedsDisplay before pausing for new frames to come in -- if any | 868 // Call setNeedsDisplay before pausing for new frames to come in -- if any |
870 // do, and are drawn, then the needsDisplay bit will be cleared. | 869 // do, and are drawn, then the needsDisplay bit will be cleared. |
871 [software_layer_ setNeedsDisplay]; | |
872 [compositing_iosurface_layer_ setNeedsDisplay]; | 870 [compositing_iosurface_layer_ setNeedsDisplay]; |
873 PauseForPendingResizeOrRepaintsAndDraw(); | 871 PauseForPendingResizeOrRepaintsAndDraw(); |
874 | 872 |
875 // We're messing with the window, so do this to ensure no flashes. | 873 // We're messing with the window, so do this to ensure no flashes. |
876 if (!use_core_animation_) | 874 if (!use_core_animation_) |
877 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 875 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
878 } | 876 } |
879 | 877 |
880 void RenderWidgetHostViewMac::WasHidden() { | 878 void RenderWidgetHostViewMac::WasHidden() { |
881 if (render_widget_host_->is_hidden()) | 879 if (render_widget_host_->is_hidden()) |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 | 1561 |
1564 // Try to finish previous copy requests after draw to get better pipelining. | 1562 // Try to finish previous copy requests after draw to get better pipelining. |
1565 if (compositing_iosurface_) | 1563 if (compositing_iosurface_) |
1566 compositing_iosurface_->CheckIfAllCopiesAreFinished(false); | 1564 compositing_iosurface_->CheckIfAllCopiesAreFinished(false); |
1567 | 1565 |
1568 // The IOSurface's size may have changed, so re-layout the layers to take | 1566 // The IOSurface's size may have changed, so re-layout the layers to take |
1569 // this into account. This may force an immediate draw. | 1567 // this into account. This may force an immediate draw. |
1570 LayoutLayers(); | 1568 LayoutLayers(); |
1571 } | 1569 } |
1572 | 1570 |
| 1571 void RenderWidgetHostViewMac::GotBrowserCompositorSoftwareFrame( |
| 1572 cc::SoftwareFrameData* frame_data, |
| 1573 float scale_factor, |
| 1574 SkCanvas* canvas) { |
| 1575 if (!frame_data || !canvas) |
| 1576 return; |
| 1577 |
| 1578 SkImageInfo info; |
| 1579 size_t row_bytes; |
| 1580 const void* pixels = canvas->peekPixels(&info, &row_bytes); |
| 1581 |
| 1582 EnsureSoftwareLayer(); |
| 1583 [software_layer_ setContentsToData:pixels |
| 1584 withRowBytes:row_bytes |
| 1585 withPixelSize:gfx::Size(info.fWidth, info.fHeight) |
| 1586 withScaleFactor:scale_factor]; |
| 1587 |
| 1588 LayoutLayers(); |
| 1589 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
| 1590 } |
| 1591 |
1573 void RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() { | 1592 void RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() { |
1574 CHECK(!use_core_animation_); | 1593 CHECK(!use_core_animation_); |
1575 CHECK(compositing_iosurface_); | 1594 CHECK(compositing_iosurface_); |
1576 | 1595 |
1577 // If there is a pending frame, it should be acked by the end of this | 1596 // If there is a pending frame, it should be acked by the end of this |
1578 // function. Note that the ack should happen only after all drawing is | 1597 // function. Note that the ack should happen only after all drawing is |
1579 // complete, so that the ack happens after any blocking due to vsync. | 1598 // complete, so that the ack happens after any blocking due to vsync. |
1580 base::ScopedClosureRunner scoped_ack( | 1599 base::ScopedClosureRunner scoped_ack( |
1581 base::Bind(&RenderWidgetHostViewMac::SendPendingSwapAck, | 1600 base::Bind(&RenderWidgetHostViewMac::SendPendingSwapAck, |
1582 weak_factory_.GetWeakPtr())); | 1601 weak_factory_.GetWeakPtr())); |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 return (software_frame_manager_->HasCurrentFrame() && | 1905 return (software_frame_manager_->HasCurrentFrame() && |
1887 (desired_size.IsEmpty() || | 1906 (desired_size.IsEmpty() || |
1888 software_frame_manager_->GetCurrentFrameSizeInDIP() == | 1907 software_frame_manager_->GetCurrentFrameSizeInDIP() == |
1889 desired_size)); | 1908 desired_size)); |
1890 } | 1909 } |
1891 return false; | 1910 return false; |
1892 } | 1911 } |
1893 | 1912 |
1894 void RenderWidgetHostViewMac::OnSwapCompositorFrame( | 1913 void RenderWidgetHostViewMac::OnSwapCompositorFrame( |
1895 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { | 1914 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { |
| 1915 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame"); |
| 1916 |
1896 if (frame->delegated_frame_data) { | 1917 if (frame->delegated_frame_data) { |
1897 if (!compositor_) { | 1918 if (!compositor_) { |
1898 compositor_.reset(new ui::Compositor(cocoa_view_)); | 1919 compositor_.reset(new ui::Compositor(cocoa_view_)); |
1899 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); | 1920 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); |
1900 delegated_frame_host_.reset(new DelegatedFrameHost(this)); | 1921 delegated_frame_host_.reset(new DelegatedFrameHost(this)); |
1901 } | 1922 } |
1902 | 1923 |
1903 // TODO(ccameron): Having the root layer set while swapping the frame will | 1924 // TODO(ccameron): Having the root layer set while swapping the frame will |
1904 // result in frames not appearing. Fix this. | 1925 // result in frames not appearing. Fix this. |
1905 compositor_->SetRootLayer(NULL); | 1926 compositor_->SetRootLayer(NULL); |
(...skipping 17 matching lines...) Expand all Loading... |
1923 output_surface_id, | 1944 output_surface_id, |
1924 frame->software_frame_data.get(), | 1945 frame->software_frame_data.get(), |
1925 frame->metadata.device_scale_factor, | 1946 frame->metadata.device_scale_factor, |
1926 render_widget_host_->GetProcess()->GetHandle())) { | 1947 render_widget_host_->GetProcess()->GetHandle())) { |
1927 render_widget_host_->GetProcess()->ReceivedBadMessage(); | 1948 render_widget_host_->GetProcess()->ReceivedBadMessage(); |
1928 return; | 1949 return; |
1929 } | 1950 } |
1930 | 1951 |
1931 // Add latency info to report when the frame finishes drawing. | 1952 // Add latency info to report when the frame finishes drawing. |
1932 AddPendingLatencyInfo(frame->metadata.latency_info); | 1953 AddPendingLatencyInfo(frame->metadata.latency_info); |
| 1954 |
| 1955 if (use_core_animation_) { |
| 1956 const void* pixels = software_frame_manager_->GetCurrentFramePixels(); |
| 1957 gfx::Size size_in_pixels = |
| 1958 software_frame_manager_->GetCurrentFrameSizeInPixels(); |
| 1959 |
| 1960 EnsureSoftwareLayer(); |
| 1961 [software_layer_ setContentsToData:pixels |
| 1962 withRowBytes:4 * size_in_pixels.width() |
| 1963 withPixelSize:size_in_pixels |
| 1964 withScaleFactor:frame->metadata.device_scale_factor]; |
| 1965 |
| 1966 // Send latency information to the host immediately, as there will be no |
| 1967 // subsequent draw call in which to do so. |
| 1968 SendPendingLatencyInfoToHost(); |
| 1969 } |
| 1970 |
1933 GotSoftwareFrame(); | 1971 GotSoftwareFrame(); |
1934 | 1972 |
1935 cc::CompositorFrameAck ack; | 1973 cc::CompositorFrameAck ack; |
1936 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | 1974 RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
1937 render_widget_host_->GetRoutingID(), | 1975 render_widget_host_->GetRoutingID(), |
1938 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), | 1976 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), |
1939 render_widget_host_->GetProcess()->GetID(), | 1977 render_widget_host_->GetProcess()->GetID(), |
1940 ack); | 1978 ack); |
1941 software_frame_manager_->SwapToNewFrameComplete( | 1979 software_frame_manager_->SwapToNewFrameComplete( |
1942 !render_widget_host_->is_hidden()); | 1980 !render_widget_host_->is_hidden()); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2066 [cocoa_view_ setNeedsDisplay:YES]; | 2104 [cocoa_view_ setNeedsDisplay:YES]; |
2067 } | 2105 } |
2068 | 2106 |
2069 // Delete software backingstore and layer. | 2107 // Delete software backingstore and layer. |
2070 software_frame_manager_->DiscardCurrentFrame(); | 2108 software_frame_manager_->DiscardCurrentFrame(); |
2071 DestroySoftwareLayer(); | 2109 DestroySoftwareLayer(); |
2072 } | 2110 } |
2073 } | 2111 } |
2074 | 2112 |
2075 void RenderWidgetHostViewMac::GotSoftwareFrame() { | 2113 void RenderWidgetHostViewMac::GotSoftwareFrame() { |
| 2114 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame"); |
| 2115 |
2076 if (!render_widget_host_) | 2116 if (!render_widget_host_) |
2077 return; | 2117 return; |
2078 | 2118 |
2079 EnsureSoftwareLayer(); | 2119 EnsureSoftwareLayer(); |
2080 LayoutLayers(); | 2120 LayoutLayers(); |
2081 SendVSyncParametersToRenderer(); | 2121 SendVSyncParametersToRenderer(); |
2082 | 2122 |
2083 // Draw the contents of the frame immediately. It is critical that this | 2123 // Draw the contents of the frame immediately. It is critical that this |
2084 // happen before the frame be acked, otherwise the new frame will likely be | 2124 // happen before the frame be acked, otherwise the new frame will likely be |
2085 // ready before the drawing is complete, thrashing the browser main thread. | 2125 // ready before the drawing is complete, thrashing the browser main thread. |
2086 if (use_core_animation_) { | 2126 if (use_core_animation_) { |
2087 [software_layer_ setNeedsDisplay]; | |
2088 [software_layer_ displayIfNeeded]; | 2127 [software_layer_ displayIfNeeded]; |
2089 } else { | 2128 } else { |
2090 [cocoa_view_ setNeedsDisplay:YES]; | 2129 [cocoa_view_ setNeedsDisplay:YES]; |
2091 [cocoa_view_ displayIfNeeded]; | 2130 [cocoa_view_ displayIfNeeded]; |
2092 } | 2131 } |
2093 | 2132 |
2094 if (last_frame_was_accelerated_) { | 2133 if (last_frame_was_accelerated_) { |
2095 last_frame_was_accelerated_ = false; | 2134 last_frame_was_accelerated_ = false; |
2096 | 2135 |
2097 // If overlapping views are allowed, then don't unbind the context | 2136 // If overlapping views are allowed, then don't unbind the context |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2322 if (compositing_iosurface_layer_) { | 2361 if (compositing_iosurface_layer_) { |
2323 // Keep calling gotNewFrame in a loop until enough display calls come in. | 2362 // Keep calling gotNewFrame in a loop until enough display calls come in. |
2324 // Each call will be separated by about a vsync. | 2363 // Each call will be separated by about a vsync. |
2325 base::MessageLoop::current()->PostTask( | 2364 base::MessageLoop::current()->PostTask( |
2326 FROM_HERE, | 2365 FROM_HERE, |
2327 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, | 2366 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, |
2328 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); | 2367 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); |
2329 [compositing_iosurface_layer_ gotNewFrame]; | 2368 [compositing_iosurface_layer_ gotNewFrame]; |
2330 } | 2369 } |
2331 if (software_layer_) { | 2370 if (software_layer_) { |
2332 // In software mode, setNeedsDisplay will almost immediately result in the | 2371 // In software mode there is not an explicit setNeedsDisplay/display loop, |
2333 // layer's draw function being called, so manually insert a pretend-vsync | 2372 // so just wait a pretend-vsync at 60 Hz. |
2334 // at 60 Hz. | |
2335 base::MessageLoop::current()->PostDelayedTask( | 2373 base::MessageLoop::current()->PostDelayedTask( |
2336 FROM_HERE, | 2374 FROM_HERE, |
2337 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, | 2375 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, |
2338 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr()), | 2376 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr()), |
2339 base::TimeDelta::FromMilliseconds(1000/60)); | 2377 base::TimeDelta::FromMilliseconds(1000/60)); |
2340 [software_layer_ setNeedsDisplay]; | 2378 SendPendingLatencyInfoToHost(); |
2341 } | 2379 } |
2342 } | 2380 } |
2343 | 2381 |
2344 void RenderWidgetHostViewMac::AddPendingSwapAck( | 2382 void RenderWidgetHostViewMac::AddPendingSwapAck( |
2345 int32 route_id, int gpu_host_id, int32 renderer_id) { | 2383 int32 route_id, int gpu_host_id, int32 renderer_id) { |
2346 // Note that multiple un-acked swaps can come in the event of a GPU process | 2384 // Note that multiple un-acked swaps can come in the event of a GPU process |
2347 // loss. Drop the old acks. | 2385 // loss. Drop the old acks. |
2348 pending_swap_ack_.reset(new PendingSwapAck( | 2386 pending_swap_ack_.reset(new PendingSwapAck( |
2349 route_id, gpu_host_id, renderer_id)); | 2387 route_id, gpu_host_id, renderer_id)); |
2350 | 2388 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2436 // Also, sometimes, especially when infobars are being removed, the | 2474 // Also, sometimes, especially when infobars are being removed, the |
2437 // setNeedsDisplay calls are dropped on the floor, and stale content is | 2475 // setNeedsDisplay calls are dropped on the floor, and stale content is |
2438 // displayed. Calling displayIfNeeded will ensure that the right size | 2476 // displayed. Calling displayIfNeeded will ensure that the right size |
2439 // frame is drawn to the screen. | 2477 // frame is drawn to the screen. |
2440 // http://crbug.com/350817 | 2478 // http://crbug.com/350817 |
2441 [compositing_iosurface_layer_ setNeedsDisplay]; | 2479 [compositing_iosurface_layer_ setNeedsDisplay]; |
2442 [compositing_iosurface_layer_ displayIfNeeded]; | 2480 [compositing_iosurface_layer_ displayIfNeeded]; |
2443 } | 2481 } |
2444 } | 2482 } |
2445 | 2483 |
2446 // Dynamically update the software layer's contents scale to match the | |
2447 // software frame. | |
2448 if (software_frame_manager_->HasCurrentFrame() && | |
2449 [software_layer_ respondsToSelector:(@selector(contentsScale))] && | |
2450 [software_layer_ respondsToSelector:(@selector(setContentsScale:))]) { | |
2451 if (software_frame_manager_->GetCurrentFrameDeviceScaleFactor() != | |
2452 [software_layer_ contentsScale]) { | |
2453 [software_layer_ setContentsScale: | |
2454 software_frame_manager_->GetCurrentFrameDeviceScaleFactor()]; | |
2455 } | |
2456 } | |
2457 // Changing the software layer's bounds and position doesn't always result | 2484 // Changing the software layer's bounds and position doesn't always result |
2458 // in the layer being anchored to the top-left. Set the layer's frame | 2485 // in the layer being anchored to the top-left. Set the layer's frame |
2459 // explicitly, since this is more reliable in practice. | 2486 // explicitly, since this is more reliable in practice. |
2460 if (software_layer_) { | 2487 if (software_layer_) { |
2461 bool frame_changed = !CGRectEqualToRect( | 2488 bool frame_changed = !CGRectEqualToRect( |
2462 new_background_frame, [software_layer_ frame]); | 2489 new_background_frame, [software_layer_ frame]); |
2463 if (frame_changed) { | 2490 if (frame_changed) { |
2464 [software_layer_ setFrame:new_background_frame]; | 2491 [software_layer_ setFrame:new_background_frame]; |
2465 [software_layer_ setNeedsDisplay]; | |
2466 } | 2492 } |
2467 } | 2493 } |
2468 } | 2494 } |
2469 | 2495 |
2470 SkBitmap::Config RenderWidgetHostViewMac::PreferredReadbackFormat() { | 2496 SkBitmap::Config RenderWidgetHostViewMac::PreferredReadbackFormat() { |
2471 return SkBitmap::kARGB_8888_Config; | 2497 return SkBitmap::kARGB_8888_Config; |
2472 } | 2498 } |
2473 | 2499 |
2474 } // namespace content | 2500 } // namespace content |
2475 | 2501 |
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3308 - (void)onNativeSurfaceBuffersSwappedWithParams: | 3334 - (void)onNativeSurfaceBuffersSwappedWithParams: |
3309 (GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)params { | 3335 (GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)params { |
3310 | 3336 |
3311 renderWidgetHostView_->CompositorSwapBuffers( | 3337 renderWidgetHostView_->CompositorSwapBuffers( |
3312 params.surface_handle, | 3338 params.surface_handle, |
3313 params.size, | 3339 params.size, |
3314 params.scale_factor, | 3340 params.scale_factor, |
3315 params.latency_info); | 3341 params.latency_info); |
3316 } | 3342 } |
3317 | 3343 |
| 3344 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data |
| 3345 withScaleFactor:(float)scale_factor |
| 3346 withCanvas:(SkCanvas*)canvas { |
| 3347 renderWidgetHostView_->GotBrowserCompositorSoftwareFrame( |
| 3348 frame_data, scale_factor, canvas); |
| 3349 } |
| 3350 |
3318 - (void)drawRect:(NSRect)dirtyRect { | 3351 - (void)drawRect:(NSRect)dirtyRect { |
3319 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); | 3352 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); |
3320 DCHECK(!renderWidgetHostView_->use_core_animation_); | 3353 DCHECK(!renderWidgetHostView_->use_core_animation_); |
3321 | 3354 |
3322 if (!renderWidgetHostView_->render_widget_host_) { | 3355 if (!renderWidgetHostView_->render_widget_host_) { |
3323 // When using CoreAnimation, this path is used to paint the contents area | 3356 // When using CoreAnimation, this path is used to paint the contents area |
3324 // white before any frames come in. When layers to draw frames exist, this | 3357 // white before any frames come in. When layers to draw frames exist, this |
3325 // is not hit. | 3358 // is not hit. |
3326 [[NSColor whiteColor] set]; | 3359 [[NSColor whiteColor] set]; |
3327 NSRectFill(dirtyRect); | 3360 NSRectFill(dirtyRect); |
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4378 // native_app_window_cocoa.mm). This requires the render host view to be | 4411 // native_app_window_cocoa.mm). This requires the render host view to be |
4379 // draggable by default. | 4412 // draggable by default. |
4380 - (BOOL)mouseDownCanMoveWindow { | 4413 - (BOOL)mouseDownCanMoveWindow { |
4381 return YES; | 4414 return YES; |
4382 } | 4415 } |
4383 | 4416 |
4384 @end | 4417 @end |
4385 | 4418 |
4386 @implementation SoftwareLayer | 4419 @implementation SoftwareLayer |
4387 | 4420 |
4388 - (id)initWithRenderWidgetHostViewMac:(content::RenderWidgetHostViewMac*)r { | 4421 - (id)init { |
4389 if (self = [super init]) { | 4422 if (self = [super init]) { |
4390 renderWidgetHostView_ = r; | |
4391 | |
4392 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; | 4423 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; |
4393 [self setAnchorPoint:CGPointMake(0, 0)]; | 4424 [self setAnchorPoint:CGPointMake(0, 0)]; |
4394 // Setting contents gravity is necessary to prevent the layer from being | 4425 // Setting contents gravity is necessary to prevent the layer from being |
4395 // scaled during dyanmic resizes (especially with devtools open). | 4426 // scaled during dyanmic resizes (especially with devtools open). |
4396 [self setContentsGravity:kCAGravityTopLeft]; | 4427 [self setContentsGravity:kCAGravityTopLeft]; |
4397 if (renderWidgetHostView_->software_frame_manager_->HasCurrentFrame() && | |
4398 [self respondsToSelector:(@selector(setContentsScale:))]) { | |
4399 [self setContentsScale:renderWidgetHostView_->software_frame_manager_-> | |
4400 GetCurrentFrameDeviceScaleFactor()]; | |
4401 } | |
4402 | |
4403 // Ensure that the transition between frames not be animated. | |
4404 [self setActions:@{ @"contents" : [NSNull null] }]; | |
4405 } | 4428 } |
4406 return self; | 4429 return self; |
4407 } | 4430 } |
4408 | 4431 |
4409 - (void)drawInContext:(CGContextRef)context { | 4432 - (void)setContentsToData:(const void *)data |
4410 TRACE_EVENT0("browser", "SoftwareLayer::drawInContext"); | 4433 withRowBytes:(size_t)rowBytes |
| 4434 withPixelSize:(gfx::Size)pixelSize |
| 4435 withScaleFactor:(float)scaleFactor { |
| 4436 TRACE_EVENT0("browser", "-[SoftwareLayer setContentsToData]"); |
4411 | 4437 |
4412 CGRect clipRect = CGContextGetClipBoundingBox(context); | 4438 // Disable animating the contents change or the scale factor change. |
4413 if (renderWidgetHostView_) { | 4439 ScopedCAActionDisabler disabler; |
4414 [renderWidgetHostView_->cocoa_view() drawWithDirtyRect:clipRect | 4440 |
4415 inContext:context]; | 4441 // Set the contents of the software CALayer to be a CGImage with the provided |
4416 } else { | 4442 // pixel data. Make a copy of the data before backing the image with them, |
4417 CGContextSetFillColorWithColor(context, | 4443 // because the same buffer will be reused for the next frame. |
4418 CGColorGetConstantColor(kCGColorWhite)); | 4444 base::ScopedCFTypeRef<CFDataRef> dataCopy( |
4419 CGContextFillRect(context, clipRect); | 4445 CFDataCreate(NULL, |
| 4446 static_cast<const UInt8 *>(data), |
| 4447 rowBytes * pixelSize.height())); |
| 4448 base::ScopedCFTypeRef<CGDataProviderRef> dataProvider( |
| 4449 CGDataProviderCreateWithCFData(dataCopy)); |
| 4450 base::ScopedCFTypeRef<CGImageRef> image( |
| 4451 CGImageCreate(pixelSize.width(), |
| 4452 pixelSize.height(), |
| 4453 8, |
| 4454 32, |
| 4455 rowBytes, |
| 4456 base::mac::GetSystemColorSpace(), |
| 4457 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, |
| 4458 dataProvider, |
| 4459 NULL, |
| 4460 false, |
| 4461 kCGRenderingIntentDefault)); |
| 4462 [self setContents:(id)image.get()]; |
| 4463 |
| 4464 // Set the contents scale of the software CALayer. |
| 4465 if ([self respondsToSelector:(@selector(contentsScale))] && |
| 4466 [self respondsToSelector:(@selector(setContentsScale:))] && |
| 4467 [self contentsScale] != scaleFactor) { |
| 4468 [self setContentsScale:scaleFactor]; |
4420 } | 4469 } |
4421 } | 4470 } |
4422 | 4471 |
4423 - (void)disableRendering { | 4472 - (void)disableRendering { |
4424 // Disable the fade-out animation as the layer is removed. | 4473 // Disable the fade-out animation as the layer is removed. |
4425 ScopedCAActionDisabler disabler; | 4474 ScopedCAActionDisabler disabler; |
4426 [self removeFromSuperlayer]; | 4475 [self removeFromSuperlayer]; |
4427 renderWidgetHostView_ = nil; | |
4428 } | 4476 } |
4429 | 4477 |
4430 @end // implementation SoftwareLayer | 4478 @end // implementation SoftwareLayer |
OLD | NEW |