Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_android.cc |
| diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc |
| index fdc7810375eb907c8fe2b6decebddd50447fc996..01429b5f6ef6a1bb7706f9bb046ec5ffb8c347d4 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_android.cc |
| +++ b/content/browser/renderer_host/render_widget_host_view_android.cc |
| @@ -147,7 +147,8 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( |
| using_delegated_renderer_(CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnableDelegatedRenderer) && |
| !CommandLine::ForCurrentProcess()->HasSwitch( |
| - switches::kDisableDelegatedRenderer)) { |
| + switches::kDisableDelegatedRenderer)), |
| + locks_on_frame_count_(0) { |
| if (!using_delegated_renderer_) { |
| texture_layer_ = cc::TextureLayer::Create(NULL); |
| layer_ = texture_layer_; |
| @@ -285,6 +286,9 @@ bool RenderWidgetHostViewAndroid::HasValidFrame() const { |
| if (texture_size_in_layer_.IsEmpty()) |
| return false; |
| + if (!frame_evictor_->HasFrame()) |
| + return false; |
| + |
| if (using_delegated_renderer_) { |
| if (!delegated_renderer_layer_.get()) |
| return false; |
| @@ -375,16 +379,37 @@ bool RenderWidgetHostViewAndroid::IsShowing() { |
| return is_showing_ && content_view_core_; |
| } |
| -void RenderWidgetHostViewAndroid::LockResources() { |
| +void RenderWidgetHostViewAndroid::LockSurfaceForCopy() { |
| DCHECK(HasValidFrame()); |
| DCHECK(host_); |
| - DCHECK(!host_->is_hidden()); |
| + DCHECK(frame_evictor_->HasFrame()); |
| frame_evictor_->LockFrame(); |
| + locks_on_frame_count_++; |
| } |
| -void RenderWidgetHostViewAndroid::UnlockResources() { |
| +void RenderWidgetHostViewAndroid::UnlockSurfaceForCopy() { |
| + if (!frame_evictor_->HasFrame() || locks_on_frame_count_ == 0) |
| + return; |
| + |
| DCHECK(HasValidFrame()); |
| frame_evictor_->UnlockFrame(); |
| + locks_on_frame_count_--; |
| + |
| + if (locks_on_frame_count_ == 0 && last_frame_info_) { |
| + InternalSwapCompositorFrame(last_frame_info_->output_surface_id, |
| + last_frame_info_->frame.Pass()); |
| + last_frame_info_.reset(); |
| + } |
| +} |
| + |
| +void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() { |
| + if (!frame_evictor_->HasFrame()) { |
| + DCHECK_EQ(locks_on_frame_count_, 0u); |
| + return; |
| + } |
| + while (locks_on_frame_count_ > 0) { |
| + UnlockSurfaceForCopy(); |
| + } |
| } |
| gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const { |
| @@ -771,9 +796,15 @@ void RenderWidgetHostViewAndroid::ComputeContentsSize( |
| UpdateAnimationSize(frame_metadata); |
| } |
| -void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( |
| +void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame( |
| uint32 output_surface_id, |
| scoped_ptr<cc::CompositorFrame> frame) { |
| + if (locks_on_frame_count_ > 0) { |
| + DCHECK(HasValidFrame()); |
| + RetainFrame(output_surface_id, frame.Pass()); |
| + return; |
| + } |
| + |
| // Always let ContentViewCore know about the new frame first, so it can decide |
| // to schedule a Draw immediately when it sees the texture layer invalidation. |
| UpdateContentViewCoreFrameMetadata(frame->metadata); |
| @@ -828,6 +859,34 @@ void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( |
| frame_evictor_->SwappedFrame(!host_->is_hidden()); |
| } |
| +void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( |
| + uint32 output_surface_id, |
| + scoped_ptr<cc::CompositorFrame> frame) { |
| + InternalSwapCompositorFrame(output_surface_id, frame.Pass()); |
| +} |
| + |
| +void RenderWidgetHostViewAndroid::RetainFrame( |
| + uint32 output_surface_id, |
| + scoped_ptr<cc::CompositorFrame> frame) { |
| + DCHECK(locks_on_frame_count_); |
| + |
| + // Store the incoming frame so that it can be swapped when all the locks have |
| + // been released. If there is already a stored frame, then send |
|
no sievers
2014/03/18 23:44:07
nit: extra space
powei
2014/03/19 17:50:42
Done.
|
| + // acknowledgement and drop it. |
| + if (last_frame_info_) { |
| + base::Closure ack_callback = |
| + base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + last_frame_info_->output_surface_id); |
| + if (host_->is_hidden()) |
| + ack_callback.Run(); |
|
no sievers
2014/03/18 23:44:07
The code does actually not match the comment above
powei
2014/03/19 17:50:42
Done.
|
| + else |
| + ack_callbacks_.push(ack_callback); |
| + } |
| + |
| + last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass())); |
| +} |
| + |
| void RenderWidgetHostViewAndroid::SynchronousFrameMetadata( |
| const cc::CompositorFrameMetadata& frame_metadata) { |
| // This is a subset of OnSwapCompositorFrame() used in the synchronous |
| @@ -1244,6 +1303,9 @@ void RenderWidgetHostViewAndroid::SetContentViewCore( |
| if (content_view_core_ && !using_synchronous_compositor_) |
| content_view_core_->GetWindowAndroid()->RemoveObserver(this); |
| + if (content_view_core != content_view_core_) |
| + ReleaseLocksOnSurface(); |
| + |
| content_view_core_ = content_view_core; |
| if (GetBrowserAccessibilityManager()) { |
| @@ -1277,6 +1339,7 @@ void RenderWidgetHostViewAndroid::OnDetachCompositor() { |
| } |
| void RenderWidgetHostViewAndroid::OnLostResources() { |
| + ReleaseLocksOnSurface(); |
| if (texture_layer_.get()) |
| texture_layer_->SetIsDrawable(false); |
| if (delegated_renderer_layer_.get()) |