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

Side by Side Diff: chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm

Issue 244043002: CoreAnimation: Reduce VA usage by extra layers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove stray comment Created 6 years, 8 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
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm » ('j') | 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 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" 5 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h"
10 #include "base/mac/scoped_cftyperef.h"
9 #include "base/mac/scoped_nsobject.h" 11 #include "base/mac/scoped_nsobject.h"
10 #include "chrome/browser/devtools/devtools_window.h" 12 #include "chrome/browser/devtools/devtools_window.h"
11 #import "chrome/browser/themes/theme_properties.h" 13 #import "chrome/browser/themes/theme_properties.h"
12 #import "chrome/browser/themes/theme_service.h" 14 #import "chrome/browser/themes/theme_service.h"
13 #import "chrome/browser/ui/cocoa/themed_window.h" 15 #import "chrome/browser/ui/cocoa/themed_window.h"
14 #include "content/public/browser/render_view_host.h" 16 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/render_widget_host_view.h" 17 #include "content/public/browser/render_widget_host_view.h"
16 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_contents_observer.h" 19 #include "content/public/browser/web_contents_observer.h"
18 #include "content/public/browser/web_contents_view.h" 20 #include "content/public/browser/web_contents_view.h"
21 #include "ui/base/cocoa/animation_utils.h"
22 #include "ui/base/ui_base_switches.h"
19 #include "ui/gfx/geometry/rect.h" 23 #include "ui/gfx/geometry/rect.h"
20 24
21 using content::WebContents; 25 using content::WebContents;
22 using content::WebContentsObserver; 26 using content::WebContentsObserver;
23 27
24 // FullscreenObserver is used by TabContentsController to monitor for the 28 // FullscreenObserver is used by TabContentsController to monitor for the
25 // showing/destruction of fullscreen render widgets. When notified, 29 // showing/destruction of fullscreen render widgets. When notified,
26 // TabContentsController will alter its child view hierarchy to either embed a 30 // TabContentsController will alter its child view hierarchy to either embed a
27 // fullscreen render widget view or restore the normal WebContentsView render 31 // fullscreen render widget view or restore the normal WebContentsView render
28 // view. The embedded fullscreen render widget will fill the user's screen in 32 // view. The embedded fullscreen render widget will fill the user's screen in
(...skipping 25 matching lines...) Expand all
54 [controller_ toggleFullscreenWidget:YES]; 58 [controller_ toggleFullscreenWidget:YES];
55 } 59 }
56 60
57 private: 61 private:
58 TabContentsController* const controller_; 62 TabContentsController* const controller_;
59 63
60 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); 64 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver);
61 }; 65 };
62 66
63 @interface TabContentsController (TabContentsContainerViewDelegate) 67 @interface TabContentsController (TabContentsContainerViewDelegate)
68 - (BOOL)contentsInFullscreenCaptureMode;
64 // Computes and returns the frame to use for the contents view within the 69 // Computes and returns the frame to use for the contents view within the
65 // container view. 70 // container view.
66 - (NSRect)frameForContentsView; 71 - (NSRect)frameForContentsView;
67 @end 72 @end
68 73
69 // An NSView with special-case handling for when the contents view does not 74 // An NSView with special-case handling for when the contents view does not
70 // expand to fill the entire tab contents area. See 'AutoEmbedFullscreen mode' 75 // expand to fill the entire tab contents area. See 'AutoEmbedFullscreen mode'
71 // in header file comments. 76 // in header file comments.
72 @interface TabContentsContainerView : NSView { 77 @interface TabContentsContainerView : NSView {
73 @private 78 @private
74 TabContentsController* delegate_; // weak 79 TabContentsController* delegate_; // weak
75 } 80 }
81
82 - (NSColor*)computeBackgroundColor;
76 @end 83 @end
77 84
78 @implementation TabContentsContainerView 85 @implementation TabContentsContainerView
79 86
80 - (id)initWithDelegate:(TabContentsController*)delegate { 87 - (id)initWithDelegate:(TabContentsController*)delegate {
81 if ((self = [super initWithFrame:NSZeroRect])) { 88 if ((self = [super initWithFrame:NSZeroRect])) {
82 delegate_ = delegate; 89 delegate_ = delegate;
90 if (!CommandLine::ForCurrentProcess()->HasSwitch(
91 switches::kDisableCoreAnimation)) {
92 ScopedCAActionDisabler disabler;
93 base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]);
94 [layer setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
95 [self setLayer:layer];
96 [self setWantsLayer:YES];
97 }
83 } 98 }
84 return self; 99 return self;
85 } 100 }
86 101
87 // Called by the delegate during dealloc to invalidate the pointer held by this 102 // Called by the delegate during dealloc to invalidate the pointer held by this
88 // view. 103 // view.
89 - (void)delegateDestroyed { 104 - (void)delegateDestroyed {
90 delegate_ = nil; 105 delegate_ = nil;
91 } 106 }
92 107
108 - (NSColor*)computeBackgroundColor {
109 // This view is sometimes flashed into visibility (e.g, when closing
110 // windows), so ensure that the flash be white in those cases.
111 if (![delegate_ contentsInFullscreenCaptureMode])
112 return [NSColor whiteColor];
113
114 // Fill with a dark tint of the new tab page's background color. This is
115 // only seen when the subview is sized specially for fullscreen tab capture.
116 NSColor* bgColor = nil;
117 ThemeService* const theme =
118 static_cast<ThemeService*>([[self window] themeProvider]);
119 if (theme)
120 bgColor = theme->GetNSColor(ThemeProperties::COLOR_NTP_BACKGROUND);
121 if (!bgColor)
122 bgColor = [[self window] backgroundColor];
123 const float kDarknessFraction = 0.80f;
124 return [bgColor blendedColorWithFraction:kDarknessFraction
125 ofColor:[NSColor blackColor]];
126 }
127
93 // Override -drawRect to fill the view with a solid color outside of the 128 // Override -drawRect to fill the view with a solid color outside of the
94 // subview's frame. 129 // subview's frame.
95 - (void)drawRect:(NSRect)dirtyRect { 130 - (void)drawRect:(NSRect)dirtyRect {
96 NSView* const contentsView = 131 NSView* const contentsView =
97 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil; 132 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil;
98 if (!contentsView || !NSContainsRect([contentsView frame], dirtyRect)) { 133 if (!contentsView || !NSContainsRect([contentsView frame], dirtyRect)) {
99 // Fill with a dark tint of the new tab page's background color. This is 134 [[self computeBackgroundColor] setFill];
100 // only seen when the subview is sized specially for fullscreen tab capture.
101 NSColor* bgColor = nil;
102 ThemeService* const theme =
103 static_cast<ThemeService*>([[self window] themeProvider]);
104 if (theme)
105 bgColor = theme->GetNSColor(ThemeProperties::COLOR_NTP_BACKGROUND);
106 if (!bgColor)
107 bgColor = [[self window] backgroundColor];
108 const float kDarknessFraction = 0.80f;
109 [[bgColor blendedColorWithFraction:kDarknessFraction
110 ofColor:[NSColor blackColor]] setFill];
111 NSRectFill(dirtyRect); 135 NSRectFill(dirtyRect);
112 } 136 }
113 [super drawRect:dirtyRect]; 137 [super drawRect:dirtyRect];
114 } 138 }
115 139
116 // Override auto-resizing logic to query the delegate for the exact frame to 140 // Override auto-resizing logic to query the delegate for the exact frame to
117 // use for the contents view. 141 // use for the contents view.
118 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { 142 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
119 NSView* const contentsView = 143 NSView* const contentsView =
120 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil; 144 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil;
121 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable || 145 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable ||
122 !delegate_) { 146 !delegate_) {
123 return; 147 return;
124 } 148 }
125 [contentsView setFrame:[delegate_ frameForContentsView]]; 149 [contentsView setFrame:[delegate_ frameForContentsView]];
126 } 150 }
127 151
152 // Update the background layer's color whenever the view needs to repaint.
153 - (void)setNeedsDisplayInRect:(NSRect)rect {
154 [super setNeedsDisplayInRect:rect];
155
156 // Convert from an NSColor to a CGColorRef.
157 NSColor* nsBackgroundColor = [self computeBackgroundColor];
158 NSColorSpace* nsColorSpace = [nsBackgroundColor colorSpace];
159 CGColorSpaceRef cgColorSpace = [nsColorSpace CGColorSpace];
160 const NSInteger numberOfComponents = [nsBackgroundColor numberOfComponents];
161 CGFloat components[numberOfComponents];
162 [nsBackgroundColor getComponents:components];
163 base::ScopedCFTypeRef<CGColorRef> cgBackgroundColor(
164 CGColorCreate(cgColorSpace, components));
165
166 ScopedCAActionDisabler disabler;
167 [[self layer] setBackgroundColor:cgBackgroundColor];
168 }
169
128 @end // @implementation TabContentsContainerView 170 @end // @implementation TabContentsContainerView
129 171
130 @implementation TabContentsController 172 @implementation TabContentsController
131 @synthesize webContents = contents_; 173 @synthesize webContents = contents_;
132 174
133 - (id)initWithContents:(WebContents*)contents 175 - (id)initWithContents:(WebContents*)contents
134 andAutoEmbedFullscreen:(BOOL)enableEmbeddedFullscreen { 176 andAutoEmbedFullscreen:(BOOL)enableEmbeddedFullscreen {
135 if ((self = [super initWithNibName:nil bundle:nil])) { 177 if ((self = [super initWithNibName:nil bundle:nil])) {
136 if (enableEmbeddedFullscreen) 178 if (enableEmbeddedFullscreen)
137 fullscreenObserver_.reset(new FullscreenObserver(self)); 179 fullscreenObserver_.reset(new FullscreenObserver(self));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 [self ensureContentsVisible]; 298 [self ensureContentsVisible];
257 } 299 }
258 } 300 }
259 301
260 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { 302 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen {
261 isEmbeddingFullscreenWidget_ = enterFullscreen && 303 isEmbeddingFullscreenWidget_ = enterFullscreen &&
262 contents_ && contents_->GetFullscreenRenderWidgetHostView(); 304 contents_ && contents_->GetFullscreenRenderWidgetHostView();
263 [self ensureContentsVisible]; 305 [self ensureContentsVisible];
264 } 306 }
265 307
266 - (NSRect)frameForContentsView { 308 - (BOOL)contentsInFullscreenCaptureMode {
267 const NSSize containerSize = [[self view] frame].size;
268 gfx::Rect rect;
269 rect.set_width(containerSize.width);
270 rect.set_height(containerSize.height);
271
272 // In most cases, the contents view is simply sized to fill the container
273 // view's bounds. Only WebContentses that are in fullscreen mode and being
274 // screen-captured will engage the special layout/sizing behavior.
275 if (!fullscreenObserver_) 309 if (!fullscreenObserver_)
276 return NSRectFromCGRect(rect.ToCGRect()); 310 return NO;
277 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|. 311 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|.
278 content::WebContents* const wc = fullscreenObserver_->web_contents(); 312 content::WebContents* const wc = fullscreenObserver_->web_contents();
279 if (!wc || 313 if (!wc ||
280 wc->GetCapturerCount() == 0 || 314 wc->GetCapturerCount() == 0 ||
281 wc->GetPreferredSize().IsEmpty() || 315 wc->GetPreferredSize().IsEmpty() ||
282 !(isEmbeddingFullscreenWidget_ || 316 !(isEmbeddingFullscreenWidget_ ||
283 (wc->GetDelegate() && 317 (wc->GetDelegate() &&
284 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { 318 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) {
319 return NO;
320 }
321 return YES;
322 }
323
324 - (NSRect)frameForContentsView {
325 const NSSize containerSize = [[self view] frame].size;
326 gfx::Rect rect;
327 rect.set_width(containerSize.width);
328 rect.set_height(containerSize.height);
329
330 // In most cases, the contents view is simply sized to fill the container
331 // view's bounds. Only WebContentses that are in fullscreen mode and being
332 // screen-captured will engage the special layout/sizing behavior.
333 if (![self contentsInFullscreenCaptureMode])
285 return NSRectFromCGRect(rect.ToCGRect()); 334 return NSRectFromCGRect(rect.ToCGRect());
286 }
287 335
288 // Size the contents view to the capture video resolution and center it. If 336 // Size the contents view to the capture video resolution and center it. If
289 // the container view is not large enough to fit it at the preferred size, 337 // the container view is not large enough to fit it at the preferred size,
290 // scale down to fit (preserving aspect ratio). 338 // scale down to fit (preserving aspect ratio).
339 content::WebContents* const wc = fullscreenObserver_->web_contents();
291 const gfx::Size captureSize = wc->GetPreferredSize(); 340 const gfx::Size captureSize = wc->GetPreferredSize();
292 if (captureSize.width() <= rect.width() && 341 if (captureSize.width() <= rect.width() &&
293 captureSize.height() <= rect.height()) { 342 captureSize.height() <= rect.height()) {
294 // No scaling, just centering. 343 // No scaling, just centering.
295 rect.ClampToCenteredSize(captureSize); 344 rect.ClampToCenteredSize(captureSize);
296 } else { 345 } else {
297 // Scale down, preserving aspect ratio, and center. 346 // Scale down, preserving aspect ratio, and center.
298 // TODO(miu): This is basically media::ComputeLetterboxRegion(), and it 347 // TODO(miu): This is basically media::ComputeLetterboxRegion(), and it
299 // looks like others have written this code elsewhere. Let's consolidate 348 // looks like others have written this code elsewhere. Let's consolidate
300 // into a shared function ui/gfx/geometry or around there. 349 // into a shared function ui/gfx/geometry or around there.
301 const int64 x = static_cast<int64>(captureSize.width()) * rect.height(); 350 const int64 x = static_cast<int64>(captureSize.width()) * rect.height();
302 const int64 y = static_cast<int64>(captureSize.height()) * rect.width(); 351 const int64 y = static_cast<int64>(captureSize.height()) * rect.width();
303 if (y < x) { 352 if (y < x) {
304 rect.ClampToCenteredSize(gfx::Size( 353 rect.ClampToCenteredSize(gfx::Size(
305 rect.width(), static_cast<int>(y / captureSize.width()))); 354 rect.width(), static_cast<int>(y / captureSize.width())));
306 } else { 355 } else {
307 rect.ClampToCenteredSize(gfx::Size( 356 rect.ClampToCenteredSize(gfx::Size(
308 static_cast<int>(x / captureSize.height()), rect.height())); 357 static_cast<int>(x / captureSize.height()), rect.height()));
309 } 358 }
310 } 359 }
311 360
312 return NSRectFromCGRect(rect.ToCGRect()); 361 return NSRectFromCGRect(rect.ToCGRect());
313 } 362 }
314 363
315 @end 364 @end
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698