| 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 4c27d8f7872a16bfb4162c4ed2866a5ea8a5fa44..c2e06c6c01b73eb7cbb57c7b6f8252bc3fa88682 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| @@ -8,7 +8,6 @@
|
| #include "base/bind_helpers.h"
|
| #include "base/command_line.h"
|
| #include "base/logging.h"
|
| -#include "base/memory/weak_ptr.h"
|
| #include "base/message_loop.h"
|
| #include "base/string_number_conversions.h"
|
| #include "content/browser/renderer_host/backing_store_skia.h"
|
| @@ -213,6 +212,11 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
|
| can_compose_inline_(true),
|
| has_composition_text_(false),
|
| current_surface_(0),
|
| + route_id_(0),
|
| + gpu_host_id_(0),
|
| + weak_factory_(this),
|
| + current_valid_release_front_request_id_(0),
|
| + is_thumbnailing_(false),
|
| paint_canvas_(NULL),
|
| synthetic_move_sent_(false),
|
| needs_update_texture_(false) {
|
| @@ -236,6 +240,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
|
| popup_parent_host_view_->popup_child_host_view_ = NULL;
|
| }
|
| aura::client::SetTooltipText(window_, NULL);
|
| + weak_factory_.InvalidateWeakPtrs();
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -283,10 +288,22 @@ RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
|
|
|
| void RenderWidgetHostViewAura::DidBecomeSelected() {
|
| host_->WasRestored();
|
| + InvalidatePendingRequestReleaseFrontRequest();
|
| + if (!route_id_ || !gpu_host_id_)
|
| + return;
|
| + RenderWidgetHostImpl::SendFrontSurfaceIsProtected(true,
|
| + route_id_,
|
| + gpu_host_id_);
|
| }
|
|
|
| void RenderWidgetHostViewAura::WasHidden() {
|
| host_->WasHidden();
|
| + InvalidatePendingRequestReleaseFrontRequest();
|
| + if (!route_id_ || !gpu_host_id_)
|
| + return;
|
| + RenderWidgetHostImpl::SendFrontSurfaceIsProtected(false,
|
| + route_id_,
|
| + gpu_host_id_);
|
| }
|
|
|
| void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
|
| @@ -449,6 +466,9 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
|
| skia::PlatformCanvas* output,
|
| base::Callback<void(bool)> callback) {
|
| base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
|
| + if (is_thumbnailing_)
|
| + return;
|
| +
|
| ui::Compositor* compositor = GetCompositor();
|
| if (!compositor)
|
| return;
|
| @@ -474,11 +494,25 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
|
| unsigned char* addr = static_cast<unsigned char*>(
|
| output->getTopDevice()->accessBitmap(true).getPixels());
|
| scoped_callback_runner.Release();
|
| + is_thumbnailing_ = true;
|
| + base::Callback<void(bool)> internal_callback = base::Bind(
|
| + &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished,
|
| + weak_factory_.GetWeakPtr(),
|
| + callback);
|
| gl_helper->CopyTextureTo(container->texture_id(),
|
| container->size(),
|
| size_in_pixel,
|
| addr,
|
| - callback);
|
| + internal_callback);
|
| +}
|
| +
|
| +void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
|
| + base::Callback<void(bool)> callback, bool result) {
|
| + is_thumbnailing_ = false;
|
| + for (size_t i = 0; i != delayed_release_front_acks_.size(); ++i)
|
| + delayed_release_front_acks_[i].Run();
|
| + delayed_release_front_acks_.clear();
|
| + callback.Run(result);
|
| }
|
|
|
| void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
|
| @@ -551,6 +585,7 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
|
| void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
|
| const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
|
| int gpu_host_id) {
|
| + InvalidatePendingRequestReleaseFrontRequest();
|
| current_surface_ = params_in_pixel.surface_handle;
|
| UpdateExternalTexture();
|
|
|
| @@ -588,6 +623,7 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
|
| void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
|
| const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
|
| int gpu_host_id) {
|
| + InvalidatePendingRequestReleaseFrontRequest();
|
| current_surface_ = params_in_pixel.surface_handle;
|
| UpdateExternalTexture();
|
|
|
| @@ -598,6 +634,8 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
|
| RenderWidgetHostImpl::AcknowledgePostSubBuffer(
|
| params_in_pixel.route_id, gpu_host_id);
|
| } 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();
|
|
|
| @@ -644,7 +682,9 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
|
| int32 width_in_pixel,
|
| int32 height_in_pixel,
|
| uint64* surface_handle,
|
| - TransportDIB::Handle* shm_handle) {
|
| + TransportDIB::Handle* shm_handle,
|
| + int32 route_id,
|
| + int gpu_host_id) {
|
| ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
|
| scoped_refptr<ImageTransportClient> surface(factory->CreateTransportClient(
|
| gfx::Size(width_in_pixel, height_in_pixel), surface_handle));
|
| @@ -655,6 +695,12 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
|
| *shm_handle = surface->Handle();
|
|
|
| image_transport_clients_[*surface_handle] = surface;
|
| +
|
| + route_id_ = route_id;
|
| + gpu_host_id_ = gpu_host_id;
|
| + RenderWidgetHostImpl::SendFrontSurfaceIsProtected(host_->IsVisible(),
|
| + route_id_,
|
| + gpu_host_id_);
|
| }
|
|
|
| void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
|
| @@ -666,6 +712,118 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
|
| image_transport_clients_.erase(surface_handle);
|
| }
|
|
|
| +void RenderWidgetHostViewAura::AcceleratedSurfaceRequestReleaseFront(
|
| + uint64 surface_handle,
|
| + int request_id,
|
| + int retry_count,
|
| + int32 route_id,
|
| + int gpu_host_id) {
|
| + // TODO(mmocny): Once we have implemented smooth tab switching on aura
|
| + // (crbug.com/126526) then this flag should switch to enabled by default, or
|
| + // be removed altogether.
|
| + if (!CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableUIReleaseFrontSurface))
|
| + return;
|
| +
|
| + // This request id becomes the only valid id. We use this id to for request
|
| + // invalidation and to protect against visibility state ABA issues.
|
| + current_valid_release_front_request_id_ = request_id;
|
| +
|
| + // This surface may have already been released if multiple suggestions were
|
| + // sent. Always send a reply since previous response may have been discarded.
|
| + if (image_transport_clients_.find(surface_handle) ==
|
| + image_transport_clients_.end()) {
|
| + SendRequestReleaseFrontAckAfterThumbnailIfNecessary(request_id,
|
| + retry_count,
|
| + true,
|
| + route_id,
|
| + gpu_host_id);
|
| + return;
|
| + }
|
| + DCHECK(current_surface_ == surface_handle);
|
| +
|
| + // Confirm that the surface is not in use, by making sure the tab is not
|
| + // visible (visibility can change since the time the request was sent out).
|
| + if (host_->IsVisible()) {
|
| + // Send an ACK informing the gpu that we are ignoring this request.
|
| + RenderWidgetHostImpl::AcknowledgeRequestReleaseFront(
|
| + request_id, retry_count, false, route_id, gpu_host_id);
|
| + return;
|
| + }
|
| +
|
| + base::Callback<void(void)> send_ack_if_valid_callback =
|
| + base::Bind(&RenderWidgetHostViewAura::ReleaseFrontSurfaceIfStillValid,
|
| + weak_factory_.GetWeakPtr(),
|
| + surface_handle,
|
| + request_id,
|
| + retry_count,
|
| + route_id,
|
| + gpu_host_id);
|
| +
|
| + ui::Compositor* compositor = GetCompositor();
|
| + // We may still be using the surface for the duration of a composite, so check
|
| + // that we aren't currently in the middle of one.
|
| + if (!compositor->CurrentlyCompositing()) {
|
| + send_ack_if_valid_callback.Run();
|
| + return;
|
| + }
|
| +
|
| + // We are in the middle of a composite, so we must delay reply.
|
| + on_compositing_ended_callbacks_.push_back(send_ack_if_valid_callback);
|
| + if (!compositor->HasObserver(this))
|
| + compositor->AddObserver(this);
|
| +}
|
| +
|
| +void RenderWidgetHostViewAura::InvalidatePendingRequestReleaseFrontRequest() {
|
| + current_valid_release_front_request_id_ = 0;
|
| +}
|
| +
|
| +void RenderWidgetHostViewAura::ReleaseFrontSurfaceIfStillValid(
|
| + uint64 surface_handle,
|
| + int request_id,
|
| + int retry_count,
|
| + int32 route_id,
|
| + int gpu_host_id) {
|
| + // Check if this request_id is valid. No need to send an ACK if not, since
|
| + // the newer, currently valid request will send one.
|
| + if (current_valid_release_front_request_id_ != request_id)
|
| + return;
|
| +
|
| + DCHECK(!host_->IsVisible());
|
| + DCHECK(current_surface_ == surface_handle);
|
| +
|
| + // Release our handle to the surface.
|
| + AcceleratedSurfaceRelease(surface_handle);
|
| + DCHECK(!current_surface_);
|
| +
|
| + // Now reply to the gpu process, potentially delayed during thumbnailing.
|
| + SendRequestReleaseFrontAckAfterThumbnailIfNecessary(request_id,
|
| + retry_count,
|
| + true,
|
| + route_id,
|
| + gpu_host_id);
|
| +}
|
| +
|
| +void RenderWidgetHostViewAura::
|
| + SendRequestReleaseFrontAckAfterThumbnailIfNecessary(
|
| + int request_id,
|
| + int retry_count,
|
| + bool was_released,
|
| + int32 route_id,
|
| + int gpu_host_id) {
|
| + base::Callback<void(void)> request_release_front_ack =
|
| + base::Bind(&RenderWidgetHostImpl::AcknowledgeRequestReleaseFront,
|
| + request_id,
|
| + retry_count,
|
| + was_released,
|
| + route_id,
|
| + gpu_host_id);
|
| + if (is_thumbnailing_)
|
| + delayed_release_front_acks_.push_back(request_release_front_ack);
|
| + else
|
| + request_release_front_ack.Run();
|
| +}
|
| +
|
| void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
|
| content::RenderWidgetHostViewBase::SetBackground(background);
|
| host_->SetBackground(background);
|
| @@ -1196,6 +1354,11 @@ void RenderWidgetHostViewAura::OnCompositingEnded(ui::Compositor* compositor) {
|
| void RenderWidgetHostViewAura::OnLostResources(ui::Compositor* compositor) {
|
| image_transport_clients_.clear();
|
| current_surface_ = 0;
|
| + route_id_ = 0;
|
| + gpu_host_id_ = 0;
|
| + current_valid_release_front_request_id_ = 0;
|
| + is_thumbnailing_ = 0;
|
| + delayed_release_front_acks_.clear();
|
| UpdateExternalTexture();
|
| locks_pending_draw_.clear();
|
|
|
|
|