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

Side by Side Diff: content/browser/web_contents/aura/overscroll_navigation_overlay.cc

Issue 278173005: Removing listening for repaints (OnUpdateRect) from OverscrollNavigationOverlay. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding load listening back to support in-page navigations properly. Created 6 years, 7 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/web_contents/aura/overscroll_navigation_overlay.h" 5 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
6 6
7 #include "content/browser/frame_host/navigation_entry_impl.h" 7 #include "content/browser/frame_host/navigation_entry_impl.h"
8 #include "content/browser/renderer_host/render_view_host_impl.h" 8 #include "content/browser/renderer_host/render_view_host_impl.h"
9 #include "content/browser/web_contents/aura/image_window_delegate.h" 9 #include "content/browser/web_contents/aura/image_window_delegate.h"
10 #include "content/browser/web_contents/web_contents_impl.h" 10 #include "content/browser/web_contents/web_contents_impl.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator); 108 DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator);
109 }; 109 };
110 110
111 OverscrollNavigationOverlay::OverscrollNavigationOverlay( 111 OverscrollNavigationOverlay::OverscrollNavigationOverlay(
112 WebContentsImpl* web_contents) 112 WebContentsImpl* web_contents)
113 : web_contents_(web_contents), 113 : web_contents_(web_contents),
114 image_delegate_(NULL), 114 image_delegate_(NULL),
115 loading_complete_(false), 115 loading_complete_(false),
116 received_paint_update_(false), 116 received_paint_update_(false),
117 pending_entry_id_(0), 117 pending_entry_id_(0),
118 slide_direction_(SLIDE_UNKNOWN), 118 slide_direction_(SLIDE_UNKNOWN) {
119 need_paint_update_(true) {
120 } 119 }
121 120
122 OverscrollNavigationOverlay::~OverscrollNavigationOverlay() { 121 OverscrollNavigationOverlay::~OverscrollNavigationOverlay() {
123 } 122 }
124 123
125 void OverscrollNavigationOverlay::StartObserving() { 124 void OverscrollNavigationOverlay::StartObserving() {
126 loading_complete_ = false; 125 loading_complete_ = false;
127 received_paint_update_ = false; 126 received_paint_update_ = false;
127 overlay_dismiss_layer_.reset();
128 pending_entry_id_ = 0; 128 pending_entry_id_ = 0;
129 Observe(web_contents_); 129 Observe(web_contents_);
130 130
131 // Make sure the overlay window is on top. 131 // Make sure the overlay window is on top.
132 if (window_.get() && window_->parent()) 132 if (window_.get() && window_->parent())
133 window_->parent()->StackChildAtTop(window_.get()); 133 window_->parent()->StackChildAtTop(window_.get());
134 134
135 // Assumes the navigation has been initiated. 135 // Assumes the navigation has been initiated.
136 NavigationEntry* pending_entry = 136 NavigationEntry* pending_entry =
137 web_contents_->GetController().GetPendingEntry(); 137 web_contents_->GetController().GetPendingEntry();
(...skipping 14 matching lines...) Expand all
152 if (window_.get() && delegate->has_image()) { 152 if (window_.get() && delegate->has_image()) {
153 window_slider_.reset(new WindowSlider(this, 153 window_slider_.reset(new WindowSlider(this,
154 window_->parent(), 154 window_->parent(),
155 window_.get())); 155 window_.get()));
156 slide_direction_ = SLIDE_UNKNOWN; 156 slide_direction_ = SLIDE_UNKNOWN;
157 } else { 157 } else {
158 window_slider_.reset(); 158 window_slider_.reset();
159 } 159 }
160 } 160 }
161 161
162 void OverscrollNavigationOverlay::SetupForTesting() {
163 need_paint_update_ = false;
164 }
165
166 void OverscrollNavigationOverlay::StopObservingIfDone() { 162 void OverscrollNavigationOverlay::StopObservingIfDone() {
167 if ((need_paint_update_ && !received_paint_update_)) { 163 // Normally we dismiss the overlay once we receive a paint update, however
164 // for in-page navigations DidFirstVisuallyNonEmptyPaint() does not get
165 // called, and we rely on loading_complete_ for those cases.
166 if (!received_paint_update_ && !loading_complete_)
168 return; 167 return;
169 }
170 168
171 // If a slide is in progress, then do not destroy the window or the slide. 169 // If a slide is in progress, then do not destroy the window or the slide.
172 if (window_slider_.get() && window_slider_->IsSlideInProgress()) 170 if (window_slider_.get() && window_slider_->IsSlideInProgress())
173 return; 171 return;
174 172
175 scoped_ptr<ui::Layer> layer; 173 // The layer to be animated by OverlayDismissAnimator
176 if (window_.get()) 174 scoped_ptr<ui::Layer> overlay_dismiss_layer;
177 layer = window_->AcquireLayer(); 175 if (overlay_dismiss_layer_)
176 overlay_dismiss_layer = overlay_dismiss_layer_.Pass();
sadrul 2014/05/27 16:48:29 Does this work correctly? From what I can see, |o
mfomitchev 2014/05/27 21:21:05 It works. In this case overlay_dismiss_layer_ is t
177 else if (window_.get())
178 overlay_dismiss_layer = window_->AcquireLayer();
178 Observe(NULL); 179 Observe(NULL);
179 window_slider_.reset(); 180 window_slider_.reset();
180 window_.reset(); 181 window_.reset();
181 image_delegate_ = NULL; 182 image_delegate_ = NULL;
182 if (layer.get()) { 183 if (overlay_dismiss_layer.get()) {
183 // OverlayDismissAnimator deletes the layer and itself when the animation 184 // OverlayDismissAnimator deletes overlay_dismiss_layer and itself when the
184 // completes. 185 // animation completes.
185 (new OverlayDismissAnimator(layer.Pass()))->Animate(); 186 (new OverlayDismissAnimator(overlay_dismiss_layer.Pass()))->Animate();
186 } 187 }
187 } 188 }
188 189
189 ui::Layer* OverscrollNavigationOverlay::CreateSlideLayer(int offset) { 190 ui::Layer* OverscrollNavigationOverlay::CreateSlideLayer(int offset) {
190 const NavigationControllerImpl& controller = web_contents_->GetController(); 191 const NavigationControllerImpl& controller = web_contents_->GetController();
191 const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( 192 const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
192 controller.GetEntryAtOffset(offset)); 193 controller.GetEntryAtOffset(offset));
193 194
194 gfx::Image image; 195 gfx::Image image;
195 if (entry && entry->screenshot().get()) { 196 if (entry && entry->screenshot().get()) {
196 std::vector<gfx::ImagePNGRep> image_reps; 197 std::vector<gfx::ImagePNGRep> image_reps;
197 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 198 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
198 ui::GetImageScale( 199 ui::GetImageScale(
199 ui::GetScaleFactorForNativeView(window_.get())))); 200 ui::GetScaleFactorForNativeView(window_.get()))));
200 image = gfx::Image(image_reps); 201 image = gfx::Image(image_reps);
201 } 202 }
202 if (!layer_delegate_) 203 if (!layer_delegate_)
203 layer_delegate_.reset(new ImageLayerDelegate()); 204 layer_delegate_.reset(new ImageLayerDelegate());
204 layer_delegate_->SetImage(image); 205 layer_delegate_->SetImage(image);
205 206
206 ui::Layer* layer = new ui::Layer(ui::LAYER_TEXTURED); 207 ui::Layer* layer = new ui::Layer(ui::LAYER_TEXTURED);
207 layer->set_delegate(layer_delegate_.get()); 208 layer->set_delegate(layer_delegate_.get());
208 return layer; 209 return layer;
209 } 210 }
210 211
211 void OverscrollNavigationOverlay::OnUpdateRect(
212 const ViewHostMsg_UpdateRect_Params& params) {
213 if (loading_complete_ &&
214 ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags)) {
215 NavigationEntry* visible_entry =
216 web_contents_->GetController().GetVisibleEntry();
217 int visible_entry_id = visible_entry ? visible_entry->GetUniqueID() : 0;
218 if (visible_entry_id == pending_entry_id_ || !pending_entry_id_) {
219 // This is a paint update after the page has been loaded. So do not wait
220 // for a 'first non-empty' paint update.
221 received_paint_update_ = true;
222 StopObservingIfDone();
223 }
224 }
225 }
226
227 ui::Layer* OverscrollNavigationOverlay::CreateBackLayer() { 212 ui::Layer* OverscrollNavigationOverlay::CreateBackLayer() {
228 if (!web_contents_->GetController().CanGoBack()) 213 if (!web_contents_->GetController().CanGoBack())
229 return NULL; 214 return NULL;
230 slide_direction_ = SLIDE_BACK; 215 slide_direction_ = SLIDE_BACK;
231 return CreateSlideLayer(-1); 216 return CreateSlideLayer(-1);
232 } 217 }
233 218
234 ui::Layer* OverscrollNavigationOverlay::CreateFrontLayer() { 219 ui::Layer* OverscrollNavigationOverlay::CreateFrontLayer() {
235 if (!web_contents_->GetController().CanGoForward()) 220 if (!web_contents_->GetController().CanGoForward())
236 return NULL; 221 return NULL;
(...skipping 11 matching lines...) Expand all
248 else if (slide_direction_ == SLIDE_FRONT) 233 else if (slide_direction_ == SLIDE_FRONT)
249 web_contents_->GetController().GoForward(); 234 web_contents_->GetController().GoForward();
250 else 235 else
251 NOTREACHED(); 236 NOTREACHED();
252 237
253 // Reset state and wait for the new navigation page to complete 238 // Reset state and wait for the new navigation page to complete
254 // loading/painting. 239 // loading/painting.
255 StartObserving(); 240 StartObserving();
256 } 241 }
257 242
258 void OverscrollNavigationOverlay::OnWindowSlideCompleted() { 243 void OverscrollNavigationOverlay::OnWindowSlideCompleted(
244 scoped_ptr<ui::Layer> layer) {
259 if (slide_direction_ == SLIDE_UNKNOWN) { 245 if (slide_direction_ == SLIDE_UNKNOWN) {
260 window_slider_.reset(); 246 window_slider_.reset();
261 StopObservingIfDone(); 247 StopObservingIfDone();
262 return; 248 return;
263 } 249 }
264 250
265 // Change the image used for the overlay window. 251 // Change the image used for the overlay window.
266 image_delegate_->SetImage(layer_delegate_->image()); 252 image_delegate_->SetImage(layer_delegate_->image());
267 window_->layer()->SetTransform(gfx::Transform()); 253 window_->layer()->SetTransform(gfx::Transform());
268 window_->SchedulePaintInRect(gfx::Rect(window_->bounds().size())); 254 window_->SchedulePaintInRect(gfx::Rect(window_->bounds().size()));
269 slide_direction_ = SLIDE_UNKNOWN; 255 slide_direction_ = SLIDE_UNKNOWN;
270 256 // We may end up dismissing the overlay before it has a chance to repaint, so
271 // Make sure the overlay layer is repainted before we dismiss it, otherwise 257 // set the slider layer to be the one animated by OverlayDismissAnimator.
272 // OverlayDismissAnimator may end up showing the wrong screenshot during the 258 if (layer.get())
273 // fadeout animation. 259 overlay_dismiss_layer_ = layer.Pass();
274 if (received_paint_update_ && need_paint_update_) { 260 StopObservingIfDone();
275 received_paint_update_ = false;
276 RenderWidgetHost* host =
277 web_contents_->GetRenderWidgetHostView()->GetRenderWidgetHost();
278 RenderViewHostImpl* view_host =
279 static_cast<RenderViewHostImpl*> (RenderViewHost::From(host));
280 view_host->ScheduleComposite();
281 } else if (!need_paint_update_) {
282 StopObservingIfDone();
283 }
284 } 261 }
285 262
286 void OverscrollNavigationOverlay::OnWindowSlideAborted() { 263 void OverscrollNavigationOverlay::OnWindowSlideAborted() {
287 StopObservingIfDone(); 264 StopObservingIfDone();
288 } 265 }
289 266
290 void OverscrollNavigationOverlay::OnWindowSliderDestroyed() { 267 void OverscrollNavigationOverlay::OnWindowSliderDestroyed() {
291 // We only want to take an action here if WindowSlider is being destroyed 268 // We only want to take an action here if WindowSlider is being destroyed
292 // outside of OverscrollNavigationOverlay. If window_slider_.get() is NULL, 269 // outside of OverscrollNavigationOverlay. If window_slider_.get() is NULL,
293 // then OverscrollNavigationOverlay is the one destroying WindowSlider, and 270 // then OverscrollNavigationOverlay is the one destroying WindowSlider, and
294 // we don't need to do anything. 271 // we don't need to do anything.
295 // This check prevents StopObservingIfDone() being called multiple times 272 // This check prevents StopObservingIfDone() being called multiple times
296 // (including recursively) for a single event. 273 // (including recursively) for a single event.
297 if (window_slider_.get()) { 274 if (window_slider_.get()) {
298 // The slider has just been destroyed. Release the ownership. 275 // The slider has just been destroyed. Release the ownership.
299 WindowSlider* slider ALLOW_UNUSED = window_slider_.release(); 276 WindowSlider* slider ALLOW_UNUSED = window_slider_.release();
300 StopObservingIfDone(); 277 StopObservingIfDone();
301 } 278 }
302 } 279 }
303 280
304 void OverscrollNavigationOverlay::DocumentOnLoadCompletedInMainFrame() {
sadrul 2014/05/27 16:48:29 This is related to document loading. Why are we re
mfomitchev 2014/05/27 21:21:05 It was helping dismiss the page sooner when we req
305 // Use the last committed entry rather than the active one, in case a
306 // pending entry has been created.
307 int committed_entry_id =
308 web_contents_->GetController().GetLastCommittedEntry()->GetUniqueID();
309 // Consider the loading completed once the main frame has loaded.
310 if (committed_entry_id == pending_entry_id_ || !pending_entry_id_) {
311 loading_complete_ = true;
312 StopObservingIfDone();
313 }
314 }
315
316 void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() { 281 void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() {
317 int visible_entry_id = 282 int visible_entry_id =
318 web_contents_->GetController().GetVisibleEntry()->GetUniqueID(); 283 web_contents_->GetController().GetVisibleEntry()->GetUniqueID();
319 if (visible_entry_id == pending_entry_id_ || !pending_entry_id_) { 284 if (visible_entry_id == pending_entry_id_ || !pending_entry_id_) {
320 received_paint_update_ = true; 285 received_paint_update_ = true;
321 StopObservingIfDone(); 286 StopObservingIfDone();
322 } 287 }
323 } 288 }
324 289
325 void OverscrollNavigationOverlay::DidStopLoading(RenderViewHost* host) { 290 void OverscrollNavigationOverlay::DidStopLoading(RenderViewHost* host) {
326 // Use the last committed entry rather than the active one, in case a 291 // Use the last committed entry rather than the active one, in case a
327 // pending entry has been created. 292 // pending entry has been created.
328 int committed_entry_id = 293 int committed_entry_id =
329 web_contents_->GetController().GetLastCommittedEntry()->GetUniqueID(); 294 web_contents_->GetController().GetLastCommittedEntry()->GetUniqueID();
330 if (committed_entry_id == pending_entry_id_ || !pending_entry_id_) { 295 if (committed_entry_id == pending_entry_id_ || !pending_entry_id_) {
331 loading_complete_ = true; 296 loading_complete_ = true;
332 if (!received_paint_update_ && need_paint_update_) {
333 // Force a repaint after the page is loaded.
334 RenderViewHostImpl* view = static_cast<RenderViewHostImpl*>(host);
335 view->ScheduleComposite();
336 }
337 StopObservingIfDone(); 297 StopObservingIfDone();
338 } 298 }
339 } 299 }
340 300
341 bool OverscrollNavigationOverlay::OnMessageReceived(
342 const IPC::Message& message) {
343 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
344 IPC_BEGIN_MESSAGE_MAP(OverscrollNavigationOverlay, message)
345 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
346 IPC_END_MESSAGE_MAP()
347 return false;
348 }
349
350 } // namespace content 301 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698