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

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

Powered by Google App Engine
This is Rietveld 408576698