diff options
author | hendrikw <hendrikw@chromium.org> | 2015-05-18 16:14:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-18 23:14:21 +0000 |
commit | e19cc6a61419d38f3ec658c5e74363d77e900c09 (patch) | |
tree | 351e34313a99f53dc3675014babdb8ff6f295822 | |
parent | 1dfbd1030bd04e76ba41bff933cd2d8fc6d1e3f0 (diff) | |
download | chromium_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.h | 4 | ||||
-rw-r--r-- | cc/layers/video_frame_provider_client_impl.cc | 5 | ||||
-rw-r--r-- | cc/layers/video_frame_provider_client_impl.h | 1 | ||||
-rw-r--r-- | cc/layers/video_layer_impl.cc | 7 | ||||
-rw-r--r-- | cc/layers/video_layer_impl.h | 1 | ||||
-rw-r--r-- | cc/layers/video_layer_impl_unittest.cc | 44 | ||||
-rw-r--r-- | cc/test/fake_video_frame_provider.cc | 4 | ||||
-rw-r--r-- | cc/test/fake_video_frame_provider.h | 1 | ||||
-rw-r--r-- | content/renderer/media/android/webmediaplayer_android.cc | 5 | ||||
-rw-r--r-- | content/renderer/media/android/webmediaplayer_android.h | 1 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_ms.cc | 5 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_ms.h | 1 | ||||
-rw-r--r-- | media/blink/video_frame_compositor.cc | 5 | ||||
-rw-r--r-- | media/blink/video_frame_compositor.h | 1 |
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; |