summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDale Curtis <dalecurtis@chromium.org>2015-06-01 11:06:03 -0700
committerDale Curtis <dalecurtis@chromium.org>2015-06-01 18:07:15 +0000
commitddd107c9c33498428e116b17be658bbc50f8bb98 (patch)
treeb1e9b2dd16818595b483a5d81ca21c55819ea75b
parenta8fe714e25e3a285863b02d7942eed86e217bab0 (diff)
downloadchromium_src-ddd107c9c33498428e116b17be658bbc50f8bb98.zip
chromium_src-ddd107c9c33498428e116b17be658bbc50f8bb98.tar.gz
chromium_src-ddd107c9c33498428e116b17be658bbc50f8bb98.tar.bz2
Merge to M44: "Don't report compositor dropped frames for invisible layers."
Wires up a DidDrawFrame() signal to VideoFrameControllers so they are always notified of DidDrawAllLayers(). The VFCs can then propagate this signal via PutCurrentFrame() to VideoFrameProvider clients. PutCurrentFrame() was effectively useless, so I repurposed it to propagate the DidDrawFrame signal as necessary. As a consequence, I removed some useless get/put symmetry checks from WebMediaPlayerMS(). BUG=492369 TEST=Move YouTube offscreen, observe zero dropped frames. unittest TBD. CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel TBR=danakj,sunnyps Review URL: https://codereview.chromium.org/1161873008 Cr-Commit-Position: refs/heads/master@{#332046} (cherry picked from commit e8024c4963b15aeaf03e18869a27c066ba98b0d6) Review URL: https://codereview.chromium.org/1150583005 Cr-Commit-Position: refs/branch-heads/2403@{#155} Cr-Branched-From: f54b8097a9c45ed4ad308133d49f05325d6c5070-refs/heads/master@{#330231}
-rw-r--r--cc/layers/video_frame_provider.h7
-rw-r--r--cc/layers/video_frame_provider_client_impl.cc15
-rw-r--r--cc/layers/video_frame_provider_client_impl.h2
-rw-r--r--cc/scheduler/video_frame_controller.h5
-rw-r--r--cc/trees/layer_tree_host_impl.cc3
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc30
-rw-r--r--content/renderer/media/webmediaplayer_ms.cc5
-rw-r--r--content/renderer/media/webmediaplayer_ms.h1
8 files changed, 58 insertions, 10 deletions
diff --git a/cc/layers/video_frame_provider.h b/cc/layers/video_frame_provider.h
index ff632f6..9b1f96c 100644
--- a/cc/layers/video_frame_provider.h
+++ b/cc/layers/video_frame_provider.h
@@ -79,8 +79,11 @@ class CC_EXPORT VideoFrameProvider {
// has been removed. http://crbug.com/439548
virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() = 0;
- // Indicates that the last frame returned via GetCurrentFrame() is expected to
- // be rendered. Must only occur after a previous call to GetCurrentFrame().
+ // Called in response to DidReceiveFrame() or a return value of true from
+ // UpdateCurrentFrame() if the current frame was considered for rendering; the
+ // frame may not been rendered for a variety of reasons (occlusion, etc).
+ // Providers may use the absence of this call as a signal to detect when a new
+ // frame missed its intended deadline.
virtual void PutCurrentFrame() = 0;
protected:
diff --git a/cc/layers/video_frame_provider_client_impl.cc b/cc/layers/video_frame_provider_client_impl.cc
index 5fab4e2..b854d6e 100644
--- a/cc/layers/video_frame_provider_client_impl.cc
+++ b/cc/layers/video_frame_provider_client_impl.cc
@@ -25,7 +25,8 @@ VideoFrameProviderClientImpl::VideoFrameProviderClientImpl(
client_(client),
active_video_layer_(nullptr),
stopped_(false),
- rendering_(false) {
+ rendering_(false),
+ needs_put_current_frame_(false) {
// This only happens during a commit on the compositor thread while the main
// thread is blocked. That makes this a thread-safe call to set the video
// frame provider client that does not require a lock. The same is true of
@@ -90,6 +91,7 @@ void VideoFrameProviderClientImpl::PutCurrentFrame() {
DCHECK(thread_checker_.CalledOnValidThread());
provider_lock_.AssertAcquired();
provider_->PutCurrentFrame();
+ needs_put_current_frame_ = false;
}
void VideoFrameProviderClientImpl::ReleaseLock() {
@@ -137,6 +139,7 @@ void VideoFrameProviderClientImpl::DidReceiveFrame() {
"active_video_layer",
!!active_video_layer_);
DCHECK(thread_checker_.CalledOnValidThread());
+ needs_put_current_frame_ = true;
if (active_video_layer_)
active_video_layer_->SetNeedsRedraw();
}
@@ -171,4 +174,14 @@ void VideoFrameProviderClientImpl::OnBeginFrame(const BeginFrameArgs& args) {
DidReceiveFrame();
}
+void VideoFrameProviderClientImpl::DidDrawFrame() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ {
+ base::AutoLock locker(provider_lock_);
+ if (provider_ && needs_put_current_frame_)
+ provider_->PutCurrentFrame();
+ }
+ needs_put_current_frame_ = false;
+}
+
} // namespace cc
diff --git a/cc/layers/video_frame_provider_client_impl.h b/cc/layers/video_frame_provider_client_impl.h
index be49e15..102e227 100644
--- a/cc/layers/video_frame_provider_client_impl.h
+++ b/cc/layers/video_frame_provider_client_impl.h
@@ -47,6 +47,7 @@ class CC_EXPORT VideoFrameProviderClientImpl
// VideoFrameController implementation.
void OnBeginFrame(const BeginFrameArgs& args) override;
+ void DidDrawFrame() override;
// VideoFrameProvider::Client implementation.
// Called on the main thread.
@@ -69,6 +70,7 @@ class CC_EXPORT VideoFrameProviderClientImpl
VideoLayerImpl* active_video_layer_;
bool stopped_;
bool rendering_;
+ bool needs_put_current_frame_;
// Since the provider lives on another thread, it can be destroyed while the
// frame controller are accessing its frame. Before being destroyed the
diff --git a/cc/scheduler/video_frame_controller.h b/cc/scheduler/video_frame_controller.h
index dee7df5..0307cd5 100644
--- a/cc/scheduler/video_frame_controller.h
+++ b/cc/scheduler/video_frame_controller.h
@@ -26,6 +26,11 @@ class CC_EXPORT VideoFrameController {
public:
virtual void OnBeginFrame(const BeginFrameArgs& args) = 0;
+ // Called upon completion of LayerTreeHostImpl::DidDrawAllLayers(), regardless
+ // of whether the controller issued a SetNeedsRedraw(). May be used to
+ // determine when SetNeedsRedraw() is called but the draw is aborted.
+ virtual void DidDrawFrame() = 0;
+
protected:
virtual ~VideoFrameController() {}
};
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index e781640..5e02cab 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1577,6 +1577,9 @@ void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
+ for (auto& it : video_frame_controllers_)
+ it->DidDrawFrame();
+
// Once all layers have been drawn, pending texture uploads should no
// longer block future uploads.
resource_provider_->MarkPendingUploadsAsNonBlocking();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 6b45ae4..ffc0b31 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -7684,12 +7684,18 @@ class FakeVideoFrameController : public VideoFrameController {
public:
void OnBeginFrame(const BeginFrameArgs& args) override {
begin_frame_args_ = args;
+ did_draw_frame_ = false;
}
- const BeginFrameArgs& begin_frame_args() { return begin_frame_args_; }
+ void DidDrawFrame() override { did_draw_frame_ = true; }
+
+ const BeginFrameArgs& begin_frame_args() const { return begin_frame_args_; }
+
+ bool did_draw_frame() const { return did_draw_frame_; }
private:
BeginFrameArgs begin_frame_args_;
+ bool did_draw_frame_ = false;
};
TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
@@ -7702,6 +7708,17 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
host_impl_->AddVideoFrameController(&controller);
EXPECT_TRUE(controller.begin_frame_args().IsValid());
host_impl_->DidFinishImplFrame();
+
+ EXPECT_FALSE(controller.did_draw_frame());
+ LayerTreeHostImpl::FrameData frame;
+ host_impl_->DidDrawAllLayers(frame);
+ EXPECT_TRUE(controller.did_draw_frame());
+
+ controller.OnBeginFrame(begin_frame_args);
+ EXPECT_FALSE(controller.did_draw_frame());
+ host_impl_->RemoveVideoFrameController(&controller);
+ host_impl_->DidDrawAllLayers(frame);
+ EXPECT_FALSE(controller.did_draw_frame());
}
TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
@@ -7720,6 +7737,17 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
EXPECT_FALSE(controller.begin_frame_args().IsValid());
host_impl_->WillBeginImplFrame(begin_frame_args);
EXPECT_TRUE(controller.begin_frame_args().IsValid());
+
+ EXPECT_FALSE(controller.did_draw_frame());
+ LayerTreeHostImpl::FrameData frame;
+ host_impl_->DidDrawAllLayers(frame);
+ EXPECT_TRUE(controller.did_draw_frame());
+
+ controller.OnBeginFrame(begin_frame_args);
+ EXPECT_FALSE(controller.did_draw_frame());
+ host_impl_->RemoveVideoFrameController(&controller);
+ host_impl_->DidDrawAllLayers(frame);
+ EXPECT_FALSE(controller.did_draw_frame());
}
TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) {
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc
index de6f33b..a7f1e0b 100644
--- a/content/renderer/media/webmediaplayer_ms.cc
+++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -108,7 +108,6 @@ WebMediaPlayerMS::WebMediaPlayerMS(
delegate_(delegate),
paused_(true),
current_frame_used_(false),
- pending_repaint_(false),
video_frame_provider_client_(NULL),
received_first_frame_(false),
total_frame_count_(0),
@@ -467,18 +466,14 @@ bool WebMediaPlayerMS::UpdateCurrentFrame(base::TimeTicks deadline_min,
scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
base::AutoLock auto_lock(current_frame_lock_);
- DCHECK(!pending_repaint_);
if (!current_frame_.get())
return NULL;
- pending_repaint_ = true;
current_frame_used_ = true;
return current_frame_;
}
void WebMediaPlayerMS::PutCurrentFrame() {
DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
- DCHECK(pending_repaint_);
- pending_repaint_ = false;
}
void WebMediaPlayerMS::OnFrameAvailable(
diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h
index 7310fd6..d01cba6 100644
--- a/content/renderer/media/webmediaplayer_ms.h
+++ b/content/renderer/media/webmediaplayer_ms.h
@@ -188,7 +188,6 @@ class WebMediaPlayerMS
bool current_frame_used_;
// |current_frame_lock_| protects |current_frame_used_| and |current_frame_|.
base::Lock current_frame_lock_;
- bool pending_repaint_;
scoped_ptr<cc_blink::WebLayerImpl> video_weblayer_;