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" | |
20 #include "ui/gl/gl_image_io_surface.h" | 19 #include "ui/gl/gl_image_io_surface.h" |
21 | 20 |
22 #if !defined(MAC_OS_X_VERSION_10_8) || \ | 21 #if !defined(MAC_OS_X_VERSION_10_8) || \ |
23 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 | 22 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 |
24 extern NSString* const AVLayerVideoGravityResize; | 23 extern NSString* const AVLayerVideoGravityResize; |
25 extern "C" void NSAccessibilityPostNotificationWithUserInfo( | 24 extern "C" void NSAccessibilityPostNotificationWithUserInfo( |
26 id object, | 25 id object, |
27 NSString* notification, | 26 NSString* notification, |
28 NSDictionary* user_info); | 27 NSDictionary* user_info); |
29 extern "C" OSStatus CMSampleBufferCreateForImageBuffer( | 28 extern "C" OSStatus CMSampleBufferCreateForImageBuffer( |
30 CFAllocatorRef, | 29 CFAllocatorRef, |
31 CVImageBufferRef, | 30 CVImageBufferRef, |
32 Boolean dataReady, | 31 Boolean dataReady, |
33 CMSampleBufferMakeDataReadyCallback, | 32 CMSampleBufferMakeDataReadyCallback, |
34 void*, | 33 void*, |
35 CMVideoFormatDescriptionRef, | 34 CMVideoFormatDescriptionRef, |
36 const CMSampleTimingInfo*, | 35 const CMSampleTimingInfo*, |
37 CMSampleBufferRef*); | 36 CMSampleBufferRef*); |
38 extern "C" CFArrayRef CMSampleBufferGetSampleAttachmentsArray(CMSampleBufferRef, | 37 extern "C" CFArrayRef CMSampleBufferGetSampleAttachmentsArray(CMSampleBufferRef, |
39 Boolean); | 38 Boolean); |
40 extern "C" OSStatus CMVideoFormatDescriptionCreateForImageBuffer( | 39 extern "C" OSStatus CMVideoFormatDescriptionCreateForImageBuffer( |
41 CFAllocatorRef, | 40 CFAllocatorRef, |
42 CVImageBufferRef, | 41 CVImageBufferRef, |
43 CMVideoFormatDescriptionRef*); | 42 CMVideoFormatDescriptionRef*); |
44 extern "C" CMTime CMTimeMake(int64_t, int32_t); | 43 extern "C" CMTime CMTimeMake(int64_t, int32_t); |
45 extern CFStringRef const kCMSampleAttachmentKey_DisplayImmediately; | 44 extern CFStringRef const kCMSampleAttachmentKey_DisplayImmediately; |
46 extern const CMTime kCMTimeInvalid; | 45 extern const CMTime kCMTimeInvalid; |
47 #endif // MAC_OS_X_VERSION_10_8 | 46 #endif // MAC_OS_X_VERSION_10_8 |
48 | 47 |
| 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 |
49 namespace ui { | 76 namespace ui { |
50 | 77 |
51 namespace { | 78 namespace { |
52 | 79 |
| 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 |
53 // This will enqueue |io_surface| to be drawn by |av_layer|. This will | 103 // This will enqueue |io_surface| to be drawn by |av_layer|. This will |
54 // retain |cv_pixel_buffer| until it is no longer being displayed. | 104 // retain |cv_pixel_buffer| until it is no longer being displayed. |
55 bool AVSampleBufferDisplayLayerEnqueueCVPixelBuffer( | 105 bool AVSampleBufferDisplayLayerEnqueueCVPixelBuffer( |
56 AVSampleBufferDisplayLayer* av_layer, | 106 AVSampleBufferDisplayLayer* av_layer, |
57 CVPixelBufferRef cv_pixel_buffer) { | 107 CVPixelBufferRef cv_pixel_buffer) { |
58 OSStatus os_status = noErr; | 108 OSStatus os_status = noErr; |
59 | 109 |
60 base::ScopedCFTypeRef<CMVideoFormatDescriptionRef> video_info; | 110 base::ScopedCFTypeRef<CMVideoFormatDescriptionRef> video_info; |
61 os_status = CMVideoFormatDescriptionCreateForImageBuffer( | 111 os_status = CMVideoFormatDescriptionCreateForImageBuffer( |
62 nullptr, cv_pixel_buffer, video_info.InitializeInto()); | 112 nullptr, cv_pixel_buffer, video_info.InitializeInto()); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 nullptr, io_surface, nullptr, cv_pixel_buffer.InitializeInto()); | 170 nullptr, io_surface, nullptr, cv_pixel_buffer.InitializeInto()); |
121 if (cv_return != kCVReturnSuccess) { | 171 if (cv_return != kCVReturnSuccess) { |
122 LOG(ERROR) << "CVPixelBufferCreateWithIOSurface failed with " << cv_return; | 172 LOG(ERROR) << "CVPixelBufferCreateWithIOSurface failed with " << cv_return; |
123 return false; | 173 return false; |
124 } | 174 } |
125 | 175 |
126 return AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, | 176 return AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, |
127 cv_pixel_buffer); | 177 cv_pixel_buffer); |
128 } | 178 } |
129 | 179 |
| 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 |
130 } // namespace | 335 } // namespace |
131 | 336 |
132 CARendererLayerTree::CARendererLayerTree() {} | 337 CARendererLayerTree::CARendererLayerTree() {} |
133 CARendererLayerTree::~CARendererLayerTree() {} | 338 CARendererLayerTree::~CARendererLayerTree() {} |
134 | 339 |
135 bool CARendererLayerTree::ScheduleCALayer(const CARendererLayerParams& params) { | 340 bool CARendererLayerTree::ScheduleCALayer(const CARendererLayerParams& params) { |
136 // Excessive logging to debug white screens (crbug.com/583805). | 341 // Excessive logging to debug white screens (crbug.com/583805). |
137 // TODO(ccameron): change this back to a DLOG. | 342 // TODO(ccameron): change this back to a DLOG. |
138 if (has_committed_) { | 343 if (has_committed_) { |
139 LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers."; | 344 LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers."; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 } | 472 } |
268 | 473 |
269 CARendererLayerTree::ContentLayer::ContentLayer( | 474 CARendererLayerTree::ContentLayer::ContentLayer( |
270 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 475 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
271 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 476 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
272 const gfx::RectF& contents_rect, | 477 const gfx::RectF& contents_rect, |
273 const gfx::Rect& rect, | 478 const gfx::Rect& rect, |
274 unsigned background_color, | 479 unsigned background_color, |
275 unsigned edge_aa_mask, | 480 unsigned edge_aa_mask, |
276 float opacity, | 481 float opacity, |
277 unsigned filter) | 482 unsigned filter, |
| 483 const CARendererLayerParams::FilterEffects& filter_effects) |
278 : io_surface(io_surface), | 484 : io_surface(io_surface), |
279 cv_pixel_buffer(cv_pixel_buffer), | 485 cv_pixel_buffer(cv_pixel_buffer), |
280 contents_rect(contents_rect), | 486 contents_rect(contents_rect), |
281 rect(rect), | 487 rect(rect), |
282 background_color(background_color), | 488 background_color(background_color), |
283 ca_edge_aa_mask(0), | 489 ca_edge_aa_mask(0), |
284 opacity(opacity), | 490 opacity(opacity), |
285 ca_filter(filter == GL_LINEAR ? kCAFilterLinear : kCAFilterNearest) { | 491 ca_filter(filter == GL_LINEAR ? kCAFilterLinear : kCAFilterNearest), |
| 492 filter_effects(filter_effects) { |
286 DCHECK(filter == GL_LINEAR || filter == GL_NEAREST); | 493 DCHECK(filter == GL_LINEAR || filter == GL_NEAREST); |
287 | 494 |
288 // Because the root layer has setGeometryFlipped:YES, there is some ambiguity | 495 // Because the root layer has setGeometryFlipped:YES, there is some ambiguity |
289 // about what exactly top and bottom mean. This ambiguity is resolved in | 496 // about what exactly top and bottom mean. This ambiguity is resolved in |
290 // different ways for solid color CALayers and for CALayers that have content | 497 // different ways for solid color CALayers and for CALayers that have content |
291 // (surprise!). For CALayers with IOSurface content, the top edge in the AA | 498 // (surprise!). For CALayers with IOSurface content, the top edge in the AA |
292 // mask refers to what appears as the bottom edge on-screen. For CALayers | 499 // mask refers to what appears as the bottom edge on-screen. For CALayers |
293 // without content (solid color layers), the top edge in the AA mask is the | 500 // without content (solid color layers), the top edge in the AA mask is the |
294 // top edge on-screen. | 501 // top edge on-screen. |
295 // https://crbug.com/567946 | 502 // https://crbug.com/567946 |
(...skipping 26 matching lines...) Expand all Loading... |
322 : io_surface(layer.io_surface), | 529 : io_surface(layer.io_surface), |
323 cv_pixel_buffer(layer.cv_pixel_buffer), | 530 cv_pixel_buffer(layer.cv_pixel_buffer), |
324 contents_rect(layer.contents_rect), | 531 contents_rect(layer.contents_rect), |
325 rect(layer.rect), | 532 rect(layer.rect), |
326 background_color(layer.background_color), | 533 background_color(layer.background_color), |
327 ca_edge_aa_mask(layer.ca_edge_aa_mask), | 534 ca_edge_aa_mask(layer.ca_edge_aa_mask), |
328 opacity(layer.opacity), | 535 opacity(layer.opacity), |
329 ca_filter(layer.ca_filter), | 536 ca_filter(layer.ca_filter), |
330 ca_layer(std::move(layer.ca_layer)), | 537 ca_layer(std::move(layer.ca_layer)), |
331 av_layer(std::move(layer.av_layer)), | 538 av_layer(std::move(layer.av_layer)), |
332 use_av_layer(layer.use_av_layer) { | 539 use_av_layer(layer.use_av_layer), |
| 540 filter_effects(layer.filter_effects) { |
333 DCHECK(!layer.ca_layer); | 541 DCHECK(!layer.ca_layer); |
334 DCHECK(!layer.av_layer); | 542 DCHECK(!layer.av_layer); |
335 } | 543 } |
336 | 544 |
337 CARendererLayerTree::ContentLayer::~ContentLayer() { | 545 CARendererLayerTree::ContentLayer::~ContentLayer() { |
338 [ca_layer removeFromSuperlayer]; | 546 [ca_layer removeFromSuperlayer]; |
339 } | 547 } |
340 | 548 |
341 bool CARendererLayerTree::RootLayer::AddContentLayer( | 549 bool CARendererLayerTree::RootLayer::AddContentLayer( |
342 const CARendererLayerParams& params) { | 550 const CARendererLayerParams& params) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 gl::GLImageIOSurface* io_surface_image = | 608 gl::GLImageIOSurface* io_surface_image = |
401 gl::GLImageIOSurface::FromGLImage(params.image); | 609 gl::GLImageIOSurface::FromGLImage(params.image); |
402 DCHECK(io_surface_image); | 610 DCHECK(io_surface_image); |
403 io_surface = io_surface_image->io_surface(); | 611 io_surface = io_surface_image->io_surface(); |
404 cv_pixel_buffer = io_surface_image->cv_pixel_buffer(); | 612 cv_pixel_buffer = io_surface_image->cv_pixel_buffer(); |
405 } | 613 } |
406 | 614 |
407 content_layers.push_back( | 615 content_layers.push_back( |
408 ContentLayer(io_surface, cv_pixel_buffer, params.contents_rect, | 616 ContentLayer(io_surface, cv_pixel_buffer, params.contents_rect, |
409 params.rect, params.background_color, params.edge_aa_mask, | 617 params.rect, params.background_color, params.edge_aa_mask, |
410 params.opacity, params.filter)); | 618 params.opacity, params.filter, params.filter_effects)); |
411 } | 619 } |
412 | 620 |
413 void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, | 621 void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, |
414 RootLayer* old_layer, | 622 RootLayer* old_layer, |
415 float scale_factor) { | 623 float scale_factor) { |
416 if (old_layer) { | 624 if (old_layer) { |
417 DCHECK(old_layer->ca_layer); | 625 DCHECK(old_layer->ca_layer); |
418 std::swap(ca_layer, old_layer->ca_layer); | 626 std::swap(ca_layer, old_layer->ca_layer); |
419 } else { | 627 } else { |
420 ca_layer.reset([[CALayer alloc] init]); | 628 ca_layer.reset([[CALayer alloc] init]); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 void CARendererLayerTree::ContentLayer::CommitToCA(CALayer* superlayer, | 736 void CARendererLayerTree::ContentLayer::CommitToCA(CALayer* superlayer, |
529 ContentLayer* old_layer, | 737 ContentLayer* old_layer, |
530 float scale_factor) { | 738 float scale_factor) { |
531 bool update_contents = true; | 739 bool update_contents = true; |
532 bool update_contents_rect = true; | 740 bool update_contents_rect = true; |
533 bool update_rect = true; | 741 bool update_rect = true; |
534 bool update_background_color = true; | 742 bool update_background_color = true; |
535 bool update_ca_edge_aa_mask = true; | 743 bool update_ca_edge_aa_mask = true; |
536 bool update_opacity = true; | 744 bool update_opacity = true; |
537 bool update_ca_filter = true; | 745 bool update_ca_filter = true; |
| 746 bool update_filter_effects = |
| 747 (old_layer && !old_layer->filter_effects.empty()) || |
| 748 !filter_effects.empty(); |
538 if (old_layer && old_layer->use_av_layer == use_av_layer) { | 749 if (old_layer && old_layer->use_av_layer == use_av_layer) { |
539 DCHECK(old_layer->ca_layer); | 750 DCHECK(old_layer->ca_layer); |
540 std::swap(ca_layer, old_layer->ca_layer); | 751 std::swap(ca_layer, old_layer->ca_layer); |
541 std::swap(av_layer, old_layer->av_layer); | 752 std::swap(av_layer, old_layer->av_layer); |
542 update_contents = old_layer->io_surface != io_surface || | 753 update_contents = old_layer->io_surface != io_surface || |
543 old_layer->cv_pixel_buffer != cv_pixel_buffer; | 754 old_layer->cv_pixel_buffer != cv_pixel_buffer; |
544 update_contents_rect = old_layer->contents_rect != contents_rect; | 755 update_contents_rect = old_layer->contents_rect != contents_rect; |
545 update_rect = old_layer->rect != rect; | 756 update_rect = old_layer->rect != rect; |
546 update_background_color = old_layer->background_color != background_color; | 757 update_background_color = old_layer->background_color != background_color; |
547 update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask; | 758 update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask; |
548 update_opacity = old_layer->opacity != opacity; | 759 update_opacity = old_layer->opacity != opacity; |
549 update_ca_filter = old_layer->ca_filter != ca_filter; | 760 update_ca_filter = old_layer->ca_filter != ca_filter; |
| 761 update_filter_effects = old_layer->filter_effects != filter_effects; |
550 } else { | 762 } else { |
551 if (use_av_layer) { | 763 if (use_av_layer) { |
552 av_layer.reset([[AVSampleBufferDisplayLayer alloc] init]); | 764 av_layer.reset([[AVSampleBufferDisplayLayer alloc] init]); |
553 ca_layer.reset([av_layer retain]); | 765 ca_layer.reset([av_layer retain]); |
554 [av_layer setVideoGravity:AVLayerVideoGravityResize]; | 766 [av_layer setVideoGravity:AVLayerVideoGravityResize]; |
555 } else { | 767 } else { |
556 ca_layer.reset([[CALayer alloc] init]); | 768 ca_layer.reset([[CALayer alloc] init]); |
557 } | 769 } |
558 [ca_layer setAnchorPoint:CGPointZero]; | 770 [ca_layer setAnchorPoint:CGPointZero]; |
559 [superlayer addSublayer:ca_layer]; | 771 [superlayer addSublayer:ca_layer]; |
560 } | 772 } |
561 DCHECK_EQ([ca_layer superlayer], superlayer); | 773 DCHECK_EQ([ca_layer superlayer], superlayer); |
562 bool update_anything = update_contents || update_contents_rect || | 774 bool update_anything = update_contents || update_contents_rect || |
563 update_rect || update_background_color || | 775 update_rect || update_background_color || |
564 update_ca_edge_aa_mask || update_opacity || | 776 update_ca_edge_aa_mask || update_opacity || |
565 update_ca_filter; | 777 update_ca_filter || update_filter_effects; |
566 if (use_av_layer) { | 778 if (use_av_layer) { |
567 if (update_contents) { | 779 if (update_contents) { |
568 if (cv_pixel_buffer) { | 780 if (cv_pixel_buffer) { |
569 AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, | 781 AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, |
570 cv_pixel_buffer); | 782 cv_pixel_buffer); |
571 } else { | 783 } else { |
572 AVSampleBufferDisplayLayerEnqueueIOSurface(av_layer, io_surface); | 784 AVSampleBufferDisplayLayerEnqueueIOSurface(av_layer, io_surface); |
573 } | 785 } |
574 } | 786 } |
575 } else { | 787 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
599 [ca_layer setBackgroundColor:srgb_background_color]; | 811 [ca_layer setBackgroundColor:srgb_background_color]; |
600 } | 812 } |
601 if (update_ca_edge_aa_mask) | 813 if (update_ca_edge_aa_mask) |
602 [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask]; | 814 [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask]; |
603 if (update_opacity) | 815 if (update_opacity) |
604 [ca_layer setOpacity:opacity]; | 816 [ca_layer setOpacity:opacity]; |
605 if (update_ca_filter) { | 817 if (update_ca_filter) { |
606 [ca_layer setMagnificationFilter:ca_filter]; | 818 [ca_layer setMagnificationFilter:ca_filter]; |
607 [ca_layer setMinificationFilter:ca_filter]; | 819 [ca_layer setMinificationFilter:ca_filter]; |
608 } | 820 } |
| 821 if (update_filter_effects) { |
| 822 UpdateFiltersOnCALayer(filter_effects, ca_layer.get()); |
| 823 } |
609 | 824 |
610 static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch( | 825 static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch( |
611 switches::kShowMacOverlayBorders); | 826 switches::kShowMacOverlayBorders); |
612 if (show_borders) { | 827 if (show_borders) { |
613 base::ScopedCFTypeRef<CGColorRef> color; | 828 base::ScopedCFTypeRef<CGColorRef> color; |
614 if (update_anything) { | 829 if (update_anything) { |
615 if (use_av_layer) { | 830 if (use_av_layer) { |
616 // Yellow represents an AV layer that changed this frame. | 831 // Yellow represents an AV layer that changed this frame. |
617 color.reset(CGColorCreateGenericRGB(1, 1, 0, 1)); | 832 color.reset(CGColorCreateGenericRGB(1, 1, 0, 1)); |
618 } else { | 833 } else { |
619 // Pink represents a CALayer that changed this frame. | 834 // Pink represents a CALayer that changed this frame. |
620 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); | 835 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); |
621 } | 836 } |
622 } else { | 837 } else { |
623 // Grey represents a CALayer that has not changed. | 838 // Grey represents a CALayer that has not changed. |
624 color.reset(CGColorCreateGenericRGB(0.5, 0.5, 0.5, 1)); | 839 color.reset(CGColorCreateGenericRGB(0.5, 0.5, 0.5, 1)); |
625 } | 840 } |
626 [ca_layer setBorderWidth:1]; | 841 [ca_layer setBorderWidth:1]; |
627 [ca_layer setBorderColor:color]; | 842 [ca_layer setBorderColor:color]; |
628 } | 843 } |
629 } | 844 } |
630 | 845 |
631 } // namespace ui | 846 } // namespace ui |
OLD | NEW |