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

Unified Diff: components/exo/surface.cc

Issue 1467943002: exo: Handle lost context situations properly. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move SharedMainThreadContextProvider Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/surface.cc
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 3f06238588078c265ef61a1321cc270a55285072..83f5972ab85b35994a95482c15308929e82d4378 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -41,8 +41,9 @@ bool ListContainsEntry(T& list, U key) {
// Surface, public:
Surface::Surface()
- : needs_commit_surface_hierarchy_(false),
- has_contents_(false),
+ : has_pending_contents_(false),
+ needs_commit_surface_hierarchy_(false),
+ update_contents_after_successful_compositing_(false),
compositor_(nullptr),
delegate_(nullptr) {
SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR));
@@ -71,6 +72,7 @@ Surface::~Surface() {
void Surface::Attach(Buffer* buffer) {
TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer->AsTracedValue());
+ has_pending_contents_ = true;
pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>();
PreferredSizeChanged();
}
@@ -197,34 +199,41 @@ void Surface::CommitSurfaceHierarchy() {
DCHECK(needs_commit_surface_hierarchy_);
needs_commit_surface_hierarchy_ = false;
- cc::TextureMailbox texture_mailbox;
- scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
- if (pending_buffer_) {
- texture_mailbox_release_callback =
- pending_buffer_->AcquireTextureMailbox(&texture_mailbox);
+ // We update contents if Attach() has been called since last commit.
+ if (has_pending_contents_) {
+ has_pending_contents_ = false;
+
+ current_buffer_ = pending_buffer_;
pending_buffer_.reset();
- has_contents_ = true;
- } else {
- // Show solid color content if there is no pending buffer.
- layer()->SetShowSolidColorContent();
- has_contents_ = false;
- }
- if (texture_mailbox_release_callback) {
- // Update layer with the new contents.
- layer()->SetTextureMailbox(texture_mailbox,
- texture_mailbox_release_callback.Pass(),
- texture_mailbox.size_in_pixels());
- layer()->SetTextureFlipped(false);
- layer()->SetBounds(gfx::Rect(layer()->bounds().origin(),
- texture_mailbox.size_in_pixels()));
- layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains(
- gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels()))));
- }
+ cc::TextureMailbox texture_mailbox;
+ scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
+ if (current_buffer_) {
+ texture_mailbox_release_callback =
+ current_buffer_->ProduceTextureMailbox(&texture_mailbox);
+ }
- // Schedule redraw of the damage region.
- layer()->SchedulePaint(pending_damage_);
- pending_damage_ = gfx::Rect();
+ if (texture_mailbox_release_callback) {
+ // Update layer with the new contents.
+ layer()->SetTextureMailbox(texture_mailbox,
+ texture_mailbox_release_callback.Pass(),
+ texture_mailbox.size_in_pixels());
+ layer()->SetTextureFlipped(false);
+ layer()->SetBounds(gfx::Rect(layer()->bounds().origin(),
+ texture_mailbox.size_in_pixels()));
+ layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains(
+ gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels()))));
+ } else {
+ // Show solid color content if no buffer is attached or we failed
+ // to produce a texture mailbox for the currently attached buffer.
+ layer()->SetShowSolidColorContent();
+ layer()->SetColor(SK_ColorBLACK);
+ }
+
+ // Schedule redraw of the damage region.
+ layer()->SchedulePaint(pending_damage_);
+ pending_damage_ = gfx::Rect();
+ }
ui::Compositor* compositor = layer()->GetCompositor();
if (compositor && !pending_frame_callbacks_.empty()) {
@@ -322,6 +331,37 @@ void Surface::OnCompositingStarted(ui::Compositor* compositor,
}
}
+void Surface::OnCompositingEnded(ui::Compositor* compositor) {
+ // Nothing to do in here unless this has been set.
+ if (!update_contents_after_successful_compositing_)
+ return;
+
+ update_contents_after_successful_compositing_ = false;
+
+ // Early out if no contents is currently assigned to the surface.
+ if (!current_buffer_)
+ return;
+
+ // Update contents by producing a new texture mailbox for the current buffer.
+ cc::TextureMailbox texture_mailbox;
+ scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback =
+ current_buffer_->ProduceTextureMailbox(&texture_mailbox);
+ if (texture_mailbox_release_callback) {
+ layer()->SetTextureMailbox(texture_mailbox,
+ texture_mailbox_release_callback.Pass(),
+ texture_mailbox.size_in_pixels());
+ layer()->SetTextureFlipped(false);
+ layer()->SchedulePaint(gfx::Rect(texture_mailbox.size_in_pixels()));
+ }
+}
+
+void Surface::OnCompositingAborted(ui::Compositor* compositor) {
+ // The contents of this surface might be lost if compositing aborted because
+ // of a lost graphics context. We recover from this by updating the contents
+ // of the surface next time the compositor successfully ends compositing.
+ update_contents_after_successful_compositing_ = true;
+}
+
void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) {
compositor->RemoveObserver(this);
compositor_ = nullptr;
« 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