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

Side by Side 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 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 "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "base/trace_event/trace_event_argument.h" 10 #include "base/trace_event/trace_event_argument.h"
(...skipping 23 matching lines...) Expand all
34 bool ListContainsEntry(T& list, U key) { 34 bool ListContainsEntry(T& list, U key) {
35 return FindListEntry(list, key) != list.end(); 35 return FindListEntry(list, key) != list.end();
36 } 36 }
37 37
38 } // namespace 38 } // namespace
39 39
40 //////////////////////////////////////////////////////////////////////////////// 40 ////////////////////////////////////////////////////////////////////////////////
41 // Surface, public: 41 // Surface, public:
42 42
43 Surface::Surface() 43 Surface::Surface()
44 : needs_commit_surface_hierarchy_(false), 44 : has_pending_contents_(false),
45 has_contents_(false), 45 needs_commit_surface_hierarchy_(false),
46 update_contents_after_successful_compositing_(false),
46 compositor_(nullptr), 47 compositor_(nullptr),
47 delegate_(nullptr) { 48 delegate_(nullptr) {
48 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR)); 49 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR));
49 set_owned_by_client(); 50 set_owned_by_client();
50 SetVisible(false); 51 SetVisible(false);
51 SetEnabled(false); 52 SetEnabled(false);
52 } 53 }
53 54
54 Surface::~Surface() { 55 Surface::~Surface() {
55 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this)); 56 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this));
56 57
57 layer()->SetShowSolidColorContent(); 58 layer()->SetShowSolidColorContent();
58 59
59 if (compositor_) 60 if (compositor_)
60 compositor_->RemoveObserver(this); 61 compositor_->RemoveObserver(this);
61 62
62 // Call pending frame callbacks with a null frame time to indicate that they 63 // Call pending frame callbacks with a null frame time to indicate that they
63 // have been cancelled. 64 // have been cancelled.
64 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 65 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
65 active_frame_callbacks_.splice(active_frame_callbacks_.end(), 66 active_frame_callbacks_.splice(active_frame_callbacks_.end(),
66 frame_callbacks_); 67 frame_callbacks_);
67 for (const auto& frame_callback : active_frame_callbacks_) 68 for (const auto& frame_callback : active_frame_callbacks_)
68 frame_callback.Run(base::TimeTicks()); 69 frame_callback.Run(base::TimeTicks());
69 } 70 }
70 71
71 void Surface::Attach(Buffer* buffer) { 72 void Surface::Attach(Buffer* buffer) {
72 TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer->AsTracedValue()); 73 TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer->AsTracedValue());
73 74
75 has_pending_contents_ = true;
74 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>(); 76 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>();
75 PreferredSizeChanged(); 77 PreferredSizeChanged();
76 } 78 }
77 79
78 void Surface::Damage(const gfx::Rect& damage) { 80 void Surface::Damage(const gfx::Rect& damage) {
79 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); 81 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString());
80 82
81 pending_damage_.Union(damage); 83 pending_damage_.Union(damage);
82 } 84 }
83 85
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 if (delegate_) 192 if (delegate_)
191 delegate_->OnSurfaceCommit(); 193 delegate_->OnSurfaceCommit();
192 else 194 else
193 CommitSurfaceHierarchy(); 195 CommitSurfaceHierarchy();
194 } 196 }
195 197
196 void Surface::CommitSurfaceHierarchy() { 198 void Surface::CommitSurfaceHierarchy() {
197 DCHECK(needs_commit_surface_hierarchy_); 199 DCHECK(needs_commit_surface_hierarchy_);
198 needs_commit_surface_hierarchy_ = false; 200 needs_commit_surface_hierarchy_ = false;
199 201
200 cc::TextureMailbox texture_mailbox; 202 // We update contents if Attach() has been called since last commit.
201 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback; 203 if (has_pending_contents_) {
202 if (pending_buffer_) { 204 has_pending_contents_ = false;
203 texture_mailbox_release_callback = 205
204 pending_buffer_->AcquireTextureMailbox(&texture_mailbox); 206 current_buffer_ = pending_buffer_;
205 pending_buffer_.reset(); 207 pending_buffer_.reset();
206 has_contents_ = true; 208
207 } else { 209 cc::TextureMailbox texture_mailbox;
208 // Show solid color content if there is no pending buffer. 210 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
209 layer()->SetShowSolidColorContent(); 211 if (current_buffer_) {
210 has_contents_ = false; 212 texture_mailbox_release_callback =
213 current_buffer_->ProduceTextureMailbox(&texture_mailbox);
214 }
215
216 if (texture_mailbox_release_callback) {
217 // Update layer with the new contents.
218 layer()->SetTextureMailbox(texture_mailbox,
219 texture_mailbox_release_callback.Pass(),
220 texture_mailbox.size_in_pixels());
221 layer()->SetTextureFlipped(false);
222 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(),
223 texture_mailbox.size_in_pixels()));
224 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains(
225 gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels()))));
226 } else {
227 // Show solid color content if no buffer is attached or we failed
228 // to produce a texture mailbox for the currently attached buffer.
229 layer()->SetShowSolidColorContent();
230 layer()->SetColor(SK_ColorBLACK);
231 }
232
233 // Schedule redraw of the damage region.
234 layer()->SchedulePaint(pending_damage_);
235 pending_damage_ = gfx::Rect();
211 } 236 }
212 237
213 if (texture_mailbox_release_callback) {
214 // Update layer with the new contents.
215 layer()->SetTextureMailbox(texture_mailbox,
216 texture_mailbox_release_callback.Pass(),
217 texture_mailbox.size_in_pixels());
218 layer()->SetTextureFlipped(false);
219 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(),
220 texture_mailbox.size_in_pixels()));
221 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains(
222 gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels()))));
223 }
224
225 // Schedule redraw of the damage region.
226 layer()->SchedulePaint(pending_damage_);
227 pending_damage_ = gfx::Rect();
228
229 ui::Compositor* compositor = layer()->GetCompositor(); 238 ui::Compositor* compositor = layer()->GetCompositor();
230 if (compositor && !pending_frame_callbacks_.empty()) { 239 if (compositor && !pending_frame_callbacks_.empty()) {
231 // Start observing the compositor for frame callbacks. 240 // Start observing the compositor for frame callbacks.
232 if (!compositor_) { 241 if (!compositor_) {
233 compositor->AddObserver(this); 242 compositor->AddObserver(this);
234 compositor_ = compositor; 243 compositor_ = compositor;
235 } 244 }
236 245
237 // Move pending frame callbacks to the end of |frame_callbacks_|. 246 // Move pending frame callbacks to the end of |frame_callbacks_|.
238 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 247 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 324
316 void Surface::OnCompositingStarted(ui::Compositor* compositor, 325 void Surface::OnCompositingStarted(ui::Compositor* compositor,
317 base::TimeTicks start_time) { 326 base::TimeTicks start_time) {
318 // Run all frame callbacks associated with the compositor's active tree. 327 // Run all frame callbacks associated with the compositor's active tree.
319 while (!active_frame_callbacks_.empty()) { 328 while (!active_frame_callbacks_.empty()) {
320 active_frame_callbacks_.front().Run(start_time); 329 active_frame_callbacks_.front().Run(start_time);
321 active_frame_callbacks_.pop_front(); 330 active_frame_callbacks_.pop_front();
322 } 331 }
323 } 332 }
324 333
334 void Surface::OnCompositingEnded(ui::Compositor* compositor) {
335 // Nothing to do in here unless this has been set.
336 if (!update_contents_after_successful_compositing_)
337 return;
338
339 update_contents_after_successful_compositing_ = false;
340
341 // Early out if no contents is currently assigned to the surface.
342 if (!current_buffer_)
343 return;
344
345 // Update contents by producing a new texture mailbox for the current buffer.
346 cc::TextureMailbox texture_mailbox;
347 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback =
348 current_buffer_->ProduceTextureMailbox(&texture_mailbox);
349 if (texture_mailbox_release_callback) {
350 layer()->SetTextureMailbox(texture_mailbox,
351 texture_mailbox_release_callback.Pass(),
352 texture_mailbox.size_in_pixels());
353 layer()->SetTextureFlipped(false);
354 layer()->SchedulePaint(gfx::Rect(texture_mailbox.size_in_pixels()));
355 }
356 }
357
358 void Surface::OnCompositingAborted(ui::Compositor* compositor) {
359 // The contents of this surface might be lost if compositing aborted because
360 // of a lost graphics context. We recover from this by updating the contents
361 // of the surface next time the compositor successfully ends compositing.
362 update_contents_after_successful_compositing_ = true;
363 }
364
325 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { 365 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) {
326 compositor->RemoveObserver(this); 366 compositor->RemoveObserver(this);
327 compositor_ = nullptr; 367 compositor_ = nullptr;
328 } 368 }
329 369
330 } // namespace exo 370 } // 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