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

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

Issue 297573003: Make delegated software renderer work on Mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebas Created 6 years, 7 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
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 #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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698