| 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 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 layer()->SetFillsBoundsOpaquely( | 501 layer()->SetFillsBoundsOpaquely( |
| 502 pending_blend_mode_ == SkXfermode::kSrc_Mode || | 502 pending_blend_mode_ == SkXfermode::kSrc_Mode || |
| 503 pending_opaque_region_.contains( | 503 pending_opaque_region_.contains( |
| 504 gfx::RectToSkIRect(gfx::Rect(layer()->size())))); | 504 gfx::RectToSkIRect(gfx::Rect(layer()->size())))); |
| 505 } | 505 } |
| 506 | 506 |
| 507 void Surface::CommitSurfaceContents() { | 507 void Surface::CommitSurfaceContents() { |
| 508 // We update contents if Attach() has been called since last commit. | 508 // We update contents if Attach() has been called since last commit. |
| 509 if (has_pending_contents_) { | 509 if (has_pending_contents_) { |
| 510 has_pending_contents_ = false; | 510 has_pending_contents_ = false; |
| 511 | |
| 512 current_buffer_ = pending_buffer_; | 511 current_buffer_ = pending_buffer_; |
| 513 pending_buffer_.reset(); | 512 pending_buffer_.reset(); |
| 514 | 513 |
| 515 cc::TextureMailbox texture_mailbox; | |
| 516 std::unique_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback; | |
| 517 if (current_buffer_) { | 514 if (current_buffer_) { |
| 515 std::unique_ptr<cc::SingleReleaseCallback> |
| 516 texture_mailbox_release_callback; |
| 517 |
| 518 cc::TextureMailbox texture_mailbox; |
| 518 texture_mailbox_release_callback = current_buffer_->ProduceTextureMailbox( | 519 texture_mailbox_release_callback = current_buffer_->ProduceTextureMailbox( |
| 519 &texture_mailbox, only_visible_on_secure_output_, | 520 &texture_mailbox, only_visible_on_secure_output_, |
| 520 true /* client_usage */); | 521 true /* client_usage */); |
| 521 } | |
| 522 | |
| 523 cc::SurfaceId old_surface_id = surface_id_; | |
| 524 surface_id_ = factory_owner_->id_allocator_->GenerateId(); | |
| 525 factory_owner_->surface_factory_->Create(surface_id_); | |
| 526 | |
| 527 gfx::Size buffer_size = texture_mailbox.size_in_pixels(); | |
| 528 gfx::SizeF scaled_buffer_size( | |
| 529 gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / pending_buffer_scale_)); | |
| 530 | |
| 531 gfx::Size layer_size; // Size of the output layer, in DIP. | |
| 532 if (!pending_viewport_.IsEmpty()) { | |
| 533 layer_size = pending_viewport_; | |
| 534 } else if (!crop_.IsEmpty()) { | |
| 535 DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(crop_.width()) || | |
| 536 !gfx::IsExpressibleAsInt(crop_.height())) | |
| 537 << "Crop rectangle size (" << crop_.size().ToString() | |
| 538 << ") most be expressible using integers when viewport is not set"; | |
| 539 layer_size = gfx::ToCeiledSize(crop_.size()); | |
| 540 } else { | |
| 541 layer_size = gfx::ToCeiledSize(scaled_buffer_size); | |
| 542 } | |
| 543 | |
| 544 // TODO(jbauman): Figure out how this interacts with the pixel size of | |
| 545 // CopyOutputRequests on the layer. | |
| 546 float contents_surface_to_layer_scale = 1.0; | |
| 547 gfx::Size contents_surface_size = layer_size; | |
| 548 | |
| 549 gfx::PointF uv_top_left(0.f, 0.f); | |
| 550 gfx::PointF uv_bottom_right(1.f, 1.f); | |
| 551 if (!crop_.IsEmpty()) { | |
| 552 uv_top_left = crop_.origin(); | |
| 553 | |
| 554 uv_top_left.Scale(1.f / scaled_buffer_size.width(), | |
| 555 1.f / scaled_buffer_size.height()); | |
| 556 uv_bottom_right = crop_.bottom_right(); | |
| 557 uv_bottom_right.Scale(1.f / scaled_buffer_size.width(), | |
| 558 1.f / scaled_buffer_size.height()); | |
| 559 } | |
| 560 | |
| 561 // pending_damage_ is in Surface coordinates. | |
| 562 gfx::Rect damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds()); | |
| 563 | |
| 564 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); | |
| 565 render_pass->SetAll(cc::RenderPassId(1, 1), | |
| 566 gfx::Rect(contents_surface_size), damage_rect, | |
| 567 gfx::Transform(), true); | |
| 568 | |
| 569 gfx::Rect quad_rect = gfx::Rect(contents_surface_size); | |
| 570 cc::SharedQuadState* quad_state = | |
| 571 render_pass->CreateAndAppendSharedQuadState(); | |
| 572 quad_state->quad_layer_bounds = contents_surface_size; | |
| 573 quad_state->visible_quad_layer_rect = quad_rect; | |
| 574 quad_state->opacity = alpha_; | |
| 575 | |
| 576 bool frame_is_opaque = false; | |
| 577 | |
| 578 std::unique_ptr<cc::DelegatedFrameData> delegated_frame( | |
| 579 new cc::DelegatedFrameData); | |
| 580 if (texture_mailbox_release_callback) { | |
| 581 cc::TransferableResource resource; | 522 cc::TransferableResource resource; |
| 582 resource.id = next_resource_id_++; | 523 resource.id = next_resource_id_++; |
| 583 resource.format = cc::RGBA_8888; | 524 resource.format = cc::RGBA_8888; |
| 584 resource.filter = | 525 resource.filter = |
| 585 texture_mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR; | 526 texture_mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR; |
| 586 resource.size = texture_mailbox.size_in_pixels(); | 527 resource.size = texture_mailbox.size_in_pixels(); |
| 587 resource.mailbox_holder = gpu::MailboxHolder(texture_mailbox.mailbox(), | 528 resource.mailbox_holder = gpu::MailboxHolder(texture_mailbox.mailbox(), |
| 588 texture_mailbox.sync_token(), | 529 texture_mailbox.sync_token(), |
| 589 texture_mailbox.target()); | 530 texture_mailbox.target()); |
| 590 resource.is_overlay_candidate = texture_mailbox.is_overlay_candidate(); | 531 resource.is_overlay_candidate = texture_mailbox.is_overlay_candidate(); |
| 591 | 532 |
| 592 cc::TextureDrawQuad* texture_quad = | |
| 593 render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); | |
| 594 float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0}; | |
| 595 gfx::Rect opaque_rect; | |
| 596 frame_is_opaque = | |
| 597 pending_blend_mode_ == SkXfermode::kSrc_Mode || | |
| 598 pending_opaque_region_.contains(gfx::RectToSkIRect(quad_rect)); | |
| 599 if (frame_is_opaque) { | |
| 600 opaque_rect = quad_rect; | |
| 601 } else if (pending_opaque_region_.isRect()) { | |
| 602 opaque_rect = gfx::SkIRectToRect(pending_opaque_region_.getBounds()); | |
| 603 } | |
| 604 | |
| 605 texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect, | |
| 606 resource.id, true, uv_top_left, uv_bottom_right, | |
| 607 SK_ColorTRANSPARENT, vertex_opacity, false, false, | |
| 608 only_visible_on_secure_output_); | |
| 609 | |
| 610 factory_owner_->release_callbacks_[resource.id] = std::make_pair( | 533 factory_owner_->release_callbacks_[resource.id] = std::make_pair( |
| 611 factory_owner_, std::move(texture_mailbox_release_callback)); | 534 factory_owner_, std::move(texture_mailbox_release_callback)); |
| 612 delegated_frame->resource_list.push_back(resource); | 535 current_resource_ = resource; |
| 613 } else { | 536 } else { |
| 614 cc::SolidColorDrawQuad* solid_quad = | 537 current_resource_.id = 0; |
| 615 render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>(); | 538 current_resource_.size = gfx::Size(); |
| 616 solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, | 539 } |
| 617 false); | 540 } |
| 618 frame_is_opaque = true; | 541 |
| 542 cc::SurfaceId old_surface_id = surface_id_; |
| 543 surface_id_ = factory_owner_->id_allocator_->GenerateId(); |
| 544 factory_owner_->surface_factory_->Create(surface_id_); |
| 545 |
| 546 gfx::Size buffer_size = current_resource_.size; |
| 547 gfx::SizeF scaled_buffer_size( |
| 548 gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / pending_buffer_scale_)); |
| 549 |
| 550 gfx::Size layer_size; // Size of the output layer, in DIP. |
| 551 if (!pending_viewport_.IsEmpty()) { |
| 552 layer_size = pending_viewport_; |
| 553 } else if (!crop_.IsEmpty()) { |
| 554 DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(crop_.width()) || |
| 555 !gfx::IsExpressibleAsInt(crop_.height())) |
| 556 << "Crop rectangle size (" << crop_.size().ToString() |
| 557 << ") most be expressible using integers when viewport is not set"; |
| 558 layer_size = gfx::ToCeiledSize(crop_.size()); |
| 559 } else { |
| 560 layer_size = gfx::ToCeiledSize(scaled_buffer_size); |
| 561 } |
| 562 |
| 563 // TODO(jbauman): Figure out how this interacts with the pixel size of |
| 564 // CopyOutputRequests on the layer. |
| 565 float contents_surface_to_layer_scale = 1.0; |
| 566 gfx::Size contents_surface_size = layer_size; |
| 567 |
| 568 gfx::PointF uv_top_left(0.f, 0.f); |
| 569 gfx::PointF uv_bottom_right(1.f, 1.f); |
| 570 if (!crop_.IsEmpty()) { |
| 571 uv_top_left = crop_.origin(); |
| 572 |
| 573 uv_top_left.Scale(1.f / scaled_buffer_size.width(), |
| 574 1.f / scaled_buffer_size.height()); |
| 575 uv_bottom_right = crop_.bottom_right(); |
| 576 uv_bottom_right.Scale(1.f / scaled_buffer_size.width(), |
| 577 1.f / scaled_buffer_size.height()); |
| 578 } |
| 579 |
| 580 // pending_damage_ is in Surface coordinates. |
| 581 gfx::Rect damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds()); |
| 582 |
| 583 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); |
| 584 render_pass->SetAll(cc::RenderPassId(1, 1), gfx::Rect(contents_surface_size), |
| 585 damage_rect, gfx::Transform(), true); |
| 586 |
| 587 gfx::Rect quad_rect = gfx::Rect(contents_surface_size); |
| 588 cc::SharedQuadState* quad_state = |
| 589 render_pass->CreateAndAppendSharedQuadState(); |
| 590 quad_state->quad_layer_bounds = contents_surface_size; |
| 591 quad_state->visible_quad_layer_rect = quad_rect; |
| 592 quad_state->opacity = alpha_; |
| 593 |
| 594 bool frame_is_opaque = false; |
| 595 |
| 596 std::unique_ptr<cc::DelegatedFrameData> delegated_frame( |
| 597 new cc::DelegatedFrameData); |
| 598 if (current_resource_.id) { |
| 599 cc::TextureDrawQuad* texture_quad = |
| 600 render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); |
| 601 float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0}; |
| 602 gfx::Rect opaque_rect; |
| 603 frame_is_opaque = |
| 604 pending_blend_mode_ == SkXfermode::kSrc_Mode || |
| 605 pending_opaque_region_.contains(gfx::RectToSkIRect(quad_rect)); |
| 606 if (frame_is_opaque) { |
| 607 opaque_rect = quad_rect; |
| 608 } else if (pending_opaque_region_.isRect()) { |
| 609 opaque_rect = gfx::SkIRectToRect(pending_opaque_region_.getBounds()); |
| 619 } | 610 } |
| 620 | 611 |
| 621 delegated_frame->render_pass_list.push_back(std::move(render_pass)); | 612 texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect, |
| 622 std::unique_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); | 613 current_resource_.id, true, uv_top_left, |
| 623 frame->delegated_frame_data = std::move(delegated_frame); | 614 uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, |
| 615 false, false, only_visible_on_secure_output_); |
| 616 delegated_frame->resource_list.push_back(current_resource_); |
| 617 } else { |
| 618 cc::SolidColorDrawQuad* solid_quad = |
| 619 render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>(); |
| 620 solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, false); |
| 621 frame_is_opaque = true; |
| 622 } |
| 624 | 623 |
| 625 factory_owner_->surface_factory_->SubmitCompositorFrame( | 624 delegated_frame->render_pass_list.push_back(std::move(render_pass)); |
| 626 surface_id_, std::move(frame), cc::SurfaceFactory::DrawCallback()); | 625 std::unique_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); |
| 626 frame->delegated_frame_data = std::move(delegated_frame); |
| 627 | 627 |
| 628 if (!old_surface_id.is_null()) { | 628 factory_owner_->surface_factory_->SubmitCompositorFrame( |
| 629 factory_owner_->surface_factory_->SetPreviousFrameSurface(surface_id_, | 629 surface_id_, std::move(frame), cc::SurfaceFactory::DrawCallback()); |
| 630 old_surface_id); | |
| 631 factory_owner_->surface_factory_->Destroy(old_surface_id); | |
| 632 } | |
| 633 | 630 |
| 634 layer()->SetShowSurface( | 631 if (!old_surface_id.is_null()) { |
| 635 surface_id_, | 632 factory_owner_->surface_factory_->SetPreviousFrameSurface(surface_id_, |
| 636 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), | 633 old_surface_id); |
| 637 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), | 634 factory_owner_->surface_factory_->Destroy(old_surface_id); |
| 638 contents_surface_size, contents_surface_to_layer_scale, layer_size); | 635 } |
| 639 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(), layer_size)); | |
| 640 layer()->SetFillsBoundsOpaquely(alpha_ == 1.0f && frame_is_opaque); | |
| 641 | 636 |
| 642 // Reset damage. | 637 layer()->SetShowSurface( |
| 643 pending_damage_.setEmpty(); | 638 surface_id_, |
| 644 } | 639 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), |
| 640 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), |
| 641 contents_surface_size, contents_surface_to_layer_scale, layer_size); |
| 642 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(), layer_size)); |
| 643 layer()->SetFillsBoundsOpaquely(alpha_ == 1.0f && frame_is_opaque); |
| 644 |
| 645 // Reset damage. |
| 646 pending_damage_.setEmpty(); |
| 647 |
| 648 DCHECK(!current_resource_.id || |
| 649 factory_owner_->release_callbacks_.count(current_resource_.id)); |
| 650 |
| 645 // Move pending frame callbacks to the end of active_frame_callbacks_ | 651 // Move pending frame callbacks to the end of active_frame_callbacks_ |
| 646 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | 652 active_frame_callbacks_.splice(active_frame_callbacks_.end(), |
| 647 pending_frame_callbacks_); | 653 pending_frame_callbacks_); |
| 648 } | 654 } |
| 649 | 655 |
| 650 void Surface::CommitSurfaceHierarchy() { | 656 void Surface::CommitSurfaceHierarchy() { |
| 651 DCHECK(needs_commit_surface_hierarchy_); | 657 DCHECK(needs_commit_surface_hierarchy_); |
| 652 needs_commit_surface_hierarchy_ = false; | 658 needs_commit_surface_hierarchy_ = false; |
| 653 | 659 |
| 654 // TODO(dcastagna): Make secure_output_only a layer property instead of a | 660 // TODO(dcastagna): Make secure_output_only a layer property instead of a |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 } | 887 } |
| 882 | 888 |
| 883 void Surface::SetSurfaceLayerContents(ui::Layer* layer) { | 889 void Surface::SetSurfaceLayerContents(ui::Layer* layer) { |
| 884 // TODO(jbauman): Implement this. | 890 // TODO(jbauman): Implement this. |
| 885 NOTIMPLEMENTED(); | 891 NOTIMPLEMENTED(); |
| 886 } | 892 } |
| 887 | 893 |
| 888 bool Surface::use_surface_layer_ = false; | 894 bool Surface::use_surface_layer_ = false; |
| 889 | 895 |
| 890 } // namespace exo | 896 } // namespace exo |
| OLD | NEW |