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

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 9af6457c37416647d7b5d03bbf10f2608d92d12a..4853fdd4bf24b624dc06d71b60b53a4fffd5e4e4 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -45,7 +45,6 @@
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ui_base_types.h"
-#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/display.h"
@@ -57,6 +56,9 @@
#include "ui/base/win/hidden_window.h"
#endif
+using gfx::RectToSkIRect;
+using gfx::SkIRectToRect;
+
using WebKit::WebScreenInfo;
using WebKit::WebTouchEvent;
@@ -263,6 +265,18 @@ class RenderWidgetHostViewAura::ResizeLock {
DISALLOW_COPY_AND_ASSIGN(ResizeLock);
};
+RenderWidgetHostViewAura::BufferPresentedParams::BufferPresentedParams(
+ int route_id,
+ int gpu_host_id,
+ uint64 surface_handle)
+ : route_id(route_id),
+ gpu_host_id(gpu_host_id),
+ surface_handle(surface_handle) {
+}
+
+RenderWidgetHostViewAura::BufferPresentedParams::~BufferPresentedParams() {
+}
+
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, public:
@@ -279,10 +293,6 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
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),
@@ -382,8 +392,6 @@ void RenderWidgetHostViewAura::WasShown() {
released_front_lock_ = GetCompositor()->GetCompositorLock();
}
- AdjustSurfaceProtection();
-
#if defined(OS_WIN)
LPARAM lparam = reinterpret_cast<LPARAM>(this);
EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
@@ -397,14 +405,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) {
@@ -711,7 +711,7 @@ 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(),
@@ -744,16 +744,13 @@ void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
accelerated_compositing_state_changed_ = true;
}
-bool RenderWidgetHostViewAura::ShouldFastACK(uint64 surface_id) {
- ui::Texture* container = image_transport_clients_[surface_id];
- DCHECK(container);
-
+bool RenderWidgetHostViewAura::ShouldSkipFrame(const gfx::Size& size) {
if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
can_lock_compositor_ == NO_PENDING_COMMIT ||
resize_locks_.empty())
return false;
- gfx::Size container_size = ConvertSizeToDIP(this, container->size());
+ gfx::Size container_size = ConvertSizeToDIP(this, size);
ResizeLockList::iterator it = resize_locks_.begin();
while (it != resize_locks_.end()) {
if ((*it)->expected_size() == container_size)
@@ -776,7 +773,6 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) {
ui::Texture* container = image_transport_clients_[current_surface_];
window_->SetExternalTexture(container);
- current_surface_in_use_by_compositor_ = true;
if (!container) {
resize_locks_.clear();
@@ -812,120 +808,135 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
}
} else {
window_->SetExternalTexture(NULL);
- if (ShouldReleaseFrontSurface() &&
- host_->is_accelerated_compositing_active()) {
- // We need to wait for a commit to clear to guarantee that all we
- // will not issue any more GL referencing the previous surface.
- ui::Compositor* compositor = GetCompositor();
- if (compositor) {
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_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, false, NULL);
- return;
+bool RenderWidgetHostViewAura::SwapBuffersPrepare(
+ const gfx::Rect& surface_rect,
+ const gfx::Rect& damage_rect,
+ BufferPresentedParams& params) {
piman 2012/11/30 03:54:32 nit: style says no non-const reference as paramete
+ DCHECK(params.surface_handle);
+ DCHECK(!params.texture_to_produce);
+
+ if (previous_surface_size_ != surface_rect.size()) {
+ // The surface could have shrunk since we skipped an update, in which
+ // case we can expect a full update.
+ DLOG_IF(ERROR, damage_rect != surface_rect) << "Expected full damage rect";
+ skipped_damage_.setEmpty();
jonathan.backer 2012/11/20 21:21:11 I like the idea of the sanity check, but we're not
no sievers 2012/12/01 00:58:38 But I do want to reset the skipped_damage_ here. T
+ previous_surface_size_ = surface_rect.size();
}
- if (ShouldFastACK(params_in_pixel.surface_handle)) {
- if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
- return;
+ if (ShouldSkipFrame(surface_rect.size()) || !GetCompositor()) {
piman 2012/11/30 03:54:32 As mentioned before, even if we don't have a compo
no sievers 2012/12/01 00:58:38 Ok, so I've changed it to *not* do the fast ack he
piman 2012/12/03 21:08:43 Yep, great.
+ skipped_damage_.op(RectToSkIRect(damage_rect), SkRegion::kUnion_Op);
+ InsertSyncPointAndACK(params);
+ return false;
}
- 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;
+ const uint64 previous_surface = current_surface_;
+ DCHECK(!previous_surface || image_transport_clients_.find(previous_surface) !=
+ image_transport_clients_.end());
+ if (previous_surface)
+ params.texture_to_produce = image_transport_clients_[previous_surface];
+
+ current_surface_ = params.surface_handle;
+ params.surface_handle = previous_surface;
piman 2012/11/30 03:54:32 nit: how about std::swap?
+ DCHECK(image_transport_clients_.find(current_surface_) !=
+ image_transport_clients_.end());
+
+ image_transport_clients_[current_surface_]->Consume(surface_rect.size());
+ released_front_lock_ = NULL;
UpdateExternalTexture();
+ return true;
+}
+
+void RenderWidgetHostViewAura::SwapBuffersCompleted(
+ const BufferPresentedParams& params) {
ui::Compositor* compositor = GetCompositor();
if (!compositor) {
- if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, true, NULL);
+ InsertSyncPointAndACK(params);
} 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));
+ // Add sending an ACK to the list of things to do OnCompositingDidCommit
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ on_compositing_did_commit_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, params));
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+ }
+}
- if (!params_in_pixel.skip_ack) {
- // Add sending an ACK to the list of things to do OnCompositingDidCommit
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id,
- true));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- }
+void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
+ int gpu_host_id) {
+ const gfx::Rect surface_rect = gfx::Rect(gfx::Point(), params_in_pixel.size);
+ BufferPresentedParams ack_params(
+ params_in_pixel.route_id, gpu_host_id, params_in_pixel.surface_handle);
+ if (!SwapBuffersPrepare(surface_rect, surface_rect, ack_params))
+ return;
+
+ previous_damage_.setRect(RectToSkIRect(surface_rect));
+ skipped_damage_.setEmpty();
+
+ ui::Compositor* compositor = GetCompositor();
jonathan.backer 2012/11/20 21:21:11 Don't we know we have a compositor here? If not |S
no sievers 2012/12/01 00:58:38 Since I changed it in the latest patch to copy the
+ if (compositor) {
+ gfx::Size surface_size = ConvertSizeToDIP(this, params_in_pixel.size);
+ window_->SchedulePaintInRect(gfx::Rect(surface_size));
}
+
+ SwapBuffersCompleted(ack_params);
}
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, false, NULL);
+ const gfx::Rect surface_rect =
+ gfx::Rect(gfx::Point(), params_in_pixel.surface_size);
+ gfx::Rect damage_rect(params_in_pixel.x,
+ params_in_pixel.y,
+ params_in_pixel.width,
+ params_in_pixel.height);
+ BufferPresentedParams ack_params(
+ params_in_pixel.route_id, gpu_host_id, params_in_pixel.surface_handle);
+ if (!SwapBuffersPrepare(surface_rect, damage_rect, ack_params))
return;
- }
- if (ShouldFastACK(params_in_pixel.surface_handle)) {
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
- return;
+ SkRegion damage(RectToSkIRect(damage_rect));
+ if (!skipped_damage_.isEmpty()) {
+ damage.op(skipped_damage_, SkRegion::kUnion_Op);
+ damage_rect = gfx::SkIRectToRect(damage.getBounds());
jonathan.backer 2012/11/20 21:21:11 Why reset |damage_rect|? Just for the following DC
+ skipped_damage_.setEmpty();
}
- current_surface_ = params_in_pixel.surface_handle;
- released_front_lock_ = NULL;
- DCHECK(current_surface_);
- UpdateExternalTexture();
+ DCHECK(surface_rect.Contains(damage_rect));
+ ui::Texture* current_texture = image_transport_clients_[current_surface_];
ui::Compositor* compositor = GetCompositor();
jonathan.backer 2012/11/20 21:21:11 Same as above. We know that we have a compositor h
- if (!compositor) {
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, true, 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) {
+ const gfx::Size surface_size_in_pixel = params_in_pixel.surface_size;
+ DLOG_IF(ERROR, ack_params.texture_to_produce &&
+ ack_params.texture_to_produce->size() != current_texture->size() &&
+ damage_rect != surface_rect) <<
+ "Expected full damage rect after size change";
+ if (ack_params.texture_to_produce && !previous_damage_.isEmpty() &&
+ ack_params.texture_to_produce->size() == current_texture->size()) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ GLHelper* gl_helper = factory->GetGLHelper();
+ gl_helper->CopySubBufferDamage(
+ current_texture->PrepareTexture(),
+ ack_params.texture_to_produce->PrepareTexture(),
+ damage,
+ previous_damage_);
+ }
+ previous_damage_ = damage;
jonathan.backer 2012/11/20 21:21:11 This seems like too much damage! We're flipping an
jonathan.backer 2012/11/21 05:47:05 Please ignore this comment.
// Co-ordinates come in OpenGL co-ordinate space.
// We need to convert to layer space.
gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect(
params_in_pixel.x,
surface_size_in_pixel.height() - params_in_pixel.y -
- params_in_pixel.height,
+ params_in_pixel.height,
params_in_pixel.width,
params_in_pixel.height));
@@ -935,17 +946,9 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
rect_to_paint.Intersect(window_->bounds());
window_->SchedulePaintInRect(rect_to_paint);
-
- // Add sending an ACK to the list of things to do OnCompositingDidCommit
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id,
- true));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
}
+
+ SwapBuffersCompleted(ack_params);
}
void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
@@ -964,60 +967,46 @@ bool RenderWidgetHostViewAura::HasAcceleratedSurface(
void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
int32 width_in_pixel,
int32 height_in_pixel,
- uint64 surface_handle) {
+ uint64 surface_handle,
+ const std::string& mailbox_name) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
scoped_refptr<ui::Texture> surface(factory->CreateTransportClient(
gfx::Size(width_in_pixel, height_in_pixel), device_scale_factor_,
- surface_handle));
+ mailbox_name));
if (!surface) {
LOG(ERROR) << "Failed to create ImageTransport texture";
return;
}
-
image_transport_clients_[surface_handle] = surface;
}
void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
uint64 surface_handle) {
- DCHECK(image_transport_clients_.find(surface_handle) !=
- image_transport_clients_.end());
- if (current_surface_ == surface_handle) {
+ // This really tells us to release the frontbuffer.
+ if (current_surface_ && ShouldReleaseFrontSurface()) {
+ ui::Compositor* compositor = GetCompositor();
+ if (compositor) {
+ // We need to wait for a commit to clear to guarantee that all we
+ // will not issue any more GL referencing the previous surface.
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ scoped_refptr<ui::Texture> surface_ref =
+ image_transport_clients_[surface_handle];
+ on_compositing_did_commit_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::
+ SetSurfaceNotInUseByCompositor,
+ AsWeakPtr(),
+ surface_ref));
jonathan.backer 2012/11/20 21:21:11 Isn't this a no-op now?
piman 2012/11/30 03:54:32 My understanding is that it's just there to keep a
no sievers 2012/12/01 00:58:38 Yes, it's there to make sure we don't delete the t
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+ }
+ image_transport_clients_.erase(current_surface_);
current_surface_ = 0;
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_ > 0 ||
- 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(
@@ -1029,7 +1018,6 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
if (!render_widget_host_view.get())
return;
--render_widget_host_view->pending_thumbnail_tasks_;
- render_widget_host_view->AdjustSurfaceProtection();
}
void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
@@ -1737,7 +1725,7 @@ void RenderWidgetHostViewAura::OnCompositingDidCommit(
if ((*it)->GrabDeferredLock())
can_lock_compositor_ = YES_DID_LOCK;
}
- RunCompositingDidCommitCallbacks(compositor);
+ RunCompositingDidCommitCallbacks();
locks_pending_commit_.clear();
}
@@ -1768,10 +1756,6 @@ void RenderWidgetHostViewAura::OnCompositingLockStateChanged(
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;
UpdateExternalTexture();
locks_pending_commit_.clear();
@@ -1913,30 +1897,31 @@ 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();
}
// static
void RenderWidgetHostViewAura::InsertSyncPointAndACK(
- int32 route_id, int gpu_host_id, bool presented,
- ui::Compositor* compositor) {
+ const BufferPresentedParams& params) {
+ if (params.texture_to_produce)
+ params.texture_to_produce->Produce();
+
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
jonathan.backer 2012/11/20 21:21:11 nit: put this in the scope with the call to Insert
piman 2012/11/30 03:54:32 Agreed, and you can combine the bodies of the 2 if
+
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();
- }
+ // If we produced a texture, we have to synchronize with the consumer of
+ // that texture.
+ if (params.texture_to_produce)
+ sync_point = factory->InsertSyncPoint();
piman 2012/11/30 03:54:32 nit: indent
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- route_id, gpu_host_id, presented, sync_point);
+ params.route_id, params.gpu_host_id, params.surface_handle, sync_point);
}
void RenderWidgetHostViewAura::AddingToRootWindow() {
@@ -1953,7 +1938,7 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() {
// frame though, because we will reissue a new frame right away without that
// composited data.
ui::Compositor* compositor = GetCompositor();
- RunCompositingDidCommitCallbacks(compositor);
+ RunCompositingDidCommitCallbacks();
locks_pending_commit_.clear();
if (compositor && compositor->HasObserver(this))
compositor->RemoveObserver(this);

Powered by Google App Engine
This is Rietveld 408576698