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

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 deps Created 4 years, 6 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
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_.Reset(pending_buffer_.buffer());
445 std::unique_ptr<cc::SingleReleaseCallback> 451 pending_buffer_.Reset(base::WeakPtr<Buffer>());
446 texture_mailbox_release_callback;
447 452
448 cc::TextureMailbox texture_mailbox; 453 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 } 454 }
471 455
472 cc::SurfaceId old_surface_id = surface_id_; 456 cc::SurfaceId old_surface_id = surface_id_;
473 if (needs_commit_to_new_surface_ || surface_id_.is_null()) { 457 if (needs_commit_to_new_surface_ || surface_id_.is_null()) {
474 needs_commit_to_new_surface_ = false; 458 needs_commit_to_new_surface_ = false;
475 surface_id_ = factory_owner_->id_allocator_->GenerateId(); 459 surface_id_ = factory_owner_->id_allocator_->GenerateId();
476 factory_owner_->surface_factory_->Create(surface_id_); 460 factory_owner_->surface_factory_->Create(surface_id_);
477 } 461 }
478 462
479 gfx::Size buffer_size = current_resource_.size; 463 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 464
564 if (!old_surface_id.is_null() && old_surface_id != surface_id_) { 465 if (!old_surface_id.is_null() && old_surface_id != surface_id_) {
565 factory_owner_->surface_factory_->SetPreviousFrameSurface(surface_id_, 466 factory_owner_->surface_factory_->SetPreviousFrameSurface(surface_id_,
566 old_surface_id); 467 old_surface_id);
567 factory_owner_->surface_factory_->Destroy(old_surface_id); 468 factory_owner_->surface_factory_->Destroy(old_surface_id);
568 } 469 }
569 470
570 content_size_ = layer_size;
571
572 if (old_surface_id != surface_id_) { 471 if (old_surface_id != surface_id_) {
472 float contents_surface_to_layer_scale = 1.0;
573 window_->layer()->SetShowSurface( 473 window_->layer()->SetShowSurface(
574 surface_id_, 474 surface_id_,
575 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), 475 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
576 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), 476 base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
577 contents_surface_size, contents_surface_to_layer_scale, layer_size); 477 content_size_, contents_surface_to_layer_scale, content_size_);
578 window_->layer()->SetBounds( 478 window_->layer()->SetBounds(
579 gfx::Rect(window_->layer()->bounds().origin(), layer_size)); 479 gfx::Rect(window_->layer()->bounds().origin(), content_size_));
580 window_->layer()->SetFillsBoundsOpaquely(state_.alpha == 1.0f && 480 window_->layer()->SetFillsBoundsOpaquely(
581 frame_is_opaque); 481 state_.alpha == 1.0f &&
482
483 state_.opaque_region.contains(
484 gfx::RectToSkIRect(gfx::Rect(content_size_))));
582 } 485 }
583 486
584 // Reset damage. 487 // Reset damage.
585 pending_damage_.setEmpty(); 488 pending_damage_.setEmpty();
586 489
587 DCHECK(!current_resource_.id || 490 DCHECK(!current_resource_.id ||
588 factory_owner_->release_callbacks_.count(current_resource_.id)); 491 factory_owner_->release_callbacks_.count(current_resource_.id));
589 492
590 // Move pending frame callbacks to the end of active_frame_callbacks_ 493 // Move pending frame callbacks to the end of active_frame_callbacks_
591 active_frame_callbacks_.splice(active_frame_callbacks_.end(), 494 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( 590 std::unique_ptr<base::trace_event::TracedValue> value(
688 new base::trace_event::TracedValue()); 591 new base::trace_event::TracedValue());
689 value->SetString("name", window_->layer()->name()); 592 value->SetString("name", window_->layer()->name());
690 return value; 593 return value;
691 } 594 }
692 595
693 //////////////////////////////////////////////////////////////////////////////// 596 ////////////////////////////////////////////////////////////////////////////////
694 // ui::LayerOwnerDelegate overrides: 597 // ui::LayerOwnerDelegate overrides:
695 598
696 void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) { 599 void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) {
697 if (!current_buffer_) 600 if (!current_buffer_.buffer())
698 return; 601 return;
699 602
700 // TODO(reveman): Give the client a chance to provide new contents. 603 // TODO(reveman): Give the client a chance to provide new contents.
701 SetSurfaceLayerContents(new_layer); 604 SetSurfaceLayerContents(new_layer);
702 } 605 }
703 606
704 void Surface::WillDraw(cc::SurfaceId id) { 607 void Surface::WillDraw(cc::SurfaceId id) {
705 while (!active_frame_callbacks_.empty()) { 608 while (!active_frame_callbacks_.empty()) {
706 active_frame_callbacks_.front().Run(base::TimeTicks::Now()); 609 active_frame_callbacks_.front().Run(base::TimeTicks::Now());
707 active_frame_callbacks_.pop_front(); 610 active_frame_callbacks_.pop_front();
(...skipping 10 matching lines...) Expand all
718 Surface::State::~State() = default; 621 Surface::State::~State() = default;
719 622
720 bool Surface::State::operator==(const State& other) { 623 bool Surface::State::operator==(const State& other) {
721 return (other.crop == crop && alpha == other.alpha && 624 return (other.crop == crop && alpha == other.alpha &&
722 other.blend_mode == blend_mode && other.viewport == viewport && 625 other.blend_mode == blend_mode && other.viewport == viewport &&
723 other.opaque_region == opaque_region && 626 other.opaque_region == opaque_region &&
724 other.buffer_scale == buffer_scale && 627 other.buffer_scale == buffer_scale &&
725 other.input_region == input_region); 628 other.input_region == input_region);
726 } 629 }
727 630
631 Surface::BufferAttachment::BufferAttachment() {}
632 Surface::BufferAttachment::~BufferAttachment() {
reveman 2016/06/23 00:44:39 nit: blank line before this
633 if (buffer_)
634 buffer_->OnDetach();
635 }
636
637 base::WeakPtr<Buffer>& Surface::BufferAttachment::buffer() {
638 return buffer_;
639 }
640
641 const base::WeakPtr<Buffer>& Surface::BufferAttachment::buffer() const {
642 return buffer_;
643 }
644
645 void Surface::BufferAttachment::Reset(base::WeakPtr<Buffer> buffer) {
646 if (buffer)
647 buffer->OnAttach();
648 if (buffer_)
649 buffer_->OnDetach();
650 buffer_ = buffer;
651 }
652
728 bool Surface::HasLayerHierarchyChanged() const { 653 bool Surface::HasLayerHierarchyChanged() const {
729 if (needs_commit_surface_hierarchy_ && has_pending_layer_changes_) 654 if (needs_commit_surface_hierarchy_ && has_pending_layer_changes_)
730 return true; 655 return true;
731 656
732 for (const auto& sub_surface_entry : pending_sub_surfaces_) { 657 for (const auto& sub_surface_entry : pending_sub_surfaces_) {
733 if (sub_surface_entry.first->HasLayerHierarchyChanged()) 658 if (sub_surface_entry.first->HasLayerHierarchyChanged())
734 return true; 659 return true;
735 } 660 }
736 return false; 661 return false;
737 } 662 }
(...skipping 12 matching lines...) Expand all
750 gfx::Size layer_size = layer->bounds().size(); 675 gfx::Size layer_size = layer->bounds().size();
751 float contents_surface_to_layer_scale = 1.0f; 676 float contents_surface_to_layer_scale = 1.0f;
752 677
753 layer->SetShowSurface( 678 layer->SetShowSurface(
754 surface_id_, 679 surface_id_,
755 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), 680 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
756 base::Bind(&RequireCallback, base::Unretained(surface_manager_)), 681 base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
757 layer_size, contents_surface_to_layer_scale, layer_size); 682 layer_size, contents_surface_to_layer_scale, layer_size);
758 } 683 }
759 684
685 void Surface::UpdateResource(bool client_usage) {
686 std::unique_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
687
688 cc::TextureMailbox texture_mailbox;
689 if (current_buffer_.buffer()) {
690 texture_mailbox_release_callback =
691 current_buffer_.buffer()->ProduceTextureMailbox(
692 &texture_mailbox, state_.only_visible_on_secure_output,
693 client_usage);
694 }
695
696 if (texture_mailbox_release_callback) {
697 cc::TransferableResource resource;
698 resource.id = next_resource_id_++;
699 resource.format = cc::RGBA_8888;
700 resource.filter =
701 texture_mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR;
702 resource.size = texture_mailbox.size_in_pixels();
703 resource.mailbox_holder = gpu::MailboxHolder(texture_mailbox.mailbox(),
704 texture_mailbox.sync_token(),
705 texture_mailbox.target());
706 resource.is_overlay_candidate = texture_mailbox.is_overlay_candidate();
707
708 factory_owner_->release_callbacks_[resource.id] = std::make_pair(
709 factory_owner_, std::move(texture_mailbox_release_callback));
710 current_resource_ = resource;
711 } else {
712 current_resource_.id = 0;
713 current_resource_.size = gfx::Size();
714 }
715 }
716
717 void Surface::UpdateSurface(bool for_commit) {
reveman 2016/06/23 00:44:39 nit: s/for_commit/full_damage/
718 gfx::Size buffer_size = current_resource_.size;
719 gfx::SizeF scaled_buffer_size(
720 gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale));
721
722 gfx::Size layer_size; // Size of the output layer, in DIP.
723 if (!state_.viewport.IsEmpty()) {
724 layer_size = state_.viewport;
725 } else if (!state_.crop.IsEmpty()) {
726 DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) ||
727 !gfx::IsExpressibleAsInt(state_.crop.height()))
728 << "Crop rectangle size (" << state_.crop.size().ToString()
729 << ") most be expressible using integers when viewport is not set";
730 layer_size = gfx::ToCeiledSize(state_.crop.size());
731 } else {
732 layer_size = gfx::ToCeiledSize(scaled_buffer_size);
733 }
734
735 content_size_ = layer_size;
736 // TODO(jbauman): Figure out how this interacts with the pixel size of
737 // CopyOutputRequests on the layer.
738 gfx::Size contents_surface_size = layer_size;
739
740 gfx::PointF uv_top_left(0.f, 0.f);
741 gfx::PointF uv_bottom_right(1.f, 1.f);
742 if (!state_.crop.IsEmpty()) {
743 uv_top_left = state_.crop.origin();
744
745 uv_top_left.Scale(1.f / scaled_buffer_size.width(),
746 1.f / scaled_buffer_size.height());
747 uv_bottom_right = state_.crop.bottom_right();
748 uv_bottom_right.Scale(1.f / scaled_buffer_size.width(),
749 1.f / scaled_buffer_size.height());
750 }
751
752 // pending_damage_ is in Surface coordinates.
753 gfx::Rect damage_rect = for_commit
reveman 2016/06/23 00:44:39 nit: s/for_commit/!full_damage/
754 ? gfx::SkIRectToRect(pending_damage_.getBounds())
755 : gfx::Rect(contents_surface_size);
756
757 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
758 render_pass->SetAll(cc::RenderPassId(1, 1), gfx::Rect(contents_surface_size),
759 damage_rect, gfx::Transform(), true);
760
761 gfx::Rect quad_rect = gfx::Rect(contents_surface_size);
762 cc::SharedQuadState* quad_state =
763 render_pass->CreateAndAppendSharedQuadState();
764 quad_state->quad_layer_bounds = contents_surface_size;
765 quad_state->visible_quad_layer_rect = quad_rect;
766 quad_state->opacity = state_.alpha;
767
768 std::unique_ptr<cc::DelegatedFrameData> delegated_frame(
769 new cc::DelegatedFrameData);
770 if (current_resource_.id) {
771 cc::TextureDrawQuad* texture_quad =
772 render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
773 float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0};
774 gfx::Rect opaque_rect;
775 if (state_.blend_mode == SkXfermode::kSrc_Mode ||
776 state_.opaque_region.contains(gfx::RectToSkIRect(quad_rect))) {
777 opaque_rect = quad_rect;
778 } else if (state_.opaque_region.isRect()) {
779 opaque_rect = gfx::SkIRectToRect(state_.opaque_region.getBounds());
780 }
781
782 texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect,
783 current_resource_.id, true, uv_top_left,
784 uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
785 false, false, state_.only_visible_on_secure_output);
786 delegated_frame->resource_list.push_back(current_resource_);
787 } else {
788 cc::SolidColorDrawQuad* solid_quad =
789 render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
790 solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, false);
791 }
792
793 delegated_frame->render_pass_list.push_back(std::move(render_pass));
794 std::unique_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
795 frame->delegated_frame_data = std::move(delegated_frame);
796
797 factory_owner_->surface_factory_->SubmitCompositorFrame(
798 surface_id_, std::move(frame), cc::SurfaceFactory::DrawCallback());
799 }
800
760 int64_t Surface::SetPropertyInternal(const void* key, 801 int64_t Surface::SetPropertyInternal(const void* key,
761 const char* name, 802 const char* name,
762 PropertyDeallocator deallocator, 803 PropertyDeallocator deallocator,
763 int64_t value, 804 int64_t value,
764 int64_t default_value) { 805 int64_t default_value) {
765 int64_t old = GetPropertyInternal(key, default_value); 806 int64_t old = GetPropertyInternal(key, default_value);
766 if (value == default_value) { 807 if (value == default_value) {
767 prop_map_.erase(key); 808 prop_map_.erase(key);
768 } else { 809 } else {
769 Value prop_value; 810 Value prop_value;
770 prop_value.name = name; 811 prop_value.name = name;
771 prop_value.value = value; 812 prop_value.value = value;
772 prop_value.deallocator = deallocator; 813 prop_value.deallocator = deallocator;
773 prop_map_[key] = prop_value; 814 prop_map_[key] = prop_value;
774 } 815 }
775 return old; 816 return old;
776 } 817 }
777 818
778 int64_t Surface::GetPropertyInternal(const void* key, 819 int64_t Surface::GetPropertyInternal(const void* key,
779 int64_t default_value) const { 820 int64_t default_value) const {
780 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); 821 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
781 if (iter == prop_map_.end()) 822 if (iter == prop_map_.end())
782 return default_value; 823 return default_value;
783 return iter->second.value; 824 return iter->second.value;
784 } 825 }
785 826
786 } // namespace exo 827 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698