OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/compositor/browser_compositor_view_mac.h" |
| 6 |
| 7 #include "base/debug/trace_event.h" |
| 8 #include "base/mac/scoped_cftyperef.h" |
| 9 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" |
| 10 #include "content/browser/renderer_host/compositing_iosurface_mac.h" |
| 11 #include "content/browser/renderer_host/software_layer_mac.h" |
| 12 #include "ui/base/cocoa/animation_utils.h" |
| 13 #include "ui/gl/scoped_cgl.h" |
| 14 |
| 15 // The default implementation of additions to the NSView interface for browser |
| 16 // compositing should never be called. Log an error if they are. |
| 17 @implementation NSView (BrowserCompositorView) |
| 18 |
| 19 - (void)gotAcceleratedIOSurfaceFrame:(uint64)surface_handle |
| 20 withPixelSize:(gfx::Size)pixel_size |
| 21 withScaleFactor:(float)scale_factor { |
| 22 DLOG(ERROR) << "-[NSView gotAcceleratedIOSurfaceFrame] called on " |
| 23 << "non-overriden class."; |
| 24 } |
| 25 |
| 26 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data |
| 27 withScaleFactor:(float)scale_factor |
| 28 withCanvas:(SkCanvas*)canvas { |
| 29 DLOG(ERROR) << "-[NSView gotSoftwareFrame] called on non-overridden class."; |
| 30 } |
| 31 |
| 32 @end // NSView (BrowserCompositorView) |
| 33 |
| 34 @implementation BrowserCompositorViewMac : NSView |
| 35 |
| 36 - (id)initWithSuperview:(NSView*)view { |
| 37 if (self = [super init]) { |
| 38 // Disable the fade-in animation as the layer and view are added. |
| 39 ScopedCAActionDisabler disabler; |
| 40 |
| 41 // Make this view host a transparent layer. |
| 42 background_layer_.reset([[CALayer alloc] init]); |
| 43 [background_layer_ setContentsGravity:kCAGravityTopLeft]; |
| 44 [self setLayer:background_layer_]; |
| 45 [self setWantsLayer:YES]; |
| 46 |
| 47 compositor_.reset(new ui::Compositor(self)); |
| 48 [view addSubview:self]; |
| 49 } |
| 50 return self; |
| 51 } |
| 52 |
| 53 // This function closely mirrors RenderWidgetHostViewMac::LayoutLayers. When |
| 54 // only delegated rendering is supported, only one copy of this code will |
| 55 // need to exist. |
| 56 - (void)layoutLayers { |
| 57 // Disable animation of the layers' resizing or repositioning. |
| 58 ScopedCAActionDisabler disabler; |
| 59 |
| 60 NSSize superview_frame_size = [[self superview] frame].size; |
| 61 [self setFrame:NSMakeRect( |
| 62 0, 0, superview_frame_size.width, superview_frame_size.height)]; |
| 63 |
| 64 CGRect new_background_frame = CGRectMake( |
| 65 0, |
| 66 0, |
| 67 superview_frame_size.width, |
| 68 superview_frame_size.height); |
| 69 [background_layer_ setFrame:new_background_frame]; |
| 70 |
| 71 // The bounds of the accelerated layer determine the size of the GL surface |
| 72 // that will be drawn to. Make sure that this is big enough to draw the |
| 73 // IOSurface. |
| 74 if (accelerated_layer_) { |
| 75 CGRect layer_bounds = CGRectMake( |
| 76 0, |
| 77 0, |
| 78 [accelerated_layer_ iosurface]->dip_io_surface_size().width(), |
| 79 [accelerated_layer_ iosurface]->dip_io_surface_size().height()); |
| 80 CGPoint layer_position = CGPointMake( |
| 81 0, |
| 82 CGRectGetHeight(new_background_frame) - CGRectGetHeight(layer_bounds)); |
| 83 bool bounds_changed = !CGRectEqualToRect( |
| 84 layer_bounds, [accelerated_layer_ bounds]); |
| 85 [accelerated_layer_ setBounds:layer_bounds]; |
| 86 [accelerated_layer_ setPosition:layer_position]; |
| 87 if (bounds_changed) { |
| 88 [accelerated_layer_ setNeedsDisplay]; |
| 89 [accelerated_layer_ displayIfNeeded]; |
| 90 } |
| 91 } |
| 92 |
| 93 // The content area of the software layer is the size of the image provided. |
| 94 // Make the bounds of the layer match the superview's bounds, to ensure that |
| 95 // the visible contents are drawn. |
| 96 [software_layer_ setBounds:new_background_frame]; |
| 97 } |
| 98 |
| 99 - (ui::Compositor*)compositor { |
| 100 return compositor_.get(); |
| 101 } |
| 102 |
| 103 - (void)gotAcceleratedIOSurfaceFrame:(uint64)surface_handle |
| 104 withPixelSize:(gfx::Size)pixel_size |
| 105 withScaleFactor:(float)scale_factor { |
| 106 ScopedCAActionDisabler disabler; |
| 107 |
| 108 // If there is not a layer for accelerated frames, create one. |
| 109 if (!accelerated_layer_) { |
| 110 // Disable the fade-in animation as the layer is added. |
| 111 ScopedCAActionDisabler disabler; |
| 112 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = |
| 113 content::CompositingIOSurfaceMac::Create(); |
| 114 accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc] |
| 115 initWithIOSurface:iosurface |
| 116 withClient:NULL]); |
| 117 [[self layer] addSublayer:accelerated_layer_]; |
| 118 } |
| 119 |
| 120 { |
| 121 bool result = true; |
| 122 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 123 [accelerated_layer_ context]->cgl_context()); |
| 124 result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent( |
| 125 [accelerated_layer_ context], surface_handle, pixel_size, scale_factor); |
| 126 // TODO(ccameron): On failure, poison the GL context, tear down the layers, |
| 127 // and request a new frame. |
| 128 ignore_result(result); |
| 129 } |
| 130 [accelerated_layer_ gotNewFrame]; |
| 131 [self layoutLayers]; |
| 132 |
| 133 // If there was a software layer, remove it. |
| 134 if (software_layer_) { |
| 135 // Disable the fade-out animation as the layer is removed. |
| 136 ScopedCAActionDisabler disabler; |
| 137 [software_layer_ removeFromSuperlayer]; |
| 138 software_layer_.reset(); |
| 139 } |
| 140 } |
| 141 |
| 142 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data |
| 143 withScaleFactor:(float)scale_factor |
| 144 withCanvas:(SkCanvas*)canvas { |
| 145 if (!frame_data || !canvas) |
| 146 return; |
| 147 |
| 148 // If there is not a layer for software frames, create one. |
| 149 if (!software_layer_) { |
| 150 // Disable the fade-in animation as the layer is added. |
| 151 ScopedCAActionDisabler disabler; |
| 152 software_layer_.reset([[SoftwareLayer alloc] init]); |
| 153 [[self layer] addSublayer:software_layer_]; |
| 154 } |
| 155 |
| 156 SkImageInfo info; |
| 157 size_t row_bytes; |
| 158 const void* pixels = canvas->peekPixels(&info, &row_bytes); |
| 159 [software_layer_ setContentsToData:pixels |
| 160 withRowBytes:row_bytes |
| 161 withPixelSize:gfx::Size(info.fWidth, info.fHeight) |
| 162 withScaleFactor:scale_factor]; |
| 163 [self layoutLayers]; |
| 164 |
| 165 // If there was an accelerated layer, remove it. |
| 166 if (accelerated_layer_) { |
| 167 // Disable the fade-out animation as the layer is removed. |
| 168 ScopedCAActionDisabler disabler; |
| 169 [accelerated_layer_ removeFromSuperlayer]; |
| 170 accelerated_layer_.reset(); |
| 171 } |
| 172 } |
| 173 |
| 174 @end // BrowserCompositorViewMac |
OLD | NEW |