Index: content/browser/renderer_host/compositor_impl_android.cc |
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc |
index a75b5ccacdab4d94023b84af9c43a95457f3cd1f..82d78e7cab860007c049931c2f376983fe15a735 100644 |
--- a/content/browser/renderer_host/compositor_impl_android.cc |
+++ b/content/browser/renderer_host/compositor_impl_android.cc |
@@ -9,6 +9,7 @@ |
#include "base/android/jni_android.h" |
#include "base/android/scoped_java_ref.h" |
+#include "base/auto_reset.h" |
#include "base/bind.h" |
#include "base/cancelable_callback.h" |
#include "base/command_line.h" |
@@ -230,7 +231,6 @@ scoped_ptr<cc::SurfaceIdAllocator> CompositorImpl::CreateSurfaceIdAllocator() { |
CompositorImpl::CompositorImpl(CompositorClient* client, |
gfx::NativeWindow root_window) |
: root_layer_(cc::Layer::Create(Compositor::LayerSettings())), |
- resource_manager_(&ui_resource_provider_), |
surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator() |
: nullptr), |
has_transparent_background_(false), |
@@ -252,6 +252,8 @@ CompositorImpl::CompositorImpl(CompositorClient* client, |
DCHECK(client); |
DCHECK(root_window); |
root_window->AttachCompositor(this); |
+ CreateLayerTreeHost(); |
+ resource_manager_.Init(host_.get()); |
} |
CompositorImpl::~CompositorImpl() { |
@@ -261,6 +263,7 @@ CompositorImpl::~CompositorImpl() { |
} |
void CompositorImpl::PostComposite(CompositingTrigger trigger) { |
+ DCHECK(host_->visible()); |
DCHECK(needs_composite_); |
DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); |
@@ -324,7 +327,7 @@ void CompositorImpl::Composite(CompositingTrigger trigger) { |
if (trigger == COMPOSITE_IMMEDIATELY) |
will_composite_immediately_ = false; |
- DCHECK(host_); |
+ DCHECK(host_->visible()); |
DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); |
DCHECK(needs_composite_); |
DCHECK(!DidCompositeThisFrame()); |
@@ -347,17 +350,13 @@ void CompositorImpl::Composite(CompositingTrigger trigger) { |
current_composite_task_->Cancel(); |
DCHECK(DidCompositeThisFrame() && !WillComposite()); |
- // Ignore ScheduleComposite() from layer tree changes during layout and |
- // animation updates that will already be reflected in the current frame |
- // we are about to draw. |
- ignore_schedule_composite_ = true; |
- |
const base::TimeTicks frame_time = base::TimeTicks::Now(); |
if (needs_animate_) { |
+ base::AutoReset<bool> auto_reset_ignore_schedule( |
+ &ignore_schedule_composite_, true); |
needs_animate_ = false; |
root_window_->Animate(frame_time); |
} |
- ignore_schedule_composite_ = false; |
did_post_swapbuffers_ = false; |
host_->Composite(frame_time); |
@@ -369,7 +368,7 @@ void CompositorImpl::Composite(CompositingTrigger trigger) { |
} |
ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() { |
- return ui_resource_provider_; |
+ return *this; |
} |
ui::ResourceManager& CompositorImpl::GetResourceManager() { |
@@ -440,8 +439,13 @@ void CompositorImpl::SetSurface(jobject surface) { |
void CompositorImpl::CreateLayerTreeHost() { |
DCHECK(!host_); |
DCHECK(!WillCompositeThisFrame()); |
- needs_composite_ = false; |
- pending_swapbuffers_ = 0; |
+ |
+ // Just in case, since we immediately hide the LTH in this function, |
+ // and we do not want to end up with a pending Composite task when the |
+ // host is hidden. |
+ base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_, |
+ true); |
+ |
cc::LayerTreeSettings settings; |
settings.renderer_settings.refresh_rate = 60.0; |
settings.renderer_settings.allow_antialiasing = false; |
@@ -468,9 +472,8 @@ void CompositorImpl::CreateLayerTreeHost() { |
params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
params.settings = &settings; |
host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); |
+ host_->SetVisible(false); |
host_->SetRootLayer(root_layer_); |
- |
- host_->SetVisible(true); |
host_->SetLayerTreeHostClientReady(); |
host_->SetViewportSize(size_); |
host_->set_has_transparent_background(has_transparent_background_); |
@@ -483,7 +486,7 @@ void CompositorImpl::CreateLayerTreeHost() { |
void CompositorImpl::SetVisible(bool visible) { |
TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible); |
if (!visible) { |
- DCHECK(host_); |
+ DCHECK(host_->visible()); |
// Look for any layers that were attached to the root for readback |
// and are waiting for Composite() to happen. |
bool readback_pending = false; |
@@ -494,24 +497,29 @@ void CompositorImpl::SetVisible(bool visible) { |
} |
} |
if (readback_pending) { |
- ignore_schedule_composite_ = true; |
+ base::AutoReset<bool> auto_reset_ignore_schedule( |
+ &ignore_schedule_composite_, true); |
host_->Composite(base::TimeTicks::Now()); |
- ignore_schedule_composite_ = false; |
} |
if (WillComposite()) |
CancelComposite(); |
- ui_resource_provider_.SetLayerTreeHost(NULL); |
- host_.reset(); |
+ host_->SetVisible(false); |
+ if (!host_->output_surface_lost()) |
+ host_->ReleaseOutputSurface(); |
+ pending_swapbuffers_ = 0; |
+ needs_composite_ = false; |
+ composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; |
establish_gpu_channel_timeout_.Stop(); |
- output_surface_request_pending_ = false; |
display_client_.reset(); |
if (current_composite_task_) { |
current_composite_task_->Cancel(); |
current_composite_task_.reset(); |
} |
- } else if (!host_) { |
- CreateLayerTreeHost(); |
- ui_resource_provider_.SetLayerTreeHost(host_.get()); |
+ } else { |
+ host_->SetVisible(true); |
+ if (output_surface_request_pending_) |
+ RequestNewOutputSurface(); |
+ SetNeedsComposite(); |
} |
} |
@@ -540,7 +548,7 @@ void CompositorImpl::SetHasTransparentBackground(bool flag) { |
} |
void CompositorImpl::SetNeedsComposite() { |
- if (!host_.get()) |
+ if (!host_->visible()) |
return; |
DCHECK(!needs_composite_ || WillComposite()); |
@@ -579,9 +587,9 @@ CreateGpuProcessViewContext( |
} |
void CompositorImpl::Layout() { |
- ignore_schedule_composite_ = true; |
+ base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_, |
+ true); |
client_->Layout(); |
- ignore_schedule_composite_ = false; |
} |
void CompositorImpl::OnGpuChannelEstablished() { |
@@ -633,8 +641,9 @@ void CompositorImpl::DidFailToInitializeOutputSurface() { |
void CompositorImpl::CreateOutputSurface() { |
// We might have had a request from a LayerTreeHost that was then |
- // deleted. |
- if (!output_surface_request_pending_) |
+ // hidden (and hidden means we don't have a native surface). |
+ // Also make sure we only handle this once. |
+ if (!output_surface_request_pending_ || !host_->visible()) |
return; |
blink::WebGraphicsContext3D::Attributes attrs; |
@@ -686,8 +695,7 @@ void CompositorImpl::CreateOutputSurface() { |
void CompositorImpl::PopulateGpuCapabilities( |
gpu::Capabilities gpu_capabilities) { |
- ui_resource_provider_.SetSupportsETC1NonPowerOfTwo( |
- gpu_capabilities.texture_format_etc1_npot); |
+ gpu_capabilities_ = gpu_capabilities; |
} |
void CompositorImpl::AddObserver(VSyncObserver* observer) { |
@@ -698,11 +706,24 @@ void CompositorImpl::RemoveObserver(VSyncObserver* observer) { |
observer_list_.RemoveObserver(observer); |
} |
+cc::UIResourceId CompositorImpl::CreateUIResource( |
+ cc::UIResourceClient* client) { |
+ return host_->CreateUIResource(client); |
+} |
+ |
+void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { |
+ host_->DeleteUIResource(resource_id); |
+} |
+ |
+bool CompositorImpl::SupportsETC1NonPowerOfTwo() const { |
+ return gpu_capabilities_.texture_format_etc1_npot; |
+} |
+ |
void CompositorImpl::ScheduleComposite() { |
- DCHECK(!needs_composite_ || WillComposite()); |
- if (ignore_schedule_composite_) |
+ if (ignore_schedule_composite_ || !host_->visible()) |
return; |
+ DCHECK_IMPLIES(needs_composite_, WillComposite()); |
needs_composite_ = true; |
// We currently expect layer tree invalidations at most once per frame |
// during normal operation and therefore try to composite immediately |
@@ -711,12 +732,16 @@ void CompositorImpl::ScheduleComposite() { |
} |
void CompositorImpl::ScheduleAnimation() { |
- DCHECK(!needs_composite_ || WillComposite()); |
needs_animate_ = true; |
- if (needs_composite_) |
+ if (!host_->visible()) |
return; |
+ if (needs_composite_) { |
+ DCHECK(WillComposite()); |
+ return; |
+ } |
+ |
TRACE_EVENT0("cc", "CompositorImpl::ScheduleAnimation"); |
needs_composite_ = true; |
PostComposite(COMPOSITE_EVENTUALLY); |
@@ -785,7 +810,7 @@ void CompositorImpl::OnVSync(base::TimeTicks frame_time, |
void CompositorImpl::SetNeedsAnimate() { |
needs_animate_ = true; |
- if (!host_) |
+ if (!host_->visible()) |
return; |
host_->SetNeedsAnimate(); |