Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: components/exo/wayland/clients/motion_events.cc

Issue 2610513006: exo: Implement presentation interface. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // Implementation of a client that produces output in the form of RGBA 5 // Implementation of a client that produces output in the form of RGBA
6 // buffers when receiving pointer/touch events. RGB contains the lower 6 // buffers when receiving pointer/touch events. RGB contains the lower
7 // 24 bits of the event timestamp and A is 0xff. 7 // 24 bits of the event timestamp and A is 0xff.
8 8
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <linux-dmabuf-unstable-v1-client-protocol.h> 10 #include <linux-dmabuf-unstable-v1-client-protocol.h>
11 #include <presentation-time-client-protocol.h>
11 #include <wayland-client-core.h> 12 #include <wayland-client-core.h>
12 #include <wayland-client-protocol.h> 13 #include <wayland-client-protocol.h>
13 14
14 #include <cmath> 15 #include <cmath>
15 #include <deque> 16 #include <deque>
16 #include <iostream> 17 #include <iostream>
17 #include <string> 18 #include <string>
18 #include <vector> 19 #include <vector>
19 20
20 #include "base/at_exit.h" 21 #include "base/at_exit.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 DEFAULT_DELETER(wl_shm_pool, wl_shm_pool_destroy) 63 DEFAULT_DELETER(wl_shm_pool, wl_shm_pool_destroy)
63 DEFAULT_DELETER(wl_buffer, wl_buffer_destroy) 64 DEFAULT_DELETER(wl_buffer, wl_buffer_destroy)
64 DEFAULT_DELETER(wl_surface, wl_surface_destroy) 65 DEFAULT_DELETER(wl_surface, wl_surface_destroy)
65 DEFAULT_DELETER(wl_region, wl_region_destroy) 66 DEFAULT_DELETER(wl_region, wl_region_destroy)
66 DEFAULT_DELETER(wl_shell, wl_shell_destroy) 67 DEFAULT_DELETER(wl_shell, wl_shell_destroy)
67 DEFAULT_DELETER(wl_shell_surface, wl_shell_surface_destroy) 68 DEFAULT_DELETER(wl_shell_surface, wl_shell_surface_destroy)
68 DEFAULT_DELETER(wl_seat, wl_seat_destroy) 69 DEFAULT_DELETER(wl_seat, wl_seat_destroy)
69 DEFAULT_DELETER(wl_pointer, wl_pointer_destroy) 70 DEFAULT_DELETER(wl_pointer, wl_pointer_destroy)
70 DEFAULT_DELETER(wl_touch, wl_touch_destroy) 71 DEFAULT_DELETER(wl_touch, wl_touch_destroy)
71 DEFAULT_DELETER(wl_callback, wl_callback_destroy) 72 DEFAULT_DELETER(wl_callback, wl_callback_destroy)
73 DEFAULT_DELETER(wp_presentation, wp_presentation_destroy)
74 DEFAULT_DELETER(struct wp_presentation_feedback,
75 wp_presentation_feedback_destroy)
72 DEFAULT_DELETER(zwp_linux_buffer_params_v1, zwp_linux_buffer_params_v1_destroy) 76 DEFAULT_DELETER(zwp_linux_buffer_params_v1, zwp_linux_buffer_params_v1_destroy)
73 DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy) 77 DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy)
74 78
75 #if defined(OZONE_PLATFORM_GBM) 79 #if defined(OZONE_PLATFORM_GBM)
76 DEFAULT_DELETER(gbm_device, gbm_device_destroy) 80 DEFAULT_DELETER(gbm_device, gbm_device_destroy)
77 DEFAULT_DELETER(gbm_bo, gbm_bo_destroy) 81 DEFAULT_DELETER(gbm_bo, gbm_bo_destroy)
78 #endif 82 #endif
79 83
80 namespace exo { 84 namespace exo {
81 namespace wayland { 85 namespace wayland {
(...skipping 22 matching lines...) Expand all
104 108
105 // Rotation speed (degrees/second). 109 // Rotation speed (degrees/second).
106 const double kRotationSpeed = 360.0; 110 const double kRotationSpeed = 360.0;
107 111
108 // Benchmark warmup frames before starting measurement. 112 // Benchmark warmup frames before starting measurement.
109 const int kBenchmarkWarmupFrames = 10; 113 const int kBenchmarkWarmupFrames = 10;
110 114
111 struct Globals { 115 struct Globals {
112 std::unique_ptr<wl_compositor> compositor; 116 std::unique_ptr<wl_compositor> compositor;
113 std::unique_ptr<wl_shm> shm; 117 std::unique_ptr<wl_shm> shm;
118 std::unique_ptr<wp_presentation> presentation;
114 std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf; 119 std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf;
115 std::unique_ptr<wl_shell> shell; 120 std::unique_ptr<wl_shell> shell;
116 std::unique_ptr<wl_seat> seat; 121 std::unique_ptr<wl_seat> seat;
117 }; 122 };
118 123
119 void RegistryHandler(void* data, 124 void RegistryHandler(void* data,
120 wl_registry* registry, 125 wl_registry* registry,
121 uint32_t id, 126 uint32_t id,
122 const char* interface, 127 const char* interface,
123 uint32_t version) { 128 uint32_t version) {
124 Globals* globals = static_cast<Globals*>(data); 129 Globals* globals = static_cast<Globals*>(data);
125 130
126 if (strcmp(interface, "wl_compositor") == 0) { 131 if (strcmp(interface, "wl_compositor") == 0) {
127 globals->compositor.reset(static_cast<wl_compositor*>( 132 globals->compositor.reset(static_cast<wl_compositor*>(
128 wl_registry_bind(registry, id, &wl_compositor_interface, 3))); 133 wl_registry_bind(registry, id, &wl_compositor_interface, 3)));
129 } else if (strcmp(interface, "wl_shm") == 0) { 134 } else if (strcmp(interface, "wl_shm") == 0) {
130 globals->shm.reset(static_cast<wl_shm*>( 135 globals->shm.reset(static_cast<wl_shm*>(
131 wl_registry_bind(registry, id, &wl_shm_interface, 1))); 136 wl_registry_bind(registry, id, &wl_shm_interface, 1)));
132 } else if (strcmp(interface, "wl_shell") == 0) { 137 } else if (strcmp(interface, "wl_shell") == 0) {
133 globals->shell.reset(static_cast<wl_shell*>( 138 globals->shell.reset(static_cast<wl_shell*>(
134 wl_registry_bind(registry, id, &wl_shell_interface, 1))); 139 wl_registry_bind(registry, id, &wl_shell_interface, 1)));
135 } else if (strcmp(interface, "wl_seat") == 0) { 140 } else if (strcmp(interface, "wl_seat") == 0) {
136 globals->seat.reset(static_cast<wl_seat*>( 141 globals->seat.reset(static_cast<wl_seat*>(
137 wl_registry_bind(registry, id, &wl_seat_interface, 5))); 142 wl_registry_bind(registry, id, &wl_seat_interface, 5)));
143 } else if (strcmp(interface, "wp_presentation") == 0) {
144 globals->presentation.reset(static_cast<wp_presentation*>(
145 wl_registry_bind(registry, id, &wp_presentation_interface, 1)));
138 } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) { 146 } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
139 globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>( 147 globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>(
140 wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1))); 148 wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1)));
141 } 149 }
142 } 150 }
143 151
144 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) { 152 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) {
145 LOG(WARNING) << "Got a registry losing event for " << id; 153 LOG(WARNING) << "Got a registry losing event for " << id;
146 } 154 }
147 155
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 wl_fixed_t y) { 272 wl_fixed_t y) {
265 EventTimeStack* stack = static_cast<EventTimeStack*>(data); 273 EventTimeStack* stack = static_cast<EventTimeStack*>(data);
266 274
267 stack->push_back(time); 275 stack->push_back(time);
268 } 276 }
269 277
270 void TouchFrame(void* data, wl_touch* touch) {} 278 void TouchFrame(void* data, wl_touch* touch) {}
271 279
272 void TouchCancel(void* data, wl_touch* touch) {} 280 void TouchCancel(void* data, wl_touch* touch) {}
273 281
274 struct Frame { 282 struct Schedule {
275 uint32_t time = 0; 283 uint32_t time = 0;
276 bool callback_pending = false; 284 bool callback_pending = false;
277 }; 285 };
278 286
279 void FrameCallback(void* data, wl_callback* callback, uint32_t time) { 287 void FrameCallback(void* data, wl_callback* callback, uint32_t time) {
280 Frame* frame = static_cast<Frame*>(data); 288 Schedule* schedule = static_cast<Schedule*>(data);
281 289
282 static uint32_t initial_time = time; 290 static uint32_t initial_time = time;
283 frame->time = time - initial_time; 291 schedule->time = time - initial_time;
284 frame->callback_pending = false; 292 schedule->callback_pending = false;
293 }
294
295 struct Frame {
296 Buffer* buffer = nullptr;
297 base::TimeDelta wall_time;
298 base::TimeDelta cpu_time;
299 std::vector<base::TimeTicks> event_times;
300 std::unique_ptr<struct wp_presentation_feedback> feedback;
301 };
302
303 struct Presentation {
304 std::deque<std::unique_ptr<Frame>> scheduled_frames;
305 base::TimeDelta wall_time;
306 base::TimeDelta cpu_time;
307 base::TimeDelta latency_time;
308 uint32_t num_frames_presented = 0;
309 uint32_t num_events_presented = 0;
310 };
311
312 void FeedbackSyncOutput(void* data,
313 struct wp_presentation_feedback* presentation_feedback,
314 wl_output* output) {}
315
316 void FeedbackPresented(void* data,
317 struct wp_presentation_feedback* presentation_feedback,
318 uint32_t tv_sec_hi,
319 uint32_t tv_sec_lo,
320 uint32_t tv_nsec,
321 uint32_t refresh,
322 uint32_t seq_hi,
323 uint32_t seq_lo,
324 uint32_t flags) {
325 Presentation* presentation = static_cast<Presentation*>(data);
326 DCHECK_GT(presentation->scheduled_frames.size(), 0u);
327 std::unique_ptr<Frame> frame =
328 std::move(presentation->scheduled_frames.front());
329 presentation->scheduled_frames.pop_front();
330
331 presentation->wall_time += frame->wall_time;
332 presentation->cpu_time += frame->cpu_time;
333 ++presentation->num_frames_presented;
334
335 int64_t seconds = (static_cast<int64_t>(tv_sec_hi) << 32) + tv_sec_lo;
336 int64_t microseconds = seconds * base::Time::kMicrosecondsPerSecond +
337 tv_nsec / base::Time::kNanosecondsPerMicrosecond;
338 base::TimeTicks presentation_time =
339 base::TimeTicks::FromInternalValue(microseconds);
340 for (const auto& event_time : frame->event_times) {
341 presentation->latency_time += presentation_time - event_time;
342 ++presentation->num_events_presented;
343 }
344 }
345
346 void FeedbackDiscarded(void* data,
347 struct wp_presentation_feedback* presentation_feedback) {
348 Presentation* presentation = static_cast<Presentation*>(data);
349 DCHECK_GT(presentation->scheduled_frames.size(), 0u);
350 std::unique_ptr<Frame> frame =
351 std::move(presentation->scheduled_frames.front());
352 presentation->scheduled_frames.pop_front();
353 LOG(WARNING) << "Frame discarded";
285 } 354 }
286 355
287 #if defined(OZONE_PLATFORM_GBM) 356 #if defined(OZONE_PLATFORM_GBM)
288 void LinuxBufferParamsCreated(void* data, 357 void LinuxBufferParamsCreated(void* data,
289 zwp_linux_buffer_params_v1* params, 358 zwp_linux_buffer_params_v1* params,
290 wl_buffer* new_buffer) { 359 wl_buffer* new_buffer) {
291 Buffer* buffer = static_cast<Buffer*>(data); 360 Buffer* buffer = static_cast<Buffer*>(data);
292 buffer->buffer.reset(new_buffer); 361 buffer->buffer.reset(new_buffer);
293 } 362 }
294 363
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 wl_display_roundtrip(display_.get()); 447 wl_display_roundtrip(display_.get());
379 448
380 if (!globals_.compositor) { 449 if (!globals_.compositor) {
381 LOG(ERROR) << "Can't find compositor interface"; 450 LOG(ERROR) << "Can't find compositor interface";
382 return 1; 451 return 1;
383 } 452 }
384 if (!globals_.shm) { 453 if (!globals_.shm) {
385 LOG(ERROR) << "Can't find shm interface"; 454 LOG(ERROR) << "Can't find shm interface";
386 return 1; 455 return 1;
387 } 456 }
457 if (!globals_.presentation) {
458 LOG(ERROR) << "Can't find presentation interface";
459 return 1;
460 }
388 if (use_drm_ && !globals_.linux_dmabuf) { 461 if (use_drm_ && !globals_.linux_dmabuf) {
389 LOG(ERROR) << "Can't find linux_dmabuf interface"; 462 LOG(ERROR) << "Can't find linux_dmabuf interface";
390 return 1; 463 return 1;
391 } 464 }
392 if (!globals_.shell) { 465 if (!globals_.shell) {
393 LOG(ERROR) << "Can't find shell interface"; 466 LOG(ERROR) << "Can't find shell interface";
394 return 1; 467 return 1;
395 } 468 }
396 if (!globals_.seat) { 469 if (!globals_.seat) {
397 LOG(ERROR) << "Can't find seat interface"; 470 LOG(ERROR) << "Can't find seat interface";
398 return 1; 471 return 1;
399 } 472 }
400 473
401 #if defined(OZONE_PLATFORM_GBM) 474 #if defined(OZONE_PLATFORM_GBM)
402 EGLenum egl_sync_type = 0; 475 EGLenum egl_sync_type = 0;
476 sk_sp<const GrGLInterface> native_interface;
403 if (use_drm_) { 477 if (use_drm_) {
404 // Number of files to look for when discovering DRM devices. 478 // Number of files to look for when discovering DRM devices.
405 const uint32_t kDrmMaxMinor = 15; 479 const uint32_t kDrmMaxMinor = 15;
406 const uint32_t kRenderNodeStart = 128; 480 const uint32_t kRenderNodeStart = 128;
407 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; 481 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor;
408 482
409 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { 483 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) {
410 std::string dri_render_node( 484 std::string dri_render_node(
411 base::StringPrintf(kDriRenderNodeTemplate, i)); 485 base::StringPrintf(kDriRenderNodeTemplate, i));
412 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); 486 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 make_current_.reset( 520 make_current_.reset(
447 new ui::ScopedMakeCurrent(gl_context_.get(), gl_surface_.get())); 521 new ui::ScopedMakeCurrent(gl_context_.get(), gl_surface_.get()));
448 522
449 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") || 523 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") ||
450 gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) { 524 gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) {
451 egl_sync_type = EGL_SYNC_FENCE_KHR; 525 egl_sync_type = EGL_SYNC_FENCE_KHR;
452 } 526 }
453 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) { 527 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) {
454 egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID; 528 egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID;
455 } 529 }
530
531 native_interface = sk_sp<const GrGLInterface>(GrGLCreateNativeInterface());
532 DCHECK(native_interface);
533 gr_context_ = sk_sp<GrContext>(GrContext::Create(
534 kOpenGL_GrBackend,
535 reinterpret_cast<GrBackendContext>(native_interface.get())));
536 DCHECK(gr_context_);
456 } 537 }
457
458 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface());
459 DCHECK(native_interface);
460 gr_context_ = sk_sp<GrContext>(GrContext::Create(
461 kOpenGL_GrBackend,
462 reinterpret_cast<GrBackendContext>(native_interface.get())));
463 DCHECK(gr_context_);
464 #endif 538 #endif
465 539
466 wl_buffer_listener buffer_listener = {BufferRelease}; 540 wl_buffer_listener buffer_listener = {BufferRelease};
467 541
468 for (size_t i = 0; i < kBuffers; ++i) { 542 for (size_t i = 0; i < kBuffers; ++i) {
469 if (!CreateBuffer(&buffers_[i])) 543 if (!CreateBuffer(&buffers_[i]))
470 return 1; 544 return 1;
471 } 545 }
472 wl_display_roundtrip(display_.get()); 546 wl_display_roundtrip(display_.get());
473 for (size_t i = 0; i < kBuffers; ++i) { 547 for (size_t i = 0; i < kBuffers; ++i) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 static_cast<wl_touch*>(wl_seat_get_touch(globals_.seat.get()))); 606 static_cast<wl_touch*>(wl_seat_get_touch(globals_.seat.get())));
533 if (!touch) { 607 if (!touch) {
534 LOG(ERROR) << "Can't get touch"; 608 LOG(ERROR) << "Can't get touch";
535 return 1; 609 return 1;
536 } 610 }
537 611
538 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion, 612 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion,
539 TouchFrame, TouchCancel}; 613 TouchFrame, TouchCancel};
540 wl_touch_add_listener(touch.get(), &touch_listener, &event_times); 614 wl_touch_add_listener(touch.get(), &touch_listener, &event_times);
541 615
542 Frame frame; 616 Schedule schedule;
543 std::unique_ptr<wl_callback> frame_callback; 617 std::unique_ptr<wl_callback> frame_callback;
544 wl_callback_listener frame_listener = {FrameCallback}; 618 wl_callback_listener frame_listener = {FrameCallback};
545 std::deque<Buffer*> pending_frames;
546 619
547 uint32_t frames = 0; 620 Presentation presentation;
621 std::deque<std::unique_ptr<Frame>> pending_frames;
622
548 size_t num_benchmark_runs_left = num_benchmark_runs_; 623 size_t num_benchmark_runs_left = num_benchmark_runs_;
549 base::TimeTicks benchmark_time; 624 base::TimeTicks benchmark_start_time;
550 base::TimeDelta benchmark_wall_time;
551 base::TimeDelta benchmark_cpu_time;
552 std::string fps_counter_text("??"); 625 std::string fps_counter_text("??");
553 626
627 wp_presentation_feedback_listener feedback_listener = {
628 FeedbackSyncOutput, FeedbackPresented, FeedbackDiscarded};
629
554 SkPaint text_paint; 630 SkPaint text_paint;
555 text_paint.setTextSize(32.0f); 631 text_paint.setTextSize(32.0f);
556 text_paint.setColor(SK_ColorWHITE); 632 text_paint.setColor(SK_ColorWHITE);
557 text_paint.setStyle(SkPaint::kFill_Style); 633 text_paint.setStyle(SkPaint::kFill_Style);
558 634
559 int dispatch_status = 0; 635 int dispatch_status = 0;
560 do { 636 do {
561 bool enqueue_frame = frame.callback_pending 637 bool enqueue_frame = schedule.callback_pending
562 ? pending_frames.size() < max_frames_pending_ 638 ? pending_frames.size() < max_frames_pending_
563 : pending_frames.empty(); 639 : pending_frames.empty();
564 if (enqueue_frame) { 640 if (enqueue_frame) {
565 Buffer* buffer = 641 Buffer* buffer =
566 std::find_if(std::begin(buffers_), std::end(buffers_), 642 std::find_if(std::begin(buffers_), std::end(buffers_),
567 [](const Buffer& buffer) { return !buffer.busy; }); 643 [](const Buffer& buffer) { return !buffer.busy; });
568 if (buffer == std::end(buffers_)) { 644 if (buffer == std::end(buffers_)) {
569 LOG(ERROR) << "Can't find free buffer"; 645 LOG(ERROR) << "Can't find free buffer";
570 return 1; 646 return 1;
571 } 647 }
572 648
649 std::unique_ptr<Frame> frame(new Frame);
Daniele Castagna 2017/01/09 17:01:33 nit: I'd go with auto frame = make_unique
reveman 2017/01/09 17:55:15 Done.
650 frame->buffer = buffer;
651
573 base::TimeTicks wall_time_start; 652 base::TimeTicks wall_time_start;
574 base::ThreadTicks cpu_time_start; 653 base::ThreadTicks cpu_time_start;
575 if (num_benchmark_runs_ || show_fps_counter_) { 654 if (num_benchmark_runs_ || show_fps_counter_) {
576 wall_time_start = base::TimeTicks::Now(); 655 wall_time_start = base::TimeTicks::Now();
577 if (frames <= kBenchmarkWarmupFrames) 656 if (presentation.num_frames_presented <= kBenchmarkWarmupFrames)
578 benchmark_time = wall_time_start; 657 benchmark_start_time = wall_time_start;
579 658
580 if ((wall_time_start - benchmark_time) > benchmark_interval_) { 659 base::TimeDelta benchmark_time = wall_time_start - benchmark_start_time;
581 uint32_t benchmark_frames = frames - kBenchmarkWarmupFrames; 660 if (benchmark_time > benchmark_interval_) {
661 uint32_t benchmark_frames =
662 presentation.num_frames_presented - kBenchmarkWarmupFrames;
582 if (num_benchmark_runs_left) { 663 if (num_benchmark_runs_left) {
583 // Print benchmark statistics for the frames produced and exit. 664 // Print benchmark statistics for the frames presented and exit.
584 // Note: frames produced is not necessarily the same as frames
585 // displayed.
586 std::cout << benchmark_frames << '\t' 665 std::cout << benchmark_frames << '\t'
587 << benchmark_wall_time.InMilliseconds() << '\t' 666 << benchmark_time.InMilliseconds() << '\t'
588 << benchmark_cpu_time.InMilliseconds() << '\t' 667 << presentation.wall_time.InMilliseconds() << '\t'
668 << presentation.cpu_time.InMilliseconds() << '\t'
669 << presentation.num_events_presented << '\t'
670 << presentation.latency_time.InMilliseconds() << '\t'
589 << std::endl; 671 << std::endl;
590 if (!--num_benchmark_runs_left) 672 if (!--num_benchmark_runs_left)
591 return 0; 673 return 0;
592 } 674 }
593 675
594 // Set FPS counter text in case it's being shown. 676 // Set FPS counter text in case it's being shown.
595 fps_counter_text = base::UintToString( 677 fps_counter_text = base::UintToString(
596 std::round(benchmark_frames / benchmark_interval_.InSecondsF())); 678 std::round(benchmark_frames / benchmark_interval_.InSecondsF()));
597 679
598 frames = kBenchmarkWarmupFrames; 680 benchmark_start_time = wall_time_start;
599 benchmark_time = wall_time_start; 681 presentation.wall_time = base::TimeDelta();
600 benchmark_wall_time = base::TimeDelta(); 682 presentation.cpu_time = base::TimeDelta();
601 benchmark_cpu_time = base::TimeDelta(); 683 presentation.latency_time = base::TimeDelta();
684 presentation.num_frames_presented = kBenchmarkWarmupFrames;
685 presentation.num_events_presented = 0;
602 } 686 }
603 687
604 cpu_time_start = base::ThreadTicks::Now(); 688 cpu_time_start = base::ThreadTicks::Now();
605 } 689 }
606 690
607 SkCanvas* canvas = buffer->sk_surface->getCanvas(); 691 SkCanvas* canvas = buffer->sk_surface->getCanvas();
608 if (event_times.empty()) { 692 if (event_times.empty()) {
609 canvas->clear(SK_ColorBLACK); 693 canvas->clear(SK_ColorBLACK);
610 } else { 694 } else {
611 // Split buffer into one horizontal rectangle for each event received 695 // Split buffer into one horizontal rectangle for each event received
612 // since last frame. Latest event at the top. 696 // since last frame. Latest event at the top.
613 int y = 0; 697 int y = 0;
614 // Note: Rounding up to ensure we cover the whole canvas. 698 // Note: Rounding up to ensure we cover the whole canvas.
615 int h = (height_ + (event_times.size() / 2)) / event_times.size(); 699 int h = (height_ + (event_times.size() / 2)) / event_times.size();
616 while (!event_times.empty()) { 700 while (!event_times.empty()) {
617 SkIRect rect = SkIRect::MakeXYWH(0, y, width_, h); 701 SkIRect rect = SkIRect::MakeXYWH(0, y, width_, h);
618 SkPaint paint; 702 SkPaint paint;
619 paint.setColor(SkColorSetRGB((event_times.back() & 0x0000ff) >> 0, 703 paint.setColor(SkColorSetRGB((event_times.back() & 0x0000ff) >> 0,
620 (event_times.back() & 0x00ff00) >> 8, 704 (event_times.back() & 0x00ff00) >> 8,
621 (event_times.back() & 0xff0000) >> 16)); 705 (event_times.back() & 0xff0000) >> 16));
622 canvas->drawIRect(rect, paint); 706 canvas->drawIRect(rect, paint);
623 std::string text = base::UintToString(event_times.back()); 707 std::string text = base::UintToString(event_times.back());
624 canvas->drawText(text.c_str(), text.length(), 8, y + 32, text_paint); 708 canvas->drawText(text.c_str(), text.length(), 8, y + 32, text_paint);
709 frame->event_times.push_back(base::TimeTicks::FromInternalValue(
710 event_times.back() * base::Time::kMicrosecondsPerMillisecond));
625 event_times.pop_back(); 711 event_times.pop_back();
626 y += h; 712 y += h;
627 } 713 }
628 } 714 }
629 715
630 // Draw rotating rects. 716 // Draw rotating rects.
631 SkScalar half_width = SkScalarHalf(width_); 717 SkScalar half_width = SkScalarHalf(width_);
632 SkScalar half_height = SkScalarHalf(height_); 718 SkScalar half_height = SkScalarHalf(height_);
633 SkIRect rect = SkIRect::MakeXYWH(-SkScalarHalf(half_width), 719 SkIRect rect = SkIRect::MakeXYWH(-SkScalarHalf(half_width),
634 -SkScalarHalf(half_height), half_width, 720 -SkScalarHalf(half_height), half_width,
635 half_height); 721 half_height);
636 SkScalar rotation = SkScalarMulDiv(frame.time, kRotationSpeed, 1000); 722 SkScalar rotation = SkScalarMulDiv(schedule.time, kRotationSpeed, 1000);
637 canvas->save(); 723 canvas->save();
638 canvas->translate(half_width, half_height); 724 canvas->translate(half_width, half_height);
639 for (size_t i = 0; i < num_rects_; ++i) { 725 for (size_t i = 0; i < num_rects_; ++i) {
640 const SkColor kColors[] = {SK_ColorBLUE, SK_ColorGREEN, 726 const SkColor kColors[] = {SK_ColorBLUE, SK_ColorGREEN,
641 SK_ColorRED, SK_ColorYELLOW, 727 SK_ColorRED, SK_ColorYELLOW,
642 SK_ColorCYAN, SK_ColorMAGENTA}; 728 SK_ColorCYAN, SK_ColorMAGENTA};
643 SkPaint paint; 729 SkPaint paint;
644 paint.setColor(SkColorSetA(kColors[i % arraysize(kColors)], 0xA0)); 730 paint.setColor(SkColorSetA(kColors[i % arraysize(kColors)], 0xA0));
645 canvas->rotate(rotation / num_rects_); 731 canvas->rotate(rotation / num_rects_);
646 canvas->drawIRect(rect, paint); 732 canvas->drawIRect(rect, paint);
(...skipping 14 matching lines...) Expand all
661 buffer->egl_sync.reset(new ScopedEglSync(eglCreateSyncKHR( 747 buffer->egl_sync.reset(new ScopedEglSync(eglCreateSyncKHR(
662 eglGetCurrentDisplay(), egl_sync_type, nullptr))); 748 eglGetCurrentDisplay(), egl_sync_type, nullptr)));
663 DCHECK(buffer->egl_sync->is_valid()); 749 DCHECK(buffer->egl_sync->is_valid());
664 } 750 }
665 #endif 751 #endif
666 752
667 glFlush(); 753 glFlush();
668 } 754 }
669 755
670 buffer->busy = true; 756 buffer->busy = true;
671 pending_frames.push_back(buffer);
672 757
673 if (num_benchmark_runs_ || show_fps_counter_) { 758 if (num_benchmark_runs_) {
674 ++frames; 759 frame->wall_time = base::TimeTicks::Now() - wall_time_start;
675 benchmark_wall_time += base::TimeTicks::Now() - wall_time_start; 760 frame->cpu_time = base::ThreadTicks::Now() - cpu_time_start;
676 benchmark_cpu_time += base::ThreadTicks::Now() - cpu_time_start;
677 } 761 }
762 pending_frames.push_back(std::move(frame));
678 continue; 763 continue;
679 } 764 }
680 765
681 if (!frame.callback_pending) { 766 if (!schedule.callback_pending) {
682 DCHECK_GT(pending_frames.size(), 0u); 767 DCHECK_GT(pending_frames.size(), 0u);
683 Buffer* buffer = pending_frames.front(); 768 std::unique_ptr<Frame> frame = std::move(pending_frames.front());
684 pending_frames.pop_front(); 769 pending_frames.pop_front();
685 770
686 wl_surface_set_buffer_scale(surface.get(), scale_); 771 wl_surface_set_buffer_scale(surface.get(), scale_);
687 wl_surface_damage(surface.get(), 0, 0, width_ / scale_, height_ / scale_); 772 wl_surface_damage(surface.get(), 0, 0, width_ / scale_, height_ / scale_);
688 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0); 773 wl_surface_attach(surface.get(), frame->buffer->buffer.get(), 0, 0);
689 774
690 #if defined(OZONE_PLATFORM_GBM) 775 #if defined(OZONE_PLATFORM_GBM)
691 if (buffer->egl_sync) { 776 if (frame->buffer->egl_sync) {
692 eglClientWaitSyncKHR(eglGetCurrentDisplay(), buffer->egl_sync->get(), 777 eglClientWaitSyncKHR(eglGetCurrentDisplay(),
778 frame->buffer->egl_sync->get(),
693 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); 779 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
694 } 780 }
695 #endif 781 #endif
696 782
697 frame_callback.reset(wl_surface_frame(surface.get())); 783 frame_callback.reset(wl_surface_frame(surface.get()));
698 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame); 784 wl_callback_add_listener(frame_callback.get(), &frame_listener,
699 frame.callback_pending = true; 785 &schedule);
786 schedule.callback_pending = true;
787
788 frame->feedback.reset(
789 wp_presentation_feedback(globals_.presentation.get(), surface.get()));
790 wp_presentation_feedback_add_listener(frame->feedback.get(),
791 &feedback_listener, &presentation);
792 presentation.scheduled_frames.push_back(std::move(frame));
793
700 wl_surface_commit(surface.get()); 794 wl_surface_commit(surface.get());
701 wl_display_flush(display_.get()); 795 wl_display_flush(display_.get());
702 continue; 796 continue;
703 } 797 }
704 798
705 dispatch_status = wl_display_dispatch(display_.get()); 799 dispatch_status = wl_display_dispatch(display_.get());
706 } while (dispatch_status != -1); 800 } while (dispatch_status != -1);
707 801
708 return 0; 802 return 0;
709 } 803 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); 993 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm)));
900 } 994 }
901 995
902 exo::wayland::clients::MotionEvents client( 996 exo::wayland::clients::MotionEvents client(
903 width, height, scale, num_rects, max_frames_pending, 997 width, height, scale, num_rects, max_frames_pending,
904 command_line->HasSwitch(switches::kFullscreen), 998 command_line->HasSwitch(switches::kFullscreen),
905 command_line->HasSwitch(switches::kShowFpsCounter), num_benchmark_runs, 999 command_line->HasSwitch(switches::kShowFpsCounter), num_benchmark_runs,
906 base::TimeDelta::FromMilliseconds(benchmark_interval_ms), use_drm.get()); 1000 base::TimeDelta::FromMilliseconds(benchmark_interval_ms), use_drm.get());
907 return client.Run(); 1001 return client.Run();
908 } 1002 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698