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 |