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

Unified Diff: content/browser/renderer_host/render_widget_host_view_aura.cc

Issue 11194042: Implement TextureImageTransportSurface using texture mailbox (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698