Index: content/browser/renderer_host/render_widget_host_view_aura.cc |
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc |
index f8565eee8930390b9190a23eae09d3e897e4b935..e2eaf25573ea54a6f776b00e5fc4e2fb9c91cf5a 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc |
@@ -256,11 +256,6 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host) |
can_compose_inline_(true), |
has_composition_text_(false), |
device_scale_factor_(1.0f), |
- current_surface_(0), |
- current_surface_is_protected_(true), |
- current_surface_in_use_by_compositor_(true), |
- protection_state_id_(0), |
- surface_route_id_(0), |
paint_canvas_(NULL), |
synthetic_move_sent_(false), |
accelerated_compositing_state_changed_(false) { |
@@ -346,8 +341,6 @@ void RenderWidgetHostViewAura::WasShown() { |
released_front_lock_ = window_->GetRootWindow()->GetCompositorLock(); |
} |
- AdjustSurfaceProtection(); |
- |
#if defined(OS_WIN) |
LPARAM lparam = reinterpret_cast<LPARAM>(this); |
EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam); |
@@ -361,14 +354,6 @@ void RenderWidgetHostViewAura::WasHidden() { |
released_front_lock_ = NULL; |
- if (ShouldReleaseFrontSurface() && |
- host_->is_accelerated_compositing_active()) { |
- current_surface_ = 0; |
- UpdateExternalTexture(); |
- } |
- |
- AdjustSurfaceProtection(); |
- |
#if defined(OS_WIN) |
aura::RootWindow* root_window = window_->GetRootWindow(); |
if (root_window) { |
@@ -476,7 +461,7 @@ bool RenderWidgetHostViewAura::HasFocus() const { |
} |
bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const { |
- return current_surface_ != 0 || !!host_->GetBackingStore(false); |
+ return current_surface_ || !!host_->GetBackingStore(false); |
} |
void RenderWidgetHostViewAura::Show() { |
@@ -534,8 +519,10 @@ void RenderWidgetHostViewAura::ImeCompositionRangeChanged( |
void RenderWidgetHostViewAura::DidUpdateBackingStore( |
const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, |
const std::vector<gfx::Rect>& copy_rects) { |
- if (accelerated_compositing_state_changed_) |
+ if (accelerated_compositing_state_changed_) { |
+ current_surface_ = pending_surface_ = NULL; |
UpdateExternalTexture(); |
+ } |
// Use the state of the RenderWidgetHost and not the window as the two may |
// differ. In particular if the window is hidden but the renderer isn't and we |
@@ -640,12 +627,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface( |
skia::PlatformBitmap* output) { |
base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); |
- std::map<uint64, scoped_refptr<ui::Texture> >::iterator it = |
- image_transport_clients_.find(current_surface_); |
- if (it == image_transport_clients_.end()) |
- return; |
- |
- ui::Texture* container = it->second; |
+ scoped_refptr<ui::Texture> container = current_surface_; |
DCHECK(container); |
gfx::Size dst_size_in_pixel = ConvertSizeToPixel(this, dst_size); |
@@ -662,11 +644,12 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface( |
output->GetBitmap().getPixels()); |
scoped_callback_runner.Release(); |
// Wrap the callback with an internal handler so that we can inject our |
- // own completion handlers (where we can call AdjustSurfaceProtection). |
+ // own completion handlers (where we can try to free the frontbuffer). |
base::Callback<void(bool)> wrapper_callback = base::Bind( |
&RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished, |
AsWeakPtr(), |
- callback); |
+ callback, |
+ container); // Hold a reference to the texture |
pending_thumbnail_tasks_.push_back(callback); |
// Convert |src_subrect| from the views coordinate (upper-left origin) into |
@@ -702,10 +685,9 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() { |
if (accelerated_compositing_state_changed_) |
accelerated_compositing_state_changed_ = false; |
- if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) { |
- ui::Texture* container = image_transport_clients_[current_surface_]; |
+ if (current_surface_ && host_->is_accelerated_compositing_active()) { |
+ ui::Texture* container = current_surface_; |
window_->SetExternalTexture(container); |
- current_surface_in_use_by_compositor_ = true; |
if (!container) { |
resize_locks_.clear(); |
@@ -742,122 +724,100 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() { |
} |
} else { |
window_->SetExternalTexture(NULL); |
- if (ShouldReleaseFrontSurface() && |
- host_->is_accelerated_compositing_active()) { |
- // The current surface may have pipelined gl commands, so always wait for |
- // the next composite to start. If the current surface is still null, |
- // then we really know its no longer in use. |
- ui::Compositor* compositor = GetCompositor(); |
- if (compositor) { |
- on_compositing_will_start_callbacks_.push_back( |
- base::Bind(&RenderWidgetHostViewAura:: |
- SetSurfaceNotInUseByCompositor, |
- AsWeakPtr())); |
- if (!compositor->HasObserver(this)) |
- compositor->AddObserver(this); |
- } |
- } |
resize_locks_.clear(); |
} |
} |
-void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( |
- const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel, |
- int gpu_host_id) { |
- surface_route_id_ = params_in_pixel.route_id; |
- // If protection state changed, then this swap is stale. We must still ACK but |
- // do not update current_surface_ since it may have been discarded. |
- if (params_in_pixel.protection_state_id && |
- params_in_pixel.protection_state_id != protection_state_id_) { |
- DCHECK(!current_surface_); |
- if (!params_in_pixel.skip_ack) |
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); |
- return; |
+void RenderWidgetHostViewAura::SwapBuffersBegin( |
+ const gfx::Size& surface_size) { |
+ scoped_refptr<ui::Texture> tmp = current_surface_; |
+ current_surface_ = pending_surface_; |
+ pending_surface_ = tmp; |
+ |
+ if (!current_surface_) { |
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
+ current_surface_ = factory->CreateTransportClient( |
+ surface_size, device_scale_factor_, mailbox_name_); |
+ if (!current_surface_) { |
+ LOG(ERROR) << "Failed to create ImageTransport texture"; |
+ return; |
+ } |
} |
- current_surface_ = params_in_pixel.surface_handle; |
- // If we don't require an ACK that means the content is not a fresh updated |
- // new frame, rather we are just resetting our handle to some old content that |
- // we still hadn't discarded. Although we could display immediately, by not |
- // resetting the compositor lock here, we give us some time to get a fresh |
- // frame which means fewer content flashes. |
- if (!params_in_pixel.skip_ack) |
- released_front_lock_ = NULL; |
+ current_surface_->Consume(surface_size); |
+ released_front_lock_ = NULL; |
UpdateExternalTexture(); |
+} |
+void RenderWidgetHostViewAura::SwapBuffersCompleted( |
+ int gpu_host_id, |
+ int route_id, |
+ scoped_refptr<ui::Texture> pending_surface) { |
ui::Compositor* compositor = GetCompositor(); |
if (!compositor) { |
// We have no compositor, so we have no way to display the surface. |
// Must still send the ACK. |
- if (!params_in_pixel.skip_ack) |
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); |
+ InsertSyncPointAndACK(route_id, gpu_host_id, pending_surface_); |
} else { |
- DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != |
- image_transport_clients_.end()); |
- gfx::Size surface_size_in_pixel = |
- image_transport_clients_[params_in_pixel.surface_handle]->size(); |
- gfx::Size surface_size = ConvertSizeToDIP(this, |
- surface_size_in_pixel); |
- window_->SchedulePaintInRect(gfx::Rect(surface_size)); |
- |
- if (!params_in_pixel.skip_ack) { |
- if (!resize_locks_.empty()) { |
- // If we are waiting for the resize, fast-track the ACK. |
- if (compositor->IsThreaded()) { |
- // We need the compositor thread to pick up the active buffer before |
- // ACKing. |
- on_compositing_did_commit_callbacks_.push_back( |
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
- params_in_pixel.route_id, |
- gpu_host_id)); |
- if (!compositor->HasObserver(this)) |
- compositor->AddObserver(this); |
- } else { |
- // The compositor will pickup the active buffer during a draw, so we |
- // can ACK immediately. |
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, |
- compositor); |
- } |
- } else { |
- // Add sending an ACK to the list of things to do OnCompositingWillStart |
- on_compositing_will_start_callbacks_.push_back( |
+ if (!resize_locks_.empty()) { |
+ // If we are waiting for the resize, fast-track the ACK. |
+ if (compositor->IsThreaded()) { |
+ // We need the compositor thread to pick up the active buffer before |
+ // ACKing. |
+ on_compositing_did_commit_callbacks_.push_back( |
base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
- params_in_pixel.route_id, |
- gpu_host_id)); |
+ route_id, gpu_host_id, pending_surface_)); |
if (!compositor->HasObserver(this)) |
compositor->AddObserver(this); |
+ } else { |
+ // The compositor will pickup the active buffer during a draw, so we |
+ // can ACK immediately. |
+ InsertSyncPointAndACK(route_id, gpu_host_id, pending_surface_); |
} |
+ } else { |
+ // Add sending an ACK to the list of things to do OnCompositingWillStart |
+ on_compositing_will_start_callbacks_.push_back( |
+ base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
+ route_id, gpu_host_id, pending_surface_)); |
+ if (!compositor->HasObserver(this)) |
+ compositor->AddObserver(this); |
} |
} |
} |
+void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( |
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel, |
+ int gpu_host_id) { |
+ SwapBuffersBegin(params_in_pixel.size); |
+ |
+ ui::Compositor* compositor = GetCompositor(); |
+ if (compositor) { |
+ gfx::Size surface_size = ConvertSizeToDIP(this, params_in_pixel.size); |
+ window_->SchedulePaintInRect(gfx::Rect(surface_size)); |
+ } |
+ |
+ SwapBuffersCompleted(gpu_host_id, |
+ params_in_pixel.route_id, |
+ pending_surface_); |
+} |
+ |
void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( |
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel, |
int gpu_host_id) { |
- surface_route_id_ = params_in_pixel.route_id; |
- // If visible state changed, then this PSB is stale. We must still ACK but |
- // do not update current_surface_. |
- if (params_in_pixel.protection_state_id && |
- params_in_pixel.protection_state_id != protection_state_id_) { |
- DCHECK(!current_surface_); |
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); |
- return; |
- } |
- current_surface_ = params_in_pixel.surface_handle; |
- released_front_lock_ = NULL; |
- DCHECK(current_surface_); |
- UpdateExternalTexture(); |
+ SwapBuffersBegin(params_in_pixel.surface_size); |
ui::Compositor* compositor = GetCompositor(); |
- if (!compositor) { |
- // We have no compositor, so we have no way to display the surface |
- // Must still send the ACK |
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); |
- } else { |
- DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != |
- image_transport_clients_.end()); |
- gfx::Size surface_size_in_pixel = |
- image_transport_clients_[params_in_pixel.surface_handle]->size(); |
+ if (compositor) { |
+ gfx::Size surface_size_in_pixel = params_in_pixel.surface_size; |
+ |
+ if (pending_surface_) { |
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
+ GLHelper* gl_helper = factory->GetGLHelper(); |
+ // TODO: Track previous damage rect and only copy the missing pieces. |
+ gl_helper->CopyTexture(current_surface_->PrepareTexture(), |
+ surface_size_in_pixel, |
+ pending_surface_->PrepareTexture()); |
+ } |
// Co-ordinates come in OpenGL co-ordinate space. |
// We need to convert to layer space. |
@@ -874,34 +834,11 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( |
rect_to_paint.Intersect(window_->bounds()); |
window_->SchedulePaintInRect(rect_to_paint); |
+ } |
- if (!resize_locks_.empty()) { |
- // If we are waiting for the resize, fast-track the ACK. |
- if (compositor->IsThreaded()) { |
- // We need the compositor thread to pick up the active buffer before |
- // ACKing. |
- on_compositing_did_commit_callbacks_.push_back( |
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
+ SwapBuffersCompleted(gpu_host_id, |
params_in_pixel.route_id, |
- gpu_host_id)); |
- if (!compositor->HasObserver(this)) |
- compositor->AddObserver(this); |
- } else { |
- // The compositor will pickup the active buffer during a draw, so we |
- // can ACK immediately. |
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, |
- compositor); |
- } |
- } else { |
- // Add sending an ACK to the list of things to do OnCompositingWillStart |
- on_compositing_will_start_callbacks_.push_back( |
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
- params_in_pixel.route_id, |
- gpu_host_id)); |
- if (!compositor->HasObserver(this)) |
- compositor->AddObserver(this); |
- } |
- } |
+ pending_surface_); |
} |
void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() { |
@@ -920,71 +857,50 @@ bool RenderWidgetHostViewAura::HasAcceleratedSurface( |
void RenderWidgetHostViewAura::AcceleratedSurfaceNew( |
int32 width_in_pixel, |
int32 height_in_pixel, |
- uint64 surface_handle) { |
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
- scoped_refptr<ui::Texture> surface(factory->CreateTransportClient( |
- gfx::Size(width_in_pixel, height_in_pixel), device_scale_factor_, |
- surface_handle)); |
- if (!surface) { |
- LOG(ERROR) << "Failed to create ImageTransport texture"; |
- return; |
- } |
- |
- image_transport_clients_[surface_handle] = surface; |
+ uint64 surface_handle, |
+ const std::vector<signed char>& mailbox_name) { |
+ // Release potential surfaces with an old mailbox name. |
+ current_surface_ = pending_surface_ = NULL; |
+ mailbox_name_ = mailbox_name; |
} |
void RenderWidgetHostViewAura::AcceleratedSurfaceRelease( |
uint64 surface_handle) { |
- DCHECK(image_transport_clients_.find(surface_handle) != |
- image_transport_clients_.end()); |
- if (current_surface_ == surface_handle) { |
- current_surface_ = 0; |
+ if (current_surface_ && ShouldReleaseFrontSurface() && |
+ host_->is_accelerated_compositing_active()) { |
+ ui::Compositor* compositor = GetCompositor(); |
+ if (compositor) { |
+ // Hold a reference to the texture through a bound argument |
+ // until after commit, so we know the impl thread won't use |
+ // it anymore. |
+ scoped_refptr<ui::Texture> surface_ref = current_surface_; |
+ on_compositing_did_commit_callbacks_.push_back( |
+ base::Bind(&RenderWidgetHostViewAura:: |
+ SetSurfaceNotInUseByCompositor, |
+ AsWeakPtr(), |
+ surface_ref)); |
+ if (!compositor->HasObserver(this)) |
+ compositor->AddObserver(this); |
+ } |
+ current_surface_ = NULL; |
UpdateExternalTexture(); |
} |
- image_transport_clients_.erase(surface_handle); |
} |
-void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(ui::Compositor*) { |
- if (current_surface_ || !host_->is_hidden()) |
- return; |
- current_surface_in_use_by_compositor_ = false; |
- AdjustSurfaceProtection(); |
-} |
- |
-void RenderWidgetHostViewAura::AdjustSurfaceProtection() { |
- // If the current surface is non null, it is protected. |
- // If we are visible, it is protected. |
- // Otherwise, change to not proctected once done thumbnailing and compositing. |
- bool surface_is_protected = |
- current_surface_ || |
- !host_->is_hidden() || |
- (current_surface_is_protected_ && |
- (!pending_thumbnail_tasks_.empty() || |
- current_surface_in_use_by_compositor_)); |
- if (current_surface_is_protected_ == surface_is_protected) |
- return; |
- current_surface_is_protected_ = surface_is_protected; |
- ++protection_state_id_; |
- |
- if (!surface_route_id_ || !shared_surface_handle_.parent_gpu_process_id) |
- return; |
- |
- RenderWidgetHostImpl::SendFrontSurfaceIsProtected( |
- surface_is_protected, |
- protection_state_id_, |
- surface_route_id_, |
- shared_surface_handle_.parent_gpu_process_id); |
+void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor( |
+ scoped_refptr<ui::Texture>) { |
} |
void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished( |
- base::Callback<void(bool)> callback, bool result) { |
+ base::Callback<void(bool)> callback, |
+ scoped_refptr<ui::Texture>, |
+ bool result) { |
for (size_t i = 0; i != pending_thumbnail_tasks_.size(); ++i) { |
if (pending_thumbnail_tasks_[i].Equals(callback)) { |
pending_thumbnail_tasks_.erase(pending_thumbnail_tasks_.begin()+i); |
break; |
} |
} |
- AdjustSurfaceProtection(); |
callback.Run(result); |
} |
@@ -1410,12 +1326,10 @@ scoped_refptr<ui::Texture> RenderWidgetHostViewAura::CopyTexture() { |
if (!gl_helper) |
return scoped_refptr<ui::Texture>(); |
- std::map<uint64, scoped_refptr<ui::Texture> >::iterator it = |
- image_transport_clients_.find(current_surface_); |
- if (it == image_transport_clients_.end()) |
+ if (!current_surface_) |
return scoped_refptr<ui::Texture>(); |
- ui::Texture* container = it->second; |
+ ui::Texture* container = current_surface_; |
DCHECK(container); |
WebKit::WebGLId texture_id = |
gl_helper->CopyTexture(container->PrepareTexture(), container->size()); |
@@ -1653,12 +1567,12 @@ void RenderWidgetHostViewAura::OnLostActive() { |
void RenderWidgetHostViewAura::OnCompositingDidCommit( |
ui::Compositor* compositor) { |
- RunCompositingDidCommitCallbacks(compositor); |
+ RunCompositingDidCommitCallbacks(); |
} |
void RenderWidgetHostViewAura::OnCompositingWillStart( |
ui::Compositor* compositor) { |
- RunCompositingWillStartCallbacks(compositor); |
+ RunCompositingWillStartCallbacks(); |
} |
void RenderWidgetHostViewAura::OnCompositingStarted( |
@@ -1678,12 +1592,7 @@ void RenderWidgetHostViewAura::OnCompositingAborted( |
// RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
void RenderWidgetHostViewAura::OnLostResources() { |
- image_transport_clients_.clear(); |
- current_surface_ = 0; |
- protection_state_id_ = 0; |
- current_surface_is_protected_ = true; |
- current_surface_in_use_by_compositor_ = true; |
- surface_route_id_ = 0; |
+ current_surface_ = pending_surface_ = NULL; |
UpdateExternalTexture(); |
locks_pending_draw_.clear(); |
@@ -1822,36 +1731,32 @@ bool RenderWidgetHostViewAura::ShouldMoveToCenter() { |
global_mouse_position_.y() > rect.bottom() - border_y; |
} |
-void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks( |
- ui::Compositor* compositor) { |
- for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator |
+void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks() { |
+ for (std::vector<base::Closure>::const_iterator |
it = on_compositing_did_commit_callbacks_.begin(); |
it != on_compositing_did_commit_callbacks_.end(); ++it) { |
- it->Run(compositor); |
+ it->Run(); |
} |
on_compositing_did_commit_callbacks_.clear(); |
} |
-void RenderWidgetHostViewAura::RunCompositingWillStartCallbacks( |
- ui::Compositor* compositor) { |
- for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator |
+void RenderWidgetHostViewAura::RunCompositingWillStartCallbacks() { |
+ for (std::vector<base::Closure>::const_iterator |
it = on_compositing_will_start_callbacks_.begin(); |
it != on_compositing_will_start_callbacks_.end(); ++it) { |
- it->Run(compositor); |
+ it->Run(); |
} |
on_compositing_will_start_callbacks_.clear(); |
} |
// static |
void RenderWidgetHostViewAura::InsertSyncPointAndACK( |
- int32 route_id, int gpu_host_id, ui::Compositor* compositor) { |
- uint32 sync_point = 0; |
- // If we have no compositor, so we must still send the ACK. A zero |
- // sync point will not be waited for in the GPU process. |
- if (compositor) { |
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
- sync_point = factory->InsertSyncPoint(); |
- } |
+ int32 route_id, int gpu_host_id, scoped_refptr<ui::Texture> texture) { |
+ if (texture) |
+ texture->Produce(); |
+ |
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
+ uint32 sync_point = factory->InsertSyncPoint(); |
RenderWidgetHostImpl::AcknowledgeBufferPresent( |
route_id, gpu_host_id, sync_point); |
@@ -1865,8 +1770,8 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() { |
// frame though, because we will reissue a new frame right away without that |
// composited data. |
ui::Compositor* compositor = GetCompositor(); |
- RunCompositingDidCommitCallbacks(compositor); |
- RunCompositingWillStartCallbacks(compositor); |
+ RunCompositingDidCommitCallbacks(); |
+ RunCompositingWillStartCallbacks(); |
locks_pending_draw_.clear(); |
if (compositor && compositor->HasObserver(this)) |
compositor->RemoveObserver(this); |