| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/surface.h" | 5 #include "components/exo/surface.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 182 |
| 183 void SurfaceFactoryOwner::SetBeginFrameSource( | 183 void SurfaceFactoryOwner::SetBeginFrameSource( |
| 184 cc::BeginFrameSource* begin_frame_source) {} | 184 cc::BeginFrameSource* begin_frame_source) {} |
| 185 | 185 |
| 186 //////////////////////////////////////////////////////////////////////////////// | 186 //////////////////////////////////////////////////////////////////////////////// |
| 187 // Surface, public: | 187 // Surface, public: |
| 188 | 188 |
| 189 Surface::Surface() | 189 Surface::Surface() |
| 190 : window_(new aura::Window(new CustomWindowDelegate(this))), | 190 : window_(new aura::Window(new CustomWindowDelegate(this))), |
| 191 has_pending_contents_(false), | 191 has_pending_contents_(false), |
| 192 surface_manager_( |
| 193 aura::Env::GetInstance()->context_factory()->GetSurfaceManager()), |
| 194 factory_owner_(new SurfaceFactoryOwner), |
| 192 needs_commit_surface_hierarchy_(false), | 195 needs_commit_surface_hierarchy_(false), |
| 193 update_contents_after_successful_compositing_(false), | |
| 194 compositor_(nullptr), | |
| 195 delegate_(nullptr) { | 196 delegate_(nullptr) { |
| 196 window_->SetType(ui::wm::WINDOW_TYPE_CONTROL); | 197 window_->SetType(ui::wm::WINDOW_TYPE_CONTROL); |
| 197 window_->SetName("ExoSurface"); | 198 window_->SetName("ExoSurface"); |
| 198 window_->SetProperty(kSurfaceKey, this); | 199 window_->SetProperty(kSurfaceKey, this); |
| 199 window_->Init(ui::LAYER_SOLID_COLOR); | 200 window_->Init(ui::LAYER_SOLID_COLOR); |
| 200 window_->set_layer_owner_delegate(this); | 201 window_->set_layer_owner_delegate(this); |
| 201 window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter)); | 202 window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter)); |
| 202 window_->set_owned_by_parent(false); | 203 window_->set_owned_by_parent(false); |
| 203 surface_manager_ = | 204 factory_owner_->surface_ = this; |
| 204 aura::Env::GetInstance()->context_factory()->GetSurfaceManager(); | 205 factory_owner_->id_allocator_ = |
| 205 if (use_surface_layer_) { | 206 aura::Env::GetInstance()->context_factory()->CreateSurfaceIdAllocator(); |
| 206 factory_owner_ = make_scoped_refptr(new SurfaceFactoryOwner); | 207 factory_owner_->surface_factory_.reset( |
| 207 factory_owner_->surface_ = this; | 208 new cc::SurfaceFactory(surface_manager_, factory_owner_.get())); |
| 208 factory_owner_->id_allocator_ = | |
| 209 aura::Env::GetInstance()->context_factory()->CreateSurfaceIdAllocator(); | |
| 210 factory_owner_->surface_factory_.reset( | |
| 211 new cc::SurfaceFactory(surface_manager_, factory_owner_.get())); | |
| 212 } | |
| 213 | |
| 214 if (!factory_owner_) { | |
| 215 window_->AddObserver(this); | |
| 216 } | |
| 217 } | 209 } |
| 218 | 210 |
| 219 Surface::~Surface() { | 211 Surface::~Surface() { |
| 220 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this)); | 212 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this)); |
| 221 | 213 |
| 222 window_->layer()->SetShowSolidColorContent(); | 214 window_->layer()->SetShowSolidColorContent(); |
| 223 | 215 |
| 224 if (factory_owner_) { | 216 factory_owner_->surface_ = nullptr; |
| 225 factory_owner_->surface_ = nullptr; | |
| 226 } else { | |
| 227 window_->RemoveObserver(this); | |
| 228 } | |
| 229 if (compositor_) | |
| 230 compositor_->RemoveObserver(this); | |
| 231 | 217 |
| 232 // Call pending frame callbacks with a null frame time to indicate that they | 218 // Call pending frame callbacks with a null frame time to indicate that they |
| 233 // have been cancelled. | 219 // have been cancelled. |
| 234 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | 220 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); |
| 235 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | 221 active_frame_callbacks_.splice(active_frame_callbacks_.end(), |
| 236 frame_callbacks_); | 222 frame_callbacks_); |
| 237 for (const auto& frame_callback : active_frame_callbacks_) | 223 for (const auto& frame_callback : active_frame_callbacks_) |
| 238 frame_callback.Run(base::TimeTicks()); | 224 frame_callback.Run(base::TimeTicks()); |
| 239 | 225 |
| 240 if (!surface_id_.is_null()) | 226 if (!surface_id_.is_null()) |
| 241 factory_owner_->surface_factory_->Destroy(surface_id_); | 227 factory_owner_->surface_factory_->Destroy(surface_id_); |
| 242 } | 228 } |
| 243 | 229 |
| 244 // static | 230 // static |
| 245 Surface* Surface::AsSurface(const aura::Window* window) { | 231 Surface* Surface::AsSurface(const aura::Window* window) { |
| 246 return window->GetProperty(kSurfaceKey); | 232 return window->GetProperty(kSurfaceKey); |
| 247 } | 233 } |
| 248 | 234 |
| 249 // static | |
| 250 void Surface::SetUseSurfaceLayer(bool use_surface_layer) { | |
| 251 use_surface_layer_ = use_surface_layer; | |
| 252 } | |
| 253 | |
| 254 void Surface::Attach(Buffer* buffer) { | 235 void Surface::Attach(Buffer* buffer) { |
| 255 TRACE_EVENT1("exo", "Surface::Attach", "buffer", | 236 TRACE_EVENT1("exo", "Surface::Attach", "buffer", |
| 256 buffer ? buffer->GetSize().ToString() : "null"); | 237 buffer ? buffer->GetSize().ToString() : "null"); |
| 257 | 238 |
| 258 has_pending_contents_ = true; | 239 has_pending_contents_ = true; |
| 259 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>(); | 240 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>(); |
| 260 } | 241 } |
| 261 | 242 |
| 262 void Surface::Damage(const gfx::Rect& damage) { | 243 void Surface::Damage(const gfx::Rect& damage) { |
| 263 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); | 244 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 } | 426 } |
| 446 | 427 |
| 447 void Surface::CommitSurfaceHierarchy() { | 428 void Surface::CommitSurfaceHierarchy() { |
| 448 DCHECK(needs_commit_surface_hierarchy_); | 429 DCHECK(needs_commit_surface_hierarchy_); |
| 449 needs_commit_surface_hierarchy_ = false; | 430 needs_commit_surface_hierarchy_ = false; |
| 450 has_pending_layer_changes_ = false; | 431 has_pending_layer_changes_ = false; |
| 451 | 432 |
| 452 state_ = pending_state_; | 433 state_ = pending_state_; |
| 453 pending_state_.only_visible_on_secure_output = false; | 434 pending_state_.only_visible_on_secure_output = false; |
| 454 | 435 |
| 455 if (factory_owner_) { | |
| 456 CommitSurfaceContents(); | |
| 457 } else { | |
| 458 CommitTextureContents(); | |
| 459 } | |
| 460 | |
| 461 // Synchronize window hierarchy. This will position and update the stacking | |
| 462 // order of all sub-surfaces after committing all pending state of sub-surface | |
| 463 // descendants. | |
| 464 aura::Window* stacking_target = nullptr; | |
| 465 for (auto& sub_surface_entry : pending_sub_surfaces_) { | |
| 466 Surface* sub_surface = sub_surface_entry.first; | |
| 467 | |
| 468 // Synchronsouly commit all pending state of the sub-surface and its | |
| 469 // decendents. | |
| 470 if (sub_surface->needs_commit_surface_hierarchy()) | |
| 471 sub_surface->CommitSurfaceHierarchy(); | |
| 472 | |
| 473 // Enable/disable sub-surface based on if it has contents. | |
| 474 if (sub_surface->has_contents()) | |
| 475 sub_surface->window()->Show(); | |
| 476 else | |
| 477 sub_surface->window()->Hide(); | |
| 478 | |
| 479 // Move sub-surface to its new position in the stack. | |
| 480 if (stacking_target) | |
| 481 window_->StackChildAbove(sub_surface->window(), stacking_target); | |
| 482 | |
| 483 // Stack next sub-surface above this sub-surface. | |
| 484 stacking_target = sub_surface->window(); | |
| 485 | |
| 486 // Update sub-surface position relative to surface origin. | |
| 487 sub_surface->window()->SetBounds(gfx::Rect( | |
| 488 sub_surface_entry.second, sub_surface->window()->layer()->size())); | |
| 489 } | |
| 490 } | |
| 491 | |
| 492 bool Surface::IsSynchronized() const { | |
| 493 return delegate_ ? delegate_->IsSurfaceSynchronized() : false; | |
| 494 } | |
| 495 | |
| 496 gfx::Rect Surface::GetHitTestBounds() const { | |
| 497 SkIRect bounds = state_.input_region.getBounds(); | |
| 498 if (!bounds.intersect( | |
| 499 gfx::RectToSkIRect(gfx::Rect(window_->layer()->size())))) | |
| 500 return gfx::Rect(); | |
| 501 return gfx::SkIRectToRect(bounds); | |
| 502 } | |
| 503 | |
| 504 bool Surface::HitTestRect(const gfx::Rect& rect) const { | |
| 505 if (HasHitTestMask()) | |
| 506 return state_.input_region.intersects(gfx::RectToSkIRect(rect)); | |
| 507 | |
| 508 return rect.Intersects(gfx::Rect(window_->layer()->size())); | |
| 509 } | |
| 510 | |
| 511 bool Surface::HasHitTestMask() const { | |
| 512 return !state_.input_region.contains( | |
| 513 gfx::RectToSkIRect(gfx::Rect(window_->layer()->size()))); | |
| 514 } | |
| 515 | |
| 516 void Surface::GetHitTestMask(gfx::Path* mask) const { | |
| 517 state_.input_region.getBoundaryPath(mask); | |
| 518 } | |
| 519 | |
| 520 void Surface::RegisterCursorProvider(Pointer* provider) { | |
| 521 cursor_providers_.insert(provider); | |
| 522 } | |
| 523 | |
| 524 void Surface::UnregisterCursorProvider(Pointer* provider) { | |
| 525 cursor_providers_.erase(provider); | |
| 526 } | |
| 527 | |
| 528 bool Surface::HasCursorProvider() const { | |
| 529 return !cursor_providers_.empty(); | |
| 530 } | |
| 531 | |
| 532 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { | |
| 533 DCHECK(!delegate_ || !delegate); | |
| 534 delegate_ = delegate; | |
| 535 } | |
| 536 | |
| 537 bool Surface::HasSurfaceDelegate() const { | |
| 538 return !!delegate_; | |
| 539 } | |
| 540 | |
| 541 void Surface::AddSurfaceObserver(SurfaceObserver* observer) { | |
| 542 observers_.AddObserver(observer); | |
| 543 } | |
| 544 | |
| 545 void Surface::RemoveSurfaceObserver(SurfaceObserver* observer) { | |
| 546 observers_.RemoveObserver(observer); | |
| 547 } | |
| 548 | |
| 549 bool Surface::HasSurfaceObserver(const SurfaceObserver* observer) const { | |
| 550 return observers_.HasObserver(observer); | |
| 551 } | |
| 552 | |
| 553 std::unique_ptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { | |
| 554 std::unique_ptr<base::trace_event::TracedValue> value( | |
| 555 new base::trace_event::TracedValue()); | |
| 556 value->SetString("name", window_->layer()->name()); | |
| 557 return value; | |
| 558 } | |
| 559 | |
| 560 //////////////////////////////////////////////////////////////////////////////// | |
| 561 // aura::WindowObserver overrides: | |
| 562 | |
| 563 void Surface::OnWindowAddedToRootWindow(aura::Window* window) { | |
| 564 DCHECK(!compositor_); | |
| 565 DCHECK(!factory_owner_); | |
| 566 compositor_ = window_->layer()->GetCompositor(); | |
| 567 compositor_->AddObserver(this); | |
| 568 } | |
| 569 | |
| 570 void Surface::OnWindowRemovingFromRootWindow(aura::Window* window, | |
| 571 aura::Window* new_root) { | |
| 572 DCHECK(compositor_); | |
| 573 compositor_->RemoveObserver(this); | |
| 574 compositor_ = nullptr; | |
| 575 } | |
| 576 | |
| 577 //////////////////////////////////////////////////////////////////////////////// | |
| 578 // ui::LayerOwnerDelegate overrides: | |
| 579 | |
| 580 void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) { | |
| 581 if (!current_buffer_) | |
| 582 return; | |
| 583 | |
| 584 // TODO(reveman): Give the client a chance to provide new contents. | |
| 585 if (factory_owner_) { | |
| 586 SetSurfaceLayerContents(new_layer); | |
| 587 } else { | |
| 588 SetTextureLayerContents(new_layer); | |
| 589 } | |
| 590 } | |
| 591 | |
| 592 //////////////////////////////////////////////////////////////////////////////// | |
| 593 // ui::CompositorObserver overrides: | |
| 594 | |
| 595 void Surface::OnCompositingDidCommit(ui::Compositor* compositor) { | |
| 596 DCHECK(!factory_owner_); | |
| 597 // Move frame callbacks to the end of |active_frame_callbacks_|. | |
| 598 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | |
| 599 frame_callbacks_); | |
| 600 } | |
| 601 | |
| 602 void Surface::OnCompositingStarted(ui::Compositor* compositor, | |
| 603 base::TimeTicks start_time) { | |
| 604 last_compositing_start_time_ = start_time; | |
| 605 } | |
| 606 | |
| 607 void Surface::OnCompositingEnded(ui::Compositor* compositor) { | |
| 608 // Run all frame callbacks associated with the compositor's active tree. | |
| 609 while (!active_frame_callbacks_.empty()) { | |
| 610 active_frame_callbacks_.front().Run(last_compositing_start_time_); | |
| 611 active_frame_callbacks_.pop_front(); | |
| 612 } | |
| 613 | |
| 614 // Nothing more to do in here unless this has been set. | |
| 615 if (!update_contents_after_successful_compositing_) | |
| 616 return; | |
| 617 | |
| 618 update_contents_after_successful_compositing_ = false; | |
| 619 | |
| 620 // Early out if no contents is currently assigned to the surface. | |
| 621 if (!current_buffer_) | |
| 622 return; | |
| 623 | |
| 624 // Update contents by producing a new texture mailbox for the current buffer. | |
| 625 SetTextureLayerContents(window_->layer()); | |
| 626 } | |
| 627 | |
| 628 void Surface::OnCompositingAborted(ui::Compositor* compositor) { | |
| 629 // The contents of this surface might be lost if compositing aborted because | |
| 630 // of a lost graphics context. We recover from this by updating the contents | |
| 631 // of the surface next time the compositor successfully ends compositing. | |
| 632 update_contents_after_successful_compositing_ = true; | |
| 633 } | |
| 634 | |
| 635 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { | |
| 636 compositor->RemoveObserver(this); | |
| 637 compositor_ = nullptr; | |
| 638 } | |
| 639 | |
| 640 void Surface::WillDraw(cc::SurfaceId id) { | |
| 641 while (!active_frame_callbacks_.empty()) { | |
| 642 active_frame_callbacks_.front().Run(base::TimeTicks::Now()); | |
| 643 active_frame_callbacks_.pop_front(); | |
| 644 } | |
| 645 } | |
| 646 | |
| 647 void Surface::CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces() { | |
| 648 if (HasLayerHierarchyChanged()) | |
| 649 SetSurfaceHierarchyNeedsCommitToNewSurfaces(); | |
| 650 } | |
| 651 | |
| 652 Surface::State::State() : input_region(SkIRect::MakeLargest()) {} | |
| 653 | |
| 654 Surface::State::~State() = default; | |
| 655 | |
| 656 bool Surface::State::operator==(const State& other) { | |
| 657 return (other.crop == crop && alpha == other.alpha && | |
| 658 other.blend_mode == blend_mode && other.viewport == viewport && | |
| 659 other.opaque_region == opaque_region && | |
| 660 other.buffer_scale == buffer_scale && | |
| 661 other.input_region == input_region); | |
| 662 } | |
| 663 | |
| 664 bool Surface::HasLayerHierarchyChanged() const { | |
| 665 if (needs_commit_surface_hierarchy_ && has_pending_layer_changes_) | |
| 666 return true; | |
| 667 | |
| 668 for (const auto& sub_surface_entry : pending_sub_surfaces_) { | |
| 669 if (sub_surface_entry.first->HasLayerHierarchyChanged()) | |
| 670 return true; | |
| 671 } | |
| 672 return false; | |
| 673 } | |
| 674 | |
| 675 void Surface::SetSurfaceHierarchyNeedsCommitToNewSurfaces() { | |
| 676 needs_commit_to_new_surface_ = true; | |
| 677 for (auto& sub_surface_entry : pending_sub_surfaces_) { | |
| 678 sub_surface_entry.first->SetSurfaceHierarchyNeedsCommitToNewSurfaces(); | |
| 679 } | |
| 680 } | |
| 681 | |
| 682 void Surface::CommitTextureContents() { | |
| 683 // We update contents if Attach() has been called since last commit. | 436 // We update contents if Attach() has been called since last commit. |
| 684 if (has_pending_contents_) { | 437 // TODO(jbauman): Support producing a new texture mailbox after lost |
| 685 has_pending_contents_ = false; | 438 // context. |
| 686 | |
| 687 current_buffer_ = pending_buffer_; | |
| 688 pending_buffer_.reset(); | |
| 689 | |
| 690 cc::TextureMailbox texture_mailbox; | |
| 691 std::unique_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback; | |
| 692 if (current_buffer_) { | |
| 693 texture_mailbox_release_callback = current_buffer_->ProduceTextureMailbox( | |
| 694 &texture_mailbox, state_.only_visible_on_secure_output, | |
| 695 true /* client_usage */); | |
| 696 } | |
| 697 | |
| 698 // Update layer with the new contents. | |
| 699 if (texture_mailbox_release_callback) { | |
| 700 texture_size_in_dip_ = gfx::ScaleToFlooredSize( | |
| 701 texture_mailbox.size_in_pixels(), 1.0f / state_.buffer_scale); | |
| 702 window_->layer()->SetTextureMailbox( | |
| 703 texture_mailbox, std::move(texture_mailbox_release_callback), | |
| 704 texture_size_in_dip_); | |
| 705 window_->layer()->SetTextureFlipped(false); | |
| 706 } else { | |
| 707 // Show solid color content if no buffer is attached or we failed | |
| 708 // to produce a texture mailbox for the currently attached buffer. | |
| 709 window_->layer()->SetShowSolidColorContent(); | |
| 710 window_->layer()->SetColor(SK_ColorBLACK); | |
| 711 } | |
| 712 | |
| 713 // Schedule redraw of the damage region. | |
| 714 for (SkRegion::Iterator it(pending_damage_); !it.done(); it.next()) | |
| 715 window_->layer()->SchedulePaint(gfx::SkIRectToRect(it.rect())); | |
| 716 | |
| 717 // Reset damage. | |
| 718 pending_damage_.setEmpty(); | |
| 719 } | |
| 720 | |
| 721 if (window_->layer()->has_external_content()) { | |
| 722 // Determine the new surface size. | |
| 723 // - Texture size in DIP defines the size if nothing else is set. | |
| 724 // - If a viewport is set then that defines the size, otherwise | |
| 725 // the crop rectangle defines the size if set. | |
| 726 gfx::Size contents_size = texture_size_in_dip_; | |
| 727 if (!state_.viewport.IsEmpty()) { | |
| 728 contents_size = state_.viewport; | |
| 729 } else if (!state_.crop.IsEmpty()) { | |
| 730 DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) || | |
| 731 !gfx::IsExpressibleAsInt(state_.crop.height())) | |
| 732 << "Crop rectangle size (" << state_.crop.size().ToString() | |
| 733 << ") most be expressible using integers when viewport is not set"; | |
| 734 contents_size = gfx::ToCeiledSize(state_.crop.size()); | |
| 735 } | |
| 736 window_->layer()->SetTextureCrop(state_.crop); | |
| 737 window_->layer()->SetTextureScale( | |
| 738 static_cast<float>(texture_size_in_dip_.width()) / | |
| 739 contents_size.width(), | |
| 740 static_cast<float>(texture_size_in_dip_.height()) / | |
| 741 contents_size.height()); | |
| 742 window_->layer()->SetTextureAlpha(state_.alpha); | |
| 743 window_->layer()->SetBounds( | |
| 744 gfx::Rect(window_->layer()->bounds().origin(), contents_size)); | |
| 745 } | |
| 746 | |
| 747 // Move pending frame callbacks to the end of |frame_callbacks_|. | |
| 748 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | |
| 749 | |
| 750 // Update alpha compositing properties. | |
| 751 // TODO(reveman): Use a more reliable way to force blending off than setting | |
| 752 // fills-bounds-opaquely. | |
| 753 window_->layer()->SetFillsBoundsOpaquely( | |
| 754 state_.blend_mode == SkXfermode::kSrc_Mode || | |
| 755 state_.opaque_region.contains( | |
| 756 gfx::RectToSkIRect(gfx::Rect(window_->layer()->size())))); | |
| 757 } | |
| 758 | |
| 759 void Surface::CommitSurfaceContents() { | |
| 760 // We update contents if Attach() has been called since last commit. | |
| 761 if (has_pending_contents_) { | 439 if (has_pending_contents_) { |
| 762 has_pending_contents_ = false; | 440 has_pending_contents_ = false; |
| 763 current_buffer_ = pending_buffer_; | 441 current_buffer_ = pending_buffer_; |
| 764 pending_buffer_.reset(); | 442 pending_buffer_.reset(); |
| 765 | 443 |
| 766 if (current_buffer_) { | 444 if (current_buffer_) { |
| 767 std::unique_ptr<cc::SingleReleaseCallback> | 445 std::unique_ptr<cc::SingleReleaseCallback> |
| 768 texture_mailbox_release_callback; | 446 texture_mailbox_release_callback; |
| 769 | 447 |
| 770 cc::TextureMailbox texture_mailbox; | 448 cc::TextureMailbox texture_mailbox; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 | 581 |
| 904 // Reset damage. | 582 // Reset damage. |
| 905 pending_damage_.setEmpty(); | 583 pending_damage_.setEmpty(); |
| 906 | 584 |
| 907 DCHECK(!current_resource_.id || | 585 DCHECK(!current_resource_.id || |
| 908 factory_owner_->release_callbacks_.count(current_resource_.id)); | 586 factory_owner_->release_callbacks_.count(current_resource_.id)); |
| 909 | 587 |
| 910 // Move pending frame callbacks to the end of active_frame_callbacks_ | 588 // Move pending frame callbacks to the end of active_frame_callbacks_ |
| 911 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | 589 active_frame_callbacks_.splice(active_frame_callbacks_.end(), |
| 912 pending_frame_callbacks_); | 590 pending_frame_callbacks_); |
| 591 |
| 592 // Synchronize window hierarchy. This will position and update the stacking |
| 593 // order of all sub-surfaces after committing all pending state of sub-surface |
| 594 // descendants. |
| 595 aura::Window* stacking_target = nullptr; |
| 596 for (auto& sub_surface_entry : pending_sub_surfaces_) { |
| 597 Surface* sub_surface = sub_surface_entry.first; |
| 598 |
| 599 // Synchronsouly commit all pending state of the sub-surface and its |
| 600 // decendents. |
| 601 if (sub_surface->needs_commit_surface_hierarchy()) |
| 602 sub_surface->CommitSurfaceHierarchy(); |
| 603 |
| 604 // Enable/disable sub-surface based on if it has contents. |
| 605 if (sub_surface->has_contents()) |
| 606 sub_surface->window()->Show(); |
| 607 else |
| 608 sub_surface->window()->Hide(); |
| 609 |
| 610 // Move sub-surface to its new position in the stack. |
| 611 if (stacking_target) |
| 612 window_->StackChildAbove(sub_surface->window(), stacking_target); |
| 613 |
| 614 // Stack next sub-surface above this sub-surface. |
| 615 stacking_target = sub_surface->window(); |
| 616 |
| 617 // Update sub-surface position relative to surface origin. |
| 618 sub_surface->window()->SetBounds(gfx::Rect( |
| 619 sub_surface_entry.second, sub_surface->window()->layer()->size())); |
| 620 } |
| 913 } | 621 } |
| 914 | 622 |
| 915 void Surface::SetTextureLayerContents(ui::Layer* layer) { | 623 bool Surface::IsSynchronized() const { |
| 916 DCHECK(current_buffer_); | 624 return delegate_ ? delegate_->IsSurfaceSynchronized() : false; |
| 625 } |
| 917 | 626 |
| 918 cc::TextureMailbox texture_mailbox; | 627 gfx::Rect Surface::GetHitTestBounds() const { |
| 919 std::unique_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback = | 628 SkIRect bounds = state_.input_region.getBounds(); |
| 920 current_buffer_->ProduceTextureMailbox( | 629 if (!bounds.intersect( |
| 921 &texture_mailbox, state_.only_visible_on_secure_output, | 630 gfx::RectToSkIRect(gfx::Rect(window_->layer()->size())))) |
| 922 false /* client_usage */); | 631 return gfx::Rect(); |
| 923 if (!texture_mailbox_release_callback) | 632 return gfx::SkIRectToRect(bounds); |
| 633 } |
| 634 |
| 635 bool Surface::HitTestRect(const gfx::Rect& rect) const { |
| 636 if (HasHitTestMask()) |
| 637 return state_.input_region.intersects(gfx::RectToSkIRect(rect)); |
| 638 |
| 639 return rect.Intersects(gfx::Rect(window_->layer()->size())); |
| 640 } |
| 641 |
| 642 bool Surface::HasHitTestMask() const { |
| 643 return !state_.input_region.contains( |
| 644 gfx::RectToSkIRect(gfx::Rect(window_->layer()->size()))); |
| 645 } |
| 646 |
| 647 void Surface::GetHitTestMask(gfx::Path* mask) const { |
| 648 state_.input_region.getBoundaryPath(mask); |
| 649 } |
| 650 |
| 651 void Surface::RegisterCursorProvider(Pointer* provider) { |
| 652 cursor_providers_.insert(provider); |
| 653 } |
| 654 |
| 655 void Surface::UnregisterCursorProvider(Pointer* provider) { |
| 656 cursor_providers_.erase(provider); |
| 657 } |
| 658 |
| 659 bool Surface::HasCursorProvider() const { |
| 660 return !cursor_providers_.empty(); |
| 661 } |
| 662 |
| 663 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { |
| 664 DCHECK(!delegate_ || !delegate); |
| 665 delegate_ = delegate; |
| 666 } |
| 667 |
| 668 bool Surface::HasSurfaceDelegate() const { |
| 669 return !!delegate_; |
| 670 } |
| 671 |
| 672 void Surface::AddSurfaceObserver(SurfaceObserver* observer) { |
| 673 observers_.AddObserver(observer); |
| 674 } |
| 675 |
| 676 void Surface::RemoveSurfaceObserver(SurfaceObserver* observer) { |
| 677 observers_.RemoveObserver(observer); |
| 678 } |
| 679 |
| 680 bool Surface::HasSurfaceObserver(const SurfaceObserver* observer) const { |
| 681 return observers_.HasObserver(observer); |
| 682 } |
| 683 |
| 684 std::unique_ptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { |
| 685 std::unique_ptr<base::trace_event::TracedValue> value( |
| 686 new base::trace_event::TracedValue()); |
| 687 value->SetString("name", window_->layer()->name()); |
| 688 return value; |
| 689 } |
| 690 |
| 691 //////////////////////////////////////////////////////////////////////////////// |
| 692 // ui::LayerOwnerDelegate overrides: |
| 693 |
| 694 void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) { |
| 695 if (!current_buffer_) |
| 924 return; | 696 return; |
| 925 | 697 |
| 926 layer->SetTextureMailbox(texture_mailbox, | 698 // TODO(reveman): Give the client a chance to provide new contents. |
| 927 std::move(texture_mailbox_release_callback), | 699 SetSurfaceLayerContents(new_layer); |
| 928 texture_size_in_dip_); | 700 } |
| 929 layer->SetTextureFlipped(false); | 701 |
| 930 layer->SetTextureCrop(state_.crop); | 702 void Surface::WillDraw(cc::SurfaceId id) { |
| 931 layer->SetTextureScale(static_cast<float>(texture_size_in_dip_.width()) / | 703 while (!active_frame_callbacks_.empty()) { |
| 932 layer->bounds().width(), | 704 active_frame_callbacks_.front().Run(base::TimeTicks::Now()); |
| 933 static_cast<float>(texture_size_in_dip_.height()) / | 705 active_frame_callbacks_.pop_front(); |
| 934 layer->bounds().height()); | 706 } |
| 935 layer->SetTextureAlpha(state_.alpha); | 707 } |
| 708 |
| 709 void Surface::CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces() { |
| 710 if (HasLayerHierarchyChanged()) |
| 711 SetSurfaceHierarchyNeedsCommitToNewSurfaces(); |
| 712 } |
| 713 |
| 714 Surface::State::State() : input_region(SkIRect::MakeLargest()) {} |
| 715 |
| 716 Surface::State::~State() = default; |
| 717 |
| 718 bool Surface::State::operator==(const State& other) { |
| 719 return (other.crop == crop && alpha == other.alpha && |
| 720 other.blend_mode == blend_mode && other.viewport == viewport && |
| 721 other.opaque_region == opaque_region && |
| 722 other.buffer_scale == buffer_scale && |
| 723 other.input_region == input_region); |
| 724 } |
| 725 |
| 726 bool Surface::HasLayerHierarchyChanged() const { |
| 727 if (needs_commit_surface_hierarchy_ && has_pending_layer_changes_) |
| 728 return true; |
| 729 |
| 730 for (const auto& sub_surface_entry : pending_sub_surfaces_) { |
| 731 if (sub_surface_entry.first->HasLayerHierarchyChanged()) |
| 732 return true; |
| 733 } |
| 734 return false; |
| 735 } |
| 736 |
| 737 void Surface::SetSurfaceHierarchyNeedsCommitToNewSurfaces() { |
| 738 needs_commit_to_new_surface_ = true; |
| 739 for (auto& sub_surface_entry : pending_sub_surfaces_) { |
| 740 sub_surface_entry.first->SetSurfaceHierarchyNeedsCommitToNewSurfaces(); |
| 741 } |
| 936 } | 742 } |
| 937 | 743 |
| 938 void Surface::SetSurfaceLayerContents(ui::Layer* layer) { | 744 void Surface::SetSurfaceLayerContents(ui::Layer* layer) { |
| 939 if (surface_id_.is_null()) | 745 if (surface_id_.is_null()) |
| 940 return; | 746 return; |
| 941 | 747 |
| 942 gfx::Size layer_size = layer->bounds().size(); | 748 gfx::Size layer_size = layer->bounds().size(); |
| 943 float contents_surface_to_layer_scale = 1.0f; | 749 float contents_surface_to_layer_scale = 1.0f; |
| 944 | 750 |
| 945 layer->SetShowSurface( | 751 layer->SetShowSurface( |
| 946 surface_id_, | 752 surface_id_, |
| 947 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), | 753 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), |
| 948 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), | 754 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), |
| 949 layer_size, contents_surface_to_layer_scale, layer_size); | 755 layer_size, contents_surface_to_layer_scale, layer_size); |
| 950 } | 756 } |
| 951 | 757 |
| 952 bool Surface::use_surface_layer_ = false; | |
| 953 | |
| 954 } // namespace exo | 758 } // namespace exo |
| OLD | NEW |