Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: components/exo/surface.cc

Issue 2083853002: exo: Recreate Surface resources on context lost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix nits Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 window_->SetProperty(kSurfaceKey, this); 199 window_->SetProperty(kSurfaceKey, this);
200 window_->Init(ui::LAYER_SOLID_COLOR); 200 window_->Init(ui::LAYER_SOLID_COLOR);
201 window_->set_layer_owner_delegate(this); 201 window_->set_layer_owner_delegate(this);
202 window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter)); 202 window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter));
203 window_->set_owned_by_parent(false); 203 window_->set_owned_by_parent(false);
204 factory_owner_->surface_ = this; 204 factory_owner_->surface_ = this;
205 factory_owner_->id_allocator_ = 205 factory_owner_->id_allocator_ =
206 aura::Env::GetInstance()->context_factory()->CreateSurfaceIdAllocator(); 206 aura::Env::GetInstance()->context_factory()->CreateSurfaceIdAllocator();
207 factory_owner_->surface_factory_.reset( 207 factory_owner_->surface_factory_.reset(
208 new cc::SurfaceFactory(surface_manager_, factory_owner_.get())); 208 new cc::SurfaceFactory(surface_manager_, factory_owner_.get()));
209 aura::Env::GetInstance()->context_factory()->AddObserver(this);
209 } 210 }
210 211
211 Surface::~Surface() { 212 Surface::~Surface() {
213 aura::Env::GetInstance()->context_factory()->RemoveObserver(this);
212 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this)); 214 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this));
213 215
214 window_->layer()->SetShowSolidColorContent(); 216 window_->layer()->SetShowSolidColorContent();
215 217
216 factory_owner_->surface_ = nullptr; 218 factory_owner_->surface_ = nullptr;
217 219
218 // Call pending frame callbacks with a null frame time to indicate that they 220 // Call pending frame callbacks with a null frame time to indicate that they
219 // have been cancelled. 221 // have been cancelled.
220 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 222 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
221 active_frame_callbacks_.splice(active_frame_callbacks_.end(), 223 active_frame_callbacks_.splice(active_frame_callbacks_.end(),
222 frame_callbacks_); 224 frame_callbacks_);
223 for (const auto& frame_callback : active_frame_callbacks_) 225 for (const auto& frame_callback : active_frame_callbacks_)
224 frame_callback.Run(base::TimeTicks()); 226 frame_callback.Run(base::TimeTicks());
225 227
226 if (!surface_id_.is_null()) 228 if (!surface_id_.is_null())
227 factory_owner_->surface_factory_->Destroy(surface_id_); 229 factory_owner_->surface_factory_->Destroy(surface_id_);
228 } 230 }
229 231
230 // static 232 // static
231 Surface* Surface::AsSurface(const aura::Window* window) { 233 Surface* Surface::AsSurface(const aura::Window* window) {
232 return window->GetProperty(kSurfaceKey); 234 return window->GetProperty(kSurfaceKey);
233 } 235 }
234 236
235 void Surface::Attach(Buffer* buffer) { 237 void Surface::Attach(Buffer* buffer) {
236 TRACE_EVENT1("exo", "Surface::Attach", "buffer", 238 TRACE_EVENT1("exo", "Surface::Attach", "buffer",
237 buffer ? buffer->GetSize().ToString() : "null"); 239 buffer ? buffer->GetSize().ToString() : "null");
238 240
239 has_pending_contents_ = true; 241 has_pending_contents_ = true;
240 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>(); 242 pending_buffer_.Reset(buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>());
241 } 243 }
242 244
243 void Surface::Damage(const gfx::Rect& damage) { 245 void Surface::Damage(const gfx::Rect& damage) {
244 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); 246 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString());
245 247
246 pending_damage_.op(gfx::RectToSkIRect(damage), SkRegion::kUnion_Op); 248 pending_damage_.op(gfx::RectToSkIRect(damage), SkRegion::kUnion_Op);
247 } 249 }
248 250
249 void Surface::RequestFrameCallback(const FrameCallback& callback) { 251 void Surface::RequestFrameCallback(const FrameCallback& callback) {
250 TRACE_EVENT0("exo", "Surface::RequestFrameCallback"); 252 TRACE_EVENT0("exo", "Surface::RequestFrameCallback");
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 404
403 void Surface::Commit() { 405 void Surface::Commit() {
404 TRACE_EVENT0("exo", "Surface::Commit"); 406 TRACE_EVENT0("exo", "Surface::Commit");
405 407
406 needs_commit_surface_hierarchy_ = true; 408 needs_commit_surface_hierarchy_ = true;
407 409
408 if (state_ != pending_state_) 410 if (state_ != pending_state_)
409 has_pending_layer_changes_ = true; 411 has_pending_layer_changes_ = true;
410 412
411 if (has_pending_contents_) { 413 if (has_pending_contents_) {
412 if (pending_buffer_ && 414 if (pending_buffer_.buffer() &&
413 (current_resource_.size != pending_buffer_->GetSize())) { 415 (current_resource_.size != pending_buffer_.buffer()->GetSize())) {
414 has_pending_layer_changes_ = true; 416 has_pending_layer_changes_ = true;
415 } else if (!pending_buffer_ && !current_resource_.size.IsEmpty()) { 417 } else if (!pending_buffer_.buffer() && !current_resource_.size.IsEmpty()) {
416 has_pending_layer_changes_ = true; 418 has_pending_layer_changes_ = true;
417 } 419 }
418 } 420 }
419 421
420 if (delegate_) { 422 if (delegate_) {
421 delegate_->OnSurfaceCommit(); 423 delegate_->OnSurfaceCommit();
422 } else { 424 } else {
423 CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); 425 CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
424 CommitSurfaceHierarchy(); 426 CommitSurfaceHierarchy();
425 } 427 }
426 } 428 }
427 429
430 void Surface::OnLostResources() {
431 if (surface_id_.is_null())
432 return;
433
434 UpdateResource(false);
435 UpdateSurface(false);
436 }
437
428 void Surface::CommitSurfaceHierarchy() { 438 void Surface::CommitSurfaceHierarchy() {
429 DCHECK(needs_commit_surface_hierarchy_); 439 DCHECK(needs_commit_surface_hierarchy_);
430 needs_commit_surface_hierarchy_ = false; 440 needs_commit_surface_hierarchy_ = false;
431 has_pending_layer_changes_ = false; 441 has_pending_layer_changes_ = false;
432 442
433 state_ = pending_state_; 443 state_ = pending_state_;
434 pending_state_.only_visible_on_secure_output = false; 444 pending_state_.only_visible_on_secure_output = false;
435 445
436 // We update contents if Attach() has been called since last commit. 446 // We update contents if Attach() has been called since last commit.
437 // TODO(jbauman): Support producing a new texture mailbox after lost
438 // context.
439 if (has_pending_contents_) { 447 if (has_pending_contents_) {
440 has_pending_contents_ = false; 448 has_pending_contents_ = false;
441 current_buffer_ = pending_buffer_;
442 pending_buffer_.reset();
443 449
444 if (current_buffer_) { 450 current_buffer_ = std::move(pending_buffer_);
445 std::unique_ptr<cc::SingleReleaseCallback>
446 texture_mailbox_release_callback;
447 451
448 cc::TextureMailbox texture_mailbox; 452 UpdateResource(true);
449 texture_mailbox_release_callback = current_buffer_->ProduceTextureMailbox(
450 &texture_mailbox, state_.only_visible_on_secure_output,
451 true /* client_usage */);
452 cc::TransferableResource resource;
453 resource.id = next_resource_id_++;
454 resource.format = cc::RGBA_8888;
455 resource.filter =
456 texture_mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR;
457 resource.size = texture_mailbox.size_in_pixels();
458 resource.mailbox_holder = gpu::MailboxHolder(texture_mailbox.mailbox(),
459 texture_mailbox.sync_token(),
460 texture_mailbox.target());
461 resource.is_overlay_candidate = texture_mailbox.is_overlay_candidate();
462
463 factory_owner_->release_callbacks_[resource.id] = std::make_pair(
464 factory_owner_, std::move(texture_mailbox_release_callback));
465 current_resource_ = resource;
466 } else {
467 current_resource_.id = 0;
468 current_resource_.size = gfx::Size();
469 }
470 } 453 }
471 454
472 cc::SurfaceId old_surface_id = surface_id_; 455 cc::SurfaceId old_surface_id = surface_id_;
473 if (needs_commit_to_new_surface_ || surface_id_.is_null()) { 456 if (needs_commit_to_new_surface_ || surface_id_.is_null()) {
474 needs_commit_to_new_surface_ = false; 457 needs_commit_to_new_surface_ = false;
475 surface_id_ = factory_owner_->id_allocator_->GenerateId(); 458 surface_id_ = factory_owner_->id_allocator_->GenerateId();
476 factory_owner_->surface_factory_->Create(surface_id_); 459 factory_owner_->surface_factory_->Create(surface_id_);
477 } 460 }
478 461
479 gfx::Size buffer_size = current_resource_.size; 462 UpdateSurface(true);
480 gfx::SizeF scaled_buffer_size(
481 gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale));
482
483 gfx::Size layer_size; // Size of the output layer, in DIP.
484 if (!state_.viewport.IsEmpty()) {
485 layer_size = state_.viewport;
486 } else if (!state_.crop.IsEmpty()) {
487 DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) ||
488 !gfx::IsExpressibleAsInt(state_.crop.height()))
489 << "Crop rectangle size (" << state_.crop.size().ToString()
490 << ") most be expressible using integers when viewport is not set";
491 layer_size = gfx::ToCeiledSize(state_.crop.size());
492 } else {
493 layer_size = gfx::ToCeiledSize(scaled_buffer_size);
494 }
495
496 // TODO(jbauman): Figure out how this interacts with the pixel size of
497 // CopyOutputRequests on the layer.
498 float contents_surface_to_layer_scale = 1.0;
499 gfx::Size contents_surface_size = layer_size;
500
501 gfx::PointF uv_top_left(0.f, 0.f);
502 gfx::PointF uv_bottom_right(1.f, 1.f);
503 if (!state_.crop.IsEmpty()) {
504 uv_top_left = state_.crop.origin();
505
506 uv_top_left.Scale(1.f / scaled_buffer_size.width(),
507 1.f / scaled_buffer_size.height());
508 uv_bottom_right = state_.crop.bottom_right();
509 uv_bottom_right.Scale(1.f / scaled_buffer_size.width(),
510 1.f / scaled_buffer_size.height());
511 }
512
513 // pending_damage_ is in Surface coordinates.
514 gfx::Rect damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds());
515
516 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
517 render_pass->SetAll(cc::RenderPassId(1, 1), gfx::Rect(contents_surface_size),
518 damage_rect, gfx::Transform(), true);
519
520 gfx::Rect quad_rect = gfx::Rect(contents_surface_size);
521 cc::SharedQuadState* quad_state =
522 render_pass->CreateAndAppendSharedQuadState();
523 quad_state->quad_layer_bounds = contents_surface_size;
524 quad_state->visible_quad_layer_rect = quad_rect;
525 quad_state->opacity = state_.alpha;
526
527 bool frame_is_opaque = false;
528
529 std::unique_ptr<cc::DelegatedFrameData> delegated_frame(
530 new cc::DelegatedFrameData);
531 if (current_resource_.id) {
532 cc::TextureDrawQuad* texture_quad =
533 render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
534 float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0};
535 gfx::Rect opaque_rect;
536 frame_is_opaque =
537 state_.blend_mode == SkXfermode::kSrc_Mode ||
538 state_.opaque_region.contains(gfx::RectToSkIRect(quad_rect));
539 if (frame_is_opaque) {
540 opaque_rect = quad_rect;
541 } else if (state_.opaque_region.isRect()) {
542 opaque_rect = gfx::SkIRectToRect(state_.opaque_region.getBounds());
543 }
544
545 texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect,
546 current_resource_.id, true, uv_top_left,
547 uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
548 false, false, state_.only_visible_on_secure_output);
549 delegated_frame->resource_list.push_back(current_resource_);
550 } else {
551 cc::SolidColorDrawQuad* solid_quad =
552 render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
553 solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, false);
554 frame_is_opaque = true;
555 }
556
557 delegated_frame->render_pass_list.push_back(std::move(render_pass));
558 std::unique_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
559 frame->delegated_frame_data = std::move(delegated_frame);
560
561 factory_owner_->surface_factory_->SubmitCompositorFrame(
562 surface_id_, std::move(frame), cc::SurfaceFactory::DrawCallback());
563 463
564 if (!old_surface_id.is_null() && old_surface_id != surface_id_) { 464 if (!old_surface_id.is_null() && old_surface_id != surface_id_) {
565 factory_owner_->surface_factory_->SetPreviousFrameSurface(surface_id_, 465 factory_owner_->surface_factory_->SetPreviousFrameSurface(surface_id_,
566 old_surface_id); 466 old_surface_id);
567 factory_owner_->surface_factory_->Destroy(old_surface_id); 467 factory_owner_->surface_factory_->Destroy(old_surface_id);
568 } 468 }
569 469
570 content_size_ = layer_size;
571
572 if (old_surface_id != surface_id_) { 470 if (old_surface_id != surface_id_) {
471 float contents_surface_to_layer_scale = 1.0;
573 window_->layer()->SetShowSurface( 472 window_->layer()->SetShowSurface(
574 surface_id_, 473 surface_id_,
575 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), 474 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
576 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), 475 base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
577 contents_surface_size, contents_surface_to_layer_scale, layer_size); 476 content_size_, contents_surface_to_layer_scale, content_size_);
578 window_->layer()->SetBounds( 477 window_->layer()->SetBounds(
579 gfx::Rect(window_->layer()->bounds().origin(), layer_size)); 478 gfx::Rect(window_->layer()->bounds().origin(), content_size_));
580 window_->layer()->SetFillsBoundsOpaquely(state_.alpha == 1.0f && 479 window_->layer()->SetFillsBoundsOpaquely(
581 frame_is_opaque); 480 state_.alpha == 1.0f &&
481
482 state_.opaque_region.contains(
483 gfx::RectToSkIRect(gfx::Rect(content_size_))));
582 } 484 }
583 485
584 // Reset damage. 486 // Reset damage.
585 pending_damage_.setEmpty(); 487 pending_damage_.setEmpty();
586 488
587 DCHECK(!current_resource_.id || 489 DCHECK(!current_resource_.id ||
588 factory_owner_->release_callbacks_.count(current_resource_.id)); 490 factory_owner_->release_callbacks_.count(current_resource_.id));
589 491
590 // Move pending frame callbacks to the end of active_frame_callbacks_ 492 // Move pending frame callbacks to the end of active_frame_callbacks_
591 active_frame_callbacks_.splice(active_frame_callbacks_.end(), 493 active_frame_callbacks_.splice(active_frame_callbacks_.end(),
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 std::unique_ptr<base::trace_event::TracedValue> value( 589 std::unique_ptr<base::trace_event::TracedValue> value(
688 new base::trace_event::TracedValue()); 590 new base::trace_event::TracedValue());
689 value->SetString("name", window_->layer()->name()); 591 value->SetString("name", window_->layer()->name());
690 return value; 592 return value;
691 } 593 }
692 594
693 //////////////////////////////////////////////////////////////////////////////// 595 ////////////////////////////////////////////////////////////////////////////////
694 // ui::LayerOwnerDelegate overrides: 596 // ui::LayerOwnerDelegate overrides:
695 597
696 void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) { 598 void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) {
697 if (!current_buffer_) 599 if (!current_buffer_.buffer())
698 return; 600 return;
699 601
700 // TODO(reveman): Give the client a chance to provide new contents. 602 // TODO(reveman): Give the client a chance to provide new contents.
701 SetSurfaceLayerContents(new_layer); 603 SetSurfaceLayerContents(new_layer);
702 } 604 }
703 605
704 void Surface::WillDraw(cc::SurfaceId id) { 606 void Surface::WillDraw(cc::SurfaceId id) {
705 while (!active_frame_callbacks_.empty()) { 607 while (!active_frame_callbacks_.empty()) {
706 active_frame_callbacks_.front().Run(base::TimeTicks::Now()); 608 active_frame_callbacks_.front().Run(base::TimeTicks::Now());
707 active_frame_callbacks_.pop_front(); 609 active_frame_callbacks_.pop_front();
(...skipping 10 matching lines...) Expand all
718 Surface::State::~State() = default; 620 Surface::State::~State() = default;
719 621
720 bool Surface::State::operator==(const State& other) { 622 bool Surface::State::operator==(const State& other) {
721 return (other.crop == crop && alpha == other.alpha && 623 return (other.crop == crop && alpha == other.alpha &&
722 other.blend_mode == blend_mode && other.viewport == viewport && 624 other.blend_mode == blend_mode && other.viewport == viewport &&
723 other.opaque_region == opaque_region && 625 other.opaque_region == opaque_region &&
724 other.buffer_scale == buffer_scale && 626 other.buffer_scale == buffer_scale &&
725 other.input_region == input_region); 627 other.input_region == input_region);
726 } 628 }
727 629
630 Surface::BufferAttachment::BufferAttachment() {}
631
632 Surface::BufferAttachment::~BufferAttachment() {
633 if (buffer_)
634 buffer_->OnDetach();
635 }
636
637 Surface::BufferAttachment& Surface::BufferAttachment::operator=(
638 BufferAttachment&& other) {
639 if (buffer_)
640 buffer_->OnDetach();
641 buffer_ = other.buffer_;
642 other.buffer_ = base::WeakPtr<Buffer>();
643 return *this;
644 }
645
646 base::WeakPtr<Buffer>& Surface::BufferAttachment::buffer() {
647 return buffer_;
648 }
649
650 const base::WeakPtr<Buffer>& Surface::BufferAttachment::buffer() const {
651 return buffer_;
652 }
653
654 void Surface::BufferAttachment::Reset(base::WeakPtr<Buffer> buffer) {
655 if (buffer)
656 buffer->OnAttach();
657 if (buffer_)
658 buffer_->OnDetach();
659 buffer_ = buffer;
660 }
661
728 bool Surface::HasLayerHierarchyChanged() const { 662 bool Surface::HasLayerHierarchyChanged() const {
729 if (needs_commit_surface_hierarchy_ && has_pending_layer_changes_) 663 if (needs_commit_surface_hierarchy_ && has_pending_layer_changes_)
730 return true; 664 return true;
731 665
732 for (const auto& sub_surface_entry : pending_sub_surfaces_) { 666 for (const auto& sub_surface_entry : pending_sub_surfaces_) {
733 if (sub_surface_entry.first->HasLayerHierarchyChanged()) 667 if (sub_surface_entry.first->HasLayerHierarchyChanged())
734 return true; 668 return true;
735 } 669 }
736 return false; 670 return false;
737 } 671 }
(...skipping 12 matching lines...) Expand all
750 gfx::Size layer_size = layer->bounds().size(); 684 gfx::Size layer_size = layer->bounds().size();
751 float contents_surface_to_layer_scale = 1.0f; 685 float contents_surface_to_layer_scale = 1.0f;
752 686
753 layer->SetShowSurface( 687 layer->SetShowSurface(
754 surface_id_, 688 surface_id_,
755 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), 689 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
756 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), 690 base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
757 layer_size, contents_surface_to_layer_scale, layer_size); 691 layer_size, contents_surface_to_layer_scale, layer_size);
758 } 692 }
759 693
694 void Surface::UpdateResource(bool client_usage) {
695 std::unique_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
696
697 cc::TextureMailbox texture_mailbox;
698 if (current_buffer_.buffer()) {
699 texture_mailbox_release_callback =
700 current_buffer_.buffer()->ProduceTextureMailbox(
701 &texture_mailbox, state_.only_visible_on_secure_output,
702 client_usage);
703 }
704
705 if (texture_mailbox_release_callback) {
706 cc::TransferableResource resource;
707 resource.id = next_resource_id_++;
708 resource.format = cc::RGBA_8888;
709 resource.filter =
710 texture_mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR;
711 resource.size = texture_mailbox.size_in_pixels();
712 resource.mailbox_holder = gpu::MailboxHolder(texture_mailbox.mailbox(),
713 texture_mailbox.sync_token(),
714 texture_mailbox.target());
715 resource.is_overlay_candidate = texture_mailbox.is_overlay_candidate();
716
717 factory_owner_->release_callbacks_[resource.id] = std::make_pair(
718 factory_owner_, std::move(texture_mailbox_release_callback));
719 current_resource_ = resource;
720 } else {
721 current_resource_.id = 0;
722 current_resource_.size = gfx::Size();
723 }
724 }
725
726 void Surface::UpdateSurface(bool full_damage) {
727 gfx::Size buffer_size = current_resource_.size;
728 gfx::SizeF scaled_buffer_size(
729 gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale));
730
731 gfx::Size layer_size; // Size of the output layer, in DIP.
732 if (!state_.viewport.IsEmpty()) {
733 layer_size = state_.viewport;
734 } else if (!state_.crop.IsEmpty()) {
735 DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) ||
736 !gfx::IsExpressibleAsInt(state_.crop.height()))
737 << "Crop rectangle size (" << state_.crop.size().ToString()
738 << ") most be expressible using integers when viewport is not set";
739 layer_size = gfx::ToCeiledSize(state_.crop.size());
740 } else {
741 layer_size = gfx::ToCeiledSize(scaled_buffer_size);
742 }
743
744 content_size_ = layer_size;
745 // TODO(jbauman): Figure out how this interacts with the pixel size of
746 // CopyOutputRequests on the layer.
747 gfx::Size contents_surface_size = layer_size;
748
749 gfx::PointF uv_top_left(0.f, 0.f);
750 gfx::PointF uv_bottom_right(1.f, 1.f);
751 if (!state_.crop.IsEmpty()) {
752 uv_top_left = state_.crop.origin();
753
754 uv_top_left.Scale(1.f / scaled_buffer_size.width(),
755 1.f / scaled_buffer_size.height());
756 uv_bottom_right = state_.crop.bottom_right();
757 uv_bottom_right.Scale(1.f / scaled_buffer_size.width(),
758 1.f / scaled_buffer_size.height());
759 }
760
761 // pending_damage_ is in Surface coordinates.
762 gfx::Rect damage_rect = full_damage
763 ? gfx::Rect(contents_surface_size)
764 : gfx::SkIRectToRect(pending_damage_.getBounds());
765
766 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
767 render_pass->SetAll(cc::RenderPassId(1, 1), gfx::Rect(contents_surface_size),
768 damage_rect, gfx::Transform(), true);
769
770 gfx::Rect quad_rect = gfx::Rect(contents_surface_size);
771 cc::SharedQuadState* quad_state =
772 render_pass->CreateAndAppendSharedQuadState();
773 quad_state->quad_layer_bounds = contents_surface_size;
774 quad_state->visible_quad_layer_rect = quad_rect;
775 quad_state->opacity = state_.alpha;
776
777 std::unique_ptr<cc::DelegatedFrameData> delegated_frame(
778 new cc::DelegatedFrameData);
779 if (current_resource_.id) {
780 cc::TextureDrawQuad* texture_quad =
781 render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
782 float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0};
783 gfx::Rect opaque_rect;
784 if (state_.blend_mode == SkXfermode::kSrc_Mode ||
785 state_.opaque_region.contains(gfx::RectToSkIRect(quad_rect))) {
786 opaque_rect = quad_rect;
787 } else if (state_.opaque_region.isRect()) {
788 opaque_rect = gfx::SkIRectToRect(state_.opaque_region.getBounds());
789 }
790
791 texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect,
792 current_resource_.id, true, uv_top_left,
793 uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
794 false, false, state_.only_visible_on_secure_output);
795 delegated_frame->resource_list.push_back(current_resource_);
796 } else {
797 cc::SolidColorDrawQuad* solid_quad =
798 render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
799 solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, false);
800 }
801
802 delegated_frame->render_pass_list.push_back(std::move(render_pass));
803 std::unique_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
804 frame->delegated_frame_data = std::move(delegated_frame);
805
806 factory_owner_->surface_factory_->SubmitCompositorFrame(
807 surface_id_, std::move(frame), cc::SurfaceFactory::DrawCallback());
808 }
809
760 int64_t Surface::SetPropertyInternal(const void* key, 810 int64_t Surface::SetPropertyInternal(const void* key,
761 const char* name, 811 const char* name,
762 PropertyDeallocator deallocator, 812 PropertyDeallocator deallocator,
763 int64_t value, 813 int64_t value,
764 int64_t default_value) { 814 int64_t default_value) {
765 int64_t old = GetPropertyInternal(key, default_value); 815 int64_t old = GetPropertyInternal(key, default_value);
766 if (value == default_value) { 816 if (value == default_value) {
767 prop_map_.erase(key); 817 prop_map_.erase(key);
768 } else { 818 } else {
769 Value prop_value; 819 Value prop_value;
770 prop_value.name = name; 820 prop_value.name = name;
771 prop_value.value = value; 821 prop_value.value = value;
772 prop_value.deallocator = deallocator; 822 prop_value.deallocator = deallocator;
773 prop_map_[key] = prop_value; 823 prop_map_[key] = prop_value;
774 } 824 }
775 return old; 825 return old;
776 } 826 }
777 827
778 int64_t Surface::GetPropertyInternal(const void* key, 828 int64_t Surface::GetPropertyInternal(const void* key,
779 int64_t default_value) const { 829 int64_t default_value) const {
780 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); 830 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
781 if (iter == prop_map_.end()) 831 if (iter == prop_map_.end())
782 return default_value; 832 return default_value;
783 return iter->second.value; 833 return iter->second.value;
784 } 834 }
785 835
786 } // namespace exo 836 } // namespace exo
OLDNEW
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698