Mir

Merge lp:~kdub/mir/report-vsync into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 2361
Proposed branch: lp:~kdub/mir/report-vsync
Merge into: lp:mir
Diff against target: 782 lines (+228/-89)
26 files modified
src/include/platform/mir/graphics/display_report.h (+2/-0)
src/platforms/android/server/display.cpp (+9/-1)
src/platforms/android/server/display.h (+2/-0)
src/platforms/android/server/fb_device.cpp (+3/-1)
src/platforms/android/server/fb_device.h (+3/-1)
src/platforms/android/server/hwc_blanking_control.cpp (+4/-3)
src/platforms/android/server/hwc_configuration.h (+6/-2)
src/platforms/mesa/server/display.cpp (+1/-1)
src/platforms/mesa/server/kms_page_flipper.cpp (+19/-10)
src/platforms/mesa/server/kms_page_flipper.h (+5/-2)
src/server/report/logging/display_report.cpp (+26/-1)
src/server/report/logging/display_report.h (+24/-13)
src/server/report/logging/logging_report_factory.cpp (+1/-1)
src/server/report/lttng/display_report.cpp (+2/-6)
src/server/report/lttng/display_report.h (+10/-11)
src/server/report/lttng/display_report_tp.h (+9/-0)
src/server/report/null/display_report.cpp (+1/-0)
src/server/report/null/display_report.h (+1/-0)
tests/include/mir_test_doubles/mock_display_report.h (+1/-2)
tests/include/mir_test_doubles/stub_display_builder.h (+5/-4)
tests/unit-tests/graphics/android/test_display.cpp (+26/-4)
tests/unit-tests/graphics/android/test_display_hotplug.cpp (+3/-3)
tests/unit-tests/graphics/android/test_hwc_configuration.cpp (+13/-7)
tests/unit-tests/graphics/mesa/test_display.cpp (+5/-4)
tests/unit-tests/graphics/mesa/test_kms_page_flipper.cpp (+20/-1)
tests/unit-tests/logging/test_display_report.cpp (+27/-11)
To merge this branch: bzr merge lp:~kdub/mir/report-vsync
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Alan Griffiths Approve
Andreas Pokorny (community) Approve
Alexandros Frantzis (community) Approve
Daniel van Vugt Abstain
Review via email: mp+251532@code.launchpad.net

Commit message

graphics: add a report_vsync method for android and mesa in mg::DisplayReport with logging, null, and lttng implementations of function.

Description of the change

graphics: add a report_vsync method for android and mesa in mg::DisplayReport with logging, null, and lttng implementations of function.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Suggest "needs fixing", but not strictly.

(1) The name arguably needs fixing because "vsync" is not an event. The two events are (a) vblank and then (about 50-60 microseconds later); (b) page flip completed. Although not all platforms will implement it as a "page flip" so the generic term we invented "post" could be used.

(2) These two equivalent reporting points would be less confusing if unified:

180 /* If the page flip we are waiting for has arrived we are done. */
181 if (page_flip_is_done(crtc_id))
182 + {
183 + report->report_vsync(std::to_string(crtc_id));
184 return;
185 + }
186
187 /* ...otherwise we become the worker */
188 worker_tid = std::this_thread::get_id();
189 @@ -140,6 +146,7 @@
190 */
191 pf_cv.notify_all();
192 }
193 + report->report_vsync(std::to_string(crtc_id));

You can do this by making ::page_flip_handler call a new `KMSPageFlipper::page_flip_handler()', as that would have access to the `report' and other private fields. And then you correctly only have to call `report_vsync' in one place.

This is fresh in my mind as I spent much of the past few days hacking this code :)

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(1) Whoops, don't call it "post". "post" is the push event at the back of the DisplayBuffer's queue, whereas you're actually measuring the pop from the front. So yeah call it "vsync" if not "scan-out" etc.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

45 + display_report->report_vsync(std::to_string(name));

The report interfaces shouldn't force any unnecessary object creation. (Like creating a string here.) In practice we've got an int - so can't we pass that and stream that to output only if reporting?

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

@Daniel,
1) seems like were keeping report_vsync() then?
2) good idea, we now call the report from the pageflip callback.

@Alan, corrected to take an int as a display id.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

Looks like a transient error:
subprocess.CalledProcessError: Command 'phablet-network --skip-setup' returned non-zero exit status 124

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(3) You don't need to pass pending_page_flips into the callback any more. Just do the erase in notify_page_flip instead...
156 + page_flip_data->flipper->notify_page_flip(page_flip_data->crtc_id);
157 page_flip_data->pending->erase(page_flip_data->crtc_id);
~~
180 - pending_page_flips[crtc_id] = PageFlipEventData{&pending_page_flips, crtc_id};
181 + pending_page_flips[crtc_id] = PageFlipEventData{&pending_page_flips, crtc_id, this};

(4) The timing is slightly off, but it's probably negligible. The report will be called after the actual page flip happened, because we're calling it from our wait function which could be anything up to a frame later than when the flip "vsync" occurred. To get accurate timings into the report, use the (presently unused) timestamp parameters in the page flip callback (which is a kernel timestamp relative to CLOCK_MONOTONIC). Although the complexity this creates might be worse than any inaccuracies in the current approach. It's also platform-specific unless you convert between clocks. So maybe not...

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK

One thought though...

239 +void mrl::DisplayReport::report_vsync(unsigned int display_id)
240 +{
241 + logger->log(ml::Severity::informational, "vsync event on [" + std::to_string(display_id) + "]", component());
242 +}

...is the raw "vsync event on [...]" log message useful or should the report be collating statistical information?

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

> (3) You don't need to pass pending_page_flips into the callback any more.

+1 but not a blocker

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

looks good, yes and agree.. that might be to much spam to be interesting. I think it might also be fine to just omit it for now, until we figure out what information might be worth interpreting.

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

(3) is a good improvement, added to this branch
(4) true, although I think it would be neglible as well (I'm interested in hundreds-of-microsecond resolution)

Also collated the vsync data so it would be reported at most once per second.

Revision history for this message
Kevin DuBois (kdub) wrote :

> (3) is a good improvement, added to this branch
> (4) true, although I think it would be neglible as well (I'm interested in
> hundreds-of-microsecond resolution)
>
> Also collated the vsync data so it would be reported at most once per second.

example output:
[1425479039.147480] graphics: 42 vsync events on [0] over 1004ms
[1425479040.148487] graphics: 60 vsync events on [0] over 1001ms
[1425479041.149372] graphics: 60 vsync events on [0] over 1000ms

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

263 + event_map[display_id]++;
264 + if (now > last_report + report_interval)
265 + {
266 + for(auto const& event : event_map)
267 + logger->log(ml::Severity::informational,
268 + std::to_string(event.second) + " vsync events on [" +
269 + std::to_string(event.first) + "] over " +
270 + std::to_string(duration_cast<milliseconds>(now - last_report).count()) + "ms",
271 + component());
272 + event_map.clear();
273 + last_report = now;
274 + }

Needs a mutex & lock

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

LGTM

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

^^manually cancelled

Revision history for this message
Robert Carr (robertcarr) wrote :

LGTM.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/include/platform/mir/graphics/display_report.h'
--- src/include/platform/mir/graphics/display_report.h 2015-01-21 07:34:50 +0000
+++ src/include/platform/mir/graphics/display_report.h 2015-03-04 14:36:55 +0000
@@ -35,6 +35,8 @@
35 virtual void report_successful_egl_buffer_swap_on_construction() = 0;35 virtual void report_successful_egl_buffer_swap_on_construction() = 0;
36 virtual void report_successful_display_construction() = 0;36 virtual void report_successful_display_construction() = 0;
37 virtual void report_egl_configuration(EGLDisplay disp, EGLConfig cfg) = 0;37 virtual void report_egl_configuration(EGLDisplay disp, EGLConfig cfg) = 0;
38 virtual void report_vsync(unsigned int display_id) = 0;
39
38 /* gbm specific */40 /* gbm specific */
39 virtual void report_successful_drm_mode_set_crtc_on_construction() = 0;41 virtual void report_successful_drm_mode_set_crtc_on_construction() = 0;
40 virtual void report_drm_master_failure(int error) = 0;42 virtual void report_drm_master_failure(int error) = 0;
4143
=== modified file 'src/platforms/android/server/display.cpp'
--- src/platforms/android/server/display.cpp 2015-03-03 06:56:37 +0000
+++ src/platforms/android/server/display.cpp 2015-03-04 14:36:55 +0000
@@ -135,9 +135,12 @@
135 std::shared_ptr<GLConfig> const& gl_config,135 std::shared_ptr<GLConfig> const& gl_config,
136 std::shared_ptr<DisplayReport> const& display_report,136 std::shared_ptr<DisplayReport> const& display_report,
137 mga::OverlayOptimization overlay_option) :137 mga::OverlayOptimization overlay_option) :
138 display_report{display_report},
138 display_buffer_builder{display_buffer_builder},139 display_buffer_builder{display_buffer_builder},
139 hwc_config{display_buffer_builder->create_hwc_configuration()},140 hwc_config{display_buffer_builder->create_hwc_configuration()},
140 hotplug_subscription{hwc_config->subscribe_to_config_changes(std::bind(&mga::Display::on_hotplug, this))},141 hotplug_subscription{hwc_config->subscribe_to_config_changes(
142 std::bind(&mga::Display::on_hotplug, this),
143 std::bind(&mga::Display::on_vsync, this, std::placeholders::_1))},
141 primary_attribs(hwc_config->active_attribs_for(mga::DisplayName::primary)),144 primary_attribs(hwc_config->active_attribs_for(mga::DisplayName::primary)),
142 external_attribs(hwc_config->active_attribs_for(mga::DisplayName::external)),145 external_attribs(hwc_config->active_attribs_for(mga::DisplayName::external)),
143 config(146 config(
@@ -269,6 +272,11 @@
269 display_change_pipe->notify_change();272 display_change_pipe->notify_change();
270}273}
271274
275void mga::Display::on_vsync(DisplayName name) const
276{
277 display_report->report_vsync(name);
278}
279
272void mga::Display::register_configuration_change_handler(280void mga::Display::register_configuration_change_handler(
273 EventHandlerRegister& event_handler,281 EventHandlerRegister& event_handler,
274 DisplayConfigurationChangeHandler const& change_handler)282 DisplayConfigurationChangeHandler const& change_handler)
275283
=== modified file 'src/platforms/android/server/display.h'
--- src/platforms/android/server/display.h 2015-03-03 06:56:37 +0000
+++ src/platforms/android/server/display.h 2015-03-04 14:36:55 +0000
@@ -80,7 +80,9 @@
8080
81private:81private:
82 void on_hotplug();82 void on_hotplug();
83 void on_vsync(DisplayName) const;
8384
85 std::shared_ptr<DisplayReport> const display_report;
84 std::shared_ptr<DisplayComponentFactory> const display_buffer_builder;86 std::shared_ptr<DisplayComponentFactory> const display_buffer_builder;
85 std::mutex mutable configuration_mutex;87 std::mutex mutable configuration_mutex;
86 bool mutable configuration_dirty{false};88 bool mutable configuration_dirty{false};
8789
=== modified file 'src/platforms/android/server/fb_device.cpp'
--- src/platforms/android/server/fb_device.cpp 2015-03-03 06:56:37 +0000
+++ src/platforms/android/server/fb_device.cpp 2015-03-04 14:36:55 +0000
@@ -68,7 +68,9 @@
68 fb_num};68 fb_num};
69}69}
7070
71mga::ConfigChangeSubscription mga::FbControl::subscribe_to_config_changes(std::function<void()> const&)71mga::ConfigChangeSubscription mga::FbControl::subscribe_to_config_changes(
72 std::function<void()> const&,
73 std::function<void(DisplayName)> const&)
72{74{
73 return nullptr;75 return nullptr;
74}76}
7577
=== modified file 'src/platforms/android/server/fb_device.h'
--- src/platforms/android/server/fb_device.h 2015-03-03 06:56:37 +0000
+++ src/platforms/android/server/fb_device.h 2015-03-04 14:36:55 +0000
@@ -37,7 +37,9 @@
37 FbControl(std::shared_ptr<framebuffer_device_t> const& fbdev);37 FbControl(std::shared_ptr<framebuffer_device_t> const& fbdev);
38 void power_mode(DisplayName, MirPowerMode) override;38 void power_mode(DisplayName, MirPowerMode) override;
39 DisplayAttribs active_attribs_for(DisplayName) override;39 DisplayAttribs active_attribs_for(DisplayName) override;
40 ConfigChangeSubscription subscribe_to_config_changes(std::function<void()> const& cb) override;40 ConfigChangeSubscription subscribe_to_config_changes(
41 std::function<void()> const& hotplug_cb,
42 std::function<void(DisplayName)> const& vsync_cb) override;
41private:43private:
42 std::shared_ptr<framebuffer_device_t> const fb_device;44 std::shared_ptr<framebuffer_device_t> const fb_device;
43};45};
4446
=== modified file 'src/platforms/android/server/hwc_blanking_control.cpp'
--- src/platforms/android/server/hwc_blanking_control.cpp 2015-03-03 06:56:37 +0000
+++ src/platforms/android/server/hwc_blanking_control.cpp 2015-03-04 14:36:55 +0000
@@ -146,13 +146,14 @@
146}146}
147147
148mga::ConfigChangeSubscription mga::HwcBlankingControl::subscribe_to_config_changes(148mga::ConfigChangeSubscription mga::HwcBlankingControl::subscribe_to_config_changes(
149 std::function<void()> const& hotplug)149 std::function<void()> const& hotplug,
150 std::function<void(DisplayName)> const& vsync)
150{151{
151 return std::make_shared<152 return std::make_shared<
152 mir::raii::PairedCalls<std::function<void()>, std::function<void()>>>(153 mir::raii::PairedCalls<std::function<void()>, std::function<void()>>>(
153 [hotplug, this]{154 [hotplug, vsync, this]{
154 hwc_device->subscribe_to_events(this,155 hwc_device->subscribe_to_events(this,
155 [](DisplayName, std::chrono::nanoseconds){},156 [vsync](DisplayName name, std::chrono::nanoseconds){ vsync(name); },
156 [hotplug](DisplayName, bool){ hotplug(); },157 [hotplug](DisplayName, bool){ hotplug(); },
157 []{});158 []{});
158 },159 },
159160
=== modified file 'src/platforms/android/server/hwc_configuration.h'
--- src/platforms/android/server/hwc_configuration.h 2015-02-13 06:12:34 +0000
+++ src/platforms/android/server/hwc_configuration.h 2015-03-04 14:36:55 +0000
@@ -50,7 +50,9 @@
50 virtual ~HwcConfiguration() = default;50 virtual ~HwcConfiguration() = default;
51 virtual void power_mode(DisplayName, MirPowerMode) = 0;51 virtual void power_mode(DisplayName, MirPowerMode) = 0;
52 virtual DisplayAttribs active_attribs_for(DisplayName) = 0; 52 virtual DisplayAttribs active_attribs_for(DisplayName) = 0;
53 virtual ConfigChangeSubscription subscribe_to_config_changes(std::function<void()> const& cb) = 0;53 virtual ConfigChangeSubscription subscribe_to_config_changes(
54 std::function<void()> const& hotplug_cb,
55 std::function<void(DisplayName)> const& vsync_cb) = 0;
5456
55protected:57protected:
56 HwcConfiguration() = default;58 HwcConfiguration() = default;
@@ -65,7 +67,9 @@
65 HwcBlankingControl(std::shared_ptr<HwcWrapper> const&);67 HwcBlankingControl(std::shared_ptr<HwcWrapper> const&);
66 void power_mode(DisplayName, MirPowerMode) override;68 void power_mode(DisplayName, MirPowerMode) override;
67 DisplayAttribs active_attribs_for(DisplayName) override;69 DisplayAttribs active_attribs_for(DisplayName) override;
68 ConfigChangeSubscription subscribe_to_config_changes(std::function<void()> const& cb) override;70 ConfigChangeSubscription subscribe_to_config_changes(
71 std::function<void()> const& hotplug_cb,
72 std::function<void(DisplayName)> const& vsync_cb) override;
6973
70private:74private:
71 DeviceQuirks quirks{PropertiesOps{}};75 DeviceQuirks quirks{PropertiesOps{}};
7276
=== modified file 'src/platforms/mesa/server/display.cpp'
--- src/platforms/mesa/server/display.cpp 2015-02-26 03:20:09 +0000
+++ src/platforms/mesa/server/display.cpp 2015-03-04 14:36:55 +0000
@@ -88,7 +88,7 @@
88 monitor(mir::udev::Context()),88 monitor(mir::udev::Context()),
89 shared_egl{*gl_config},89 shared_egl{*gl_config},
90 output_container{platform->drm->fd,90 output_container{platform->drm->fd,
91 std::make_shared<KMSPageFlipper>(platform->drm->fd)},91 std::make_shared<KMSPageFlipper>(platform->drm->fd, listener)},
92 current_display_configuration{platform->drm->fd},92 current_display_configuration{platform->drm->fd},
93 gl_config{gl_config}93 gl_config{gl_config}
94{94{
9595
=== modified file 'src/platforms/mesa/server/kms_page_flipper.cpp'
--- src/platforms/mesa/server/kms_page_flipper.cpp 2015-01-22 09:00:14 +0000
+++ src/platforms/mesa/server/kms_page_flipper.cpp 2015-03-04 14:36:55 +0000
@@ -37,15 +37,18 @@
37 void* data)37 void* data)
38{38{
39 auto page_flip_data = static_cast<mgm::PageFlipEventData*>(data);39 auto page_flip_data = static_cast<mgm::PageFlipEventData*>(data);
40 page_flip_data->pending->erase(page_flip_data->crtc_id);40 page_flip_data->flipper->notify_page_flip(page_flip_data->crtc_id);
41}41}
4242
43}43}
4444
45mgm::KMSPageFlipper::KMSPageFlipper(int drm_fd)45mgm::KMSPageFlipper::KMSPageFlipper(
46 : drm_fd{drm_fd},46 int drm_fd,
47 pending_page_flips(),47 std::shared_ptr<DisplayReport> const& report) :
48 worker_tid()48 drm_fd{drm_fd},
49 report{report},
50 pending_page_flips(),
51 worker_tid()
49{52{
50}53}
5154
@@ -56,7 +59,7 @@
56 if (pending_page_flips.find(crtc_id) != pending_page_flips.end())59 if (pending_page_flips.find(crtc_id) != pending_page_flips.end())
57 BOOST_THROW_EXCEPTION(std::logic_error("Page flip for crtc_id is already scheduled"));60 BOOST_THROW_EXCEPTION(std::logic_error("Page flip for crtc_id is already scheduled"));
5861
59 pending_page_flips[crtc_id] = PageFlipEventData{&pending_page_flips, crtc_id};62 pending_page_flips[crtc_id] = PageFlipEventData{crtc_id, this};
6063
61 auto ret = drmModePageFlip(drm_fd, crtc_id, fb_id,64 auto ret = drmModePageFlip(drm_fd, crtc_id, fb_id,
62 DRM_MODE_PAGE_FLIP_EVENT,65 DRM_MODE_PAGE_FLIP_EVENT,
@@ -154,3 +157,9 @@
154{157{
155 return pending_page_flips.find(crtc_id) == pending_page_flips.end();158 return pending_page_flips.find(crtc_id) == pending_page_flips.end();
156}159}
160
161void mgm::KMSPageFlipper::notify_page_flip(uint32_t crtc_id)
162{
163 report->report_vsync(crtc_id);
164 pending_page_flips.erase(crtc_id);
165}
157166
=== modified file 'src/platforms/mesa/server/kms_page_flipper.h'
--- src/platforms/mesa/server/kms_page_flipper.h 2015-01-22 09:00:14 +0000
+++ src/platforms/mesa/server/kms_page_flipper.h 2015-03-04 14:36:55 +0000
@@ -39,26 +39,29 @@
39namespace mesa39namespace mesa
40{40{
4141
42class KMSPageFlipper;
42struct PageFlipEventData43struct PageFlipEventData
43{44{
44 std::unordered_map<uint32_t,PageFlipEventData>* pending;
45 uint32_t crtc_id;45 uint32_t crtc_id;
46 KMSPageFlipper* flipper;
46};47};
4748
48class KMSPageFlipper : public PageFlipper49class KMSPageFlipper : public PageFlipper
49{50{
50public:51public:
51 KMSPageFlipper(int drm_fd);52 KMSPageFlipper(int drm_fd, std::shared_ptr<DisplayReport> const& report);
5253
53 bool schedule_flip(uint32_t crtc_id, uint32_t fb_id);54 bool schedule_flip(uint32_t crtc_id, uint32_t fb_id);
54 void wait_for_flip(uint32_t crtc_id);55 void wait_for_flip(uint32_t crtc_id);
5556
56 std::thread::id debug_get_worker_tid();57 std::thread::id debug_get_worker_tid();
5758
59 void notify_page_flip(uint32_t crtc_id);
58private:60private:
59 bool page_flip_is_done(uint32_t crtc_id);61 bool page_flip_is_done(uint32_t crtc_id);
6062
61 int const drm_fd;63 int const drm_fd;
64 std::shared_ptr<DisplayReport> const report;
62 std::unordered_map<uint32_t,PageFlipEventData> pending_page_flips;65 std::unordered_map<uint32_t,PageFlipEventData> pending_page_flips;
63 std::mutex pf_mutex;66 std::mutex pf_mutex;
64 std::condition_variable pf_cv;67 std::condition_variable pf_cv;
6568
=== modified file 'src/server/report/logging/display_report.cpp'
--- src/server/report/logging/display_report.cpp 2015-01-21 07:34:50 +0000
+++ src/server/report/logging/display_report.cpp 2015-03-04 14:36:55 +0000
@@ -25,7 +25,12 @@
25namespace ml=mir::logging;25namespace ml=mir::logging;
26namespace mrl=mir::report::logging;26namespace mrl=mir::report::logging;
2727
28mrl::DisplayReport::DisplayReport(const std::shared_ptr<ml::Logger>& logger) : logger(logger)28mrl::DisplayReport::DisplayReport(
29 std::shared_ptr<ml::Logger> const& logger,
30 std::shared_ptr<time::Clock> const& clock) :
31 logger(logger),
32 clock(clock),
33 last_report(clock->now())
29{34{
30}35}
3136
@@ -141,3 +146,23 @@
141 " [" + i.name + "] : " + std::to_string(value), component());146 " [" + i.name + "] : " + std::to_string(value), component());
142 }147 }
143}148}
149
150void mrl::DisplayReport::report_vsync(unsigned int display_id)
151{
152 using namespace std::chrono;
153 seconds const static report_interval{1};
154 std::unique_lock<decltype(vsync_event_mutex)> lk(vsync_event_mutex);
155 auto now = clock->now();
156 event_map[display_id]++;
157 if (now > last_report + report_interval)
158 {
159 for(auto const& event : event_map)
160 logger->log(ml::Severity::informational,
161 std::to_string(event.second) + " vsync events on [" +
162 std::to_string(event.first) + "] over " +
163 std::to_string(duration_cast<milliseconds>(now - last_report).count()) + "ms",
164 component());
165 event_map.clear();
166 last_report = now;
167 }
168}
144169
=== modified file 'src/server/report/logging/display_report.h'
--- src/server/report/logging/display_report.h 2015-01-21 07:34:50 +0000
+++ src/server/report/logging/display_report.h 2015-03-04 14:36:55 +0000
@@ -21,8 +21,11 @@
21#define MIR_REPORT_LOGGING_DISPLAY_REPORTER_H_21#define MIR_REPORT_LOGGING_DISPLAY_REPORTER_H_
2222
23#include "mir/graphics/display_report.h"23#include "mir/graphics/display_report.h"
24#include "mir/time/clock.h"
2425
26#include <unordered_map>
25#include <memory>27#include <memory>
28#include <mutex>
2629
27namespace mir30namespace mir
28{31{
@@ -41,25 +44,33 @@
4144
42 static const char* component();45 static const char* component();
4346
44 DisplayReport(const std::shared_ptr<mir::logging::Logger>& logger);47 DisplayReport(
48 std::shared_ptr<mir::logging::Logger> const& logger,
49 std::shared_ptr<time::Clock> const& clock);
50
45 virtual ~DisplayReport();51 virtual ~DisplayReport();
4652
47 virtual void report_successful_setup_of_native_resources();53 virtual void report_successful_setup_of_native_resources() override;
48 virtual void report_successful_egl_make_current_on_construction();54 virtual void report_successful_egl_make_current_on_construction() override;
49 virtual void report_successful_egl_buffer_swap_on_construction();55 virtual void report_successful_egl_buffer_swap_on_construction() override;
50 virtual void report_successful_drm_mode_set_crtc_on_construction();56 virtual void report_successful_drm_mode_set_crtc_on_construction() override;
51 virtual void report_successful_display_construction();57 virtual void report_successful_display_construction() override;
52 virtual void report_drm_master_failure(int error);58 virtual void report_vsync(unsigned int display_id) override;
53 virtual void report_vt_switch_away_failure();59 virtual void report_drm_master_failure(int error) override;
54 virtual void report_vt_switch_back_failure();60 virtual void report_vt_switch_away_failure() override;
55 virtual void report_egl_configuration(EGLDisplay disp, EGLConfig cfg);61 virtual void report_vt_switch_back_failure() override;
62 virtual void report_egl_configuration(EGLDisplay disp, EGLConfig cfg) override;
5663
57 protected:64 protected:
58 DisplayReport(const DisplayReport&) = delete;65 DisplayReport(DisplayReport const&) = delete;
59 DisplayReport& operator=(const DisplayReport&) = delete;66 DisplayReport& operator=(DisplayReport const&) = delete;
6067
61 private:68 private:
62 std::shared_ptr<mir::logging::Logger> logger;69 std::shared_ptr<mir::logging::Logger> const logger;
70 std::shared_ptr<time::Clock> const clock;
71 std::mutex vsync_event_mutex;
72 mir::time::Timestamp last_report;
73 std::unordered_map<unsigned int, unsigned int> event_map;
63};74};
64}75}
65}76}
6677
=== modified file 'src/server/report/logging/logging_report_factory.cpp'
--- src/server/report/logging/logging_report_factory.cpp 2015-02-13 06:12:34 +0000
+++ src/server/report/logging/logging_report_factory.cpp 2015-03-04 14:36:55 +0000
@@ -45,7 +45,7 @@
4545
46std::shared_ptr<mir::graphics::DisplayReport> mr::LoggingReportFactory::create_display_report()46std::shared_ptr<mir::graphics::DisplayReport> mr::LoggingReportFactory::create_display_report()
47{47{
48 return std::make_shared<logging::DisplayReport>(logger);48 return std::make_shared<logging::DisplayReport>(logger, clock);
49}49}
5050
51std::shared_ptr<mir::scene::SceneReport> mr::LoggingReportFactory::create_scene_report()51std::shared_ptr<mir::scene::SceneReport> mr::LoggingReportFactory::create_scene_report()
5252
=== modified file 'src/server/report/lttng/display_report.cpp'
--- src/server/report/lttng/display_report.cpp 2014-02-09 16:18:16 +0000
+++ src/server/report/lttng/display_report.cpp 2015-03-04 14:36:55 +0000
@@ -35,7 +35,6 @@
35DISPLAY_REPORT_TRACE_CALL(report_successful_drm_mode_set_crtc_on_construction)35DISPLAY_REPORT_TRACE_CALL(report_successful_drm_mode_set_crtc_on_construction)
36DISPLAY_REPORT_TRACE_CALL(report_vt_switch_away_failure)36DISPLAY_REPORT_TRACE_CALL(report_vt_switch_away_failure)
37DISPLAY_REPORT_TRACE_CALL(report_vt_switch_back_failure)37DISPLAY_REPORT_TRACE_CALL(report_vt_switch_back_failure)
38DISPLAY_REPORT_TRACE_CALL(report_gpu_composition_in_use)
3938
40#undef DISPLAY_REPORT_TRACE_CALL39#undef DISPLAY_REPORT_TRACE_CALL
4140
@@ -43,15 +42,12 @@
43{42{
44}43}
4544
46
47void mir::report::lttng::DisplayReport::report_drm_master_failure(int error)45void mir::report::lttng::DisplayReport::report_drm_master_failure(int error)
48{46{
49 mir_tracepoint(mir_server_display, report_drm_master_failure, strerror(error));47 mir_tracepoint(mir_server_display, report_drm_master_failure, strerror(error));
50}48}
5149
5250void mir::report::lttng::DisplayReport::report_vsync(unsigned int display_id)
53void mir::report::lttng::DisplayReport::report_hwc_composition_in_use(int major, int minor)
54{51{
55 mir_tracepoint(mir_server_display, report_hwc_composition_in_use, major, minor);52 mir_tracepoint(mir_server_display, report_vsync, display_id);
56}53}
57
5854
=== modified file 'src/server/report/lttng/display_report.h'
--- src/server/report/lttng/display_report.h 2014-02-17 22:35:23 +0000
+++ src/server/report/lttng/display_report.h 2015-03-04 14:36:55 +0000
@@ -36,17 +36,16 @@
36 DisplayReport() = default;36 DisplayReport() = default;
37 virtual ~DisplayReport() noexcept(true) = default;37 virtual ~DisplayReport() noexcept(true) = default;
3838
39 virtual void report_successful_setup_of_native_resources();39 virtual void report_successful_setup_of_native_resources() override;
40 virtual void report_successful_egl_make_current_on_construction();40 virtual void report_successful_egl_make_current_on_construction() override;
41 virtual void report_successful_egl_buffer_swap_on_construction();41 virtual void report_successful_egl_buffer_swap_on_construction() override;
42 virtual void report_successful_display_construction();42 virtual void report_successful_display_construction() override;
43 virtual void report_egl_configuration(EGLDisplay disp, EGLConfig cfg);43 virtual void report_egl_configuration(EGLDisplay disp, EGLConfig cfg) override;
44 virtual void report_successful_drm_mode_set_crtc_on_construction();44 virtual void report_successful_drm_mode_set_crtc_on_construction() override;
45 virtual void report_drm_master_failure(int error);45 virtual void report_drm_master_failure(int error) override;
46 virtual void report_vt_switch_away_failure();46 virtual void report_vt_switch_away_failure() override;
47 virtual void report_vt_switch_back_failure();47 virtual void report_vt_switch_back_failure() override;
48 virtual void report_hwc_composition_in_use(int major, int minor);48 virtual void report_vsync(unsigned int display_id) override;
49 virtual void report_gpu_composition_in_use();
5049
51private:50private:
52 ServerTracepointProvider tp_provider;51 ServerTracepointProvider tp_provider;
5352
=== modified file 'src/server/report/lttng/display_report_tp.h'
--- src/server/report/lttng/display_report_tp.h 2015-01-21 07:34:50 +0000
+++ src/server/report/lttng/display_report_tp.h 2015-03-04 14:36:55 +0000
@@ -62,6 +62,15 @@
62 )62 )
63)63)
6464
65TRACEPOINT_EVENT(
66 mir_server_display,
67 report_vsync,
68 TP_ARGS(int, id),
69 TP_FIELDS(
70 ctf_integer(int, id, id)
71 )
72)
73
65#endif /* MIR_LTTNG_DISPLAY_REPORT_TP_H_ */74#endif /* MIR_LTTNG_DISPLAY_REPORT_TP_H_ */
6675
67#include <lttng/tracepoint-event.h>76#include <lttng/tracepoint-event.h>
6877
=== modified file 'src/server/report/null/display_report.cpp'
--- src/server/report/null/display_report.cpp 2015-01-21 07:34:50 +0000
+++ src/server/report/null/display_report.cpp 2015-03-04 14:36:55 +0000
@@ -29,3 +29,4 @@
29void mrn::DisplayReport::report_vt_switch_away_failure() {}29void mrn::DisplayReport::report_vt_switch_away_failure() {}
30void mrn::DisplayReport::report_vt_switch_back_failure() {}30void mrn::DisplayReport::report_vt_switch_back_failure() {}
31void mrn::DisplayReport::report_egl_configuration(EGLDisplay, EGLConfig) {}31void mrn::DisplayReport::report_egl_configuration(EGLDisplay, EGLConfig) {}
32void mrn::DisplayReport::report_vsync(unsigned int) {}
3233
=== modified file 'src/server/report/null/display_report.h'
--- src/server/report/null/display_report.h 2015-01-21 07:34:50 +0000
+++ src/server/report/null/display_report.h 2015-03-04 14:36:55 +0000
@@ -43,6 +43,7 @@
43 void report_vt_switch_away_failure() override;43 void report_vt_switch_away_failure() override;
44 void report_vt_switch_back_failure() override;44 void report_vt_switch_back_failure() override;
45 void report_egl_configuration(EGLDisplay disp, EGLConfig cfg) override;45 void report_egl_configuration(EGLDisplay disp, EGLConfig cfg) override;
46 void report_vsync(unsigned int display_id) override;
46};47};
47}48}
48}49}
4950
=== modified file 'tests/include/mir_test_doubles/mock_display_report.h'
--- tests/include/mir_test_doubles/mock_display_report.h 2013-05-10 18:16:51 +0000
+++ tests/include/mir_test_doubles/mock_display_report.h 2015-03-04 14:36:55 +0000
@@ -41,9 +41,8 @@
41 MOCK_METHOD1(report_drm_master_failure, void(int));41 MOCK_METHOD1(report_drm_master_failure, void(int));
42 MOCK_METHOD0(report_vt_switch_away_failure, void());42 MOCK_METHOD0(report_vt_switch_away_failure, void());
43 MOCK_METHOD0(report_vt_switch_back_failure, void());43 MOCK_METHOD0(report_vt_switch_back_failure, void());
44 MOCK_METHOD2(report_hwc_composition_in_use, void(int,int));
45 MOCK_METHOD0(report_gpu_composition_in_use, void());
46 MOCK_METHOD2(report_egl_configuration, void(EGLDisplay,EGLConfig));44 MOCK_METHOD2(report_egl_configuration, void(EGLDisplay,EGLConfig));
45 MOCK_METHOD1(report_vsync, void(unsigned int));
47};46};
4847
49}48}
5049
=== modified file 'tests/include/mir_test_doubles/stub_display_builder.h'
--- tests/include/mir_test_doubles/stub_display_builder.h 2015-02-26 03:20:09 +0000
+++ tests/include/mir_test_doubles/stub_display_builder.h 2015-03-04 14:36:55 +0000
@@ -47,7 +47,7 @@
47 MockHwcConfiguration()47 MockHwcConfiguration()
48 {48 {
49 using namespace testing;49 using namespace testing;
50 ON_CALL(*this, subscribe_to_config_changes(_)).WillByDefault(Return(nullptr));50 ON_CALL(*this, subscribe_to_config_changes(_,_)).WillByDefault(Return(nullptr));
51 ON_CALL(*this, active_attribs_for(graphics::android::DisplayName::primary))51 ON_CALL(*this, active_attribs_for(graphics::android::DisplayName::primary))
52 .WillByDefault(testing::Return(graphics::android::DisplayAttribs{52 .WillByDefault(testing::Return(graphics::android::DisplayAttribs{
53 {0,0},{0,0}, 0.0, true, mir_pixel_format_abgr_8888, 2}));53 {0,0},{0,0}, 0.0, true, mir_pixel_format_abgr_8888, 2}));
@@ -57,8 +57,9 @@
57 }57 }
58 MOCK_METHOD2(power_mode, void(graphics::android::DisplayName, MirPowerMode));58 MOCK_METHOD2(power_mode, void(graphics::android::DisplayName, MirPowerMode));
59 MOCK_METHOD1(active_attribs_for, graphics::android::DisplayAttribs(graphics::android::DisplayName));59 MOCK_METHOD1(active_attribs_for, graphics::android::DisplayAttribs(graphics::android::DisplayName));
60 MOCK_METHOD1(subscribe_to_config_changes,60 MOCK_METHOD2(subscribe_to_config_changes,
61 graphics::android::ConfigChangeSubscription(std::function<void()> const&));61 graphics::android::ConfigChangeSubscription(
62 std::function<void()> const&, std::function<void(graphics::android::DisplayName)> const&));
62};63};
6364
64struct StubHwcConfiguration : public graphics::android::HwcConfiguration65struct StubHwcConfiguration : public graphics::android::HwcConfiguration
@@ -77,7 +78,7 @@
7778
78 79
79 graphics::android::ConfigChangeSubscription subscribe_to_config_changes(80 graphics::android::ConfigChangeSubscription subscribe_to_config_changes(
80 std::function<void()> const&) override81 std::function<void()> const&, std::function<void(graphics::android::DisplayName)> const&) override
81 {82 {
82 return nullptr;83 return nullptr;
83 }84 }
8485
=== modified file 'tests/unit-tests/graphics/android/test_display.cpp'
--- tests/unit-tests/graphics/android/test_display.cpp 2015-03-03 06:56:37 +0000
+++ tests/unit-tests/graphics/android/test_display.cpp 2015-03-04 14:36:55 +0000
@@ -554,7 +554,7 @@
554 auto use_count_before = subscription.use_count();554 auto use_count_before = subscription.use_count();
555 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)555 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)
556 {556 {
557 EXPECT_CALL(mock_config, subscribe_to_config_changes(_))557 EXPECT_CALL(mock_config, subscribe_to_config_changes(_,_))
558 .WillOnce(Return(subscription));558 .WillOnce(Return(subscription));
559 });559 });
560 {560 {
@@ -596,7 +596,7 @@
596596
597 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)597 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)
598 {598 {
599 EXPECT_CALL(mock_config, subscribe_to_config_changes(_))599 EXPECT_CALL(mock_config, subscribe_to_config_changes(_,_))
600 .WillOnce(DoAll(SaveArg<0>(&hotplug_fn), Return(subscription)));600 .WillOnce(DoAll(SaveArg<0>(&hotplug_fn), Return(subscription)));
601 EXPECT_CALL(mock_config, active_attribs_for(mga::DisplayName::primary))601 EXPECT_CALL(mock_config, active_attribs_for(mga::DisplayName::primary))
602 .Times(2)602 .Times(2)
@@ -645,7 +645,7 @@
645 return mga::DisplayAttribs{645 return mga::DisplayAttribs{
646 {20,20}, {4,4}, 50.0f, external_connected, mir_pixel_format_abgr_8888, 2};646 {20,20}, {4,4}, 50.0f, external_connected, mir_pixel_format_abgr_8888, 2};
647 }));647 }));
648 EXPECT_CALL(mock_config, subscribe_to_config_changes(_))648 EXPECT_CALL(mock_config, subscribe_to_config_changes(_,_))
649 .WillOnce(DoAll(SaveArg<0>(&hotplug_fn), Return(std::make_shared<char>('2'))));649 .WillOnce(DoAll(SaveArg<0>(&hotplug_fn), Return(std::make_shared<char>('2'))));
650 });650 });
651651
@@ -694,7 +694,7 @@
694 bool external_connected = true;694 bool external_connected = true;
695 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)695 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)
696 {696 {
697 EXPECT_CALL(mock_config, subscribe_to_config_changes(_))697 EXPECT_CALL(mock_config, subscribe_to_config_changes(_,_))
698 .WillOnce(DoAll(SaveArg<0>(&hotplug_fn), Return(std::make_shared<char>('2'))));698 .WillOnce(DoAll(SaveArg<0>(&hotplug_fn), Return(std::make_shared<char>('2'))));
699 ON_CALL(mock_config, active_attribs_for(mga::DisplayName::primary))699 ON_CALL(mock_config, active_attribs_for(mga::DisplayName::primary))
700 .WillByDefault(Return(700 .WillByDefault(Return(
@@ -779,3 +779,25 @@
779 });779 });
780 display.configure(*configuration);780 display.configure(*configuration);
781}781}
782
783TEST_F(Display, reports_vsync)
784{
785 using namespace testing;
786 std::function<void(mga::DisplayName)> vsync_fn = [](mga::DisplayName){};
787 auto report = std::make_shared<NiceMock<mtd::MockDisplayReport>>();
788 EXPECT_CALL(*report, report_vsync(_));
789 stub_db_factory->with_next_config([&](mtd::MockHwcConfiguration& mock_config)
790 {
791 EXPECT_CALL(mock_config, subscribe_to_config_changes(_,_))
792 .WillOnce(DoAll(SaveArg<1>(&vsync_fn), Return(std::make_shared<char>('2'))));
793 });
794
795 mga::Display display(
796 stub_db_factory,
797 stub_gl_program_factory,
798 stub_gl_config,
799 report,
800 mga::OverlayOptimization::enabled);
801
802 vsync_fn(mga::DisplayName::primary);
803}
782804
=== modified file 'tests/unit-tests/graphics/android/test_display_hotplug.cpp'
--- tests/unit-tests/graphics/android/test_display_hotplug.cpp 2015-02-13 06:12:34 +0000
+++ tests/unit-tests/graphics/android/test_display_hotplug.cpp 2015-03-04 14:36:55 +0000
@@ -47,7 +47,7 @@
47 return mga::DisplayAttribs{{0,0}, {0,0}, 0.0, true, mir_pixel_format_abgr_8888, 2};47 return mga::DisplayAttribs{{0,0}, {0,0}, 0.0, true, mir_pixel_format_abgr_8888, 2};
48 } 48 }
49 mga::ConfigChangeSubscription subscribe_to_config_changes(49 mga::ConfigChangeSubscription subscribe_to_config_changes(
50 std::function<void()> const& cb) override50 std::function<void()> const& cb, std::function<void(mga::DisplayName)> const&) override
51 {51 {
52 hotplug_fn = cb;52 hotplug_fn = cb;
53 return {};53 return {};
@@ -72,9 +72,9 @@
72 return wrapped.active_attribs_for(d);72 return wrapped.active_attribs_for(d);
73 } 73 }
74 mga::ConfigChangeSubscription subscribe_to_config_changes(74 mga::ConfigChangeSubscription subscribe_to_config_changes(
75 std::function<void()> const& cb) override75 std::function<void()> const& hotplug, std::function<void(mga::DisplayName)> const& vsync) override
76 {76 {
77 return wrapped.subscribe_to_config_changes(cb);77 return wrapped.subscribe_to_config_changes(hotplug, vsync);
78 }78 }
79 mga::HwcConfiguration& wrapped;79 mga::HwcConfiguration& wrapped;
80 };80 };
8181
=== modified file 'tests/unit-tests/graphics/android/test_hwc_configuration.cpp'
--- tests/unit-tests/graphics/android/test_hwc_configuration.cpp 2015-03-03 06:56:37 +0000
+++ tests/unit-tests/graphics/android/test_hwc_configuration.cpp 2015-03-04 14:36:55 +0000
@@ -228,17 +228,23 @@
228 EXPECT_THAT(attribs.vrefresh_hz, Eq(0.0f));228 EXPECT_THAT(attribs.vrefresh_hz, Eq(0.0f));
229}229}
230230
231TEST_F(HwcConfiguration, subscribes_to_hotplug)231TEST_F(HwcConfiguration, subscribes_to_hotplug_and_vsync)
232{232{
233 using namespace testing;233 using namespace testing;
234 std::function<void(mga::DisplayName, bool)> hotplug_fn([](mga::DisplayName, bool){});234 std::function<void(mga::DisplayName, bool)> hotplug_fn([](mga::DisplayName, bool){});
235 std::function<void(mga::DisplayName, std::chrono::nanoseconds)> vsync_fn(
236 [](mga::DisplayName, std::chrono::nanoseconds){});
235 EXPECT_CALL(*mock_hwc_wrapper, subscribe_to_events(_,_,_,_))237 EXPECT_CALL(*mock_hwc_wrapper, subscribe_to_events(_,_,_,_))
236 .WillOnce(SaveArg<2>(&hotplug_fn));238 .WillOnce(DoAll(SaveArg<1>(&vsync_fn), SaveArg<2>(&hotplug_fn)));
237 EXPECT_CALL(*mock_hwc_wrapper, unsubscribe_from_events_(_));239 EXPECT_CALL(*mock_hwc_wrapper, unsubscribe_from_events_(_));
238240
239 unsigned int call_count{0};241 unsigned int hotplug_call_count{0};
240 auto subscription = config.subscribe_to_config_changes([&]{ call_count++; });242 unsigned int vsync_call_count{0};
241 hotplug_fn(mga::DisplayName::primary, true);243 auto subscription = config.subscribe_to_config_changes(
242 hotplug_fn(mga::DisplayName::primary, true);244 [&]{ hotplug_call_count++; }, [&](mga::DisplayName){ vsync_call_count++; });
243 EXPECT_THAT(call_count, Eq(2));245 hotplug_fn(mga::DisplayName::primary, true);
246 hotplug_fn(mga::DisplayName::primary, true);
247 vsync_fn(mga::DisplayName::primary, std::chrono::nanoseconds(33));
248 EXPECT_THAT(hotplug_call_count, Eq(2));
249 EXPECT_THAT(vsync_call_count, Eq(1));
244}250}
245251
=== modified file 'tests/unit-tests/graphics/mesa/test_display.cpp'
--- tests/unit-tests/graphics/mesa/test_display.cpp 2015-02-26 03:20:09 +0000
+++ tests/unit-tests/graphics/mesa/test_display.cpp 2015-03-04 14:36:55 +0000
@@ -28,6 +28,7 @@
2828
29#include "mir_test_doubles/mock_egl.h"29#include "mir_test_doubles/mock_egl.h"
30#include "mir_test_doubles/mock_gl.h"30#include "mir_test_doubles/mock_gl.h"
31#include "mir_test_doubles/advanceable_clock.h"
31#include "src/server/report/null_report_factory.h"32#include "src/server/report/null_report_factory.h"
32#include "mir_test_doubles/mock_display_report.h"33#include "mir_test_doubles/mock_display_report.h"
33#include "mir_test_doubles/null_virtual_terminal.h"34#include "mir_test_doubles/null_virtual_terminal.h"
@@ -525,7 +526,7 @@
525 using namespace ::testing;526 using namespace ::testing;
526527
527 auto logger = std::make_shared<MockLogger>();528 auto logger = std::make_shared<MockLogger>();
528 auto reporter = std::make_shared<mrl::DisplayReport>(logger);529 auto reporter = std::make_shared<mrl::DisplayReport>(logger, std::make_shared<mtd::AdvanceableClock>());
529530
530 EXPECT_CALL(531 EXPECT_CALL(
531 *logger,532 *logger,
@@ -541,7 +542,7 @@
541 using namespace ::testing;542 using namespace ::testing;
542543
543 auto logger = std::make_shared<MockLogger>();544 auto logger = std::make_shared<MockLogger>();
544 auto reporter = std::make_shared<mrl::DisplayReport>(logger);545 auto reporter = std::make_shared<mrl::DisplayReport>(logger, std::make_shared<mtd::AdvanceableClock>());
545546
546 EXPECT_CALL(547 EXPECT_CALL(
547 *logger,548 *logger,
@@ -557,7 +558,7 @@
557 using namespace ::testing;558 using namespace ::testing;
558559
559 auto logger = std::make_shared<MockLogger>();560 auto logger = std::make_shared<MockLogger>();
560 auto reporter = std::make_shared<mrl::DisplayReport>(logger);561 auto reporter = std::make_shared<mrl::DisplayReport>(logger, std::make_shared<mtd::AdvanceableClock>());
561562
562 EXPECT_CALL(563 EXPECT_CALL(
563 *logger,564 *logger,
@@ -573,7 +574,7 @@
573 using namespace ::testing;574 using namespace ::testing;
574575
575 auto logger = std::make_shared<MockLogger>();576 auto logger = std::make_shared<MockLogger>();
576 auto reporter = std::make_shared<mrl::DisplayReport>(logger);577 auto reporter = std::make_shared<mrl::DisplayReport>(logger, std::make_shared<mtd::AdvanceableClock>());
577578
578 EXPECT_CALL(579 EXPECT_CALL(
579 *logger,580 *logger,
580581
=== modified file 'tests/unit-tests/graphics/mesa/test_kms_page_flipper.cpp'
--- tests/unit-tests/graphics/mesa/test_kms_page_flipper.cpp 2015-01-22 09:00:14 +0000
+++ tests/unit-tests/graphics/mesa/test_kms_page_flipper.cpp 2015-03-04 14:36:55 +0000
@@ -45,10 +45,11 @@
45{45{
46public:46public:
47 KMSPageFlipperTest()47 KMSPageFlipperTest()
48 : page_flipper{mock_drm.fake_drm.fd()}48 : page_flipper{mock_drm.fake_drm.fd(), mt::fake_shared(report)}
49 {49 {
50 }50 }
5151
52 testing::NiceMock<mtd::MockDisplayReport> report;
52 testing::NiceMock<mtd::MockDRM> mock_drm;53 testing::NiceMock<mtd::MockDRM> mock_drm;
53 mgm::KMSPageFlipper page_flipper;54 mgm::KMSPageFlipper page_flipper;
54};55};
@@ -121,6 +122,24 @@
121 page_flipper.wait_for_flip(crtc_id);122 page_flipper.wait_for_flip(crtc_id);
122}123}
123124
125TEST_F(KMSPageFlipperTest, wait_for_flip_reports_vsync)
126{
127 using namespace testing;
128 uint32_t const crtc_id{10};
129 uint32_t const fb_id{101};
130 void* user_data{nullptr};
131 ON_CALL(mock_drm, drmModePageFlip(_, _, _, _, _))
132 .WillByDefault(DoAll(SaveArg<4>(&user_data), Return(0)));
133 ON_CALL(mock_drm, drmHandleEvent(_, _))
134 .WillByDefault(DoAll(InvokePageFlipHandler(&user_data), Return(0)));
135
136 EXPECT_CALL(report, report_vsync(crtc_id));
137
138 page_flipper.schedule_flip(crtc_id, fb_id);
139 EXPECT_EQ(1, write(mock_drm.fake_drm.write_fd(), "a", 1));
140 page_flipper.wait_for_flip(crtc_id);
141}
142
124TEST_F(KMSPageFlipperTest, wait_for_non_scheduled_page_flip_doesnt_block)143TEST_F(KMSPageFlipperTest, wait_for_non_scheduled_page_flip_doesnt_block)
125{144{
126 using namespace testing;145 using namespace testing;
127146
=== modified file 'tests/unit-tests/logging/test_display_report.cpp'
--- tests/unit-tests/logging/test_display_report.cpp 2015-01-21 07:34:50 +0000
+++ tests/unit-tests/logging/test_display_report.cpp 2015-03-04 14:36:55 +0000
@@ -19,6 +19,7 @@
19#include "src/server/report/logging/display_report.h"19#include "src/server/report/logging/display_report.h"
20#include "mir/logging/logger.h"20#include "mir/logging/logger.h"
21#include "mir_test_doubles/mock_egl.h"21#include "mir_test_doubles/mock_egl.h"
22#include "mir_test_doubles/advanceable_clock.h"
2223
23#include <gtest/gtest.h>24#include <gtest/gtest.h>
24#include <gmock/gmock.h>25#include <gmock/gmock.h>
@@ -39,16 +40,8 @@
3940
40struct DisplayReport : public testing::Test41struct DisplayReport : public testing::Test
41{42{
42 DisplayReport()43 std::shared_ptr<mtd::AdvanceableClock> const clock{std::make_shared<mtd::AdvanceableClock>()};
43 {44 std::shared_ptr<MockLogger> logger{std::make_shared<MockLogger>()};
44 }
45
46 void SetUp()
47 {
48 logger = std::make_shared<MockLogger>();
49 }
50
51 std::shared_ptr<MockLogger> logger;
52 mtd::MockEGL mock_egl;45 mtd::MockEGL mock_egl;
53};46};
5447
@@ -123,6 +116,29 @@
123 component));116 component));
124 }117 }
125118
126 mrl::DisplayReport report(logger);119 mrl::DisplayReport report(logger, clock);
127 report.report_egl_configuration(disp, config);120 report.report_egl_configuration(disp, config);
128}121}
122
123TEST_F(DisplayReport, reports_vsync)
124{
125 std::chrono::milliseconds interval(1500);
126 unsigned int display1_id {1223};
127 unsigned int display2_id {4492};
128 std::string display1_name(std::to_string(display1_id));
129 std::string display2_name(std::to_string(display2_id));
130 EXPECT_CALL(*logger, log(
131 ml::Severity::informational,
132 "2 vsync events on [" + display1_name + "] over " + std::to_string(interval.count()) + "ms",
133 component));
134 EXPECT_CALL(*logger, log(
135 ml::Severity::informational,
136 "1 vsync events on [" + display2_name + "] over " + std::to_string(interval.count()) + "ms",
137 component));
138 mrl::DisplayReport report(logger, clock);
139
140 report.report_vsync(display1_id);
141 report.report_vsync(display2_id);
142 clock->advance_by(interval);
143 report.report_vsync(display1_id);
144}

Subscribers

People subscribed via source and target branches