| 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 // 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> |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 }; | 152 }; |
| 153 using ScopedTexture = base::ScopedGeneric<GLuint, DeleteTextureTraits>; | 153 using ScopedTexture = base::ScopedGeneric<GLuint, DeleteTextureTraits>; |
| 154 | 154 |
| 155 struct DeleteEglImageTraits { | 155 struct DeleteEglImageTraits { |
| 156 static EGLImageKHR InvalidValue() { return 0; } | 156 static EGLImageKHR InvalidValue() { return 0; } |
| 157 static void Free(EGLImageKHR image) { | 157 static void Free(EGLImageKHR image) { |
| 158 eglDestroyImageKHR(eglGetCurrentDisplay(), image); | 158 eglDestroyImageKHR(eglGetCurrentDisplay(), image); |
| 159 } | 159 } |
| 160 }; | 160 }; |
| 161 using ScopedEglImage = base::ScopedGeneric<EGLImageKHR, DeleteEglImageTraits>; | 161 using ScopedEglImage = base::ScopedGeneric<EGLImageKHR, DeleteEglImageTraits>; |
| 162 |
| 163 struct DeleteEglSyncTraits { |
| 164 static EGLSyncKHR InvalidValue() { return 0; } |
| 165 static void Free(EGLSyncKHR sync) { |
| 166 eglDestroySyncKHR(eglGetCurrentDisplay(), sync); |
| 167 } |
| 168 }; |
| 169 using ScopedEglSync = base::ScopedGeneric<EGLSyncKHR, DeleteEglSyncTraits>; |
| 162 #endif | 170 #endif |
| 163 | 171 |
| 164 struct Buffer { | 172 struct Buffer { |
| 165 std::unique_ptr<wl_buffer> buffer; | 173 std::unique_ptr<wl_buffer> buffer; |
| 166 bool busy = false; | 174 bool busy = false; |
| 167 #if defined(OZONE_PLATFORM_GBM) | 175 #if defined(OZONE_PLATFORM_GBM) |
| 168 std::unique_ptr<gbm_bo> bo; | 176 std::unique_ptr<gbm_bo> bo; |
| 169 std::unique_ptr<ScopedEglImage> egl_image; | 177 std::unique_ptr<ScopedEglImage> egl_image; |
| 178 std::unique_ptr<ScopedEglSync> egl_sync; |
| 170 std::unique_ptr<ScopedTexture> texture; | 179 std::unique_ptr<ScopedTexture> texture; |
| 171 #endif | 180 #endif |
| 172 std::unique_ptr<zwp_linux_buffer_params_v1> params; | 181 std::unique_ptr<zwp_linux_buffer_params_v1> params; |
| 173 base::SharedMemory shared_memory; | 182 base::SharedMemory shared_memory; |
| 174 std::unique_ptr<wl_shm_pool> shm_pool; | 183 std::unique_ptr<wl_shm_pool> shm_pool; |
| 175 sk_sp<SkSurface> sk_surface; | 184 sk_sp<SkSurface> sk_surface; |
| 176 }; | 185 }; |
| 177 | 186 |
| 178 void BufferRelease(void* data, wl_buffer* /* buffer */) { | 187 void BufferRelease(void* data, wl_buffer* /* buffer */) { |
| 179 Buffer* buffer = static_cast<Buffer*>(data); | 188 Buffer* buffer = static_cast<Buffer*>(data); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 } | 401 } |
| 393 if (!globals_.shell) { | 402 if (!globals_.shell) { |
| 394 LOG(ERROR) << "Can't find shell interface"; | 403 LOG(ERROR) << "Can't find shell interface"; |
| 395 return 1; | 404 return 1; |
| 396 } | 405 } |
| 397 if (!globals_.seat) { | 406 if (!globals_.seat) { |
| 398 LOG(ERROR) << "Can't find seat interface"; | 407 LOG(ERROR) << "Can't find seat interface"; |
| 399 return 1; | 408 return 1; |
| 400 } | 409 } |
| 401 | 410 |
| 411 #if defined(OZONE_PLATFORM_GBM) |
| 402 EGLenum egl_sync_type = 0; | 412 EGLenum egl_sync_type = 0; |
| 403 #if defined(OZONE_PLATFORM_GBM) | |
| 404 if (use_drm_) { | 413 if (use_drm_) { |
| 405 // Number of files to look for when discovering DRM devices. | 414 // Number of files to look for when discovering DRM devices. |
| 406 const uint32_t kDrmMaxMinor = 15; | 415 const uint32_t kDrmMaxMinor = 15; |
| 407 const uint32_t kRenderNodeStart = 128; | 416 const uint32_t kRenderNodeStart = 128; |
| 408 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; | 417 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; |
| 409 | 418 |
| 410 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { | 419 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { |
| 411 std::string dri_render_node( | 420 std::string dri_render_node( |
| 412 base::StringPrintf(kDriRenderNodeTemplate, i)); | 421 base::StringPrintf(kDriRenderNodeTemplate, i)); |
| 413 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); | 422 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 429 LOG_IF(ERROR, use_drm_) << "Can't find drm device: '" << *use_drm_ << "'"; | 438 LOG_IF(ERROR, use_drm_) << "Can't find drm device: '" << *use_drm_ << "'"; |
| 430 LOG_IF(ERROR, !use_drm_) << "Can't find drm device"; | 439 LOG_IF(ERROR, !use_drm_) << "Can't find drm device"; |
| 431 return 1; | 440 return 1; |
| 432 } | 441 } |
| 433 | 442 |
| 434 device_.reset(gbm_create_device(drm_fd_.get())); | 443 device_.reset(gbm_create_device(drm_fd_.get())); |
| 435 if (!device_) { | 444 if (!device_) { |
| 436 LOG(ERROR) << "Can't create gbm device"; | 445 LOG(ERROR) << "Can't create gbm device"; |
| 437 return 1; | 446 return 1; |
| 438 } | 447 } |
| 448 |
| 449 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") || |
| 450 gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) { |
| 451 egl_sync_type = EGL_SYNC_FENCE_KHR; |
| 452 } |
| 453 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) { |
| 454 egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID; |
| 455 } |
| 439 } | 456 } |
| 440 | 457 |
| 441 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); | 458 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); |
| 442 DCHECK(native_interface); | 459 DCHECK(native_interface); |
| 443 gr_context_ = sk_sp<GrContext>(GrContext::Create( | 460 gr_context_ = sk_sp<GrContext>(GrContext::Create( |
| 444 kOpenGL_GrBackend, | 461 kOpenGL_GrBackend, |
| 445 reinterpret_cast<GrBackendContext>(native_interface.get()))); | 462 reinterpret_cast<GrBackendContext>(native_interface.get()))); |
| 446 DCHECK(gr_context_); | 463 DCHECK(gr_context_); |
| 447 | |
| 448 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") || | |
| 449 gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) { | |
| 450 egl_sync_type = EGL_SYNC_FENCE_KHR; | |
| 451 } | |
| 452 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) { | |
| 453 egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID; | |
| 454 } | |
| 455 #endif | 464 #endif |
| 456 | 465 |
| 457 wl_buffer_listener buffer_listener = {BufferRelease}; | 466 wl_buffer_listener buffer_listener = {BufferRelease}; |
| 458 | 467 |
| 459 for (size_t i = 0; i < kBuffers; ++i) { | 468 for (size_t i = 0; i < kBuffers; ++i) { |
| 460 if (!CreateBuffer(&buffers_[i])) | 469 if (!CreateBuffer(&buffers_[i])) |
| 461 return 1; | 470 return 1; |
| 462 } | 471 } |
| 463 wl_display_roundtrip(display_.get()); | 472 wl_display_roundtrip(display_.get()); |
| 464 for (size_t i = 0; i < kBuffers; ++i) { | 473 for (size_t i = 0; i < kBuffers; ++i) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 return 1; | 535 return 1; |
| 527 } | 536 } |
| 528 | 537 |
| 529 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion, | 538 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion, |
| 530 TouchFrame, TouchCancel}; | 539 TouchFrame, TouchCancel}; |
| 531 wl_touch_add_listener(touch.get(), &touch_listener, &event_times); | 540 wl_touch_add_listener(touch.get(), &touch_listener, &event_times); |
| 532 | 541 |
| 533 Frame frame; | 542 Frame frame; |
| 534 std::unique_ptr<wl_callback> frame_callback; | 543 std::unique_ptr<wl_callback> frame_callback; |
| 535 wl_callback_listener frame_listener = {FrameCallback}; | 544 wl_callback_listener frame_listener = {FrameCallback}; |
| 536 std::deque<wl_buffer*> pending_frames; | 545 std::deque<Buffer*> pending_frames; |
| 537 | 546 |
| 538 uint32_t frames = 0; | 547 uint32_t frames = 0; |
| 539 size_t num_benchmark_runs_left = num_benchmark_runs_; | 548 size_t num_benchmark_runs_left = num_benchmark_runs_; |
| 540 base::TimeTicks benchmark_time; | 549 base::TimeTicks benchmark_time; |
| 541 base::TimeDelta benchmark_wall_time; | 550 base::TimeDelta benchmark_wall_time; |
| 542 base::TimeDelta benchmark_cpu_time; | 551 base::TimeDelta benchmark_cpu_time; |
| 543 std::string fps_counter_text("??"); | 552 std::string fps_counter_text("??"); |
| 544 | 553 |
| 545 SkPaint text_paint; | 554 SkPaint text_paint; |
| 546 text_paint.setTextSize(32.0f); | 555 text_paint.setTextSize(32.0f); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 canvas->restore(); | 648 canvas->restore(); |
| 640 | 649 |
| 641 // Draw FPS counter. | 650 // Draw FPS counter. |
| 642 if (show_fps_counter_) { | 651 if (show_fps_counter_) { |
| 643 canvas->drawText(fps_counter_text.c_str(), fps_counter_text.length(), | 652 canvas->drawText(fps_counter_text.c_str(), fps_counter_text.length(), |
| 644 width_ - 48, 32, text_paint); | 653 width_ - 48, 32, text_paint); |
| 645 } | 654 } |
| 646 | 655 |
| 647 if (gr_context_) { | 656 if (gr_context_) { |
| 648 gr_context_->flush(); | 657 gr_context_->flush(); |
| 658 |
| 659 #if defined(OZONE_PLATFORM_GBM) |
| 660 if (egl_sync_type) { |
| 661 buffer->egl_sync.reset(new ScopedEglSync(eglCreateSyncKHR( |
| 662 eglGetCurrentDisplay(), egl_sync_type, nullptr))); |
| 663 DCHECK(buffer->egl_sync->is_valid()); |
| 664 } |
| 665 #endif |
| 666 |
| 649 glFlush(); | 667 glFlush(); |
| 650 | |
| 651 if (egl_sync_type) { | |
| 652 EGLSyncKHR sync = | |
| 653 eglCreateSyncKHR(eglGetCurrentDisplay(), egl_sync_type, nullptr); | |
| 654 DCHECK(sync != EGL_NO_SYNC_KHR); | |
| 655 eglClientWaitSyncKHR(eglGetCurrentDisplay(), sync, | |
| 656 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, | |
| 657 EGL_FOREVER_KHR); | |
| 658 eglDestroySyncKHR(eglGetCurrentDisplay(), sync); | |
| 659 } | |
| 660 } | 668 } |
| 661 | 669 |
| 662 buffer->busy = true; | 670 buffer->busy = true; |
| 663 pending_frames.push_back(buffer->buffer.get()); | 671 pending_frames.push_back(buffer); |
| 664 | 672 |
| 665 if (num_benchmark_runs_ || show_fps_counter_) { | 673 if (num_benchmark_runs_ || show_fps_counter_) { |
| 666 ++frames; | 674 ++frames; |
| 667 benchmark_wall_time += base::TimeTicks::Now() - wall_time_start; | 675 benchmark_wall_time += base::TimeTicks::Now() - wall_time_start; |
| 668 benchmark_cpu_time += base::ThreadTicks::Now() - cpu_time_start; | 676 benchmark_cpu_time += base::ThreadTicks::Now() - cpu_time_start; |
| 669 } | 677 } |
| 670 continue; | 678 continue; |
| 671 } | 679 } |
| 672 | 680 |
| 673 if (!frame.callback_pending) { | 681 if (!frame.callback_pending) { |
| 674 DCHECK_GT(pending_frames.size(), 0u); | 682 DCHECK_GT(pending_frames.size(), 0u); |
| 683 Buffer* buffer = pending_frames.front(); |
| 684 pending_frames.pop_front(); |
| 685 |
| 675 wl_surface_set_buffer_scale(surface.get(), scale_); | 686 wl_surface_set_buffer_scale(surface.get(), scale_); |
| 676 wl_surface_damage(surface.get(), 0, 0, width_ / scale_, height_ / scale_); | 687 wl_surface_damage(surface.get(), 0, 0, width_ / scale_, height_ / scale_); |
| 677 wl_surface_attach(surface.get(), pending_frames.front(), 0, 0); | 688 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0); |
| 678 pending_frames.pop_front(); | 689 |
| 690 #if defined(OZONE_PLATFORM_GBM) |
| 691 if (buffer->egl_sync) { |
| 692 eglClientWaitSyncKHR(eglGetCurrentDisplay(), buffer->egl_sync->get(), |
| 693 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); |
| 694 } |
| 695 #endif |
| 679 | 696 |
| 680 frame_callback.reset(wl_surface_frame(surface.get())); | 697 frame_callback.reset(wl_surface_frame(surface.get())); |
| 681 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame); | 698 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame); |
| 682 frame.callback_pending = true; | 699 frame.callback_pending = true; |
| 683 wl_surface_commit(surface.get()); | 700 wl_surface_commit(surface.get()); |
| 684 wl_display_flush(display_.get()); | 701 wl_display_flush(display_.get()); |
| 685 continue; | 702 continue; |
| 686 } | 703 } |
| 687 | 704 |
| 688 dispatch_status = wl_display_dispatch(display_.get()); | 705 dispatch_status = wl_display_dispatch(display_.get()); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); | 899 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); |
| 883 } | 900 } |
| 884 | 901 |
| 885 exo::wayland::clients::MotionEvents client( | 902 exo::wayland::clients::MotionEvents client( |
| 886 width, height, scale, num_rects, max_frames_pending, | 903 width, height, scale, num_rects, max_frames_pending, |
| 887 command_line->HasSwitch(switches::kFullscreen), | 904 command_line->HasSwitch(switches::kFullscreen), |
| 888 command_line->HasSwitch(switches::kShowFpsCounter), num_benchmark_runs, | 905 command_line->HasSwitch(switches::kShowFpsCounter), num_benchmark_runs, |
| 889 base::TimeDelta::FromMilliseconds(benchmark_interval_ms), use_drm.get()); | 906 base::TimeDelta::FromMilliseconds(benchmark_interval_ms), use_drm.get()); |
| 890 return client.Run(); | 907 return client.Run(); |
| 891 } | 908 } |
| OLD | NEW |