diff options
author | jbauman <jbauman@chromium.org> | 2014-08-23 15:10:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-23 22:11:22 +0000 |
commit | 878e9535344a864efec4c5137e3b1363f911f378 (patch) | |
tree | db49794dd511d715d608144356c06c6d19a8faa7 | |
parent | ef468cde5048721e27faa4265f70f2fd0e424618 (diff) | |
download | chromium_src-878e9535344a864efec4c5137e3b1363f911f378.zip chromium_src-878e9535344a864efec4c5137e3b1363f911f378.tar.gz chromium_src-878e9535344a864efec4c5137e3b1363f911f378.tar.bz2 |
Add callback when queueing frame on Surface to create backpressure.
When a frame is queued on a surface, a callback can queued that will be called when that surface is used to draw a frame. This can be used to create backpressure on renderers or the browser compositor.
BUG=
Review URL: https://codereview.chromium.org/465673003
Cr-Commit-Position: refs/heads/master@{#291605}
-rw-r--r-- | cc/surfaces/display.cc | 7 | ||||
-rw-r--r-- | cc/surfaces/surface.cc | 14 | ||||
-rw-r--r-- | cc/surfaces/surface.h | 8 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator_unittest.cc | 10 | ||||
-rw-r--r-- | cc/surfaces/surface_factory.cc | 5 | ||||
-rw-r--r-- | cc/surfaces/surface_factory.h | 6 | ||||
-rw-r--r-- | cc/surfaces/surface_factory_unittest.cc | 2 | ||||
-rw-r--r-- | cc/surfaces/surfaces_pixeltest.cc | 12 | ||||
-rw-r--r-- | content/browser/compositor/delegated_frame_host.cc | 11 | ||||
-rw-r--r-- | content/browser/compositor/surface_display_output_surface.cc | 11 | ||||
-rw-r--r-- | content/browser/compositor/surface_display_output_surface.h | 2 | ||||
-rw-r--r-- | mojo/services/surfaces/surfaces_impl.cc | 3 |
12 files changed, 68 insertions, 23 deletions
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index df64a6c..4e01b70 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc @@ -116,6 +116,13 @@ bool Display::Draw() { disable_picture_quad_image_filtering); CompositorFrameMetadata metadata; renderer_->SwapBuffers(metadata); + for (std::set<SurfaceId>::iterator it = contained_surfaces_.begin(); + it != contained_surfaces_.end(); + ++it) { + Surface* surface = manager_->GetSurfaceForId(*it); + if (surface) + surface->RunDrawCallbacks(); + } return true; } diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index 55c7392..32d6395 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc @@ -23,7 +23,8 @@ Surface::~Surface() { } } -void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame) { +void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, + const base::Closure& callback) { scoped_ptr<CompositorFrame> previous_frame = current_frame_.Pass(); current_frame_ = frame.Pass(); factory_->ReceiveFromChild( @@ -36,10 +37,21 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame) { &previous_resources); factory_->UnrefResources(previous_resources); } + if (!draw_callback_.is_null()) + draw_callback_.Run(); + draw_callback_ = callback; } const CompositorFrame* Surface::GetEligibleFrame() { return current_frame_.get(); } +void Surface::RunDrawCallbacks() { + if (!draw_callback_.is_null()) { + base::Closure callback = draw_callback_; + draw_callback_ = base::Closure(); + callback.Run(); + } +} + } // namespace cc diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h index 403d2e5..c76530b 100644 --- a/cc/surfaces/surface.h +++ b/cc/surfaces/surface.h @@ -5,6 +5,7 @@ #ifndef CC_SURFACES_SURFACE_H_ #define CC_SURFACES_SURFACE_H_ +#include "base/callback.h" #include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" @@ -26,10 +27,13 @@ class CC_SURFACES_EXPORT Surface { const gfx::Size& size() const { return size_; } SurfaceId surface_id() const { return surface_id_; } - void QueueFrame(scoped_ptr<CompositorFrame> frame); + void QueueFrame(scoped_ptr<CompositorFrame> frame, + const base::Closure& draw_callback); // Returns the most recent frame that is eligible to be rendered. const CompositorFrame* GetEligibleFrame(); + void RunDrawCallbacks(); + SurfaceFactory* factory() { return factory_; } private: @@ -39,6 +43,8 @@ class CC_SURFACES_EXPORT Surface { // TODO(jamesr): Support multiple frames in flight. scoped_ptr<CompositorFrame> current_frame_; + base::Closure draw_callback_; + DISALLOW_COPY_AND_ASSIGN(Surface); }; diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc index 766753a..cd857ba 100644 --- a/cc/surfaces/surface_aggregator_unittest.cc +++ b/cc/surfaces/surface_aggregator_unittest.cc @@ -118,7 +118,7 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory_.SubmitFrame(surface_id, frame.Pass()); + factory_.SubmitFrame(surface_id, frame.Pass(), base::Closure()); } void QueuePassAsFrame(scoped_ptr<RenderPass> pass, SurfaceId surface_id) { @@ -128,7 +128,7 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = delegated_frame_data.Pass(); - factory_.SubmitFrame(surface_id, child_frame.Pass()); + factory_.SubmitFrame(surface_id, child_frame.Pass(), base::Closure()); } protected: @@ -700,7 +700,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = child_frame_data.Pass(); - factory_.SubmitFrame(child_surface_id, child_frame.Pass()); + factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure()); test::Quad root_quads[] = {test::Quad::SolidColorQuad(1), test::Quad::SurfaceQuad(child_surface_id)}; @@ -725,7 +725,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = root_frame_data.Pass(); - factory_.SubmitFrame(root_surface_id_, root_frame.Pass()); + factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure()); std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = @@ -887,7 +887,7 @@ void SubmitFrameWithResources(ResourceProvider::ResourceId* resource_ids, frame_data->render_pass_list.push_back(pass.Pass()); scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory->SubmitFrame(surface_id, frame.Pass()); + factory->SubmitFrame(surface_id, frame.Pass(), base::Closure()); } TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index d17e98e..94f98fc 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc @@ -35,11 +35,12 @@ void SurfaceFactory::Destroy(SurfaceId surface_id) { } void SurfaceFactory::SubmitFrame(SurfaceId surface_id, - scoped_ptr<CompositorFrame> frame) { + scoped_ptr<CompositorFrame> frame, + const base::Closure& callback) { OwningSurfaceMap::iterator it = surface_map_.find(surface_id); DCHECK(it != surface_map_.end()); DCHECK(it->second->factory() == this); - it->second->QueueFrame(frame.Pass()); + it->second->QueueFrame(frame.Pass(), callback); manager_->SurfaceModified(surface_id); } diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h index c74f973..fafa53c54 100644 --- a/cc/surfaces/surface_factory.h +++ b/cc/surfaces/surface_factory.h @@ -5,6 +5,7 @@ #ifndef CC_SURFACES_SURFACE_FACTORY_H_ #define CC_SURFACES_SURFACE_FACTORY_H_ +#include "base/callback_forward.h" #include "base/containers/scoped_ptr_hash_map.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" @@ -37,7 +38,10 @@ class CC_SURFACES_EXPORT SurfaceFactory void Destroy(SurfaceId surface_id); // A frame can only be submitted to a surface created by this factory, // although the frame may reference surfaces created by other factories. - void SubmitFrame(SurfaceId surface_id, scoped_ptr<CompositorFrame> frame); + // The callback is called the first time this frame is used to draw. + void SubmitFrame(SurfaceId surface_id, + scoped_ptr<CompositorFrame> frame, + const base::Closure& callback); SurfaceFactoryClient* client() { return client_; } diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index 886c246..0815636 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc @@ -56,7 +56,7 @@ class SurfaceFactoryTest : public testing::Test { } scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory_.SubmitFrame(surface_id_, frame.Pass()); + factory_.SubmitFrame(surface_id_, frame.Pass(), base::Closure()); } void UnrefResources(ResourceProvider::ResourceId* ids_to_unref, diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc index a30f017..bdc7c40 100644 --- a/cc/surfaces/surfaces_pixeltest.cc +++ b/cc/surfaces/surfaces_pixeltest.cc @@ -87,7 +87,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) { SurfaceId root_surface_id = allocator_.GenerateId(); factory_.Create(root_surface_id, device_viewport_size_); - factory_.SubmitFrame(root_surface_id, root_frame.Pass()); + factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); SurfaceAggregator aggregator(&manager_, resource_provider_.get()); std::set<SurfaceId> surface_set; @@ -142,7 +142,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = delegated_frame_data.Pass(); - factory_.SubmitFrame(root_surface_id, root_frame.Pass()); + factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); } { @@ -169,7 +169,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = delegated_frame_data.Pass(); - factory_.SubmitFrame(child_surface_id, child_frame.Pass()); + factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure()); } SurfaceAggregator aggregator(&manager_, resource_provider_.get()); @@ -240,7 +240,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = delegated_frame_data.Pass(); - factory_.SubmitFrame(root_surface_id, root_frame.Pass()); + factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); } { @@ -275,7 +275,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = delegated_frame_data.Pass(); - factory_.SubmitFrame(left_child_id, child_frame.Pass()); + factory_.SubmitFrame(left_child_id, child_frame.Pass(), base::Closure()); } { @@ -310,7 +310,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = delegated_frame_data.Pass(); - factory_.SubmitFrame(right_child_id, child_frame.Pass()); + factory_.SubmitFrame(right_child_id, child_frame.Pass(), base::Closure()); } SurfaceAggregator aggregator(&manager_, resource_provider_.get()); diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc index d2322fe..d416ae8 100644 --- a/content/browser/compositor/delegated_frame_host.cc +++ b/content/browser/compositor/delegated_frame_host.cc @@ -379,7 +379,12 @@ void DelegatedFrameHost::SwapDelegatedFrame( scoped_ptr<cc::CompositorFrame> compositor_frame = make_scoped_ptr(new cc::CompositorFrame()); compositor_frame->delegated_frame_data = frame_data.Pass(); - surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass()); + surface_factory_->SubmitFrame( + surface_id_, + compositor_frame.Pass(), + base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, + AsWeakPtr(), + output_surface_id)); } else { if (!resource_collection_) { resource_collection_ = new cc::DelegatedFrameResourceCollection; @@ -416,9 +421,9 @@ void DelegatedFrameHost::SwapDelegatedFrame( pending_delegated_ack_count_++; ui::Compositor* compositor = client_->GetCompositor(); - if (!compositor || !modified_layers) { + if (!compositor) { SendDelegatedFrameAck(output_surface_id); - } else { + } else if (!use_surfaces_) { std::vector<ui::LatencyInfo>::const_iterator it; for (it = latency_info.begin(); it != latency_info.end(); ++it) compositor->SetLatencyInfo(*it); diff --git a/content/browser/compositor/surface_display_output_surface.cc b/content/browser/compositor/surface_display_output_surface.cc index b4697a0..527b621 100644 --- a/content/browser/compositor/surface_display_output_surface.cc +++ b/content/browser/compositor/surface_display_output_surface.cc @@ -48,10 +48,13 @@ void SurfaceDisplayOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { scoped_ptr<cc::CompositorFrame> frame_copy(new cc::CompositorFrame()); frame->AssignTo(frame_copy.get()); - factory_.SubmitFrame(surface_id_, frame_copy.Pass()); + factory_.SubmitFrame( + surface_id_, + frame_copy.Pass(), + base::Bind(&SurfaceDisplayOutputSurface::SwapBuffersComplete, + base::Unretained(this))); client_->DidSwapBuffers(); - client_->DidSwapBuffersComplete(); } void SurfaceDisplayOutputSurface::ReturnResources( @@ -62,4 +65,8 @@ void SurfaceDisplayOutputSurface::ReturnResources( client_->ReclaimResources(&ack); } +void SurfaceDisplayOutputSurface::SwapBuffersComplete() { + client_->DidSwapBuffersComplete(); +} + } // namespace content diff --git a/content/browser/compositor/surface_display_output_surface.h b/content/browser/compositor/surface_display_output_surface.h index 8f4e49b..57406cc 100644 --- a/content/browser/compositor/surface_display_output_surface.h +++ b/content/browser/compositor/surface_display_output_surface.h @@ -41,6 +41,8 @@ class SurfaceDisplayOutputSurface : public cc::OutputSurface, const cc::ReturnedResourceArray& resources) OVERRIDE; private: + void SwapBuffersComplete(); + cc::Display* display_; cc::SurfaceManager* surface_manager_; cc::SurfaceFactory factory_; diff --git a/mojo/services/surfaces/surfaces_impl.cc b/mojo/services/surfaces/surfaces_impl.cc index 7f24a0f..410e8d0 100644 --- a/mojo/services/surfaces/surfaces_impl.cc +++ b/mojo/services/surfaces/surfaces_impl.cc @@ -49,7 +49,8 @@ void SurfacesImpl::SubmitFrame(SurfaceIdPtr id, FramePtr frame_ptr) { << " should be namespace " << id_namespace_; return; } - factory_.SubmitFrame(id.To<cc::SurfaceId>(), mojo::ConvertTo(frame_ptr)); + factory_.SubmitFrame( + id.To<cc::SurfaceId>(), mojo::ConvertTo(frame_ptr), base::Closure()); client_->FrameSubmitted(); } |