| 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 aa47afe55950ee844e60e18282fff685e97450c5..6a24c83574be316914717a63f2bb414d8c19d66b 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| @@ -11,6 +11,8 @@
|
| #include "base/logging.h"
|
| #include "base/message_loop.h"
|
| #include "base/string_number_conversions.h"
|
| +#include "cc/compositor_frame.h"
|
| +#include "cc/compositor_frame_ack.h"
|
| #include "content/browser/renderer_host/backing_store_aura.h"
|
| #include "content/browser/renderer_host/dip_util.h"
|
| #include "content/browser/renderer_host/overscroll_controller.h"
|
| @@ -274,6 +276,59 @@ bool PointerEventActivates(const ui::Event& event) {
|
| return false;
|
| }
|
|
|
| +// Swap ack for the renderer when kCompositeToMailbox is enabled.
|
| +void SendCompositorFrameAck(
|
| + int32 route_id,
|
| + int renderer_host_id,
|
| + const cc::Mailbox& received_mailbox,
|
| + const gfx::Size& received_size,
|
| + bool skip_frame,
|
| + const scoped_refptr<ui::Texture>& texture_to_produce) {
|
| + cc::CompositorFrameAck ack;
|
| + ack.gl_frame_data.reset(new cc::GLFrameData());
|
| + DCHECK(!texture_to_produce || !skip_frame);
|
| + if (texture_to_produce) {
|
| + std::string mailbox_name = texture_to_produce->Produce();
|
| + std::copy(mailbox_name.data(),
|
| + mailbox_name.data() + mailbox_name.length(),
|
| + reinterpret_cast<char*>(ack.gl_frame_data->mailbox.name));
|
| + ack.gl_frame_data->size = texture_to_produce->size();
|
| + ack.gl_frame_data->sync_point =
|
| + content::ImageTransportFactory::GetInstance()->InsertSyncPoint();
|
| + } else if (skip_frame) {
|
| + // Skip the frame, i.e. tell the producer to reuse the same buffer that
|
| + // we just received.
|
| + ack.gl_frame_data->size = received_size;
|
| + ack.gl_frame_data->mailbox = received_mailbox;
|
| + }
|
| +
|
| + RenderWidgetHostImpl::SendSwapCompositorFrameAck(
|
| + route_id, renderer_host_id, ack);
|
| +}
|
| +
|
| +void AcknowledgeBufferForGpu(
|
| + int32 route_id,
|
| + int gpu_host_id,
|
| + const std::string& received_mailbox,
|
| + bool skip_frame,
|
| + const scoped_refptr<ui::Texture>& texture_to_produce) {
|
| + AcceleratedSurfaceMsg_BufferPresented_Params ack;
|
| + uint32 sync_point = 0;
|
| + DCHECK(!texture_to_produce || !skip_frame);
|
| + if (texture_to_produce) {
|
| + ack.mailbox_name = texture_to_produce->Produce();
|
| + sync_point =
|
| + content::ImageTransportFactory::GetInstance()->InsertSyncPoint();
|
| + } else if (skip_frame) {
|
| + ack.mailbox_name = received_mailbox;
|
| + ack.sync_point = 0;
|
| + }
|
| +
|
| + ack.sync_point = sync_point;
|
| + RenderWidgetHostImpl::AcknowledgeBufferPresent(
|
| + route_id, gpu_host_id, ack);
|
| +}
|
| +
|
| } // namespace
|
|
|
| // We need to watch for mouse events outside a Web Popup or its parent
|
| @@ -522,16 +577,6 @@ class RenderWidgetHostViewAura::ResizeLock {
|
| DISALLOW_COPY_AND_ASSIGN(ResizeLock);
|
| };
|
|
|
| -RenderWidgetHostViewAura::BufferPresentedParams::BufferPresentedParams(
|
| - int route_id,
|
| - int gpu_host_id)
|
| - : route_id(route_id),
|
| - gpu_host_id(gpu_host_id) {
|
| -}
|
| -
|
| -RenderWidgetHostViewAura::BufferPresentedParams::~BufferPresentedParams() {
|
| -}
|
| -
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // RenderWidgetHostViewAura, public:
|
|
|
| @@ -1118,10 +1163,7 @@ bool RenderWidgetHostViewAura::SwapBuffersPrepare(
|
| const gfx::Rect& surface_rect,
|
| const gfx::Rect& damage_rect,
|
| const std::string& mailbox_name,
|
| - BufferPresentedParams* params) {
|
| - DCHECK(!mailbox_name.empty());
|
| - DCHECK(!params->texture_to_produce);
|
| -
|
| + const BufferPresentedCallback& ack_callback) {
|
| if (last_swapped_surface_size_ != surface_rect.size()) {
|
| // The surface could have shrunk since we skipped an update, in which
|
| // case we can expect a full update.
|
| @@ -1130,22 +1172,17 @@ bool RenderWidgetHostViewAura::SwapBuffersPrepare(
|
| last_swapped_surface_size_ = surface_rect.size();
|
| }
|
|
|
| - if (ShouldSkipFrame(surface_rect.size())) {
|
| + if (ShouldSkipFrame(surface_rect.size()) || mailbox_name.empty()) {
|
| skipped_damage_.op(RectToSkIRect(damage_rect), SkRegion::kUnion_Op);
|
| - AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
|
| - ack_params.mailbox_name = mailbox_name;
|
| - ack_params.sync_point = 0;
|
| - RenderWidgetHostImpl::AcknowledgeBufferPresent(
|
| - params->route_id, params->gpu_host_id, ack_params);
|
| + ack_callback.Run(true, scoped_refptr<ui::Texture>());
|
| return false;
|
| }
|
|
|
| - params->texture_to_produce = current_surface_;
|
| -
|
| ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
|
| current_surface_ = factory->CreateTransportClient(device_scale_factor_);
|
| if (!current_surface_) {
|
| LOG(ERROR) << "Failed to create ImageTransport texture";
|
| + ack_callback.Run(true, scoped_refptr<ui::Texture>());
|
| return false;
|
| }
|
|
|
| @@ -1157,15 +1194,16 @@ bool RenderWidgetHostViewAura::SwapBuffersPrepare(
|
| }
|
|
|
| void RenderWidgetHostViewAura::SwapBuffersCompleted(
|
| - const BufferPresentedParams& params) {
|
| + const BufferPresentedCallback& ack_callback,
|
| + const scoped_refptr<ui::Texture>& texture_to_return) {
|
| ui::Compositor* compositor = GetCompositor();
|
| if (!compositor) {
|
| - InsertSyncPointAndACK(params);
|
| + ack_callback.Run(false, texture_to_return);
|
| } else {
|
| // 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));
|
| + base::Bind(ack_callback, false, texture_to_return));
|
| if (!compositor->HasObserver(this))
|
| compositor->AddObserver(this);
|
| }
|
| @@ -1203,39 +1241,85 @@ void RenderWidgetHostViewAura::UpdateCutoutRects() {
|
| 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);
|
| + BufferPresentedCallback ack_callback = base::Bind(
|
| + &AcknowledgeBufferForGpu,
|
| + params_in_pixel.route_id,
|
| + gpu_host_id,
|
| + params_in_pixel.mailbox_name);
|
| + BuffersSwapped(
|
| + params_in_pixel.size, params_in_pixel.mailbox_name, ack_callback);
|
| +}
|
| +
|
| +void RenderWidgetHostViewAura::OnSwapCompositorFrame(
|
| + const cc::CompositorFrame& frame) {
|
| + if (!frame.gl_frame_data || frame.gl_frame_data->mailbox.isZero())
|
| + return;
|
| +
|
| + BufferPresentedCallback ack_callback = base::Bind(
|
| + &SendCompositorFrameAck,
|
| + host_->GetRoutingID(), host_->GetProcess()->GetID(),
|
| + frame.gl_frame_data->mailbox, frame.gl_frame_data->size);
|
| +
|
| + if (!frame.gl_frame_data->sync_point) {
|
| + LOG(ERROR) << "CompositorFrame without sync point. Skipping frame...";
|
| + ack_callback.Run(true, scoped_refptr<ui::Texture>());
|
| + return;
|
| + }
|
| +
|
| + ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
|
| + factory->WaitSyncPoint(frame.gl_frame_data->sync_point);
|
| +
|
| + std::string mailbox_name(
|
| + reinterpret_cast<const char*>(frame.gl_frame_data->mailbox.name),
|
| + sizeof(frame.gl_frame_data->mailbox.name));
|
| + BuffersSwapped(
|
| + frame.gl_frame_data->size, mailbox_name, ack_callback);
|
| +}
|
| +
|
| +void RenderWidgetHostViewAura::BuffersSwapped(
|
| + const gfx::Size& size,
|
| + const std::string& mailbox_name,
|
| + const BufferPresentedCallback& ack_callback) {
|
| + scoped_refptr<ui::Texture> texture_to_return(current_surface_);
|
| + const gfx::Rect surface_rect = gfx::Rect(gfx::Point(), size);
|
| if (!SwapBuffersPrepare(
|
| - surface_rect, surface_rect, params_in_pixel.mailbox_name, &ack_params))
|
| + surface_rect, surface_rect, mailbox_name, ack_callback)) {
|
| return;
|
| + }
|
|
|
| previous_damage_.setRect(RectToSkIRect(surface_rect));
|
| skipped_damage_.setEmpty();
|
|
|
| ui::Compositor* compositor = GetCompositor();
|
| if (compositor) {
|
| - gfx::Size surface_size = ConvertSizeToDIP(this, params_in_pixel.size);
|
| + gfx::Size surface_size = ConvertSizeToDIP(this, size);
|
| window_->SchedulePaintInRect(gfx::Rect(surface_size));
|
| }
|
|
|
| if (paint_observer_)
|
| paint_observer_->OnUpdateCompositorContent();
|
| - SwapBuffersCompleted(ack_params);
|
| +
|
| + SwapBuffersCompleted(ack_callback, texture_to_return);
|
| }
|
|
|
| void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
|
| const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
|
| int gpu_host_id) {
|
| + scoped_refptr<ui::Texture> previous_texture(current_surface_);
|
| 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);
|
| + BufferPresentedCallback ack_callback = base::Bind(
|
| + &AcknowledgeBufferForGpu, params_in_pixel.route_id, gpu_host_id,
|
| + params_in_pixel.mailbox_name);
|
| +
|
| if (!SwapBuffersPrepare(
|
| - surface_rect, damage_rect, params_in_pixel.mailbox_name, &ack_params))
|
| + surface_rect, damage_rect, params_in_pixel.mailbox_name, ack_callback)) {
|
| return;
|
| + }
|
|
|
| SkRegion damage(RectToSkIRect(damage_rect));
|
| if (!skipped_damage_.isEmpty()) {
|
| @@ -1247,17 +1331,17 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
|
| ui::Texture* current_texture = current_surface_.get();
|
|
|
| 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() &&
|
| + DLOG_IF(ERROR, previous_texture &&
|
| + previous_texture->size() != current_texture->size() &&
|
| SkIRectToRect(damage.getBounds()) != 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()) {
|
| + if (previous_texture && !previous_damage_.isEmpty() &&
|
| + previous_texture->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(),
|
| + previous_texture->PrepareTexture(),
|
| damage,
|
| previous_damage_);
|
| }
|
| @@ -1284,7 +1368,7 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
|
| window_->SchedulePaintInRect(rect_to_paint);
|
| }
|
|
|
| - SwapBuffersCompleted(ack_params);
|
| + SwapBuffersCompleted(ack_callback, previous_texture);
|
| }
|
|
|
| void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
|
| @@ -2308,24 +2392,6 @@ void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks() {
|
| on_compositing_did_commit_callbacks_.clear();
|
| }
|
|
|
| -// static
|
| -void RenderWidgetHostViewAura::InsertSyncPointAndACK(
|
| - const BufferPresentedParams& params) {
|
| - uint32 sync_point = 0;
|
| - AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
|
| -
|
| - // If we produced a texture, we have to synchronize with the consumer of
|
| - // that texture.
|
| - if (params.texture_to_produce) {
|
| - ack_params.mailbox_name = params.texture_to_produce->Produce();
|
| - sync_point = ImageTransportFactory::GetInstance()->InsertSyncPoint();
|
| - }
|
| -
|
| - ack_params.sync_point = sync_point;
|
| - RenderWidgetHostImpl::AcknowledgeBufferPresent(
|
| - params.route_id, params.gpu_host_id, ack_params);
|
| -}
|
| -
|
| void RenderWidgetHostViewAura::AddedToRootWindow() {
|
| window_->GetRootWindow()->AddRootWindowObserver(this);
|
| host_->ParentChanged(GetNativeViewId());
|
|
|