OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/compositor/gpu_vsync_begin_frame_source.h" | 5 #include "content/browser/compositor/gpu_vsync_begin_frame_source.h" |
6 | 6 |
7 namespace content { | 7 namespace content { |
8 | 8 |
9 GpuVSyncBeginFrameSource::GpuVSyncBeginFrameSource( | 9 GpuVSyncBeginFrameSource::GpuVSyncBeginFrameSource( |
10 GpuVSyncControl* vsync_control) | 10 GpuVSyncControl* vsync_control) |
11 : cc::ExternalBeginFrameSource(this), | 11 : cc::ExternalBeginFrameSource(this), |
12 vsync_control_(vsync_control), | 12 vsync_control_(vsync_control), |
13 needs_begin_frames_(false), | 13 needs_begin_frames_(false), |
14 next_sequence_number_(cc::BeginFrameArgs::kStartingFrameNumber) { | 14 next_sequence_number_(cc::BeginFrameArgs::kStartingFrameNumber) { |
15 DCHECK(vsync_control); | 15 DCHECK(vsync_control); |
16 } | 16 } |
17 | 17 |
18 GpuVSyncBeginFrameSource::~GpuVSyncBeginFrameSource() = default; | 18 GpuVSyncBeginFrameSource::~GpuVSyncBeginFrameSource() = default; |
19 | 19 |
20 void GpuVSyncBeginFrameSource::OnVSync(base::TimeTicks timestamp, | 20 void GpuVSyncBeginFrameSource::OnVSync(base::TimeTicks timestamp, |
21 base::TimeDelta interval) { | 21 base::TimeDelta interval) { |
22 if (!needs_begin_frames_) | 22 if (!needs_begin_frames_) |
23 return; | 23 return; |
24 | 24 |
25 base::TimeTicks now = base::TimeTicks::Now(); | 25 base::TimeTicks now = Now(); |
26 base::TimeTicks deadline = now.SnappedToNextTick(timestamp, interval); | 26 base::TimeTicks deadline = now.SnappedToNextTick(timestamp, interval); |
27 | 27 |
28 TRACE_EVENT1("cc", "GpuVSyncBeginFrameSource::OnVSync", "latency", | 28 TRACE_EVENT1("cc", "GpuVSyncBeginFrameSource::OnVSync", "latency", |
29 (now - timestamp).ToInternalValue()); | 29 (now - timestamp).ToInternalValue()); |
30 | 30 |
31 next_sequence_number_++; | 31 next_sequence_number_++; |
32 OnBeginFrame(cc::BeginFrameArgs::Create( | 32 OnBeginFrame(cc::BeginFrameArgs::Create( |
33 BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, timestamp, | 33 BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, timestamp, |
34 deadline, interval, cc::BeginFrameArgs::NORMAL)); | 34 deadline, interval, cc::BeginFrameArgs::NORMAL)); |
35 } | 35 } |
36 | 36 |
37 void GpuVSyncBeginFrameSource::OnNeedsBeginFrames(bool needs_begin_frames) { | 37 void GpuVSyncBeginFrameSource::OnNeedsBeginFrames(bool needs_begin_frames) { |
38 needs_begin_frames_ = needs_begin_frames; | 38 needs_begin_frames_ = needs_begin_frames; |
39 vsync_control_->SetNeedsVSync(needs_begin_frames); | 39 vsync_control_->SetNeedsVSync(needs_begin_frames); |
40 } | 40 } |
41 | 41 |
| 42 base::TimeTicks GpuVSyncBeginFrameSource::Now() const { |
| 43 return base::TimeTicks::Now(); |
| 44 } |
| 45 |
| 46 cc::BeginFrameArgs GpuVSyncBeginFrameSource::GetMissedBeginFrameArgs( |
| 47 cc::BeginFrameObserver* obs) { |
| 48 if (!last_begin_frame_args_.IsValid()) |
| 49 return cc::BeginFrameArgs(); |
| 50 |
| 51 base::TimeTicks now = Now(); |
| 52 base::TimeTicks estimated_next_timestamp = now.SnappedToNextTick( |
| 53 last_begin_frame_args_.frame_time, last_begin_frame_args_.interval); |
| 54 base::TimeTicks missed_timestamp = |
| 55 estimated_next_timestamp - last_begin_frame_args_.interval; |
| 56 |
| 57 if (missed_timestamp > last_begin_frame_args_.frame_time) { |
| 58 // The projected missed timestamp is newer than the last known timestamp. |
| 59 // In this case create BeginFrameArgs with a new sequence number. |
| 60 next_sequence_number_++; |
| 61 last_begin_frame_args_ = cc::BeginFrameArgs::Create( |
| 62 BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, |
| 63 missed_timestamp, estimated_next_timestamp, |
| 64 last_begin_frame_args_.interval, cc::BeginFrameArgs::MISSED); |
| 65 return last_begin_frame_args_; |
| 66 } |
| 67 |
| 68 // The last known args object is up-to-date. Skip sending notification |
| 69 // if the observer has already seen it. |
| 70 const cc::BeginFrameArgs& last_observer_args = obs->LastUsedBeginFrameArgs(); |
| 71 if (last_observer_args.IsValid() && |
| 72 last_begin_frame_args_.frame_time <= last_observer_args.frame_time) { |
| 73 return cc::BeginFrameArgs(); |
| 74 } |
| 75 |
| 76 cc::BeginFrameArgs missed_args = last_begin_frame_args_; |
| 77 missed_args.type = cc::BeginFrameArgs::MISSED; |
| 78 return missed_args; |
| 79 } |
| 80 |
42 } // namespace content | 81 } // namespace content |
OLD | NEW |