summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhendrikw <hendrikw@chromium.org>2015-05-18 16:14:14 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-18 23:14:21 +0000
commite19cc6a61419d38f3ec658c5e74363d77e900c09 (patch)
tree351e34313a99f53dc3675014babdb8ff6f295822
parent1dfbd1030bd04e76ba41bff933cd2d8fc6d1e3f0 (diff)
downloadchromium_src-e19cc6a61419d38f3ec658c5e74363d77e900c09.zip
chromium_src-e19cc6a61419d38f3ec658c5e74363d77e900c09.tar.gz
chromium_src-e19cc6a61419d38f3ec658c5e74363d77e900c09.tar.bz2
cc: Video layers without a frame should not occlude
Added VisibleContentOpaqueRegion() to the VideoLayerImpl, if a frame hasn't been set yet, then we don't have an opaque region. + test BUG=460612 Review URL: https://codereview.chromium.org/1134663005 Cr-Commit-Position: refs/heads/master@{#330449}
-rw-r--r--cc/layers/video_frame_provider.h4
-rw-r--r--cc/layers/video_frame_provider_client_impl.cc5
-rw-r--r--cc/layers/video_frame_provider_client_impl.h1
-rw-r--r--cc/layers/video_layer_impl.cc7
-rw-r--r--cc/layers/video_layer_impl.h1
-rw-r--r--cc/layers/video_layer_impl_unittest.cc44
-rw-r--r--cc/test/fake_video_frame_provider.cc4
-rw-r--r--cc/test/fake_video_frame_provider.h1
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc5
-rw-r--r--content/renderer/media/android/webmediaplayer_android.h1
-rw-r--r--content/renderer/media/webmediaplayer_ms.cc5
-rw-r--r--content/renderer/media/webmediaplayer_ms.h1
-rw-r--r--media/blink/video_frame_compositor.cc5
-rw-r--r--media/blink/video_frame_compositor.h1
14 files changed, 85 insertions, 0 deletions
diff --git a/cc/layers/video_frame_provider.h b/cc/layers/video_frame_provider.h
index ff632f6..aa6a8216 100644
--- a/cc/layers/video_frame_provider.h
+++ b/cc/layers/video_frame_provider.h
@@ -67,6 +67,10 @@ class CC_EXPORT VideoFrameProvider {
virtual bool UpdateCurrentFrame(base::TimeTicks deadline_min,
base::TimeTicks deadline_max) = 0;
+ // Returns true if GetCurrentFrame() will return a non-null frame and false
+ // otherwise. Aside from thread locks, the state won't change.
+ virtual bool HasCurrentFrame() = 0;
+
// Returns the current frame, which may have been updated by a recent call to
// UpdateCurrentFrame(). A call to this method does not ensure that the frame
// will be rendered. A subsequent call to PutCurrentFrame() must be made if
diff --git a/cc/layers/video_frame_provider_client_impl.cc b/cc/layers/video_frame_provider_client_impl.cc
index 5fab4e2..ed2b900 100644
--- a/cc/layers/video_frame_provider_client_impl.cc
+++ b/cc/layers/video_frame_provider_client_impl.cc
@@ -98,6 +98,11 @@ void VideoFrameProviderClientImpl::ReleaseLock() {
provider_lock_.Release();
}
+bool VideoFrameProviderClientImpl::HasCurrentFrame() {
+ base::AutoLock locker(provider_lock_);
+ return provider_ && provider_->HasCurrentFrame();
+}
+
const gfx::Transform& VideoFrameProviderClientImpl::StreamTextureMatrix()
const {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/cc/layers/video_frame_provider_client_impl.h b/cc/layers/video_frame_provider_client_impl.h
index be49e15..d49e51d 100644
--- a/cc/layers/video_frame_provider_client_impl.h
+++ b/cc/layers/video_frame_provider_client_impl.h
@@ -42,6 +42,7 @@ class CC_EXPORT VideoFrameProviderClientImpl
scoped_refptr<media::VideoFrame> AcquireLockAndCurrentFrame();
void PutCurrentFrame();
void ReleaseLock();
+ bool HasCurrentFrame();
const gfx::Transform& StreamTextureMatrix() const;
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index d81713a..d73786d 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -388,6 +388,13 @@ void VideoLayerImpl::DidDraw(ResourceProvider* resource_provider) {
provider_client_impl_->ReleaseLock();
}
+SimpleEnclosedRegion VideoLayerImpl::VisibleContentOpaqueRegion() const {
+ // If we don't have a frame yet, then we don't have an opaque region.
+ if (!provider_client_impl_->HasCurrentFrame())
+ return SimpleEnclosedRegion();
+ return LayerImpl::VisibleContentOpaqueRegion();
+}
+
void VideoLayerImpl::ReleaseResources() {
updater_ = nullptr;
}
diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h
index 0a61798..aea38b5 100644
--- a/cc/layers/video_layer_impl.h
+++ b/cc/layers/video_layer_impl.h
@@ -38,6 +38,7 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
void AppendQuads(RenderPass* render_pass,
AppendQuadsData* append_quads_data) override;
void DidDraw(ResourceProvider* resource_provider) override;
+ SimpleEnclosedRegion VisibleContentOpaqueRegion() const override;
void DidBecomeActive() override;
void ReleaseResources() override;
diff --git a/cc/layers/video_layer_impl_unittest.cc b/cc/layers/video_layer_impl_unittest.cc
index 40ab5b7..b0ecff9 100644
--- a/cc/layers/video_layer_impl_unittest.cc
+++ b/cc/layers/video_layer_impl_unittest.cc
@@ -85,6 +85,50 @@ TEST(VideoLayerImplTest, Occlusion) {
}
}
+TEST(VideoLayerImplTest, OccludesOtherLayers) {
+ gfx::Size layer_size(1000, 1000);
+ gfx::Rect visible(layer_size);
+
+ LayerTestCommon::LayerImplTest impl;
+ impl.host_impl()->SetViewportSize(layer_size);
+ DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
+ auto active_tree = impl.host_impl()->active_tree();
+
+ // Create a video layer with no frame on top of another layer.
+ scoped_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3);
+ layer_impl->SetHasRenderSurface(true);
+ layer_impl->SetBounds(layer_size);
+ layer_impl->SetContentBounds(layer_size);
+ layer_impl->SetDrawsContent(true);
+ const auto& draw_properties = layer_impl->draw_properties();
+
+ FakeVideoFrameProvider provider;
+ scoped_ptr<VideoLayerImpl> video_layer_impl = VideoLayerImpl::Create(
+ active_tree, 4, &provider, media::VIDEO_ROTATION_0);
+ video_layer_impl->SetBounds(layer_size);
+ video_layer_impl->SetContentBounds(layer_size);
+ video_layer_impl->SetDrawsContent(true);
+ video_layer_impl->SetContentsOpaque(true);
+
+ layer_impl->AddChild(video_layer_impl.Pass());
+ active_tree->SetRootLayer(layer_impl.Pass());
+
+ active_tree->UpdateDrawProperties(false);
+
+ // We don't have a frame yet, so the video doesn't occlude the layer below it.
+ EXPECT_FALSE(draw_properties.occlusion_in_content_space.IsOccluded(visible));
+
+ scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
+ media::VideoFrame::YV12, gfx::Size(10, 10), gfx::Rect(10, 10),
+ gfx::Size(10, 10), base::TimeDelta());
+ provider.set_frame(video_frame);
+ active_tree->set_needs_update_draw_properties();
+ active_tree->UpdateDrawProperties(false);
+
+ // We have a frame now, so the video occludes the layer below it.
+ EXPECT_TRUE(draw_properties.occlusion_in_content_space.IsOccluded(visible));
+}
+
TEST(VideoLayerImplTest, DidBecomeActiveShouldSetActiveVideoLayer) {
LayerTestCommon::LayerImplTest impl;
DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
diff --git a/cc/test/fake_video_frame_provider.cc b/cc/test/fake_video_frame_provider.cc
index 3f4b40b..b979b0c 100644
--- a/cc/test/fake_video_frame_provider.cc
+++ b/cc/test/fake_video_frame_provider.cc
@@ -23,6 +23,10 @@ void FakeVideoFrameProvider::SetVideoFrameProviderClient(Client* client) {
client_ = client;
}
+bool FakeVideoFrameProvider::HasCurrentFrame() {
+ return frame_;
+}
+
scoped_refptr<media::VideoFrame> FakeVideoFrameProvider::GetCurrentFrame() {
return frame_;
}
diff --git a/cc/test/fake_video_frame_provider.h b/cc/test/fake_video_frame_provider.h
index 53903c9..da68d5b 100644
--- a/cc/test/fake_video_frame_provider.h
+++ b/cc/test/fake_video_frame_provider.h
@@ -19,6 +19,7 @@ class FakeVideoFrameProvider : public VideoFrameProvider {
void SetVideoFrameProviderClient(Client* client) override;
bool UpdateCurrentFrame(base::TimeTicks deadline_min,
base::TimeTicks deadline_max) override;
+ bool HasCurrentFrame() override;
scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
void PutCurrentFrame() override {}
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 763bdaa..16f17f4 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -1280,6 +1280,11 @@ bool WebMediaPlayerAndroid::UpdateCurrentFrame(base::TimeTicks deadline_min,
return false;
}
+bool WebMediaPlayerAndroid::HasCurrentFrame() {
+ base::AutoLock auto_lock(current_frame_lock_);
+ return current_frame_;
+}
+
scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() {
scoped_refptr<VideoFrame> video_frame;
{
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h
index 5d5f653..2627ac0 100644
--- a/content/renderer/media/android/webmediaplayer_android.h
+++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -187,6 +187,7 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer,
cc::VideoFrameProvider::Client* client) override;
bool UpdateCurrentFrame(base::TimeTicks deadline_min,
base::TimeTicks deadline_max) override;
+ bool HasCurrentFrame() override;
scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
void PutCurrentFrame() override;
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc
index de6f33b..556d58a 100644
--- a/content/renderer/media/webmediaplayer_ms.cc
+++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -464,6 +464,11 @@ bool WebMediaPlayerMS::UpdateCurrentFrame(base::TimeTicks deadline_min,
return false;
}
+bool WebMediaPlayerMS::HasCurrentFrame() {
+ base::AutoLock auto_lock(current_frame_lock_);
+ return current_frame_;
+}
+
scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
base::AutoLock auto_lock(current_frame_lock_);
diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h
index 7310fd6..7a5ba71 100644
--- a/content/renderer/media/webmediaplayer_ms.h
+++ b/content/renderer/media/webmediaplayer_ms.h
@@ -136,6 +136,7 @@ class WebMediaPlayerMS
cc::VideoFrameProvider::Client* client) override;
bool UpdateCurrentFrame(base::TimeTicks deadline_min,
base::TimeTicks deadline_max) override;
+ bool HasCurrentFrame() override;
scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
void PutCurrentFrame() override;
diff --git a/media/blink/video_frame_compositor.cc b/media/blink/video_frame_compositor.cc
index 3e19254..648e585 100644
--- a/media/blink/video_frame_compositor.cc
+++ b/media/blink/video_frame_compositor.cc
@@ -124,6 +124,11 @@ bool VideoFrameCompositor::UpdateCurrentFrame(base::TimeTicks deadline_min,
return CallRender(deadline_min, deadline_max, false);
}
+bool VideoFrameCompositor::HasCurrentFrame() {
+ DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ return current_frame_;
+}
+
void VideoFrameCompositor::Start(RenderCallback* callback) {
TRACE_EVENT0("media", "VideoFrameCompositor::Start");
diff --git a/media/blink/video_frame_compositor.h b/media/blink/video_frame_compositor.h
index 6b34b11..c775b0c 100644
--- a/media/blink/video_frame_compositor.h
+++ b/media/blink/video_frame_compositor.h
@@ -78,6 +78,7 @@ class MEDIA_EXPORT VideoFrameCompositor
cc::VideoFrameProvider::Client* client) override;
bool UpdateCurrentFrame(base::TimeTicks deadline_min,
base::TimeTicks deadline_max) override;
+ bool HasCurrentFrame() override;
scoped_refptr<VideoFrame> GetCurrentFrame() override;
void PutCurrentFrame() override;