OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "ui/accelerated_widget_mac/ca_renderer_layer_tree.h" | 5 #include "ui/accelerated_widget_mac/ca_renderer_layer_tree.h" |
6 | 6 |
7 #include <AVFoundation/AVFoundation.h> | 7 #include <AVFoundation/AVFoundation.h> |
8 #include <CoreMedia/CoreMedia.h> | 8 #include <CoreMedia/CoreMedia.h> |
9 #include <CoreVideo/CoreVideo.h> | 9 #include <CoreVideo/CoreVideo.h> |
10 #include <GLES2/gl2extchromium.h> | 10 #include <GLES2/gl2extchromium.h> |
11 | 11 |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/mac/sdk_forward_declarations.h" | 13 #include "base/mac/sdk_forward_declarations.h" |
14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
15 #include "third_party/skia/include/core/SkColor.h" | 15 #include "third_party/skia/include/core/SkColor.h" |
16 #include "ui/base/cocoa/animation_utils.h" | 16 #include "ui/base/cocoa/animation_utils.h" |
17 #include "ui/base/ui_base_switches.h" | 17 #include "ui/base/ui_base_switches.h" |
18 #include "ui/gfx/geometry/dip_util.h" | 18 #include "ui/gfx/geometry/dip_util.h" |
| 19 #include "ui/gl/ca_renderer_layer_params.h" |
19 #include "ui/gl/gl_image_io_surface.h" | 20 #include "ui/gl/gl_image_io_surface.h" |
20 | 21 |
21 #if !defined(MAC_OS_X_VERSION_10_8) || \ | 22 #if !defined(MAC_OS_X_VERSION_10_8) || \ |
22 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 | 23 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 |
23 extern NSString* const AVLayerVideoGravityResize; | 24 extern NSString* const AVLayerVideoGravityResize; |
24 extern "C" void NSAccessibilityPostNotificationWithUserInfo( | 25 extern "C" void NSAccessibilityPostNotificationWithUserInfo( |
25 id object, | 26 id object, |
26 NSString* notification, | 27 NSString* notification, |
27 NSDictionary* user_info); | 28 NSDictionary* user_info); |
28 extern "C" OSStatus CMSampleBufferCreateForImageBuffer( | 29 extern "C" OSStatus CMSampleBufferCreateForImageBuffer( |
29 CFAllocatorRef, | 30 CFAllocatorRef, |
30 CVImageBufferRef, | 31 CVImageBufferRef, |
31 Boolean dataReady, | 32 Boolean dataReady, |
32 CMSampleBufferMakeDataReadyCallback, | 33 CMSampleBufferMakeDataReadyCallback, |
33 void*, | 34 void*, |
34 CMVideoFormatDescriptionRef, | 35 CMVideoFormatDescriptionRef, |
35 const CMSampleTimingInfo*, | 36 const CMSampleTimingInfo*, |
36 CMSampleBufferRef*); | 37 CMSampleBufferRef*); |
37 extern "C" CFArrayRef CMSampleBufferGetSampleAttachmentsArray(CMSampleBufferRef, | 38 extern "C" CFArrayRef CMSampleBufferGetSampleAttachmentsArray(CMSampleBufferRef, |
38 Boolean); | 39 Boolean); |
39 extern "C" OSStatus CMVideoFormatDescriptionCreateForImageBuffer( | 40 extern "C" OSStatus CMVideoFormatDescriptionCreateForImageBuffer( |
40 CFAllocatorRef, | 41 CFAllocatorRef, |
41 CVImageBufferRef, | 42 CVImageBufferRef, |
42 CMVideoFormatDescriptionRef*); | 43 CMVideoFormatDescriptionRef*); |
43 extern "C" CMTime CMTimeMake(int64_t, int32_t); | 44 extern "C" CMTime CMTimeMake(int64_t, int32_t); |
44 extern CFStringRef const kCMSampleAttachmentKey_DisplayImmediately; | 45 extern CFStringRef const kCMSampleAttachmentKey_DisplayImmediately; |
45 extern const CMTime kCMTimeInvalid; | 46 extern const CMTime kCMTimeInvalid; |
46 #endif // MAC_OS_X_VERSION_10_8 | 47 #endif // MAC_OS_X_VERSION_10_8 |
47 | 48 |
48 // CAFilter and CAColorMatrix are QuartzCore SPI. | |
49 @interface CAFilter : NSObject<NSCopying, NSMutableCopying, NSCoding> | |
50 @end | |
51 | |
52 @interface CAFilter (QuartzCoreSPI) | |
53 + (CAFilter*)filterWithType:(NSString*)type; | |
54 @end | |
55 | |
56 // TODO(erikchen): Test out the named filter kCAFilterColorInvert. | |
57 // https://crbug.com/581526. | |
58 extern NSString* const kCAFilterColorMatrix; | |
59 extern NSString* const kCAFilterColorMonochrome; | |
60 extern NSString* const kCAFilterColorHueRotate; | |
61 extern NSString* const kCAFilterColorSaturate; | |
62 extern NSString* const kCAFilterGaussianBlur; | |
63 | |
64 struct CAColorMatrix { | |
65 float m11, m12, m13, m14, m15; | |
66 float m21, m22, m23, m24, m25; | |
67 float m31, m32, m33, m34, m35; | |
68 float m41, m42, m43, m44, m45; | |
69 }; | |
70 typedef struct CAColorMatrix CAColorMatrix; | |
71 | |
72 @interface NSValue (QuartzCoreSPI) | |
73 + (NSValue*)valueWithCAColorMatrix:(CAColorMatrix)t; | |
74 @end | |
75 | |
76 namespace ui { | 49 namespace ui { |
77 | 50 |
78 namespace { | 51 namespace { |
79 | 52 |
80 float Blend(float from, float to, float progress) { | |
81 return from + (to - from) * progress; | |
82 } | |
83 | |
84 #ifndef M_PI | |
85 #define M_PI 3.14159265358979323846 | |
86 #endif | |
87 | |
88 double DegreeToRadians(double degree) { return degree * M_PI / 180.0; } | |
89 | |
90 // These values were obtained from https://www.w3.org/TR/filter-effects/. | |
91 static const double kSepiaFullConstants[3][3] = { | |
92 { 0.393, 0.769, 0.189 }, | |
93 { 0.349, 0.686, 0.168 }, | |
94 { 0.272, 0.534, 0.131 } | |
95 }; | |
96 | |
97 static const double kSepiaNoneConstants[3][3] = { | |
98 { 1, 0, 0 }, | |
99 { 0, 1, 0 }, | |
100 { 0, 0, 1 } | |
101 }; | |
102 | |
103 // This will enqueue |io_surface| to be drawn by |av_layer|. This will | 53 // This will enqueue |io_surface| to be drawn by |av_layer|. This will |
104 // retain |cv_pixel_buffer| until it is no longer being displayed. | 54 // retain |cv_pixel_buffer| until it is no longer being displayed. |
105 bool AVSampleBufferDisplayLayerEnqueueCVPixelBuffer( | 55 bool AVSampleBufferDisplayLayerEnqueueCVPixelBuffer( |
106 AVSampleBufferDisplayLayer* av_layer, | 56 AVSampleBufferDisplayLayer* av_layer, |
107 CVPixelBufferRef cv_pixel_buffer) { | 57 CVPixelBufferRef cv_pixel_buffer) { |
108 OSStatus os_status = noErr; | 58 OSStatus os_status = noErr; |
109 | 59 |
110 base::ScopedCFTypeRef<CMVideoFormatDescriptionRef> video_info; | 60 base::ScopedCFTypeRef<CMVideoFormatDescriptionRef> video_info; |
111 os_status = CMVideoFormatDescriptionCreateForImageBuffer( | 61 os_status = CMVideoFormatDescriptionCreateForImageBuffer( |
112 nullptr, cv_pixel_buffer, video_info.InitializeInto()); | 62 nullptr, cv_pixel_buffer, video_info.InitializeInto()); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 nullptr, io_surface, nullptr, cv_pixel_buffer.InitializeInto()); | 120 nullptr, io_surface, nullptr, cv_pixel_buffer.InitializeInto()); |
171 if (cv_return != kCVReturnSuccess) { | 121 if (cv_return != kCVReturnSuccess) { |
172 LOG(ERROR) << "CVPixelBufferCreateWithIOSurface failed with " << cv_return; | 122 LOG(ERROR) << "CVPixelBufferCreateWithIOSurface failed with " << cv_return; |
173 return false; | 123 return false; |
174 } | 124 } |
175 | 125 |
176 return AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, | 126 return AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, |
177 cv_pixel_buffer); | 127 cv_pixel_buffer); |
178 } | 128 } |
179 | 129 |
180 // If the filter effect can be represented as a named filter, return it. | |
181 // Otherwise, return nil. | |
182 CAFilter* NamedFilterForType(CARendererLayerParams::FilterEffectType type, | |
183 float amount) { | |
184 CAFilter* filter = nil; | |
185 switch (type) { | |
186 case CARendererLayerParams::FilterEffectType::GRAYSCALE: | |
187 filter = [CAFilter filterWithType:kCAFilterColorMonochrome]; | |
188 [filter setValue:@(amount) forKey:@"inputAmount"]; | |
189 break; | |
190 case CARendererLayerParams::FilterEffectType::SATURATE: | |
191 filter = [CAFilter filterWithType:kCAFilterColorSaturate]; | |
192 [filter setValue:@(amount) forKey:@"inputAmount"]; | |
193 break; | |
194 case CARendererLayerParams::FilterEffectType::HUE_ROTATE: | |
195 filter = [CAFilter filterWithType:kCAFilterColorHueRotate]; | |
196 [filter setValue:@(DegreeToRadians(amount)) forKey:@"inputAngle"]; | |
197 break; | |
198 case CARendererLayerParams::FilterEffectType::BLUR: | |
199 filter = [CAFilter filterWithType:kCAFilterGaussianBlur]; | |
200 [filter setValue:@(amount) forKey:@"inputRadius"]; | |
201 break; | |
202 default: | |
203 break; | |
204 } | |
205 return filter; | |
206 } | |
207 | |
208 // If the filter effect has a corresponding color matrix, return it. Otherwise, | |
209 // return nil. | |
210 NSValue* ColorMatrixForType(CARendererLayerParams::FilterEffectType type, | |
211 float amount) { | |
212 switch (type) { | |
213 case CARendererLayerParams::FilterEffectType::SEPIA: | |
214 { | |
215 float t = std::min(std::max(0.0f, amount), 1.0f); | |
216 CAColorMatrix colorMatrix = { | |
217 Blend(kSepiaNoneConstants[0][0], kSepiaFullConstants[0][0], t), | |
218 Blend(kSepiaNoneConstants[0][1], kSepiaFullConstants[0][1], t), | |
219 Blend(kSepiaNoneConstants[0][2], kSepiaFullConstants[0][2], t), | |
220 0, 0, | |
221 | |
222 Blend(kSepiaNoneConstants[1][0], kSepiaFullConstants[1][0], t), | |
223 Blend(kSepiaNoneConstants[1][1], kSepiaFullConstants[1][1], t), | |
224 Blend(kSepiaNoneConstants[1][2], kSepiaFullConstants[1][2], t), | |
225 0, 0, | |
226 | |
227 Blend(kSepiaNoneConstants[2][0], kSepiaFullConstants[2][0], t), | |
228 Blend(kSepiaNoneConstants[2][1], kSepiaFullConstants[2][1], t), | |
229 Blend(kSepiaNoneConstants[2][2], kSepiaFullConstants[2][2], t), | |
230 0, 0, 0, 0, 0, 1, 0 | |
231 }; | |
232 return [NSValue valueWithCAColorMatrix:colorMatrix]; | |
233 } | |
234 case CARendererLayerParams::FilterEffectType::INVERT: | |
235 { | |
236 float multiplier = 1 - amount * 2; | |
237 CAColorMatrix colorMatrix = { | |
238 multiplier, 0, 0, 0, amount, | |
239 0, multiplier, 0, 0, amount, | |
240 0, 0, multiplier, 0, amount, | |
241 0, 0, 0, 1, 0 | |
242 }; | |
243 return [NSValue valueWithCAColorMatrix:colorMatrix]; | |
244 } | |
245 case CARendererLayerParams::FilterEffectType::BRIGHTNESS: | |
246 { | |
247 CAColorMatrix colorMatrix = { | |
248 amount, 0, 0, 0, 0, | |
249 0, amount, 0, 0, 0, | |
250 0, 0, amount, 0, 0, | |
251 0, 0, 0, 1, 0 | |
252 }; | |
253 return [NSValue valueWithCAColorMatrix:colorMatrix]; | |
254 } | |
255 case CARendererLayerParams::FilterEffectType::CONTRAST: | |
256 { | |
257 float intercept = -0.5 * amount + 0.5; | |
258 CAColorMatrix colorMatrix = { | |
259 amount, 0, 0, 0, intercept, | |
260 0, amount, 0, 0, intercept, | |
261 0, 0, amount, 0, intercept, | |
262 0, 0, 0, 1, 0 | |
263 }; | |
264 return [NSValue valueWithCAColorMatrix:colorMatrix]; | |
265 } | |
266 case CARendererLayerParams::FilterEffectType::OPACITY: | |
267 { | |
268 CAColorMatrix colorMatrix = { | |
269 1, 0, 0, 0, 0, | |
270 0, 1, 0, 0, 0, | |
271 0, 0, 1, 0, 0, | |
272 0, 0, 0, amount, 0 | |
273 }; | |
274 return [NSValue valueWithCAColorMatrix:colorMatrix]; | |
275 } | |
276 default: | |
277 return nil; | |
278 } | |
279 } | |
280 | |
281 // Updates the CALayer to accurately represent the given |filter_effects|. | |
282 void UpdateFiltersOnCALayer( | |
283 const CARendererLayerParams::FilterEffects& filter_effects, | |
284 CALayer* layer) { | |
285 if (filter_effects.empty()) { | |
286 // It's possible that this enables shadow properties, even if there were | |
287 // none before. That's an implementation detail of Core Animation. | |
288 [layer setShadowOffset:CGSizeZero]; | |
289 [layer setShadowColor:nil]; | |
290 [layer setShadowRadius:0]; | |
291 [layer setShadowOpacity:0]; | |
292 layer.filters = @[]; | |
293 return; | |
294 } | |
295 | |
296 NSMutableArray* filters = [NSMutableArray array]; | |
297 for (const CARendererLayerParams::FilterEffect& filter_effect : | |
298 filter_effects) { | |
299 CAFilter* filter = | |
300 NamedFilterForType(filter_effect.type, filter_effect.amount); | |
301 if (filter) { | |
302 [filters addObject:filter]; | |
303 continue; | |
304 } | |
305 | |
306 NSValue* color_matrix = | |
307 ColorMatrixForType(filter_effect.type, filter_effect.amount); | |
308 if (color_matrix) { | |
309 CAFilter* filter = [CAFilter filterWithType:kCAFilterColorMatrix]; | |
310 [filter setValue:color_matrix forKey:@"inputColorMatrix"]; | |
311 [filters addObject:filter]; | |
312 continue; | |
313 } | |
314 | |
315 DCHECK_EQ(CARendererLayerParams::FilterEffectType::DROP_SHADOW, | |
316 filter_effect.type); | |
317 [layer setShadowOffset:CGSizeMake(filter_effect.drop_shadow_offset.x(), | |
318 filter_effect.drop_shadow_offset.y())]; | |
319 | |
320 CGFloat rgba_color_components[4] = { | |
321 SkColorGetR(filter_effect.drop_shadow_color) / 255., | |
322 SkColorGetG(filter_effect.drop_shadow_color) / 255., | |
323 SkColorGetB(filter_effect.drop_shadow_color) / 255., | |
324 SkColorGetA(filter_effect.drop_shadow_color) / 255., | |
325 }; | |
326 base::ScopedCFTypeRef<CGColorRef> srgb_color(CGColorCreate( | |
327 CGColorSpaceCreateWithName(kCGColorSpaceSRGB), rgba_color_components)); | |
328 [layer setShadowColor:srgb_color.get()]; | |
329 [layer setShadowRadius:filter_effect.amount]; | |
330 [layer setShadowOpacity:1]; | |
331 } | |
332 layer.filters = filters; | |
333 } | |
334 | |
335 } // namespace | 130 } // namespace |
336 | 131 |
337 CARendererLayerTree::CARendererLayerTree() {} | 132 CARendererLayerTree::CARendererLayerTree() {} |
338 CARendererLayerTree::~CARendererLayerTree() {} | 133 CARendererLayerTree::~CARendererLayerTree() {} |
339 | 134 |
340 bool CARendererLayerTree::ScheduleCALayer(const CARendererLayerParams& params) { | 135 bool CARendererLayerTree::ScheduleCALayer(const CARendererLayerParams& params) { |
341 // Excessive logging to debug white screens (crbug.com/583805). | 136 // Excessive logging to debug white screens (crbug.com/583805). |
342 // TODO(ccameron): change this back to a DLOG. | 137 // TODO(ccameron): change this back to a DLOG. |
343 if (has_committed_) { | 138 if (has_committed_) { |
344 LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers."; | 139 LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers."; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 } | 267 } |
473 | 268 |
474 CARendererLayerTree::ContentLayer::ContentLayer( | 269 CARendererLayerTree::ContentLayer::ContentLayer( |
475 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 270 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
476 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 271 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
477 const gfx::RectF& contents_rect, | 272 const gfx::RectF& contents_rect, |
478 const gfx::Rect& rect, | 273 const gfx::Rect& rect, |
479 unsigned background_color, | 274 unsigned background_color, |
480 unsigned edge_aa_mask, | 275 unsigned edge_aa_mask, |
481 float opacity, | 276 float opacity, |
482 unsigned filter, | 277 unsigned filter) |
483 const CARendererLayerParams::FilterEffects& filter_effects) | |
484 : io_surface(io_surface), | 278 : io_surface(io_surface), |
485 cv_pixel_buffer(cv_pixel_buffer), | 279 cv_pixel_buffer(cv_pixel_buffer), |
486 contents_rect(contents_rect), | 280 contents_rect(contents_rect), |
487 rect(rect), | 281 rect(rect), |
488 background_color(background_color), | 282 background_color(background_color), |
489 ca_edge_aa_mask(0), | 283 ca_edge_aa_mask(0), |
490 opacity(opacity), | 284 opacity(opacity), |
491 ca_filter(filter == GL_LINEAR ? kCAFilterLinear : kCAFilterNearest), | 285 ca_filter(filter == GL_LINEAR ? kCAFilterLinear : kCAFilterNearest) { |
492 filter_effects(filter_effects) { | |
493 DCHECK(filter == GL_LINEAR || filter == GL_NEAREST); | 286 DCHECK(filter == GL_LINEAR || filter == GL_NEAREST); |
494 | 287 |
495 // Because the root layer has setGeometryFlipped:YES, there is some ambiguity | 288 // Because the root layer has setGeometryFlipped:YES, there is some ambiguity |
496 // about what exactly top and bottom mean. This ambiguity is resolved in | 289 // about what exactly top and bottom mean. This ambiguity is resolved in |
497 // different ways for solid color CALayers and for CALayers that have content | 290 // different ways for solid color CALayers and for CALayers that have content |
498 // (surprise!). For CALayers with IOSurface content, the top edge in the AA | 291 // (surprise!). For CALayers with IOSurface content, the top edge in the AA |
499 // mask refers to what appears as the bottom edge on-screen. For CALayers | 292 // mask refers to what appears as the bottom edge on-screen. For CALayers |
500 // without content (solid color layers), the top edge in the AA mask is the | 293 // without content (solid color layers), the top edge in the AA mask is the |
501 // top edge on-screen. | 294 // top edge on-screen. |
502 // https://crbug.com/567946 | 295 // https://crbug.com/567946 |
(...skipping 26 matching lines...) Expand all Loading... |
529 : io_surface(layer.io_surface), | 322 : io_surface(layer.io_surface), |
530 cv_pixel_buffer(layer.cv_pixel_buffer), | 323 cv_pixel_buffer(layer.cv_pixel_buffer), |
531 contents_rect(layer.contents_rect), | 324 contents_rect(layer.contents_rect), |
532 rect(layer.rect), | 325 rect(layer.rect), |
533 background_color(layer.background_color), | 326 background_color(layer.background_color), |
534 ca_edge_aa_mask(layer.ca_edge_aa_mask), | 327 ca_edge_aa_mask(layer.ca_edge_aa_mask), |
535 opacity(layer.opacity), | 328 opacity(layer.opacity), |
536 ca_filter(layer.ca_filter), | 329 ca_filter(layer.ca_filter), |
537 ca_layer(std::move(layer.ca_layer)), | 330 ca_layer(std::move(layer.ca_layer)), |
538 av_layer(std::move(layer.av_layer)), | 331 av_layer(std::move(layer.av_layer)), |
539 use_av_layer(layer.use_av_layer), | 332 use_av_layer(layer.use_av_layer) { |
540 filter_effects(layer.filter_effects) { | |
541 DCHECK(!layer.ca_layer); | 333 DCHECK(!layer.ca_layer); |
542 DCHECK(!layer.av_layer); | 334 DCHECK(!layer.av_layer); |
543 } | 335 } |
544 | 336 |
545 CARendererLayerTree::ContentLayer::~ContentLayer() { | 337 CARendererLayerTree::ContentLayer::~ContentLayer() { |
546 [ca_layer removeFromSuperlayer]; | 338 [ca_layer removeFromSuperlayer]; |
547 } | 339 } |
548 | 340 |
549 bool CARendererLayerTree::RootLayer::AddContentLayer( | 341 bool CARendererLayerTree::RootLayer::AddContentLayer( |
550 const CARendererLayerParams& params) { | 342 const CARendererLayerParams& params) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 gl::GLImageIOSurface* io_surface_image = | 400 gl::GLImageIOSurface* io_surface_image = |
609 gl::GLImageIOSurface::FromGLImage(params.image); | 401 gl::GLImageIOSurface::FromGLImage(params.image); |
610 DCHECK(io_surface_image); | 402 DCHECK(io_surface_image); |
611 io_surface = io_surface_image->io_surface(); | 403 io_surface = io_surface_image->io_surface(); |
612 cv_pixel_buffer = io_surface_image->cv_pixel_buffer(); | 404 cv_pixel_buffer = io_surface_image->cv_pixel_buffer(); |
613 } | 405 } |
614 | 406 |
615 content_layers.push_back( | 407 content_layers.push_back( |
616 ContentLayer(io_surface, cv_pixel_buffer, params.contents_rect, | 408 ContentLayer(io_surface, cv_pixel_buffer, params.contents_rect, |
617 params.rect, params.background_color, params.edge_aa_mask, | 409 params.rect, params.background_color, params.edge_aa_mask, |
618 params.opacity, params.filter, params.filter_effects)); | 410 params.opacity, params.filter)); |
619 } | 411 } |
620 | 412 |
621 void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, | 413 void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, |
622 RootLayer* old_layer, | 414 RootLayer* old_layer, |
623 float scale_factor) { | 415 float scale_factor) { |
624 if (old_layer) { | 416 if (old_layer) { |
625 DCHECK(old_layer->ca_layer); | 417 DCHECK(old_layer->ca_layer); |
626 std::swap(ca_layer, old_layer->ca_layer); | 418 std::swap(ca_layer, old_layer->ca_layer); |
627 } else { | 419 } else { |
628 ca_layer.reset([[CALayer alloc] init]); | 420 ca_layer.reset([[CALayer alloc] init]); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 void CARendererLayerTree::ContentLayer::CommitToCA(CALayer* superlayer, | 528 void CARendererLayerTree::ContentLayer::CommitToCA(CALayer* superlayer, |
737 ContentLayer* old_layer, | 529 ContentLayer* old_layer, |
738 float scale_factor) { | 530 float scale_factor) { |
739 bool update_contents = true; | 531 bool update_contents = true; |
740 bool update_contents_rect = true; | 532 bool update_contents_rect = true; |
741 bool update_rect = true; | 533 bool update_rect = true; |
742 bool update_background_color = true; | 534 bool update_background_color = true; |
743 bool update_ca_edge_aa_mask = true; | 535 bool update_ca_edge_aa_mask = true; |
744 bool update_opacity = true; | 536 bool update_opacity = true; |
745 bool update_ca_filter = true; | 537 bool update_ca_filter = true; |
746 bool update_filter_effects = | |
747 (old_layer && !old_layer->filter_effects.empty()) || | |
748 !filter_effects.empty(); | |
749 if (old_layer && old_layer->use_av_layer == use_av_layer) { | 538 if (old_layer && old_layer->use_av_layer == use_av_layer) { |
750 DCHECK(old_layer->ca_layer); | 539 DCHECK(old_layer->ca_layer); |
751 std::swap(ca_layer, old_layer->ca_layer); | 540 std::swap(ca_layer, old_layer->ca_layer); |
752 std::swap(av_layer, old_layer->av_layer); | 541 std::swap(av_layer, old_layer->av_layer); |
753 update_contents = old_layer->io_surface != io_surface || | 542 update_contents = old_layer->io_surface != io_surface || |
754 old_layer->cv_pixel_buffer != cv_pixel_buffer; | 543 old_layer->cv_pixel_buffer != cv_pixel_buffer; |
755 update_contents_rect = old_layer->contents_rect != contents_rect; | 544 update_contents_rect = old_layer->contents_rect != contents_rect; |
756 update_rect = old_layer->rect != rect; | 545 update_rect = old_layer->rect != rect; |
757 update_background_color = old_layer->background_color != background_color; | 546 update_background_color = old_layer->background_color != background_color; |
758 update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask; | 547 update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask; |
759 update_opacity = old_layer->opacity != opacity; | 548 update_opacity = old_layer->opacity != opacity; |
760 update_ca_filter = old_layer->ca_filter != ca_filter; | 549 update_ca_filter = old_layer->ca_filter != ca_filter; |
761 update_filter_effects = old_layer->filter_effects != filter_effects; | |
762 } else { | 550 } else { |
763 if (use_av_layer) { | 551 if (use_av_layer) { |
764 av_layer.reset([[AVSampleBufferDisplayLayer alloc] init]); | 552 av_layer.reset([[AVSampleBufferDisplayLayer alloc] init]); |
765 ca_layer.reset([av_layer retain]); | 553 ca_layer.reset([av_layer retain]); |
766 [av_layer setVideoGravity:AVLayerVideoGravityResize]; | 554 [av_layer setVideoGravity:AVLayerVideoGravityResize]; |
767 } else { | 555 } else { |
768 ca_layer.reset([[CALayer alloc] init]); | 556 ca_layer.reset([[CALayer alloc] init]); |
769 } | 557 } |
770 [ca_layer setAnchorPoint:CGPointZero]; | 558 [ca_layer setAnchorPoint:CGPointZero]; |
771 [superlayer addSublayer:ca_layer]; | 559 [superlayer addSublayer:ca_layer]; |
772 } | 560 } |
773 DCHECK_EQ([ca_layer superlayer], superlayer); | 561 DCHECK_EQ([ca_layer superlayer], superlayer); |
774 bool update_anything = update_contents || update_contents_rect || | 562 bool update_anything = update_contents || update_contents_rect || |
775 update_rect || update_background_color || | 563 update_rect || update_background_color || |
776 update_ca_edge_aa_mask || update_opacity || | 564 update_ca_edge_aa_mask || update_opacity || |
777 update_ca_filter || update_filter_effects; | 565 update_ca_filter; |
778 if (use_av_layer) { | 566 if (use_av_layer) { |
779 if (update_contents) { | 567 if (update_contents) { |
780 if (cv_pixel_buffer) { | 568 if (cv_pixel_buffer) { |
781 AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, | 569 AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, |
782 cv_pixel_buffer); | 570 cv_pixel_buffer); |
783 } else { | 571 } else { |
784 AVSampleBufferDisplayLayerEnqueueIOSurface(av_layer, io_surface); | 572 AVSampleBufferDisplayLayerEnqueueIOSurface(av_layer, io_surface); |
785 } | 573 } |
786 } | 574 } |
787 } else { | 575 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
811 [ca_layer setBackgroundColor:srgb_background_color]; | 599 [ca_layer setBackgroundColor:srgb_background_color]; |
812 } | 600 } |
813 if (update_ca_edge_aa_mask) | 601 if (update_ca_edge_aa_mask) |
814 [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask]; | 602 [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask]; |
815 if (update_opacity) | 603 if (update_opacity) |
816 [ca_layer setOpacity:opacity]; | 604 [ca_layer setOpacity:opacity]; |
817 if (update_ca_filter) { | 605 if (update_ca_filter) { |
818 [ca_layer setMagnificationFilter:ca_filter]; | 606 [ca_layer setMagnificationFilter:ca_filter]; |
819 [ca_layer setMinificationFilter:ca_filter]; | 607 [ca_layer setMinificationFilter:ca_filter]; |
820 } | 608 } |
821 if (update_filter_effects) { | |
822 UpdateFiltersOnCALayer(filter_effects, ca_layer.get()); | |
823 } | |
824 | 609 |
825 static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch( | 610 static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch( |
826 switches::kShowMacOverlayBorders); | 611 switches::kShowMacOverlayBorders); |
827 if (show_borders) { | 612 if (show_borders) { |
828 base::ScopedCFTypeRef<CGColorRef> color; | 613 base::ScopedCFTypeRef<CGColorRef> color; |
829 if (update_anything) { | 614 if (update_anything) { |
830 if (use_av_layer) { | 615 if (use_av_layer) { |
831 // Yellow represents an AV layer that changed this frame. | 616 // Yellow represents an AV layer that changed this frame. |
832 color.reset(CGColorCreateGenericRGB(1, 1, 0, 1)); | 617 color.reset(CGColorCreateGenericRGB(1, 1, 0, 1)); |
833 } else { | 618 } else { |
834 // Pink represents a CALayer that changed this frame. | 619 // Pink represents a CALayer that changed this frame. |
835 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); | 620 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); |
836 } | 621 } |
837 } else { | 622 } else { |
838 // Grey represents a CALayer that has not changed. | 623 // Grey represents a CALayer that has not changed. |
839 color.reset(CGColorCreateGenericRGB(0.5, 0.5, 0.5, 1)); | 624 color.reset(CGColorCreateGenericRGB(0.5, 0.5, 0.5, 1)); |
840 } | 625 } |
841 [ca_layer setBorderWidth:1]; | 626 [ca_layer setBorderWidth:1]; |
842 [ca_layer setBorderColor:color]; | 627 [ca_layer setBorderColor:color]; |
843 } | 628 } |
844 } | 629 } |
845 | 630 |
846 } // namespace ui | 631 } // namespace ui |
OLD | NEW |