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

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

Issue 10052018: Drop frontbuffers with ui-use-gpu-process, synchronized with browser, decoupled from backbuffer dro… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Major simplification! Created 8 years, 6 months 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 c3405a6197858354e26d9f73adfeb68a1c8df457..2729cefeedcca88526f32001b6b4d407e15e7b93 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -9,7 +9,6 @@
#include "base/command_line.h"
#include "base/debug/trace_event.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"
@@ -215,6 +214,10 @@ 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),
piman 2012/06/11 21:32:24 ALLOW_THIS_IN_INITIALIZER_LIST
mmocny 2012/06/12 18:26:18 Not needed once using SupportsWeakPtr. On 2012/06
+ is_thumbnailing_(false),
paint_canvas_(NULL),
synthetic_move_sent_(false),
needs_update_texture_(false) {
@@ -238,6 +241,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
popup_parent_host_view_->popup_child_host_view_ = NULL;
}
aura::client::SetTooltipText(window_, NULL);
+ weak_factory_.InvalidateWeakPtrs();
piman 2012/06/11 21:32:24 Do you need this? weak_factory_ will invalidate th
mmocny 2012/06/12 18:26:18 Done.
}
////////////////////////////////////////////////////////////////////////////////
@@ -287,10 +291,31 @@ RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
void RenderWidgetHostViewAura::DidBecomeSelected() {
host_->WasRestored();
+
+ if (!current_surface_ && host_->is_accelerated_compositing_active() &&
+ !released_front_lock_.get())
+ released_front_lock_ = window_->GetRootWindow()->GetCompositorLock();
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableUIReleaseFrontSurface)) {
piman 2012/06/11 21:32:24 Rather than parsing the command line every time th
mmocny 2012/06/12 18:26:18 Done, using static bool inside anon namespace help
+ SendSurfaceIsProtectedBasedOnVisibilityWhenReady();
+ // Reset this here in case there is an outstanding callback to remove
+ // frontbuffer protection. This protects against ABA issues.
+ on_thumbnailing_ended_callback_.Reset();
+ }
}
void RenderWidgetHostViewAura::WasHidden() {
host_->WasHidden();
+
+ released_front_lock_ = NULL;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableUIReleaseFrontSurface)) {
+ current_surface_ = 0;
+ UpdateExternalTexture();
+ SendSurfaceIsProtectedBasedOnVisibilityWhenReady();
+ }
}
void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
@@ -453,6 +478,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
skia::PlatformCanvas* output,
base::Callback<void(bool)> callback) {
base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
+
ui::Compositor* compositor = GetCompositor();
if (!compositor)
return;
@@ -478,11 +504,31 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
unsigned char* addr = static_cast<unsigned char*>(
output->getTopDevice()->accessBitmap(true).getPixels());
scoped_callback_runner.Release();
+ // on_thumbnailing_ended_callback_ is not set up to handle multiple concurrent
+ // thumbnail requests, nor would doing that be a good idea. Could early exit
+ // instead of DCHECK if this is not already handled by thumbnailer generater.
+ DCHECK(!is_thumbnailing_);
piman 2012/06/11 21:32:24 Please check with mazda that this is ensured. That
mmocny 2012/06/12 18:26:18 Had a talk with @mazda. It is not correct to igno
+ is_thumbnailing_ = true;
+ // Wrap the callback with an internal handler so that we can inject our
+ // own completion handlers. Used to delay informing gpu process that it can
+ // discard frontbuffer until after we finish thumbnailing.
+ base::Callback<void(bool)> wrapper_callback = base::Bind(
+ &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished,
+ weak_factory_.GetWeakPtr(),
+ callback);
gl_helper->CopyTextureTo(container->texture_id(),
container->size(),
size_in_pixel,
addr,
- callback);
+ wrapper_callback);
+}
+
+void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
+ base::Callback<void(bool)> callback, bool result) {
+ is_thumbnailing_ = false;
+ if(!on_thumbnailing_ended_callback_.is_null())
+ on_thumbnailing_ended_callback_.Run();
+ callback.Run(result);
}
void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
@@ -499,13 +545,16 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
needs_update_texture_ = false;
if (current_surface_ != 0 &&
host_->is_accelerated_compositing_active()) {
-
+ DCHECK(image_transport_clients_.find(current_surface_) !=
+ image_transport_clients_.end());
ImageTransportClient* container =
image_transport_clients_[current_surface_];
if (container)
container->Update();
window_->SetExternalTexture(container);
+ released_front_lock_ = NULL;
+
if (!container) {
resize_locks_.clear();
} else {
@@ -548,7 +597,16 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
int gpu_host_id) {
+ // If we are not visible then this swap is stale. We must still ACK but do not
piman 2012/06/11 21:32:24 I think there's still ABA issues. Say at some poin
mmocny 2012/06/11 21:45:09 Keen observation! I will add this. On 2012/06/11
mmocny 2012/06/12 18:26:18 Done.
+ // reset current_surface_ so that we do not try to display this surface later.
+ if (!host_->IsVisible()) {
+ DCHECK(!current_surface_);
+ RenderWidgetHostImpl::AcknowledgeSwapBuffers(params_in_pixel.route_id,
+ gpu_host_id);
+ return;
+ }
current_surface_ = params_in_pixel.surface_handle;
+ DCHECK(current_surface_);
UpdateExternalTexture();
ui::Compositor* compositor = GetCompositor();
@@ -558,6 +616,8 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
RenderWidgetHostImpl::AcknowledgeSwapBuffers(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();
gfx::Size surface_size = content::ConvertSizeToDIP(this,
@@ -585,7 +645,16 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
int gpu_host_id) {
+ // If we are not visible then this PSB is stale. We must still ACK but do not
+ // reset current_surface_ so that we do not try to display this surface later.
+ if (!host_->IsVisible()) {
+ DCHECK(!current_surface_);
+ RenderWidgetHostImpl::AcknowledgePostSubBuffer(params_in_pixel.route_id,
+ gpu_host_id);
+ return;
+ }
current_surface_ = params_in_pixel.surface_handle;
+ DCHECK(current_surface_);
UpdateExternalTexture();
ui::Compositor* compositor = GetCompositor();
@@ -595,6 +664,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();
@@ -641,7 +712,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));
@@ -652,10 +725,15 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
*shm_handle = surface->Handle();
image_transport_clients_[*surface_handle] = surface;
+
+ route_id_ = route_id;
+ gpu_host_id_ = gpu_host_id;
}
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;
UpdateExternalTexture();
@@ -663,6 +741,62 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
image_transport_clients_.erase(surface_handle);
}
+void RenderWidgetHostViewAura::
+ SendSurfaceIsProtectedBasedOnVisibilityWhenReady() {
+ if (!route_id_ || !gpu_host_id_)
+ return;
+ if (host_->IsVisible()) {
+ RenderWidgetHostImpl::SendFrontSurfaceIsProtected(true,
+ route_id_,
+ gpu_host_id_);
+ return;
+ }
+ DCHECK(!current_surface_);
+
+ ui::Compositor* compositor = GetCompositor();
+ // If we are currently compositing, schedule this function to be called again
+ // after we finish. This function must handle changes to state due to this
+ // delay.
+ // Note: There is no ABA issue because if visibility changes to true and back,
+ // we know we didn't schedule a composite during that time.
+ if (compositor->DrawPending()) {
+ on_compositing_ended_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::
+ SendSurfaceIsProtectedFalseAfterThumbnailerFinished,
+ weak_factory_.GetWeakPtr()));
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+ return;
+ }
+
+ SendSurfaceIsProtectedFalseAfterThumbnailerFinished();
+}
+
+void RenderWidgetHostViewAura::
+ SendSurfaceIsProtectedFalseAfterThumbnailerFinished() {
+ if (!route_id_ || !gpu_host_id_)
+ return;
+ if (host_->IsVisible())
+ return;
+ DCHECK(!current_surface_);
+ // If we are currently thumbnailing, schedule this function to be called again
+ // after we finish. This function must handle changes to state due to this
+ // delay.
+ // Note: We guard against ABA issue with visibility changes by resetting the
+ // on_thumbnailing_ended_callback_ in DidBecomeSelected.
+ if (is_thumbnailing_) {
+ on_thumbnailing_ended_callback_ =
piman 2012/06/11 21:32:24 Do you need to make this a callback? You could jus
mmocny 2012/06/11 21:45:09 Sounds great, will do. On 2012/06/11 21:32:24, pi
mmocny 2012/06/12 18:26:18 Done.
+ base::Bind(&RenderWidgetHostViewAura::
+ SendSurfaceIsProtectedFalseAfterThumbnailerFinished,
+ weak_factory_.GetWeakPtr());
+ return;
+ }
+
+ RenderWidgetHostImpl::SendFrontSurfaceIsProtected(false,
+ route_id_,
+ gpu_host_id_);
+}
+
void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
content::RenderWidgetHostViewBase::SetBackground(background);
host_->SetBackground(background);
@@ -1203,6 +1337,9 @@ void RenderWidgetHostViewAura::OnCompositingAborted(
void RenderWidgetHostViewAura::OnLostResources(ui::Compositor* compositor) {
image_transport_clients_.clear();
current_surface_ = 0;
+ route_id_ = 0;
+ gpu_host_id_ = 0;
+ is_thumbnailing_ = 0;
piman 2012/06/11 21:32:24 The thumbnailing callback should be called either
mmocny 2012/06/12 18:26:18 Done.
UpdateExternalTexture();
locks_pending_draw_.clear();

Powered by Google App Engine
This is Rietveld 408576698