Index: content/browser/renderer_host/delegated_frame_host.cc |
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc |
index 3ea311ce025522466402e7eb7e7258f9aaf67485..3289064241aadbdc3d523d86166ed67a651eccac 100644 |
--- a/content/browser/renderer_host/delegated_frame_host.cc |
+++ b/content/browser/renderer_host/delegated_frame_host.cc |
@@ -11,6 +11,7 @@ |
#include "base/callback_helpers.h" |
#include "base/command_line.h" |
+#include "base/debug/stack_trace.h" |
#include "base/memory/ptr_util.h" |
#include "base/time/default_tick_clock.h" |
#include "cc/output/compositor_frame.h" |
@@ -70,14 +71,17 @@ DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) |
pending_delegated_ack_count_(0), |
skipped_frames_(false), |
background_color_(SK_ColorRED), |
+ surface_client_id_(0), |
current_scale_factor_(1.f), |
can_lock_compositor_(YES_CAN_LOCK), |
delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
+ ImageTransportFactory* context_factory = ImageTransportFactory::GetInstance(); |
+ context_factory->GetContextFactory()->AddObserver(this); |
ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
- factory->GetContextFactory()->AddObserver(this); |
- id_allocator_ = factory->GetContextFactory()->CreateSurfaceIdAllocator(); |
- factory->GetSurfaceManager()->RegisterSurfaceFactoryClient( |
- id_allocator_->client_id(), this); |
+ cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
+ surface_client_id_ = factory->GetContextFactory()->AllocateSurfaceClientId(); |
+ surface_factory_ = base::WrapUnique( |
+ new cc::SurfaceFactory(surface_client_id_, manager, this)); |
} |
void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { |
@@ -204,7 +208,7 @@ void DelegatedFrameHost::EndFrameSubscription() { |
} |
uint32_t DelegatedFrameHost::GetSurfaceClientId() { |
- return id_allocator_->client_id(); |
+ return surface_client_id_; |
} |
cc::SurfaceId DelegatedFrameHost::SurfaceIdAtPoint( |
@@ -372,7 +376,7 @@ void DelegatedFrameHost::AttemptFrameSubscriberCapture( |
subscriber_texture->target())); |
} |
- if (surface_factory_.get()) { |
+ if (surface_factory_) { |
// To avoid unnecessary composites, go directly to the Surface rather than |
// through RequestCopyOfOutput (which goes through the browser |
// compositor). |
@@ -387,6 +391,7 @@ void DelegatedFrameHost::AttemptFrameSubscriberCapture( |
} |
void DelegatedFrameHost::SwapDelegatedFrame(uint32_t output_surface_id, |
+ const cc::SurfaceId& surface_id, |
cc::CompositorFrame frame) { |
DCHECK(frame.delegated_frame_data.get()); |
#if defined(OS_CHROMEOS) |
@@ -434,6 +439,10 @@ void DelegatedFrameHost::SwapDelegatedFrame(uint32_t output_surface_id, |
} |
if (output_surface_id != last_output_surface_id_) { |
+ // The surface_id should change if we have a new output surface. If it |
+ // hasn't then the client is misbehaving and we should just ignore the swap. |
+ if (surface_id_ == surface_id) |
+ return; |
// Resource ids are scoped by the output surface. |
// If the originating output surface doesn't match the last one, it |
// indicates the renderer's output surface may have been recreated, in which |
@@ -443,7 +452,6 @@ void DelegatedFrameHost::SwapDelegatedFrame(uint32_t output_surface_id, |
// the DelegatedRendererLayer. |
EvictDelegatedFrame(); |
- surface_factory_.reset(); |
if (!surface_returned_resources_.empty()) { |
SendReclaimCompositorResources(last_output_surface_id_, |
false /* is_swap_ack */); |
@@ -461,23 +469,18 @@ void DelegatedFrameHost::SwapDelegatedFrame(uint32_t output_surface_id, |
} else { |
ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
- if (!surface_factory_) { |
- surface_factory_ = |
- base::WrapUnique(new cc::SurfaceFactory(manager, this)); |
- } |
- if (surface_id_.is_null() || frame_size != current_surface_size_ || |
- frame_size_in_dip != current_frame_size_in_dip_) { |
+ |
+ if (surface_id_ != surface_id) { |
if (!surface_id_.is_null()) |
surface_factory_->Destroy(surface_id_); |
- surface_id_ = id_allocator_->GenerateId(); |
+ surface_id_ = cc::SurfaceId(surface_client_id_, surface_id.local_id(), |
+ surface_id.nonce()); |
surface_factory_->Create(surface_id_); |
// manager must outlive compositors using it. |
client_->DelegatedFrameHostGetLayer()->SetShowSurface( |
surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), |
base::Bind(&RequireCallback, base::Unretained(manager)), frame_size, |
frame_device_scale_factor, frame_size_in_dip); |
- current_surface_size_ = frame_size; |
- current_scale_factor_ = frame_device_scale_factor; |
} |
frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), |
@@ -577,6 +580,15 @@ void DelegatedFrameHost::EvictDelegatedFrame() { |
if (!surface_id_.is_null()) { |
surface_factory_->Destroy(surface_id_); |
surface_id_ = cc::SurfaceId(); |
+ |
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
+ surface_client_id_ = |
+ factory->GetContextFactory()->AllocateSurfaceClientId(); |
+ cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
+ uint32_t parent = surface_factory_->parent_client_id(); |
+ surface_factory_.reset( |
+ new cc::SurfaceFactory(surface_client_id_, manager, this)); |
+ surface_factory_->SetParent(parent); |
} |
delegated_frame_evictor_->DiscardedFrame(); |
UpdateGutters(); |
@@ -747,6 +759,11 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo( |
//////////////////////////////////////////////////////////////////////////////// |
// DelegatedFrameHost, ui::CompositorObserver implementation: |
+void DelegatedFrameHost::OnCompositingInitialized(ui::Compositor* compositor) { |
+ uint32_t parent = compositor->surface_id_allocator()->client_id(); |
+ surface_factory_->SetParent(parent); |
+} |
+ |
void DelegatedFrameHost::OnCompositingDidCommit(ui::Compositor* compositor) { |
if (can_lock_compositor_ == NO_PENDING_COMMIT) { |
can_lock_compositor_ = YES_CAN_LOCK; |
@@ -817,8 +834,6 @@ DelegatedFrameHost::~DelegatedFrameHost() { |
if (!surface_id_.is_null()) |
surface_factory_->Destroy(surface_id_); |
- factory->GetSurfaceManager()->UnregisterSurfaceFactoryClient( |
- id_allocator_->client_id()); |
DCHECK(!vsync_manager_.get()); |
} |
@@ -833,10 +848,10 @@ void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { |
vsync_manager_ = compositor_->vsync_manager(); |
vsync_manager_->AddObserver(this); |
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
- uint32_t parent = compositor->surface_id_allocator()->client_id(); |
- factory->GetSurfaceManager()->RegisterSurfaceNamespaceHierarchy( |
- parent, id_allocator_->client_id()); |
+ if (compositor->initialized()) { |
+ uint32_t parent = compositor->surface_id_allocator()->client_id(); |
+ surface_factory_->SetParent(parent); |
+ } |
} |
void DelegatedFrameHost::ResetCompositor() { |
@@ -853,10 +868,7 @@ void DelegatedFrameHost::ResetCompositor() { |
vsync_manager_ = NULL; |
} |
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
- uint32_t parent = compositor_->surface_id_allocator()->client_id(); |
- factory->GetSurfaceManager()->UnregisterSurfaceNamespaceHierarchy( |
- parent, id_allocator_->client_id()); |
+ surface_factory_->SetParent(0); |
compositor_ = nullptr; |
} |