Commit 0484f40a authored by Mounir Lamouri's avatar Mounir Lamouri Committed by Commit Bot

VideoSurfaceLayer: add flag to force frame submission regardless of visibility.

Picture-in-Picture requires submission even if the video may appear as
not visible to the frame submitter. This is adding a flag that is turned
on when a video enters Picture-in-Picture.

Bug: 865940
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I98ece11c4ad91ba2c34cafad711c50068fc91384
Reviewed-on: https://chromium-review.googlesource.com/1147542
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Reviewed-by: default avatarCJ DiMeglio <lethalantidote@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577781}
parent 51ca9ce3
......@@ -208,10 +208,13 @@ void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host,
if (!web_contents()->IsBeingDestroyed() && pip_player_.has_value() &&
pip_player_->render_frame_host == render_frame_host) {
content::PictureInPictureWindowController::GetOrCreateForWebContents(
web_contents())
->UpdatePlaybackState(false /* is not playing */,
reached_end_of_stream);
PictureInPictureWindowControllerImpl* pip_controller =
PictureInPictureWindowControllerImpl::FromWebContents(
web_contents_impl());
if (pip_controller) {
pip_controller->UpdatePlaybackState(false /* is not playing */,
reached_end_of_stream);
}
}
if (removed_audio || removed_video) {
......@@ -260,10 +263,13 @@ void MediaWebContentsObserver::OnMediaPlaying(
if (!web_contents()->IsBeingDestroyed() && pip_player_.has_value() &&
pip_player_->render_frame_host == render_frame_host) {
content::PictureInPictureWindowController::GetOrCreateForWebContents(
web_contents())
->UpdatePlaybackState(true /* is playing */,
false /* reached_end_of_stream */);
PictureInPictureWindowControllerImpl* pip_controller =
PictureInPictureWindowControllerImpl::FromWebContents(
web_contents_impl());
if (pip_controller) {
pip_controller->UpdatePlaybackState(true /* is not playing */,
false /* reached_end_of_stream */);
}
}
// Notify observers of the new player.
......@@ -349,13 +355,16 @@ void MediaWebContentsObserver::OnPictureInPictureSurfaceChanged(
DCHECK(surface_id.is_valid());
DCHECK(pip_player_);
pip_player_ = MediaPlayerId(render_frame_host, delegate_id);
PictureInPictureWindowControllerImpl* pip_controller =
PictureInPictureWindowControllerImpl::FromWebContents(
web_contents_impl());
DCHECK(pip_controller);
pip_player_ = MediaPlayerId(render_frame_host, delegate_id);
pip_controller->EmbedSurface(surface_id, natural_size);
// The PictureInPictureWindowController instance may not have been created by
// the embedder.
if (pip_controller)
pip_controller->EmbedSurface(surface_id, natural_size);
}
void MediaWebContentsObserver::ClearWakeLocks(
......
......@@ -80,9 +80,11 @@ VideoFrameCompositor::~VideoFrameCompositor() {
void VideoFrameCompositor::EnableSubmission(
const viz::SurfaceId& id,
media::VideoRotation rotation,
bool force_submit,
blink::WebFrameSinkDestroyedCallback frame_sink_destroyed_callback) {
DCHECK(task_runner_->BelongsToCurrentThread());
submitter_->SetRotation(rotation);
submitter_->SetForceSubmit(force_submit);
submitter_->EnableSubmission(id, std::move(frame_sink_destroyed_callback));
client_ = submitter_.get();
}
......@@ -316,4 +318,8 @@ void VideoFrameCompositor::UpdateRotation(media::VideoRotation rotation) {
submitter_->SetRotation(rotation);
}
void VideoFrameCompositor::SetForceSubmit(bool force_submit) {
submitter_->SetForceSubmit(force_submit);
}
} // namespace media
......@@ -85,6 +85,7 @@ class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink,
virtual void EnableSubmission(
const viz::SurfaceId& id,
media::VideoRotation rotation,
bool force_submit,
blink::WebFrameSinkDestroyedCallback frame_sink_destroyed_callback);
// cc::VideoFrameProvider implementation. These methods must be called on the
......@@ -131,6 +132,9 @@ class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink,
// Updates the rotation information for frames given to |submitter_|.
void UpdateRotation(media::VideoRotation rotation);
// Notifies the |submitter_| that the frames must be submitted.
void SetForceSubmit(bool);
void set_tick_clock_for_testing(const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
}
......
......@@ -34,6 +34,7 @@ class MockWebVideoFrameSubmitter : public blink::WebVideoFrameSubmitter {
MOCK_METHOD1(Initialize, void(cc::VideoFrameProvider*));
MOCK_METHOD1(SetRotation, void(media::VideoRotation));
MOCK_METHOD1(UpdateSubmissionState, void(bool));
MOCK_METHOD1(SetForceSubmit, void(bool));
void DidReceiveFrame() override { ++did_receive_frame_count_; }
int did_receive_frame_count() { return did_receive_frame_count_; }
......@@ -70,9 +71,11 @@ class VideoFrameCompositorTest : public VideoRendererSink::RenderCallback,
base::RunLoop().RunUntilIdle();
EXPECT_CALL(*submitter_,
SetRotation(Eq(media::VideoRotation::VIDEO_ROTATION_90)));
EXPECT_CALL(*submitter_, SetForceSubmit(false));
EXPECT_CALL(*submitter_, EnableSubmission(Eq(viz::SurfaceId()), _));
compositor_->EnableSubmission(viz::SurfaceId(),
media::VideoRotation::VIDEO_ROTATION_90,
false,
base::BindRepeating([] {}));
}
......
......@@ -413,10 +413,7 @@ void WebMediaPlayerImpl::OnSurfaceIdUpdated(viz::SurfaceId surface_id) {
// disabled.
// The viz::SurfaceId may be updated when the video begins playback or when
// the size of the video changes.
if (client_ &&
client_->DisplayType() ==
WebMediaPlayer::DisplayType::kPictureInPicture &&
!client_->IsInAutoPIP()) {
if (client_ && IsInPictureInPicture() && !client_->IsInAutoPIP()) {
delegate_->DidPictureInPictureSurfaceChange(
delegate_id_, surface_id, pipeline_metadata_.natural_size);
}
......@@ -522,6 +519,15 @@ void WebMediaPlayerImpl::OnHasNativeControlsChanged(bool has_native_controls) {
void WebMediaPlayerImpl::OnDisplayTypeChanged(
WebMediaPlayer::DisplayType display_type) {
if (surface_layer_for_video_enabled_) {
vfc_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&VideoFrameCompositor::SetForceSubmit,
base::Unretained(compositor_.get()),
display_type == WebMediaPlayer::DisplayType::kPictureInPicture));
}
if (!watch_time_reporter_)
return;
......@@ -812,9 +818,7 @@ void WebMediaPlayerImpl::ExitPictureInPicture(
void WebMediaPlayerImpl::RegisterPictureInPictureWindowResizeCallback(
blink::WebMediaPlayer::PipWindowResizedCallback callback) {
DCHECK(client_->DisplayType() ==
WebMediaPlayer::DisplayType::kPictureInPicture &&
!client_->IsInAutoPIP());
DCHECK(IsInPictureInPicture() && !client_->IsInAutoPIP());
delegate_->RegisterPictureInPictureWindowResizeCallback(delegate_id_,
std::move(callback));
......@@ -1649,6 +1653,7 @@ void WebMediaPlayerImpl::OnMetadata(PipelineMetadata metadata) {
&VideoFrameCompositor::EnableSubmission,
base::Unretained(compositor_.get()), bridge_->GetSurfaceId(),
pipeline_metadata_.video_decoder_config.video_rotation(),
IsInPictureInPicture(),
BindToCurrentLoop(base::BindRepeating(
&WebMediaPlayerImpl::OnFrameSinkDestroyed, AsWeakPtr()))));
bridge_->SetContentsOpaque(opaque_);
......@@ -2089,18 +2094,15 @@ void WebMediaPlayerImpl::OnBecamePersistentVideo(bool value) {
void WebMediaPlayerImpl::OnPictureInPictureModeEnded() {
// It is possible for this method to be called when the player is no longer in
// Picture-in-Picture mode.
if (!client_ || client_->DisplayType() !=
WebMediaPlayer::DisplayType::kPictureInPicture) {
if (!client_ || !IsInPictureInPicture())
return;
}
client_->PictureInPictureStopped();
}
void WebMediaPlayerImpl::OnPictureInPictureControlClicked(
const std::string& control_id) {
if (client_ && client_->DisplayType() ==
WebMediaPlayer::DisplayType::kPictureInPicture) {
if (client_ && IsInPictureInPicture()) {
client_->PictureInPictureControlClicked(
blink::WebString::FromUTF8(control_id));
}
......@@ -2967,7 +2969,7 @@ bool WebMediaPlayerImpl::IsBackgroundOptimizationCandidate() const {
DCHECK(main_task_runner_->BelongsToCurrentThread());
// Don't optimize Picture-in-Picture players.
if (client_->DisplayType() == WebMediaPlayer::DisplayType::kPictureInPicture)
if (IsInPictureInPicture())
return false;
#if defined(OS_ANDROID) // WMPI_CAST
......@@ -3219,4 +3221,10 @@ void WebMediaPlayerImpl::RecordEncryptionScheme(
EncryptionSchemeUMA::kCount);
}
bool WebMediaPlayerImpl::IsInPictureInPicture() const {
DCHECK(client_);
return client_->DisplayType() ==
WebMediaPlayer::DisplayType::kPictureInPicture;
}
} // namespace media
......@@ -581,6 +581,11 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
void RecordEncryptionScheme(const std::string& stream_name,
const EncryptionScheme& encryption_scheme);
// Returns whether the player is currently displayed in Picture-in-Picture.
// It will return true even if the player is in AutoPIP mode.
// The player MUST have a `client_` when this call happen.
bool IsInPictureInPicture() const;
blink::WebLocalFrame* const frame_;
// The playback state last reported to |delegate_|, to avoid setting duplicate
......
......@@ -319,9 +319,10 @@ class MockVideoFrameCompositor : public VideoFrameCompositor {
// MOCK_METHOD doesn't like OnceCallback.
void SetOnNewProcessedFrameCallback(OnNewProcessedFrameCB cb) override {}
MOCK_METHOD0(GetCurrentFrameAndUpdateIfStale, scoped_refptr<VideoFrame>());
MOCK_METHOD3(EnableSubmission,
MOCK_METHOD4(EnableSubmission,
void(const viz::SurfaceId&,
media::VideoRotation,
bool,
blink::WebFrameSinkDestroyedCallback));
};
......@@ -770,7 +771,7 @@ TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendNoVideoMemoryUsage) {
EXPECT_CALL(client_, SetCcLayer(_)).Times(0);
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillOnce(ReturnRef(surface_id_));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
}
......@@ -1167,7 +1168,7 @@ TEST_F(WebMediaPlayerImplTest, NoStreams) {
if (base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo)) {
EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer()).Times(0);
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId()).Times(0);
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _)).Times(0);
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _)).Times(0);
}
// Nothing should happen. In particular, no assertions should fail.
......@@ -1186,7 +1187,7 @@ TEST_F(WebMediaPlayerImplTest, NaturalSizeChange) {
EXPECT_CALL(client_, SetCcLayer(_)).Times(0);
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillOnce(ReturnRef(surface_id_));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
} else {
EXPECT_CALL(client_, SetCcLayer(NotNull()));
......@@ -1213,7 +1214,7 @@ TEST_F(WebMediaPlayerImplTest, NaturalSizeChange_Rotated) {
EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillOnce(ReturnRef(surface_id_));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
} else {
EXPECT_CALL(client_, SetCcLayer(NotNull()));
......@@ -1241,7 +1242,7 @@ TEST_F(WebMediaPlayerImplTest, VideoLockedWhenPausedWhenHidden) {
EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillOnce(ReturnRef(surface_id_));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
} else {
EXPECT_CALL(client_, SetCcLayer(NotNull()));
......@@ -1317,7 +1318,7 @@ TEST_F(WebMediaPlayerImplTest, InfiniteDuration) {
EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillOnce(ReturnRef(surface_id_));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
} else {
EXPECT_CALL(client_, SetCcLayer(NotNull()));
......@@ -1356,7 +1357,7 @@ TEST_F(WebMediaPlayerImplTest, SetContentsLayerGetsWebLayerFromBridge) {
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillOnce(ReturnRef(surface_id_));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
// We only call the callback to create the bridge in OnMetadata, so we need
// to call it.
......@@ -1394,7 +1395,7 @@ TEST_F(WebMediaPlayerImplTest, PictureInPictureTriggerCallback) {
EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
.WillRepeatedly(ReturnRef(surface_id_));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _));
EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
PipelineMetadata metadata;
......
......@@ -54,6 +54,9 @@ class BLINK_PLATFORM_EXPORT WebVideoFrameSubmitter
// Updates whether we should submit frames or not based on whether the video
// is visible on screen.
virtual void UpdateSubmissionState(bool) = 0;
// Set whether frames should always be submitted regardless of visibility.
virtual void SetForceSubmit(bool) = 0;
};
} // namespace blink
......
......@@ -62,14 +62,19 @@ void VideoFrameSubmitter::EnableSubmission(
}
void VideoFrameSubmitter::UpdateSubmissionState(bool should_submit) {
should_submit_ = should_submit;
should_submit_internal_ = should_submit;
UpdateSubmissionStateInternal();
}
void VideoFrameSubmitter::SetForceSubmit(bool force_submit) {
force_submit_ = force_submit;
UpdateSubmissionStateInternal();
}
void VideoFrameSubmitter::UpdateSubmissionStateInternal() {
if (compositor_frame_sink_) {
compositor_frame_sink_->SetNeedsBeginFrame(is_rendering_ && should_submit_);
if (should_submit_)
compositor_frame_sink_->SetNeedsBeginFrame(is_rendering_ && ShouldSubmit());
if (ShouldSubmit())
SubmitSingleFrame();
else if (!frame_size_.IsEmpty())
SubmitEmptyFrame();
......@@ -110,6 +115,10 @@ void VideoFrameSubmitter::SubmitSingleFrame() {
}
}
bool VideoFrameSubmitter::ShouldSubmit() const {
return should_submit_internal_ || force_submit_;
}
void VideoFrameSubmitter::DidReceiveFrame() {
DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_);
DCHECK(provider_);
......@@ -127,7 +136,7 @@ void VideoFrameSubmitter::StartRendering() {
is_rendering_ = true;
if (compositor_frame_sink_)
compositor_frame_sink_->SetNeedsBeginFrame(is_rendering_ && should_submit_);
compositor_frame_sink_->SetNeedsBeginFrame(is_rendering_ && ShouldSubmit());
}
void VideoFrameSubmitter::Initialize(cc::VideoFrameProvider* provider) {
......@@ -193,7 +202,7 @@ void VideoFrameSubmitter::SubmitFrame(
scoped_refptr<media::VideoFrame> video_frame) {
TRACE_EVENT0("media", "VideoFrameSubmitter::SubmitFrame");
DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_);
if (!compositor_frame_sink_ || !should_submit_)
if (!compositor_frame_sink_ || !ShouldSubmit())
return;
// TODO(mlamouri): the `frame_size_` is expected to be consistent but seems to
......@@ -234,7 +243,7 @@ void VideoFrameSubmitter::SubmitFrame(
void VideoFrameSubmitter::SubmitEmptyFrame() {
TRACE_EVENT0("media", "VideoFrameSubmitter::SubmitEmptyFrame");
DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_);
DCHECK(compositor_frame_sink_ && !should_submit_);
DCHECK(compositor_frame_sink_ && !ShouldSubmit());
DCHECK(!frame_size_.IsEmpty());
viz::CompositorFrame compositor_frame;
......@@ -321,7 +330,7 @@ void VideoFrameSubmitter::OnContextLost() {
// We need to trigger another submit so that surface_id's get propagated
// correctly. If we don't, we don't get any more signals to update the
// submission state.
should_submit_ = true;
should_submit_internal_ = true;
}
void VideoFrameSubmitter::DidReceiveCompositorFrameAck(
......
......@@ -64,6 +64,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
void SetRotation(media::VideoRotation) override;
void EnableSubmission(viz::SurfaceId, WebFrameSinkDestroyedCallback) override;
void UpdateSubmissionState(bool) override;
void SetForceSubmit(bool) override;
// viz::ContextLostObserver implementation.
void OnContextLost() override;
......@@ -88,6 +89,8 @@ class PLATFORM_EXPORT VideoFrameSubmitter
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest, ContextLostDuringSubmit);
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest,
ShouldSubmitPreventsSubmission);
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest,
SetForceSubmitForcesSubmission);
void StartSubmitting();
void UpdateSubmissionStateInternal();
......@@ -100,6 +103,10 @@ class PLATFORM_EXPORT VideoFrameSubmitter
// ending rendering.
void SubmitSingleFrame();
// Return whether the submitter should submit frames based on its current
// state.
bool ShouldSubmit() const;
cc::VideoFrameProvider* provider_ = nullptr;
scoped_refptr<ui::ContextProviderCommandBuffer> context_provider_;
viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
......@@ -112,7 +119,9 @@ class PLATFORM_EXPORT VideoFrameSubmitter
bool is_rendering_;
// If we are not on screen, we should not submit.
bool should_submit_ = false;
bool should_submit_internal_ = false;
// Whether frames should always be submitted.
bool force_submit_ = false;
media::VideoRotation rotation_;
// Size of the video frame being submitted. It is set the first time a frame
......
......@@ -279,6 +279,8 @@ TEST_F(VideoFrameSubmitterTest, ShouldSubmitPreventsSubmission) {
submitter_->UpdateSubmissionState(false);
scoped_task_environment_.RunUntilIdle();
EXPECT_FALSE(submitter_->ShouldSubmit());
EXPECT_CALL(*sink_, SetNeedsBeginFrame(false));
submitter_->StartRendering();
scoped_task_environment_.RunUntilIdle();
......@@ -296,12 +298,84 @@ TEST_F(VideoFrameSubmitterTest, ShouldSubmitPreventsSubmission) {
submitter_->UpdateSubmissionState(true);
scoped_task_environment_.RunUntilIdle();
EXPECT_TRUE(submitter_->ShouldSubmit());
EXPECT_CALL(*sink_, SetNeedsBeginFrame(false));
EXPECT_CALL(*sink_, DoSubmitCompositorFrame(_, _)).Times(1);
EXPECT_CALL(*provider_, GetCurrentFrame()).Times(0);
submitter_->UpdateSubmissionState(false);
scoped_task_environment_.RunUntilIdle();
EXPECT_FALSE(submitter_->ShouldSubmit());
EXPECT_CALL(*provider_, GetCurrentFrame())
.WillOnce(Return(media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
gfx::Size(8, 8), base::TimeDelta())));
EXPECT_CALL(*provider_, PutCurrentFrame());
submitter_->SubmitSingleFrame();
}
// Tests that when set to true SetForceSubmit forces frame submissions.
// regardless of the internal submit state.
TEST_F(VideoFrameSubmitterTest, SetForceSubmitForcesSubmission) {
MakeSubmitter();
scoped_task_environment_.RunUntilIdle();
EXPECT_CALL(*sink_, SetNeedsBeginFrame(false));
submitter_->UpdateSubmissionState(false);
scoped_task_environment_.RunUntilIdle();
EXPECT_FALSE(submitter_->ShouldSubmit());
EXPECT_CALL(*provider_, GetCurrentFrame())
.WillOnce(Return(media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
gfx::Size(8, 8), base::TimeDelta())));
EXPECT_CALL(*provider_, PutCurrentFrame());
submitter_->SetForceSubmit(true);
EXPECT_TRUE(submitter_->ShouldSubmit());
EXPECT_CALL(*sink_, SetNeedsBeginFrame(false));
EXPECT_CALL(*sink_, DoSubmitCompositorFrame(_, _)).Times(1);
EXPECT_CALL(*resource_provider_, AppendQuads(_, _, _));
EXPECT_CALL(*resource_provider_, PrepareSendToParent(_, _));
EXPECT_CALL(*resource_provider_, ReleaseFrameResources());
EXPECT_CALL(*sink_, SetNeedsBeginFrame(true));
submitter_->StartRendering();
scoped_task_environment_.RunUntilIdle();
EXPECT_CALL(*sink_, SetNeedsBeginFrame(true));
EXPECT_CALL(*provider_, GetCurrentFrame())
.WillOnce(Return(media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
gfx::Size(8, 8), base::TimeDelta())));
EXPECT_CALL(*sink_, DoSubmitCompositorFrame(_, _)).Times(1);
EXPECT_CALL(*provider_, PutCurrentFrame());
EXPECT_CALL(*resource_provider_, AppendQuads(_, _, _));
EXPECT_CALL(*resource_provider_, PrepareSendToParent(_, _));
EXPECT_CALL(*resource_provider_, ReleaseFrameResources());
submitter_->UpdateSubmissionState(true);
scoped_task_environment_.RunUntilIdle();
EXPECT_TRUE(submitter_->ShouldSubmit());
EXPECT_CALL(*sink_, SetNeedsBeginFrame(true));
EXPECT_CALL(*sink_, DoSubmitCompositorFrame(_, _)).Times(1);
EXPECT_CALL(*provider_, PutCurrentFrame());
EXPECT_CALL(*provider_, GetCurrentFrame())
.WillOnce(Return(media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
gfx::Size(8, 8), base::TimeDelta())));
EXPECT_CALL(*resource_provider_, AppendQuads(_, _, _));
EXPECT_CALL(*resource_provider_, PrepareSendToParent(_, _));
EXPECT_CALL(*resource_provider_, ReleaseFrameResources());
submitter_->UpdateSubmissionState(false);
scoped_task_environment_.RunUntilIdle();
EXPECT_TRUE(submitter_->ShouldSubmit());
EXPECT_CALL(*provider_, GetCurrentFrame())
.WillOnce(Return(media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment