| 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> |
| 11 #include <linux-explicit-synchronization-unstable-v1-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 <deque> | 15 #include <deque> |
| 15 #include <iostream> | 16 #include <iostream> |
| 16 #include <string> | 17 #include <string> |
| 17 #include <vector> | 18 #include <vector> |
| 18 | 19 |
| 19 #include "base/at_exit.h" | 20 #include "base/at_exit.h" |
| 20 #include "base/command_line.h" | 21 #include "base/command_line.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 DEFAULT_DELETER(wl_shm_pool, wl_shm_pool_destroy) | 62 DEFAULT_DELETER(wl_shm_pool, wl_shm_pool_destroy) |
| 62 DEFAULT_DELETER(wl_buffer, wl_buffer_destroy) | 63 DEFAULT_DELETER(wl_buffer, wl_buffer_destroy) |
| 63 DEFAULT_DELETER(wl_surface, wl_surface_destroy) | 64 DEFAULT_DELETER(wl_surface, wl_surface_destroy) |
| 64 DEFAULT_DELETER(wl_region, wl_region_destroy) | 65 DEFAULT_DELETER(wl_region, wl_region_destroy) |
| 65 DEFAULT_DELETER(wl_shell, wl_shell_destroy) | 66 DEFAULT_DELETER(wl_shell, wl_shell_destroy) |
| 66 DEFAULT_DELETER(wl_shell_surface, wl_shell_surface_destroy) | 67 DEFAULT_DELETER(wl_shell_surface, wl_shell_surface_destroy) |
| 67 DEFAULT_DELETER(wl_seat, wl_seat_destroy) | 68 DEFAULT_DELETER(wl_seat, wl_seat_destroy) |
| 68 DEFAULT_DELETER(wl_pointer, wl_pointer_destroy) | 69 DEFAULT_DELETER(wl_pointer, wl_pointer_destroy) |
| 69 DEFAULT_DELETER(wl_touch, wl_touch_destroy) | 70 DEFAULT_DELETER(wl_touch, wl_touch_destroy) |
| 70 DEFAULT_DELETER(wl_callback, wl_callback_destroy) | 71 DEFAULT_DELETER(wl_callback, wl_callback_destroy) |
| 72 DEFAULT_DELETER(zcr_linux_explicit_synchronization_v1, |
| 73 zcr_linux_explicit_synchronization_v1_destroy) |
| 74 DEFAULT_DELETER(zcr_synchronization_v1, zcr_synchronization_v1_destroy) |
| 71 DEFAULT_DELETER(zwp_linux_buffer_params_v1, zwp_linux_buffer_params_v1_destroy) | 75 DEFAULT_DELETER(zwp_linux_buffer_params_v1, zwp_linux_buffer_params_v1_destroy) |
| 72 DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy) | 76 DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy) |
| 73 | 77 |
| 74 #if defined(OZONE_PLATFORM_GBM) | 78 #if defined(OZONE_PLATFORM_GBM) |
| 75 DEFAULT_DELETER(gbm_device, gbm_device_destroy) | 79 DEFAULT_DELETER(gbm_device, gbm_device_destroy) |
| 76 DEFAULT_DELETER(gbm_bo, gbm_bo_destroy) | 80 DEFAULT_DELETER(gbm_bo, gbm_bo_destroy) |
| 77 #endif | 81 #endif |
| 78 | 82 |
| 79 namespace exo { | 83 namespace exo { |
| 80 namespace wayland { | 84 namespace wayland { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 103 | 107 |
| 104 // Rotation speed (degrees/second). | 108 // Rotation speed (degrees/second). |
| 105 const double kRotationSpeed = 360.0; | 109 const double kRotationSpeed = 360.0; |
| 106 | 110 |
| 107 // Benchmark interval in seconds. | 111 // Benchmark interval in seconds. |
| 108 const int kBenchmarkInterval = 5; | 112 const int kBenchmarkInterval = 5; |
| 109 | 113 |
| 110 struct Globals { | 114 struct Globals { |
| 111 std::unique_ptr<wl_compositor> compositor; | 115 std::unique_ptr<wl_compositor> compositor; |
| 112 std::unique_ptr<wl_shm> shm; | 116 std::unique_ptr<wl_shm> shm; |
| 117 std::unique_ptr<zcr_linux_explicit_synchronization_v1> |
| 118 linux_explicit_synchronization; |
| 113 std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf; | 119 std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf; |
| 114 std::unique_ptr<wl_shell> shell; | 120 std::unique_ptr<wl_shell> shell; |
| 115 std::unique_ptr<wl_seat> seat; | 121 std::unique_ptr<wl_seat> seat; |
| 116 }; | 122 }; |
| 117 | 123 |
| 118 void RegistryHandler(void* data, | 124 void RegistryHandler(void* data, |
| 119 wl_registry* registry, | 125 wl_registry* registry, |
| 120 uint32_t id, | 126 uint32_t id, |
| 121 const char* interface, | 127 const char* interface, |
| 122 uint32_t version) { | 128 uint32_t version) { |
| 123 Globals* globals = static_cast<Globals*>(data); | 129 Globals* globals = static_cast<Globals*>(data); |
| 124 | 130 |
| 125 if (strcmp(interface, "wl_compositor") == 0) { | 131 if (strcmp(interface, "wl_compositor") == 0) { |
| 126 globals->compositor.reset(static_cast<wl_compositor*>( | 132 globals->compositor.reset(static_cast<wl_compositor*>( |
| 127 wl_registry_bind(registry, id, &wl_compositor_interface, 3))); | 133 wl_registry_bind(registry, id, &wl_compositor_interface, 3))); |
| 128 } else if (strcmp(interface, "wl_shm") == 0) { | 134 } else if (strcmp(interface, "wl_shm") == 0) { |
| 129 globals->shm.reset(static_cast<wl_shm*>( | 135 globals->shm.reset(static_cast<wl_shm*>( |
| 130 wl_registry_bind(registry, id, &wl_shm_interface, 1))); | 136 wl_registry_bind(registry, id, &wl_shm_interface, 1))); |
| 131 } else if (strcmp(interface, "wl_shell") == 0) { | 137 } else if (strcmp(interface, "wl_shell") == 0) { |
| 132 globals->shell.reset(static_cast<wl_shell*>( | 138 globals->shell.reset(static_cast<wl_shell*>( |
| 133 wl_registry_bind(registry, id, &wl_shell_interface, 1))); | 139 wl_registry_bind(registry, id, &wl_shell_interface, 1))); |
| 134 } else if (strcmp(interface, "wl_seat") == 0) { | 140 } else if (strcmp(interface, "wl_seat") == 0) { |
| 135 globals->seat.reset(static_cast<wl_seat*>( | 141 globals->seat.reset(static_cast<wl_seat*>( |
| 136 wl_registry_bind(registry, id, &wl_seat_interface, 5))); | 142 wl_registry_bind(registry, id, &wl_seat_interface, 5))); |
| 143 } else if (strcmp(interface, "zcr_linux_explicit_synchronization_v1") == 0) { |
| 144 globals->linux_explicit_synchronization.reset( |
| 145 static_cast<zcr_linux_explicit_synchronization_v1*>(wl_registry_bind( |
| 146 registry, id, &zcr_linux_explicit_synchronization_v1_interface, |
| 147 1))); |
| 137 } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) { | 148 } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) { |
| 138 globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>( | 149 globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>( |
| 139 wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1))); | 150 wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1))); |
| 140 } | 151 } |
| 141 } | 152 } |
| 142 | 153 |
| 143 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) { | 154 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) { |
| 144 LOG(WARNING) << "Got a registry losing event for " << id; | 155 LOG(WARNING) << "Got a registry losing event for " << id; |
| 145 } | 156 } |
| 146 | 157 |
| 147 #if defined(OZONE_PLATFORM_GBM) | 158 #if defined(OZONE_PLATFORM_GBM) |
| 148 struct DeleteTextureTraits { | 159 struct DeleteTextureTraits { |
| 149 static GLuint InvalidValue() { return 0; } | 160 static GLuint InvalidValue() { return 0; } |
| 150 static void Free(GLuint texture) { glDeleteTextures(1, &texture); } | 161 static void Free(GLuint texture) { glDeleteTextures(1, &texture); } |
| 151 }; | 162 }; |
| 152 using ScopedTexture = base::ScopedGeneric<GLuint, DeleteTextureTraits>; | 163 using ScopedTexture = base::ScopedGeneric<GLuint, DeleteTextureTraits>; |
| 153 | 164 |
| 154 struct DeleteEglImageTraits { | 165 struct DeleteEglImageTraits { |
| 155 static EGLImageKHR InvalidValue() { return 0; } | 166 static EGLImageKHR InvalidValue() { return 0; } |
| 156 static void Free(EGLImageKHR image) { | 167 static void Free(EGLImageKHR image) { |
| 157 eglDestroyImageKHR(eglGetCurrentDisplay(), image); | 168 eglDestroyImageKHR(eglGetCurrentDisplay(), image); |
| 158 } | 169 } |
| 159 }; | 170 }; |
| 160 using ScopedEglImage = base::ScopedGeneric<EGLImageKHR, DeleteEglImageTraits>; | 171 using ScopedEglImage = base::ScopedGeneric<EGLImageKHR, DeleteEglImageTraits>; |
| 172 |
| 173 struct DeleteEglSyncTraits { |
| 174 static EGLSyncKHR InvalidValue() { return 0; } |
| 175 static void Free(EGLSyncKHR sync) { |
| 176 eglDestroySyncKHR(eglGetCurrentDisplay(), sync); |
| 177 } |
| 178 }; |
| 179 using ScopedEglSync = base::ScopedGeneric<EGLSyncKHR, DeleteEglSyncTraits>; |
| 161 #endif | 180 #endif |
| 162 | 181 |
| 163 struct Buffer { | 182 struct Buffer { |
| 164 std::unique_ptr<wl_buffer> buffer; | 183 std::unique_ptr<wl_buffer> buffer; |
| 165 bool busy = false; | 184 bool busy = false; |
| 166 #if defined(OZONE_PLATFORM_GBM) | 185 #if defined(OZONE_PLATFORM_GBM) |
| 167 std::unique_ptr<gbm_bo> bo; | 186 std::unique_ptr<gbm_bo> bo; |
| 168 std::unique_ptr<ScopedEglImage> egl_image; | 187 std::unique_ptr<ScopedEglImage> egl_image; |
| 188 std::unique_ptr<ScopedEglSync> egl_sync; |
| 169 std::unique_ptr<ScopedTexture> texture; | 189 std::unique_ptr<ScopedTexture> texture; |
| 170 #endif | 190 #endif |
| 171 std::unique_ptr<zwp_linux_buffer_params_v1> params; | 191 std::unique_ptr<zwp_linux_buffer_params_v1> params; |
| 172 base::SharedMemory shared_memory; | 192 base::SharedMemory shared_memory; |
| 173 std::unique_ptr<wl_shm_pool> shm_pool; | 193 std::unique_ptr<wl_shm_pool> shm_pool; |
| 174 sk_sp<SkSurface> sk_surface; | 194 sk_sp<SkSurface> sk_surface; |
| 175 }; | 195 }; |
| 176 | 196 |
| 177 void BufferRelease(void* data, wl_buffer* /* buffer */) { | 197 void BufferRelease(void* data, wl_buffer* /* buffer */) { |
| 178 Buffer* buffer = static_cast<Buffer*>(data); | 198 Buffer* buffer = static_cast<Buffer*>(data); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 } // namespace | 316 } // namespace |
| 297 | 317 |
| 298 class MotionEvents { | 318 class MotionEvents { |
| 299 public: | 319 public: |
| 300 MotionEvents(size_t width, | 320 MotionEvents(size_t width, |
| 301 size_t height, | 321 size_t height, |
| 302 int scale, | 322 int scale, |
| 303 size_t num_rects, | 323 size_t num_rects, |
| 304 size_t max_frames_pending, | 324 size_t max_frames_pending, |
| 305 bool fullscreen, | 325 bool fullscreen, |
| 326 bool use_explicit_synchronization, |
| 306 const std::string* use_drm) | 327 const std::string* use_drm) |
| 307 : width_(width), | 328 : width_(width), |
| 308 height_(height), | 329 height_(height), |
| 309 scale_(scale), | 330 scale_(scale), |
| 310 num_rects_(num_rects), | 331 num_rects_(num_rects), |
| 311 max_frames_pending_(max_frames_pending), | 332 max_frames_pending_(max_frames_pending), |
| 312 fullscreen_(fullscreen), | 333 fullscreen_(fullscreen), |
| 334 use_explicit_synchronization_(use_explicit_synchronization), |
| 313 use_drm_(use_drm) {} | 335 use_drm_(use_drm) {} |
| 314 | 336 |
| 315 // Initialize and run client main loop. | 337 // Initialize and run client main loop. |
| 316 int Run(); | 338 int Run(); |
| 317 | 339 |
| 318 private: | 340 private: |
| 319 bool CreateBuffer(Buffer* buffer); | 341 bool CreateBuffer(Buffer* buffer); |
| 320 | 342 |
| 321 const size_t width_; | 343 const size_t width_; |
| 322 const size_t height_; | 344 const size_t height_; |
| 323 const int scale_; | 345 const int scale_; |
| 324 const size_t num_rects_; | 346 const size_t num_rects_; |
| 325 const size_t max_frames_pending_; | 347 const size_t max_frames_pending_; |
| 326 const bool fullscreen_; | 348 const bool fullscreen_; |
| 349 const bool use_explicit_synchronization_; |
| 327 const std::string* use_drm_; | 350 const std::string* use_drm_; |
| 328 | 351 |
| 329 Globals globals_; | 352 Globals globals_; |
| 330 std::unique_ptr<wl_display> display_; | 353 std::unique_ptr<wl_display> display_; |
| 331 | 354 |
| 332 #if defined(OZONE_PLATFORM_GBM) | 355 #if defined(OZONE_PLATFORM_GBM) |
| 333 base::ScopedFD drm_fd_; | 356 base::ScopedFD drm_fd_; |
| 334 std::unique_ptr<gbm_device> device_; | 357 std::unique_ptr<gbm_device> device_; |
| 335 #endif | 358 #endif |
| 336 | 359 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 wl_display_roundtrip(display_.get()); | 392 wl_display_roundtrip(display_.get()); |
| 370 | 393 |
| 371 if (!globals_.compositor) { | 394 if (!globals_.compositor) { |
| 372 LOG(ERROR) << "Can't find compositor interface"; | 395 LOG(ERROR) << "Can't find compositor interface"; |
| 373 return 1; | 396 return 1; |
| 374 } | 397 } |
| 375 if (!globals_.shm) { | 398 if (!globals_.shm) { |
| 376 LOG(ERROR) << "Can't find shm interface"; | 399 LOG(ERROR) << "Can't find shm interface"; |
| 377 return 1; | 400 return 1; |
| 378 } | 401 } |
| 402 if (use_explicit_synchronization_ && |
| 403 !globals_.linux_explicit_synchronization) { |
| 404 LOG(ERROR) << "Can't find linux_explicit_synchronization interface"; |
| 405 return 1; |
| 406 } |
| 379 if (use_drm_ && !globals_.linux_dmabuf) { | 407 if (use_drm_ && !globals_.linux_dmabuf) { |
| 380 LOG(ERROR) << "Can't find linux_dmabuf interface"; | 408 LOG(ERROR) << "Can't find linux_dmabuf interface"; |
| 381 return 1; | 409 return 1; |
| 382 } | 410 } |
| 383 if (!globals_.shell) { | 411 if (!globals_.shell) { |
| 384 LOG(ERROR) << "Can't find shell interface"; | 412 LOG(ERROR) << "Can't find shell interface"; |
| 385 return 1; | 413 return 1; |
| 386 } | 414 } |
| 387 if (!globals_.seat) { | 415 if (!globals_.seat) { |
| 388 LOG(ERROR) << "Can't find seat interface"; | 416 LOG(ERROR) << "Can't find seat interface"; |
| 389 return 1; | 417 return 1; |
| 390 } | 418 } |
| 391 | 419 |
| 420 #if defined(OZONE_PLATFORM_GBM) |
| 392 EGLenum egl_sync_type = 0; | 421 EGLenum egl_sync_type = 0; |
| 393 #if defined(OZONE_PLATFORM_GBM) | |
| 394 if (use_drm_) { | 422 if (use_drm_) { |
| 395 // Number of files to look for when discovering DRM devices. | 423 // Number of files to look for when discovering DRM devices. |
| 396 const uint32_t kDrmMaxMinor = 15; | 424 const uint32_t kDrmMaxMinor = 15; |
| 397 const uint32_t kRenderNodeStart = 128; | 425 const uint32_t kRenderNodeStart = 128; |
| 398 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; | 426 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; |
| 399 | 427 |
| 400 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { | 428 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { |
| 401 std::string dri_render_node( | 429 std::string dri_render_node( |
| 402 base::StringPrintf(kDriRenderNodeTemplate, i)); | 430 base::StringPrintf(kDriRenderNodeTemplate, i)); |
| 403 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); | 431 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 419 LOG_IF(ERROR, use_drm_) << "Can't find drm device: '" << *use_drm_ << "'"; | 447 LOG_IF(ERROR, use_drm_) << "Can't find drm device: '" << *use_drm_ << "'"; |
| 420 LOG_IF(ERROR, !use_drm_) << "Can't find drm device"; | 448 LOG_IF(ERROR, !use_drm_) << "Can't find drm device"; |
| 421 return 1; | 449 return 1; |
| 422 } | 450 } |
| 423 | 451 |
| 424 device_.reset(gbm_create_device(drm_fd_.get())); | 452 device_.reset(gbm_create_device(drm_fd_.get())); |
| 425 if (!device_) { | 453 if (!device_) { |
| 426 LOG(ERROR) << "Can't create gbm device"; | 454 LOG(ERROR) << "Can't create gbm device"; |
| 427 return 1; | 455 return 1; |
| 428 } | 456 } |
| 457 |
| 458 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") || |
| 459 gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) { |
| 460 egl_sync_type = EGL_SYNC_FENCE_KHR; |
| 461 } |
| 462 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) { |
| 463 egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID; |
| 464 } |
| 429 } | 465 } |
| 430 | 466 |
| 431 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); | 467 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); |
| 432 DCHECK(native_interface); | 468 DCHECK(native_interface); |
| 433 gr_context_ = sk_sp<GrContext>(GrContext::Create( | 469 gr_context_ = sk_sp<GrContext>(GrContext::Create( |
| 434 kOpenGL_GrBackend, | 470 kOpenGL_GrBackend, |
| 435 reinterpret_cast<GrBackendContext>(native_interface.get()))); | 471 reinterpret_cast<GrBackendContext>(native_interface.get()))); |
| 436 DCHECK(gr_context_); | 472 DCHECK(gr_context_); |
| 437 | |
| 438 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") || | |
| 439 gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) { | |
| 440 egl_sync_type = EGL_SYNC_FENCE_KHR; | |
| 441 } | |
| 442 if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) { | |
| 443 egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID; | |
| 444 } | |
| 445 #endif | 473 #endif |
| 446 | 474 |
| 447 wl_buffer_listener buffer_listener = {BufferRelease}; | 475 wl_buffer_listener buffer_listener = {BufferRelease}; |
| 448 | 476 |
| 449 for (size_t i = 0; i < kBuffers; ++i) { | 477 for (size_t i = 0; i < kBuffers; ++i) { |
| 450 if (!CreateBuffer(&buffers_[i])) | 478 if (!CreateBuffer(&buffers_[i])) |
| 451 return 1; | 479 return 1; |
| 452 } | 480 } |
| 453 wl_display_roundtrip(display_.get()); | 481 wl_display_roundtrip(display_.get()); |
| 454 for (size_t i = 0; i < kBuffers; ++i) { | 482 for (size_t i = 0; i < kBuffers; ++i) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 469 std::unique_ptr<wl_region> opaque_region(static_cast<wl_region*>( | 497 std::unique_ptr<wl_region> opaque_region(static_cast<wl_region*>( |
| 470 wl_compositor_create_region(globals_.compositor.get()))); | 498 wl_compositor_create_region(globals_.compositor.get()))); |
| 471 if (!opaque_region) { | 499 if (!opaque_region) { |
| 472 LOG(ERROR) << "Can't create region"; | 500 LOG(ERROR) << "Can't create region"; |
| 473 return 1; | 501 return 1; |
| 474 } | 502 } |
| 475 | 503 |
| 476 wl_region_add(opaque_region.get(), 0, 0, width_, height_); | 504 wl_region_add(opaque_region.get(), 0, 0, width_, height_); |
| 477 wl_surface_set_opaque_region(surface.get(), opaque_region.get()); | 505 wl_surface_set_opaque_region(surface.get(), opaque_region.get()); |
| 478 | 506 |
| 507 std::unique_ptr<zcr_synchronization_v1> synchronization; |
| 508 if (use_explicit_synchronization_) { |
| 509 synchronization.reset(static_cast<zcr_synchronization_v1*>( |
| 510 zcr_linux_explicit_synchronization_v1_get_synchronization( |
| 511 globals_.linux_explicit_synchronization.get(), surface.get()))); |
| 512 if (!synchronization) { |
| 513 LOG(ERROR) << "Can't get synchronization"; |
| 514 return 1; |
| 515 } |
| 516 } |
| 517 |
| 479 std::unique_ptr<wl_shell_surface> shell_surface( | 518 std::unique_ptr<wl_shell_surface> shell_surface( |
| 480 static_cast<wl_shell_surface*>( | 519 static_cast<wl_shell_surface*>( |
| 481 wl_shell_get_shell_surface(globals_.shell.get(), surface.get()))); | 520 wl_shell_get_shell_surface(globals_.shell.get(), surface.get()))); |
| 482 if (!shell_surface) { | 521 if (!shell_surface) { |
| 483 LOG(ERROR) << "Can't get shell surface"; | 522 LOG(ERROR) << "Can't get shell surface"; |
| 484 return 1; | 523 return 1; |
| 485 } | 524 } |
| 486 | 525 |
| 487 wl_shell_surface_set_title(shell_surface.get(), kClientTitle); | 526 wl_shell_surface_set_title(shell_surface.get(), kClientTitle); |
| 488 | 527 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 516 return 1; | 555 return 1; |
| 517 } | 556 } |
| 518 | 557 |
| 519 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion, | 558 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion, |
| 520 TouchFrame, TouchCancel}; | 559 TouchFrame, TouchCancel}; |
| 521 wl_touch_add_listener(touch.get(), &touch_listener, &event_times); | 560 wl_touch_add_listener(touch.get(), &touch_listener, &event_times); |
| 522 | 561 |
| 523 Frame frame; | 562 Frame frame; |
| 524 std::unique_ptr<wl_callback> frame_callback; | 563 std::unique_ptr<wl_callback> frame_callback; |
| 525 wl_callback_listener frame_listener = {FrameCallback}; | 564 wl_callback_listener frame_listener = {FrameCallback}; |
| 526 std::deque<wl_buffer*> pending_frames; | 565 std::deque<Buffer*> pending_frames; |
| 527 | 566 |
| 528 uint32_t frames = 0; | 567 uint32_t frames = 0; |
| 529 base::TimeTicks benchmark_time = base::TimeTicks::Now(); | 568 base::TimeTicks benchmark_time = base::TimeTicks::Now(); |
| 530 base::TimeDelta benchmark_interval = | 569 base::TimeDelta benchmark_interval = |
| 531 base::TimeDelta::FromSeconds(kBenchmarkInterval); | 570 base::TimeDelta::FromSeconds(kBenchmarkInterval); |
| 532 base::TimeDelta benchmark_wall_time; | 571 base::TimeDelta benchmark_wall_time; |
| 533 base::TimeDelta benchmark_cpu_time; | 572 base::TimeDelta benchmark_cpu_time; |
| 534 | 573 |
| 535 int dispatch_status = 0; | 574 int dispatch_status = 0; |
| 536 do { | 575 do { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 SK_ColorRED, SK_ColorYELLOW, | 642 SK_ColorRED, SK_ColorYELLOW, |
| 604 SK_ColorCYAN, SK_ColorMAGENTA}; | 643 SK_ColorCYAN, SK_ColorMAGENTA}; |
| 605 paint.setColor(SkColorSetA(kColors[i % arraysize(kColors)], 0xA0)); | 644 paint.setColor(SkColorSetA(kColors[i % arraysize(kColors)], 0xA0)); |
| 606 canvas->rotate(rotation / num_rects_); | 645 canvas->rotate(rotation / num_rects_); |
| 607 canvas->drawIRect(rect, paint); | 646 canvas->drawIRect(rect, paint); |
| 608 } | 647 } |
| 609 | 648 |
| 610 canvas->restore(); | 649 canvas->restore(); |
| 611 if (gr_context_) { | 650 if (gr_context_) { |
| 612 gr_context_->flush(); | 651 gr_context_->flush(); |
| 652 |
| 653 #if defined(OZONE_PLATFORM_GBM) |
| 654 if (egl_sync_type) { |
| 655 buffer->egl_sync.reset(new ScopedEglSync(eglCreateSyncKHR( |
| 656 eglGetCurrentDisplay(), egl_sync_type, nullptr))); |
| 657 DCHECK(buffer->egl_sync->is_valid()); |
| 658 } |
| 659 #endif |
| 660 |
| 613 glFlush(); | 661 glFlush(); |
| 614 | |
| 615 if (egl_sync_type) { | |
| 616 EGLSyncKHR sync = | |
| 617 eglCreateSyncKHR(eglGetCurrentDisplay(), egl_sync_type, nullptr); | |
| 618 DCHECK(sync != EGL_NO_SYNC_KHR); | |
| 619 eglClientWaitSyncKHR(eglGetCurrentDisplay(), sync, | |
| 620 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, | |
| 621 EGL_FOREVER_KHR); | |
| 622 eglDestroySyncKHR(eglGetCurrentDisplay(), sync); | |
| 623 } | |
| 624 } | 662 } |
| 625 | 663 |
| 626 buffer->busy = true; | 664 buffer->busy = true; |
| 627 pending_frames.push_back(buffer->buffer.get()); | 665 pending_frames.push_back(buffer); |
| 628 | 666 |
| 629 ++frames; | 667 ++frames; |
| 630 benchmark_wall_time += base::TimeTicks::Now() - wall_time_start; | 668 benchmark_wall_time += base::TimeTicks::Now() - wall_time_start; |
| 631 benchmark_cpu_time += base::ThreadTicks::Now() - cpu_time_start; | 669 benchmark_cpu_time += base::ThreadTicks::Now() - cpu_time_start; |
| 632 continue; | 670 continue; |
| 633 } | 671 } |
| 634 | 672 |
| 635 if (!frame.callback_pending) { | 673 if (!frame.callback_pending) { |
| 636 DCHECK_GT(pending_frames.size(), 0u); | 674 DCHECK_GT(pending_frames.size(), 0u); |
| 675 Buffer* buffer = pending_frames.front(); |
| 676 pending_frames.pop_front(); |
| 677 |
| 637 wl_surface_set_buffer_scale(surface.get(), scale_); | 678 wl_surface_set_buffer_scale(surface.get(), scale_); |
| 638 wl_surface_attach(surface.get(), pending_frames.front(), 0, 0); | 679 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0); |
| 639 pending_frames.pop_front(); | 680 |
| 681 #if defined(OZONE_PLATFORM_GBM) |
| 682 if (buffer->egl_sync->is_valid()) { |
| 683 if (use_explicit_synchronization_) { |
| 684 DCHECK_EQ(egl_sync_type, |
| 685 static_cast<EGLenum>(EGL_SYNC_NATIVE_FENCE_ANDROID)); |
| 686 base::ScopedFD fence_fd(eglDupNativeFenceFDANDROID( |
| 687 eglGetCurrentDisplay(), buffer->egl_sync->get())); |
| 688 DCHECK(fence_fd.is_valid()); |
| 689 DCHECK(synchronization); |
| 690 zcr_synchronization_v1_set_acquire_fence(synchronization.get(), |
| 691 fence_fd.get()); |
| 692 } else { |
| 693 eglClientWaitSyncKHR(eglGetCurrentDisplay(), buffer->egl_sync->get(), |
| 694 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, |
| 695 EGL_FOREVER_KHR); |
| 696 } |
| 697 } |
| 698 #endif |
| 640 | 699 |
| 641 frame_callback.reset(wl_surface_frame(surface.get())); | 700 frame_callback.reset(wl_surface_frame(surface.get())); |
| 642 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame); | 701 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame); |
| 643 frame.callback_pending = true; | 702 frame.callback_pending = true; |
| 644 wl_surface_commit(surface.get()); | 703 wl_surface_commit(surface.get()); |
| 645 wl_display_flush(display_.get()); | 704 wl_display_flush(display_.get()); |
| 646 continue; | 705 continue; |
| 647 } | 706 } |
| 648 | 707 |
| 649 dispatch_status = wl_display_dispatch(display_.get()); | 708 dispatch_status = wl_display_dispatch(display_.get()); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 | 812 |
| 754 // Specifies the number of rotating rects to draw. | 813 // Specifies the number of rotating rects to draw. |
| 755 const char kNumRects[] = "num-rects"; | 814 const char kNumRects[] = "num-rects"; |
| 756 | 815 |
| 757 // Specifies the maximum number of pending frames. | 816 // Specifies the maximum number of pending frames. |
| 758 const char kMaxFramesPending[] = "max-frames-pending"; | 817 const char kMaxFramesPending[] = "max-frames-pending"; |
| 759 | 818 |
| 760 // Specifies if client should be fullscreen. | 819 // Specifies if client should be fullscreen. |
| 761 const char kFullscreen[] = "fullscreen"; | 820 const char kFullscreen[] = "fullscreen"; |
| 762 | 821 |
| 822 // Specifies if client should be using explicit synchronization. |
| 823 const char kUseExplicitSynchronization[] = "use-explicit-synchronization"; |
| 824 |
| 763 // Use drm buffer instead of shared memory. | 825 // Use drm buffer instead of shared memory. |
| 764 const char kUseDrm[] = "use-drm"; | 826 const char kUseDrm[] = "use-drm"; |
| 765 | 827 |
| 766 } // namespace switches | 828 } // namespace switches |
| 767 | 829 |
| 768 int main(int argc, char* argv[]) { | 830 int main(int argc, char* argv[]) { |
| 769 base::AtExitManager exit_manager; | 831 base::AtExitManager exit_manager; |
| 770 base::CommandLine::Init(argc, argv); | 832 base::CommandLine::Init(argc, argv); |
| 771 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 833 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 772 | 834 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 } | 868 } |
| 807 | 869 |
| 808 std::unique_ptr<std::string> use_drm; | 870 std::unique_ptr<std::string> use_drm; |
| 809 if (command_line->HasSwitch(switches::kUseDrm)) { | 871 if (command_line->HasSwitch(switches::kUseDrm)) { |
| 810 use_drm.reset( | 872 use_drm.reset( |
| 811 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); | 873 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); |
| 812 } | 874 } |
| 813 | 875 |
| 814 exo::wayland::clients::MotionEvents client( | 876 exo::wayland::clients::MotionEvents client( |
| 815 width, height, scale, num_rects, max_frames_pending, | 877 width, height, scale, num_rects, max_frames_pending, |
| 816 command_line->HasSwitch(switches::kFullscreen), use_drm.get()); | 878 command_line->HasSwitch(switches::kFullscreen), |
| 879 command_line->HasSwitch(switches::kUseExplicitSynchronization), |
| 880 use_drm.get()); |
| 817 return client.Run(); | 881 return client.Run(); |
| 818 } | 882 } |
| OLD | NEW |