| 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> |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 bool is_clipped, | 134 bool is_clipped, |
| 135 const gfx::Rect& clip_rect, | 135 const gfx::Rect& clip_rect, |
| 136 unsigned sorting_context_id, | 136 unsigned sorting_context_id, |
| 137 const gfx::Transform& transform, | 137 const gfx::Transform& transform, |
| 138 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 138 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 139 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 139 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
| 140 const gfx::RectF& contents_rect, | 140 const gfx::RectF& contents_rect, |
| 141 const gfx::Rect& rect, | 141 const gfx::Rect& rect, |
| 142 unsigned background_color, | 142 unsigned background_color, |
| 143 unsigned edge_aa_mask, | 143 unsigned edge_aa_mask, |
| 144 float opacity) { | 144 float opacity, |
| 145 unsigned filter) { |
| 145 // Excessive logging to debug white screens (crbug.com/583805). | 146 // Excessive logging to debug white screens (crbug.com/583805). |
| 146 // TODO(ccameron): change this back to a DLOG. | 147 // TODO(ccameron): change this back to a DLOG. |
| 147 if (has_committed_) { | 148 if (has_committed_) { |
| 148 LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers."; | 149 LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers."; |
| 149 return false; | 150 return false; |
| 150 } | 151 } |
| 151 return root_layer_.AddContentLayer(is_clipped, clip_rect, sorting_context_id, | 152 return root_layer_.AddContentLayer(is_clipped, clip_rect, sorting_context_id, |
| 152 transform, io_surface, cv_pixel_buffer, | 153 transform, io_surface, cv_pixel_buffer, |
| 153 contents_rect, rect, background_color, | 154 contents_rect, rect, background_color, |
| 154 edge_aa_mask, opacity); | 155 edge_aa_mask, opacity, filter); |
| 155 } | 156 } |
| 156 | 157 |
| 157 void CARendererLayerTree::CommitScheduledCALayers( | 158 void CARendererLayerTree::CommitScheduledCALayers( |
| 158 CALayer* superlayer, | 159 CALayer* superlayer, |
| 159 std::unique_ptr<CARendererLayerTree> old_tree, | 160 std::unique_ptr<CARendererLayerTree> old_tree, |
| 160 float scale_factor) { | 161 float scale_factor) { |
| 161 TRACE_EVENT0("gpu", "CARendererLayerTree::CommitScheduledCALayers"); | 162 TRACE_EVENT0("gpu", "CARendererLayerTree::CommitScheduledCALayers"); |
| 162 RootLayer* old_root_layer = nullptr; | 163 RootLayer* old_root_layer = nullptr; |
| 163 if (old_tree) { | 164 if (old_tree) { |
| 164 DCHECK(old_tree->has_committed_); | 165 DCHECK(old_tree->has_committed_); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 [ca_layer removeFromSuperlayer]; | 279 [ca_layer removeFromSuperlayer]; |
| 279 } | 280 } |
| 280 | 281 |
| 281 CARendererLayerTree::ContentLayer::ContentLayer( | 282 CARendererLayerTree::ContentLayer::ContentLayer( |
| 282 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 283 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 283 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 284 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
| 284 const gfx::RectF& contents_rect, | 285 const gfx::RectF& contents_rect, |
| 285 const gfx::Rect& rect, | 286 const gfx::Rect& rect, |
| 286 unsigned background_color, | 287 unsigned background_color, |
| 287 unsigned edge_aa_mask, | 288 unsigned edge_aa_mask, |
| 288 float opacity) | 289 float opacity, |
| 290 unsigned filter) |
| 289 : io_surface(io_surface), | 291 : io_surface(io_surface), |
| 290 cv_pixel_buffer(cv_pixel_buffer), | 292 cv_pixel_buffer(cv_pixel_buffer), |
| 291 contents_rect(contents_rect), | 293 contents_rect(contents_rect), |
| 292 rect(rect), | 294 rect(rect), |
| 293 background_color(background_color), | 295 background_color(background_color), |
| 294 ca_edge_aa_mask(0), | 296 ca_edge_aa_mask(0), |
| 295 opacity(opacity) { | 297 opacity(opacity), |
| 298 ca_filter(filter == GL_LINEAR ? kCAFilterLinear : kCAFilterNearest) { |
| 299 DCHECK(filter == GL_LINEAR || filter == GL_NEAREST); |
| 300 |
| 296 // Because the root layer has setGeometryFlipped:YES, there is some ambiguity | 301 // Because the root layer has setGeometryFlipped:YES, there is some ambiguity |
| 297 // about what exactly top and bottom mean. This ambiguity is resolved in | 302 // about what exactly top and bottom mean. This ambiguity is resolved in |
| 298 // different ways for solid color CALayers and for CALayers that have content | 303 // different ways for solid color CALayers and for CALayers that have content |
| 299 // (surprise!). For CALayers with IOSurface content, the top edge in the AA | 304 // (surprise!). For CALayers with IOSurface content, the top edge in the AA |
| 300 // mask refers to what appears as the bottom edge on-screen. For CALayers | 305 // mask refers to what appears as the bottom edge on-screen. For CALayers |
| 301 // without content (solid color layers), the top edge in the AA mask is the | 306 // without content (solid color layers), the top edge in the AA mask is the |
| 302 // top edge on-screen. | 307 // top edge on-screen. |
| 303 // https://crbug.com/567946 | 308 // https://crbug.com/567946 |
| 304 if (edge_aa_mask & GL_CA_LAYER_EDGE_LEFT_CHROMIUM) | 309 if (edge_aa_mask & GL_CA_LAYER_EDGE_LEFT_CHROMIUM) |
| 305 ca_edge_aa_mask |= kCALayerLeftEdge; | 310 ca_edge_aa_mask |= kCALayerLeftEdge; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 331 } | 336 } |
| 332 | 337 |
| 333 CARendererLayerTree::ContentLayer::ContentLayer(ContentLayer&& layer) | 338 CARendererLayerTree::ContentLayer::ContentLayer(ContentLayer&& layer) |
| 334 : io_surface(layer.io_surface), | 339 : io_surface(layer.io_surface), |
| 335 cv_pixel_buffer(layer.cv_pixel_buffer), | 340 cv_pixel_buffer(layer.cv_pixel_buffer), |
| 336 contents_rect(layer.contents_rect), | 341 contents_rect(layer.contents_rect), |
| 337 rect(layer.rect), | 342 rect(layer.rect), |
| 338 background_color(layer.background_color), | 343 background_color(layer.background_color), |
| 339 ca_edge_aa_mask(layer.ca_edge_aa_mask), | 344 ca_edge_aa_mask(layer.ca_edge_aa_mask), |
| 340 opacity(layer.opacity), | 345 opacity(layer.opacity), |
| 346 ca_filter(layer.ca_filter), |
| 341 ca_layer(std::move(layer.ca_layer)), | 347 ca_layer(std::move(layer.ca_layer)), |
| 342 av_layer(std::move(layer.av_layer)), | 348 av_layer(std::move(layer.av_layer)), |
| 343 use_av_layer(layer.use_av_layer) { | 349 use_av_layer(layer.use_av_layer) { |
| 344 DCHECK(!layer.ca_layer); | 350 DCHECK(!layer.ca_layer); |
| 345 DCHECK(!layer.av_layer); | 351 DCHECK(!layer.av_layer); |
| 346 } | 352 } |
| 347 | 353 |
| 348 CARendererLayerTree::ContentLayer::~ContentLayer() { | 354 CARendererLayerTree::ContentLayer::~ContentLayer() { |
| 349 [ca_layer removeFromSuperlayer]; | 355 [ca_layer removeFromSuperlayer]; |
| 350 } | 356 } |
| 351 | 357 |
| 352 bool CARendererLayerTree::RootLayer::AddContentLayer( | 358 bool CARendererLayerTree::RootLayer::AddContentLayer( |
| 353 bool is_clipped, | 359 bool is_clipped, |
| 354 const gfx::Rect& clip_rect, | 360 const gfx::Rect& clip_rect, |
| 355 unsigned sorting_context_id, | 361 unsigned sorting_context_id, |
| 356 const gfx::Transform& transform, | 362 const gfx::Transform& transform, |
| 357 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 363 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 358 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 364 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
| 359 const gfx::RectF& contents_rect, | 365 const gfx::RectF& contents_rect, |
| 360 const gfx::Rect& rect, | 366 const gfx::Rect& rect, |
| 361 unsigned background_color, | 367 unsigned background_color, |
| 362 unsigned edge_aa_mask, | 368 unsigned edge_aa_mask, |
| 363 float opacity) { | 369 float opacity, |
| 370 unsigned filter) { |
| 364 bool needs_new_clip_and_sorting_layer = true; | 371 bool needs_new_clip_and_sorting_layer = true; |
| 365 | 372 |
| 366 // In sorting_context_id 0, all quads are listed in back-to-front order. | 373 // In sorting_context_id 0, all quads are listed in back-to-front order. |
| 367 // This is accomplished by having the CALayers be siblings of each other. | 374 // This is accomplished by having the CALayers be siblings of each other. |
| 368 // If a quad has a 3D transform, it is necessary to put it in its own sorting | 375 // If a quad has a 3D transform, it is necessary to put it in its own sorting |
| 369 // context, so that it will not intersect with quads before and after it. | 376 // context, so that it will not intersect with quads before and after it. |
| 370 bool is_singleton_sorting_context = | 377 bool is_singleton_sorting_context = |
| 371 !sorting_context_id && !transform.IsFlat(); | 378 !sorting_context_id && !transform.IsFlat(); |
| 372 | 379 |
| 373 if (!clip_and_sorting_layers.empty()) { | 380 if (!clip_and_sorting_layers.empty()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 391 needs_new_clip_and_sorting_layer = false; | 398 needs_new_clip_and_sorting_layer = false; |
| 392 } | 399 } |
| 393 } | 400 } |
| 394 if (needs_new_clip_and_sorting_layer) { | 401 if (needs_new_clip_and_sorting_layer) { |
| 395 clip_and_sorting_layers.push_back( | 402 clip_and_sorting_layers.push_back( |
| 396 ClipAndSortingLayer(is_clipped, clip_rect, sorting_context_id, | 403 ClipAndSortingLayer(is_clipped, clip_rect, sorting_context_id, |
| 397 is_singleton_sorting_context)); | 404 is_singleton_sorting_context)); |
| 398 } | 405 } |
| 399 clip_and_sorting_layers.back().AddContentLayer( | 406 clip_and_sorting_layers.back().AddContentLayer( |
| 400 transform, io_surface, cv_pixel_buffer, contents_rect, rect, | 407 transform, io_surface, cv_pixel_buffer, contents_rect, rect, |
| 401 background_color, edge_aa_mask, opacity); | 408 background_color, edge_aa_mask, opacity, filter); |
| 402 return true; | 409 return true; |
| 403 } | 410 } |
| 404 | 411 |
| 405 void CARendererLayerTree::ClipAndSortingLayer::AddContentLayer( | 412 void CARendererLayerTree::ClipAndSortingLayer::AddContentLayer( |
| 406 const gfx::Transform& transform, | 413 const gfx::Transform& transform, |
| 407 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 414 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 408 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 415 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
| 409 const gfx::RectF& contents_rect, | 416 const gfx::RectF& contents_rect, |
| 410 const gfx::Rect& rect, | 417 const gfx::Rect& rect, |
| 411 unsigned background_color, | 418 unsigned background_color, |
| 412 unsigned edge_aa_mask, | 419 unsigned edge_aa_mask, |
| 413 float opacity) { | 420 float opacity, |
| 421 unsigned filter) { |
| 414 bool needs_new_transform_layer = true; | 422 bool needs_new_transform_layer = true; |
| 415 if (!transform_layers.empty()) { | 423 if (!transform_layers.empty()) { |
| 416 const TransformLayer& current_layer = transform_layers.back(); | 424 const TransformLayer& current_layer = transform_layers.back(); |
| 417 if (current_layer.transform == transform) | 425 if (current_layer.transform == transform) |
| 418 needs_new_transform_layer = false; | 426 needs_new_transform_layer = false; |
| 419 } | 427 } |
| 420 if (needs_new_transform_layer) | 428 if (needs_new_transform_layer) |
| 421 transform_layers.push_back(TransformLayer(transform)); | 429 transform_layers.push_back(TransformLayer(transform)); |
| 422 transform_layers.back().AddContentLayer(io_surface, cv_pixel_buffer, | 430 transform_layers.back().AddContentLayer(io_surface, cv_pixel_buffer, |
| 423 contents_rect, rect, background_color, | 431 contents_rect, rect, background_color, |
| 424 edge_aa_mask, opacity); | 432 edge_aa_mask, opacity, filter); |
| 425 } | 433 } |
| 426 | 434 |
| 427 void CARendererLayerTree::TransformLayer::AddContentLayer( | 435 void CARendererLayerTree::TransformLayer::AddContentLayer( |
| 428 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 436 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 429 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, | 437 base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer, |
| 430 const gfx::RectF& contents_rect, | 438 const gfx::RectF& contents_rect, |
| 431 const gfx::Rect& rect, | 439 const gfx::Rect& rect, |
| 432 unsigned background_color, | 440 unsigned background_color, |
| 433 unsigned edge_aa_mask, | 441 unsigned edge_aa_mask, |
| 434 float opacity) { | 442 float opacity, |
| 443 unsigned filter) { |
| 435 content_layers.push_back(ContentLayer(io_surface, cv_pixel_buffer, | 444 content_layers.push_back(ContentLayer(io_surface, cv_pixel_buffer, |
| 436 contents_rect, rect, background_color, | 445 contents_rect, rect, background_color, |
| 437 edge_aa_mask, opacity)); | 446 edge_aa_mask, opacity, filter)); |
| 438 } | 447 } |
| 439 | 448 |
| 440 void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, | 449 void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, |
| 441 RootLayer* old_layer, | 450 RootLayer* old_layer, |
| 442 float scale_factor) { | 451 float scale_factor) { |
| 443 if (old_layer) { | 452 if (old_layer) { |
| 444 DCHECK(old_layer->ca_layer); | 453 DCHECK(old_layer->ca_layer); |
| 445 std::swap(ca_layer, old_layer->ca_layer); | 454 std::swap(ca_layer, old_layer->ca_layer); |
| 446 } else { | 455 } else { |
| 447 ca_layer.reset([[CALayer alloc] init]); | 456 ca_layer.reset([[CALayer alloc] init]); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 | 563 |
| 555 void CARendererLayerTree::ContentLayer::CommitToCA(CALayer* superlayer, | 564 void CARendererLayerTree::ContentLayer::CommitToCA(CALayer* superlayer, |
| 556 ContentLayer* old_layer, | 565 ContentLayer* old_layer, |
| 557 float scale_factor) { | 566 float scale_factor) { |
| 558 bool update_contents = true; | 567 bool update_contents = true; |
| 559 bool update_contents_rect = true; | 568 bool update_contents_rect = true; |
| 560 bool update_rect = true; | 569 bool update_rect = true; |
| 561 bool update_background_color = true; | 570 bool update_background_color = true; |
| 562 bool update_ca_edge_aa_mask = true; | 571 bool update_ca_edge_aa_mask = true; |
| 563 bool update_opacity = true; | 572 bool update_opacity = true; |
| 573 bool update_ca_filter = true; |
| 564 if (old_layer && old_layer->use_av_layer == use_av_layer) { | 574 if (old_layer && old_layer->use_av_layer == use_av_layer) { |
| 565 DCHECK(old_layer->ca_layer); | 575 DCHECK(old_layer->ca_layer); |
| 566 std::swap(ca_layer, old_layer->ca_layer); | 576 std::swap(ca_layer, old_layer->ca_layer); |
| 567 std::swap(av_layer, old_layer->av_layer); | 577 std::swap(av_layer, old_layer->av_layer); |
| 568 update_contents = old_layer->io_surface != io_surface || | 578 update_contents = old_layer->io_surface != io_surface || |
| 569 old_layer->cv_pixel_buffer != cv_pixel_buffer; | 579 old_layer->cv_pixel_buffer != cv_pixel_buffer; |
| 570 update_contents_rect = old_layer->contents_rect != contents_rect; | 580 update_contents_rect = old_layer->contents_rect != contents_rect; |
| 571 update_rect = old_layer->rect != rect; | 581 update_rect = old_layer->rect != rect; |
| 572 update_background_color = old_layer->background_color != background_color; | 582 update_background_color = old_layer->background_color != background_color; |
| 573 update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask; | 583 update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask; |
| 574 update_opacity = old_layer->opacity != opacity; | 584 update_opacity = old_layer->opacity != opacity; |
| 585 update_ca_filter = old_layer->ca_filter != ca_filter; |
| 575 } else { | 586 } else { |
| 576 if (use_av_layer) { | 587 if (use_av_layer) { |
| 577 av_layer.reset([[AVSampleBufferDisplayLayer alloc] init]); | 588 av_layer.reset([[AVSampleBufferDisplayLayer alloc] init]); |
| 578 ca_layer.reset([av_layer retain]); | 589 ca_layer.reset([av_layer retain]); |
| 579 [av_layer setVideoGravity:AVLayerVideoGravityResize]; | 590 [av_layer setVideoGravity:AVLayerVideoGravityResize]; |
| 580 } else { | 591 } else { |
| 581 ca_layer.reset([[CALayer alloc] init]); | 592 ca_layer.reset([[CALayer alloc] init]); |
| 582 } | 593 } |
| 583 [ca_layer setAnchorPoint:CGPointZero]; | 594 [ca_layer setAnchorPoint:CGPointZero]; |
| 584 [superlayer addSublayer:ca_layer]; | 595 [superlayer addSublayer:ca_layer]; |
| 585 } | 596 } |
| 586 DCHECK_EQ([ca_layer superlayer], superlayer); | 597 DCHECK_EQ([ca_layer superlayer], superlayer); |
| 587 bool update_anything = update_contents || update_contents_rect || | 598 bool update_anything = update_contents || update_contents_rect || |
| 588 update_rect || update_background_color || | 599 update_rect || update_background_color || |
| 589 update_ca_edge_aa_mask || update_opacity; | 600 update_ca_edge_aa_mask || update_opacity || |
| 601 update_ca_filter; |
| 590 if (use_av_layer) { | 602 if (use_av_layer) { |
| 591 if (update_contents) { | 603 if (update_contents) { |
| 592 if (cv_pixel_buffer) { | 604 if (cv_pixel_buffer) { |
| 593 AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, | 605 AVSampleBufferDisplayLayerEnqueueCVPixelBuffer(av_layer, |
| 594 cv_pixel_buffer); | 606 cv_pixel_buffer); |
| 595 } else { | 607 } else { |
| 596 AVSampleBufferDisplayLayerEnqueueIOSurface(av_layer, io_surface); | 608 AVSampleBufferDisplayLayerEnqueueIOSurface(av_layer, io_surface); |
| 597 } | 609 } |
| 598 } | 610 } |
| 599 } else { | 611 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 619 SkColorGetA(background_color) / 255., | 631 SkColorGetA(background_color) / 255., |
| 620 }; | 632 }; |
| 621 base::ScopedCFTypeRef<CGColorRef> srgb_background_color(CGColorCreate( | 633 base::ScopedCFTypeRef<CGColorRef> srgb_background_color(CGColorCreate( |
| 622 CGColorSpaceCreateWithName(kCGColorSpaceSRGB), rgba_color_components)); | 634 CGColorSpaceCreateWithName(kCGColorSpaceSRGB), rgba_color_components)); |
| 623 [ca_layer setBackgroundColor:srgb_background_color]; | 635 [ca_layer setBackgroundColor:srgb_background_color]; |
| 624 } | 636 } |
| 625 if (update_ca_edge_aa_mask) | 637 if (update_ca_edge_aa_mask) |
| 626 [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask]; | 638 [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask]; |
| 627 if (update_opacity) | 639 if (update_opacity) |
| 628 [ca_layer setOpacity:opacity]; | 640 [ca_layer setOpacity:opacity]; |
| 641 if (update_ca_filter) { |
| 642 [ca_layer setMagnificationFilter:ca_filter]; |
| 643 [ca_layer setMinificationFilter:ca_filter]; |
| 644 } |
| 629 | 645 |
| 630 static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch( | 646 static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 631 switches::kShowMacOverlayBorders); | 647 switches::kShowMacOverlayBorders); |
| 632 if (show_borders) { | 648 if (show_borders) { |
| 633 base::ScopedCFTypeRef<CGColorRef> color; | 649 base::ScopedCFTypeRef<CGColorRef> color; |
| 634 if (update_anything) { | 650 if (update_anything) { |
| 635 if (use_av_layer) { | 651 if (use_av_layer) { |
| 636 // Green represents an AV layer that changed this frame. | 652 // Green represents an AV layer that changed this frame. |
| 637 color.reset(CGColorCreateGenericRGB(0, 1, 0, 1)); | 653 color.reset(CGColorCreateGenericRGB(0, 1, 0, 1)); |
| 638 } else { | 654 } else { |
| 639 // Pink represents a CALayer that changed this frame. | 655 // Pink represents a CALayer that changed this frame. |
| 640 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); | 656 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); |
| 641 } | 657 } |
| 642 } else { | 658 } else { |
| 643 // Grey represents a CALayer that has not changed. | 659 // Grey represents a CALayer that has not changed. |
| 644 color.reset(CGColorCreateGenericRGB(0, 0, 0, 0.1)); | 660 color.reset(CGColorCreateGenericRGB(0, 0, 0, 0.1)); |
| 645 } | 661 } |
| 646 [ca_layer setBorderWidth:1]; | 662 [ca_layer setBorderWidth:1]; |
| 647 [ca_layer setBorderColor:color]; | 663 [ca_layer setBorderColor:color]; |
| 648 } | 664 } |
| 649 } | 665 } |
| 650 | 666 |
| 651 } // namespace ui | 667 } // namespace ui |
| OLD | NEW |