| 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 <wayland-client-core.h> | 11 #include <wayland-client-core.h> |
| 12 #include <wayland-client-protocol.h> | 12 #include <wayland-client-protocol.h> |
| 13 | 13 |
| 14 #include <iostream> | 14 #include <iostream> |
| 15 #include <string> |
| 15 #include <vector> | 16 #include <vector> |
| 16 | 17 |
| 17 #include "base/at_exit.h" | 18 #include "base/at_exit.h" |
| 18 #include "base/command_line.h" | 19 #include "base/command_line.h" |
| 19 #include "base/logging.h" | 20 #include "base/logging.h" |
| 20 #include "base/macros.h" | 21 #include "base/macros.h" |
| 21 #include "base/memory/shared_memory.h" | 22 #include "base/memory/shared_memory.h" |
| 22 #include "base/scoped_generic.h" | 23 #include "base/scoped_generic.h" |
| 23 #include "base/strings/string_number_conversions.h" | 24 #include "base/strings/string_number_conversions.h" |
| 25 #include "base/strings/stringprintf.h" |
| 24 #include "base/time/time.h" | 26 #include "base/time/time.h" |
| 25 #include "third_party/skia/include/core/SkCanvas.h" | 27 #include "third_party/skia/include/core/SkCanvas.h" |
| 26 #include "third_party/skia/include/core/SkRefCnt.h" | 28 #include "third_party/skia/include/core/SkRefCnt.h" |
| 27 #include "third_party/skia/include/core/SkSurface.h" | 29 #include "third_party/skia/include/core/SkSurface.h" |
| 28 #include "third_party/skia/include/gpu/GrContext.h" | 30 #include "third_party/skia/include/gpu/GrContext.h" |
| 29 #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h" | 31 #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h" |
| 30 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" | 32 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" |
| 31 #include "ui/gl/gl_bindings.h" | 33 #include "ui/gl/gl_bindings.h" |
| 32 #include "ui/gl/gl_context.h" | 34 #include "ui/gl/gl_context.h" |
| 33 #include "ui/gl/gl_enums.h" | 35 #include "ui/gl/gl_enums.h" |
| 34 #include "ui/gl/gl_surface.h" | 36 #include "ui/gl/gl_surface.h" |
| 35 #include "ui/gl/gl_surface_egl.h" | 37 #include "ui/gl/gl_surface_egl.h" |
| 36 #include "ui/gl/init/gl_factory.h" | 38 #include "ui/gl/init/gl_factory.h" |
| 37 #include "ui/gl/scoped_make_current.h" | 39 #include "ui/gl/scoped_make_current.h" |
| 38 | 40 |
| 39 #if defined(OZONE_PLATFORM_GBM) | 41 #if defined(OZONE_PLATFORM_GBM) |
| 40 #include <drm_fourcc.h> | 42 #include <drm_fourcc.h> |
| 41 #include <gbm.h> | 43 #include <gbm.h> |
| 44 #include <xf86drm.h> |
| 42 #endif | 45 #endif |
| 43 | 46 |
| 44 // Convenient macro that is used to define default deleters for object | 47 // Convenient macro that is used to define default deleters for object |
| 45 // types allowing them to be used with std::unique_ptr. | 48 // types allowing them to be used with std::unique_ptr. |
| 46 #define DEFAULT_DELETER(TypeName, DeleteFunction) \ | 49 #define DEFAULT_DELETER(TypeName, DeleteFunction) \ |
| 47 namespace std { \ | 50 namespace std { \ |
| 48 template <> \ | 51 template <> \ |
| 49 struct default_delete<TypeName> { \ | 52 struct default_delete<TypeName> { \ |
| 50 void operator()(TypeName* ptr) { DeleteFunction(ptr); } \ | 53 void operator()(TypeName* ptr) { DeleteFunction(ptr); } \ |
| 51 }; \ | 54 }; \ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 // Buffer format. | 86 // Buffer format. |
| 84 const int32_t kShmFormat = WL_SHM_FORMAT_ARGB8888; | 87 const int32_t kShmFormat = WL_SHM_FORMAT_ARGB8888; |
| 85 const SkColorType kColorType = kBGRA_8888_SkColorType; | 88 const SkColorType kColorType = kBGRA_8888_SkColorType; |
| 86 #if defined(OZONE_PLATFORM_GBM) | 89 #if defined(OZONE_PLATFORM_GBM) |
| 87 const GrPixelConfig kGrPixelConfig = kBGRA_8888_GrPixelConfig; | 90 const GrPixelConfig kGrPixelConfig = kBGRA_8888_GrPixelConfig; |
| 88 const int32_t kDrmFormat = DRM_FORMAT_ABGR8888; | 91 const int32_t kDrmFormat = DRM_FORMAT_ABGR8888; |
| 89 #endif | 92 #endif |
| 90 const size_t kBytesPerPixel = 4; | 93 const size_t kBytesPerPixel = 4; |
| 91 | 94 |
| 92 #if defined(OZONE_PLATFORM_GBM) | 95 #if defined(OZONE_PLATFORM_GBM) |
| 93 // DRI render node path. | 96 // DRI render node path template. |
| 94 const char kDriRenderNode[] = "/dev/dri/renderD128"; | 97 const char kDriRenderNodeTemplate[] = "/dev/dri/renderD%u"; |
| 95 #endif | 98 #endif |
| 96 | 99 |
| 97 // Number of buffers. | 100 // Number of buffers. |
| 98 const size_t kBuffers = 3; | 101 const size_t kBuffers = 3; |
| 99 | 102 |
| 100 // Rotation speed (degrees/second). | 103 // Rotation speed (degrees/second). |
| 101 const double kRotationSpeed = 360.0; | 104 const double kRotationSpeed = 360.0; |
| 102 | 105 |
| 103 // Benchmark interval in seconds. | 106 // Benchmark interval in seconds. |
| 104 const int kBenchmarkInterval = 5; | 107 const int kBenchmarkInterval = 5; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 #endif | 293 #endif |
| 291 | 294 |
| 292 } // namespace | 295 } // namespace |
| 293 | 296 |
| 294 class MotionEvents { | 297 class MotionEvents { |
| 295 public: | 298 public: |
| 296 MotionEvents(size_t width, | 299 MotionEvents(size_t width, |
| 297 size_t height, | 300 size_t height, |
| 298 int scale, | 301 int scale, |
| 299 size_t num_rects, | 302 size_t num_rects, |
| 300 bool use_drm, | 303 const std::string* use_drm, |
| 301 bool fullscreen) | 304 bool fullscreen) |
| 302 : width_(width), | 305 : width_(width), |
| 303 height_(height), | 306 height_(height), |
| 304 scale_(scale), | 307 scale_(scale), |
| 305 num_rects_(num_rects), | 308 num_rects_(num_rects), |
| 306 use_drm_(use_drm), | 309 use_drm_(use_drm), |
| 307 fullscreen_(fullscreen) {} | 310 fullscreen_(fullscreen) {} |
| 308 | 311 |
| 309 // Initialize and run client main loop. | 312 // Initialize and run client main loop. |
| 310 int Run(); | 313 int Run(); |
| 311 | 314 |
| 312 private: | 315 private: |
| 313 bool CreateBuffer(Buffer* buffer); | 316 bool CreateBuffer(Buffer* buffer); |
| 314 size_t stride() const { return width_ * kBytesPerPixel; } | 317 size_t stride() const { return width_ * kBytesPerPixel; } |
| 315 size_t buffer_size() const { return stride() * height_; } | 318 size_t buffer_size() const { return stride() * height_; } |
| 316 | 319 |
| 317 const size_t width_; | 320 const size_t width_; |
| 318 const size_t height_; | 321 const size_t height_; |
| 319 const int scale_; | 322 const int scale_; |
| 320 const size_t num_rects_; | 323 const size_t num_rects_; |
| 321 const bool use_drm_; | 324 const std::string* use_drm_; |
| 322 const bool fullscreen_; | 325 const bool fullscreen_; |
| 323 | 326 |
| 324 Globals globals_; | 327 Globals globals_; |
| 325 std::unique_ptr<wl_display> display_; | 328 std::unique_ptr<wl_display> display_; |
| 326 | 329 |
| 327 #if defined(OZONE_PLATFORM_GBM) | 330 #if defined(OZONE_PLATFORM_GBM) |
| 328 base::ScopedFD drm_fd_; | 331 base::ScopedFD drm_fd_; |
| 329 std::unique_ptr<gbm_device> device_; | 332 std::unique_ptr<gbm_device> device_; |
| 330 #endif | 333 #endif |
| 331 | 334 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 if (!globals_.shell) { | 380 if (!globals_.shell) { |
| 378 LOG(ERROR) << "Can't find shell interface"; | 381 LOG(ERROR) << "Can't find shell interface"; |
| 379 return 1; | 382 return 1; |
| 380 } | 383 } |
| 381 if (!globals_.seat) { | 384 if (!globals_.seat) { |
| 382 LOG(ERROR) << "Can't find seat interface"; | 385 LOG(ERROR) << "Can't find seat interface"; |
| 383 return 1; | 386 return 1; |
| 384 } | 387 } |
| 385 | 388 |
| 386 #if defined(OZONE_PLATFORM_GBM) | 389 #if defined(OZONE_PLATFORM_GBM) |
| 387 drm_fd_.reset(open(kDriRenderNode, O_RDWR)); | 390 if (use_drm_) { |
| 388 if (drm_fd_.get() < 0) { | 391 // Number of files to look for when discovering DRM devices. |
| 389 LOG(ERROR) << "Can't open drm device '" << kDriRenderNode << "'"; | 392 const uint32_t kDrmMaxMinor = 15; |
| 390 return 1; | 393 const uint32_t kRenderNodeStart = 128; |
| 394 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; |
| 395 |
| 396 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { |
| 397 std::string dri_render_node( |
| 398 base::StringPrintf(kDriRenderNodeTemplate, i)); |
| 399 base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); |
| 400 if (drm_fd.get() < 0) |
| 401 continue; |
| 402 drmVersionPtr drm_version = drmGetVersion(drm_fd.get()); |
| 403 if (!drm_version) { |
| 404 LOG(ERROR) << "Can't get version for device: '" << dri_render_node |
| 405 << "'"; |
| 406 return 1; |
| 407 } |
| 408 if (strstr(drm_version->name, use_drm_->c_str())) { |
| 409 drm_fd_ = std::move(drm_fd); |
| 410 break; |
| 411 } |
| 412 } |
| 413 |
| 414 if (drm_fd_.get() < 0) { |
| 415 LOG_IF(ERROR, use_drm_) << "Can't find drm device: '" << *use_drm_ << "'"; |
| 416 LOG_IF(ERROR, !use_drm_) << "Can't find drm device"; |
| 417 return 1; |
| 418 } |
| 419 |
| 420 device_.reset(gbm_create_device(drm_fd_.get())); |
| 421 if (!device_) { |
| 422 LOG(ERROR) << "Can't create gbm device"; |
| 423 return 1; |
| 424 } |
| 391 } | 425 } |
| 392 | 426 |
| 393 device_.reset(gbm_create_device(drm_fd_.get())); | |
| 394 if (!device_) { | |
| 395 LOG(ERROR) << "Can't create gbm device"; | |
| 396 return 1; | |
| 397 } | |
| 398 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); | 427 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); |
| 399 DCHECK(native_interface); | 428 DCHECK(native_interface); |
| 400 gr_context_ = sk_sp<GrContext>(GrContext::Create( | 429 gr_context_ = sk_sp<GrContext>(GrContext::Create( |
| 401 kOpenGL_GrBackend, | 430 kOpenGL_GrBackend, |
| 402 reinterpret_cast<GrBackendContext>(native_interface.get()))); | 431 reinterpret_cast<GrBackendContext>(native_interface.get()))); |
| 403 DCHECK(gr_context_); | 432 DCHECK(gr_context_); |
| 404 #endif | 433 #endif |
| 405 | 434 |
| 406 wl_buffer_listener buffer_listener = {BufferRelease}; | 435 wl_buffer_listener buffer_listener = {BufferRelease}; |
| 407 | 436 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 } | 729 } |
| 701 | 730 |
| 702 size_t num_rects = 1; | 731 size_t num_rects = 1; |
| 703 if (command_line->HasSwitch(switches::kNumRects) && | 732 if (command_line->HasSwitch(switches::kNumRects) && |
| 704 !base::StringToSizeT( | 733 !base::StringToSizeT( |
| 705 command_line->GetSwitchValueASCII(switches::kNumRects), &num_rects)) { | 734 command_line->GetSwitchValueASCII(switches::kNumRects), &num_rects)) { |
| 706 LOG(ERROR) << "Invalid value for " << switches::kNumRects; | 735 LOG(ERROR) << "Invalid value for " << switches::kNumRects; |
| 707 return 1; | 736 return 1; |
| 708 } | 737 } |
| 709 | 738 |
| 710 bool use_drm = command_line->HasSwitch(switches::kUseDrm); | 739 std::unique_ptr<std::string> use_drm; |
| 740 if (command_line->HasSwitch(switches::kUseDrm)) { |
| 741 use_drm.reset( |
| 742 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); |
| 743 } |
| 744 |
| 711 bool fullscreen = command_line->HasSwitch(switches::kFullscreen); | 745 bool fullscreen = command_line->HasSwitch(switches::kFullscreen); |
| 712 | 746 |
| 713 exo::wayland::clients::MotionEvents client(width, height, scale, num_rects, | 747 exo::wayland::clients::MotionEvents client(width, height, scale, num_rects, |
| 714 use_drm, fullscreen); | 748 use_drm.get(), fullscreen); |
| 715 return client.Run(); | 749 return client.Run(); |
| 716 } | 750 } |
| OLD | NEW |