if (context_provider_)
context_provider_->RemoveObserver(this);
- waiting_for_compositor_ack_ = false;
+ waiting_for_compositor_ack_ = 0;
last_frame_id_.reset();
if (video_frame_provider_)
WTF::Vector<viz::ReturnedResource> resources) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
ReclaimResources(std::move(resources));
- waiting_for_compositor_ack_ = false;
+
+ // `waiting_for_compositor_ack_` may be set to zero during SubmitEmptyFrame()
+ // or upon ContextLost().
+ if (waiting_for_compositor_ack_ == 0) {
+ DCHECK(!last_frame_id_);
+ return;
+ }
+
+ --waiting_for_compositor_ack_;
}
void VideoFrameSubmitter::OnBeginFrame(
}
#endif // defined(TIZEN_TV_UPSTREAM_MULTIMEDIA)
- if (!compositor_frame_sink_ || !ShouldSubmit())
+ if (!compositor_frame_sink_ || !ShouldSubmit()) {
return false;
+ }
// Not submitting a frame when waiting for a previous ack saves memory by
// not building up unused remote side resources. See https://crbug.com/830828.
//
// Similarly we don't submit the same frame multiple times.
- if (waiting_for_compositor_ack_ || last_frame_id_ == video_frame->unique_id())
+ if (last_frame_id_ == video_frame->unique_id()) {
return false;
-
- last_frame_id_ = video_frame->unique_id();
+ }
gfx::Size frame_size(video_frame->natural_size());
return false;
}
+ bool frame_size_changed = false;
if (frame_size_ != frame_size) {
if (!frame_size_.IsEmpty())
GenerateNewSurfaceId();
frame_size_ = frame_size;
+ frame_size_changed = true;
+ }
+
+ // We can't delay frame size changes even if we have a pending compositor ACK
+ // because a relayout signal is already in flight on the main thread.
+ if (waiting_for_compositor_ack_ > 0 && !frame_size_changed) {
+ return false;
}
+ last_frame_id_ = video_frame->unique_id();
+
auto frame_token = ++next_frame_token_;
auto source_id = begin_frame_ack.frame_id.source_id;
if (source_id != viz::BeginFrameArgs::kManualSourceId) {
last_begin_frame_args_);
resource_provider_->ReleaseFrameResources();
- waiting_for_compositor_ack_ = true;
+ ++waiting_for_compositor_ack_;
return true;
}
frame_trackers_.NotifySubmitFrame(frame_token, false, begin_frame_ack,
last_begin_frame_args_);
- // We don't set |waiting_for_compositor_ack_| here since we want to allow a
+ // We set `waiting_for_compositor_ack_` to zero here since we want to allow a
// subsequent real frame to replace it at any time if needed.
+ waiting_for_compositor_ack_ = 0;
}
void VideoFrameSubmitter::SubmitSingleFrame() {
begin_frame_source_(new viz::FakeExternalBeginFrameSource(0.f, false)),
video_frame_provider_(new StrictMock<MockVideoFrameProvider>()),
context_provider_(viz::TestContextProvider::Create()) {
- if (GetParam()) {
+ if (HasBeginFrameAcks()) {
scoped_feature_list_.InitAndEnableFeature(features::kOnBeginFrameAcks);
} else {
scoped_feature_list_.InitAndDisableFeature(features::kOnBeginFrameAcks);
task_environment_.RunUntilIdle();
}
+ bool HasBeginFrameAcks() const { return GetParam(); }
+
void MakeSubmitter() { MakeSubmitter(base::DoNothing()); }
void MakeSubmitter(
const WTF::HashMap<uint32_t, viz::FrameTimingDetails>& timing_details,
bool frame_ack,
WTF::Vector<viz::ReturnedResource> resources) {
- if (GetParam()) {
+ if (HasBeginFrameAcks() && frame_ack) {
EXPECT_CALL(*resource_provider_, ReceiveReturnsFromParent(_));
}
submitter_->OnBeginFrame(args, timing_details, frame_ack,
EXPECT_SUBMISSION(SubmissionType::kBeginFrame);
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
AckSubmittedFrame();
EXPECT_CALL(*sink_, DidNotProduceFrame(_));
args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
EXPECT_CALL(*sink_, SetNeedsBeginFrame(true));
submitter_->StartRendering();
task_environment_.RunUntilIdle();
- AckSubmittedFrame();
EXPECT_CALL(*video_frame_provider_, UpdateCurrentFrame(_, _))
.WillOnce(Return(true));
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
AckSubmittedFrame();
args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
EXPECT_CALL(*sink_, SetNeedsBeginFrame(true));
submitter_->StartRendering();
task_environment_.RunUntilIdle();
- AckSubmittedFrame();
auto frame = media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
AckSubmittedFrame();
}
EXPECT_SUBMISSION(SubmissionType::kBeginFrame);
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
args.type = viz::BeginFrameArgs::MISSED;
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
EXPECT_SUBMISSION(SubmissionType::kBeginFrame);
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
// DidNotProduceFrame should be called because no frame will be submitted
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
EXPECT_EQ(sink_->last_submitted_compositor_frame().size_in_pixels(),
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
// 180 deg rotation has same size.
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
EXPECT_EQ(sink_->last_submitted_compositor_frame().size_in_pixels(),
EXPECT_SUBMISSION(SubmissionType::kBeginFrame);
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
EXPECT_EQ(sink_->last_submitted_compositor_frame()
EXPECT_CALL(*resource_provider_, ReleaseFrameResources());
viz::BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
BEGINFRAME_FROM_HERE, now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
AckSubmittedFrame();
EXPECT_CALL(*sink_, DidNotProduceFrame(_));
args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
now_src_.get());
- OnBeginFrame(args, {}, true, WTF::Vector<viz::ReturnedResource>());
+ OnBeginFrame(args, {}, false, WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
}
auto args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
now_src_.get());
- OnBeginFrame(args, timing_details, true,
+ OnBeginFrame(args, timing_details, false,
WTF::Vector<viz::ReturnedResource>());
task_environment_.RunUntilIdle();
AckSubmittedFrame();
testing::Bool(),
[](auto& info) {
return info.param ? "BeginFrameAcks"
- : "CompositoFrameAcks";
+ : "CompositorFrameAcks";
});
} // namespace blink