summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjbauman <jbauman@chromium.org>2014-08-23 15:10:23 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-23 22:11:22 +0000
commit878e9535344a864efec4c5137e3b1363f911f378 (patch)
treedb49794dd511d715d608144356c06c6d19a8faa7
parentef468cde5048721e27faa4265f70f2fd0e424618 (diff)
downloadchromium_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.cc7
-rw-r--r--cc/surfaces/surface.cc14
-rw-r--r--cc/surfaces/surface.h8
-rw-r--r--cc/surfaces/surface_aggregator_unittest.cc10
-rw-r--r--cc/surfaces/surface_factory.cc5
-rw-r--r--cc/surfaces/surface_factory.h6
-rw-r--r--cc/surfaces/surface_factory_unittest.cc2
-rw-r--r--cc/surfaces/surfaces_pixeltest.cc12
-rw-r--r--content/browser/compositor/delegated_frame_host.cc11
-rw-r--r--content/browser/compositor/surface_display_output_surface.cc11
-rw-r--r--content/browser/compositor/surface_display_output_surface.h2
-rw-r--r--mojo/services/surfaces/surfaces_impl.cc3
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();
}