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

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

Issue 2477383002: exo: Add max frames pending flag to motion event client. (Closed)
Patch Set: address feedback Created 4 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <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 <deque>
14 #include <iostream> 15 #include <iostream>
15 #include <string> 16 #include <string>
16 #include <vector> 17 #include <vector>
17 18
18 #include "base/at_exit.h" 19 #include "base/at_exit.h"
19 #include "base/command_line.h" 20 #include "base/command_line.h"
20 #include "base/logging.h" 21 #include "base/logging.h"
21 #include "base/macros.h" 22 #include "base/macros.h"
22 #include "base/memory/shared_memory.h" 23 #include "base/memory/shared_memory.h"
23 #include "base/scoped_generic.h" 24 #include "base/scoped_generic.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 const int32_t kDrmFormat = DRM_FORMAT_ABGR8888; 92 const int32_t kDrmFormat = DRM_FORMAT_ABGR8888;
92 #endif 93 #endif
93 const size_t kBytesPerPixel = 4; 94 const size_t kBytesPerPixel = 4;
94 95
95 #if defined(OZONE_PLATFORM_GBM) 96 #if defined(OZONE_PLATFORM_GBM)
96 // DRI render node path template. 97 // DRI render node path template.
97 const char kDriRenderNodeTemplate[] = "/dev/dri/renderD%u"; 98 const char kDriRenderNodeTemplate[] = "/dev/dri/renderD%u";
98 #endif 99 #endif
99 100
100 // Number of buffers. 101 // Number of buffers.
101 const size_t kBuffers = 3; 102 const size_t kBuffers = 8;
102 103
103 // Rotation speed (degrees/second). 104 // Rotation speed (degrees/second).
104 const double kRotationSpeed = 360.0; 105 const double kRotationSpeed = 360.0;
105 106
106 // Benchmark interval in seconds. 107 // Benchmark interval in seconds.
107 const int kBenchmarkInterval = 5; 108 const int kBenchmarkInterval = 5;
108 109
109 struct Globals { 110 struct Globals {
110 std::unique_ptr<wl_compositor> compositor; 111 std::unique_ptr<wl_compositor> compositor;
111 std::unique_ptr<wl_shm> shm; 112 std::unique_ptr<wl_shm> shm;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 #endif 294 #endif
294 295
295 } // namespace 296 } // namespace
296 297
297 class MotionEvents { 298 class MotionEvents {
298 public: 299 public:
299 MotionEvents(size_t width, 300 MotionEvents(size_t width,
300 size_t height, 301 size_t height,
301 int scale, 302 int scale,
302 size_t num_rects, 303 size_t num_rects,
303 const std::string* use_drm, 304 size_t max_frames_pending,
304 bool fullscreen) 305 bool fullscreen,
306 const std::string* use_drm)
305 : width_(width), 307 : width_(width),
306 height_(height), 308 height_(height),
307 scale_(scale), 309 scale_(scale),
308 num_rects_(num_rects), 310 num_rects_(num_rects),
309 use_drm_(use_drm), 311 max_frames_pending_(max_frames_pending),
310 fullscreen_(fullscreen) {} 312 fullscreen_(fullscreen),
313 use_drm_(use_drm) {}
311 314
312 // Initialize and run client main loop. 315 // Initialize and run client main loop.
313 int Run(); 316 int Run();
314 317
315 private: 318 private:
316 bool CreateBuffer(Buffer* buffer); 319 bool CreateBuffer(Buffer* buffer);
317 size_t stride() const { return width_ * kBytesPerPixel; }
318 size_t buffer_size() const { return stride() * height_; }
319 320
320 const size_t width_; 321 const size_t width_;
321 const size_t height_; 322 const size_t height_;
322 const int scale_; 323 const int scale_;
323 const size_t num_rects_; 324 const size_t num_rects_;
325 const size_t max_frames_pending_;
326 const bool fullscreen_;
324 const std::string* use_drm_; 327 const std::string* use_drm_;
325 const bool fullscreen_;
326 328
327 Globals globals_; 329 Globals globals_;
328 std::unique_ptr<wl_display> display_; 330 std::unique_ptr<wl_display> display_;
329 331
330 #if defined(OZONE_PLATFORM_GBM) 332 #if defined(OZONE_PLATFORM_GBM)
331 base::ScopedFD drm_fd_; 333 base::ScopedFD drm_fd_;
332 std::unique_ptr<gbm_device> device_; 334 std::unique_ptr<gbm_device> device_;
333 #endif 335 #endif
334 336
335 scoped_refptr<gl::GLSurface> gl_surface_; 337 scoped_refptr<gl::GLSurface> gl_surface_;
(...skipping 11 matching lines...) Expand all
347 if (!display_) { 349 if (!display_) {
348 LOG(ERROR) << "wl_display_connect failed"; 350 LOG(ERROR) << "wl_display_connect failed";
349 return 1; 351 return 1;
350 } 352 }
351 353
352 bool gl_initialized = gl::init::InitializeGLOneOff(); 354 bool gl_initialized = gl::init::InitializeGLOneOff();
353 DCHECK(gl_initialized); 355 DCHECK(gl_initialized);
354 gl_surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size()); 356 gl_surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size());
355 gl_context_ = 357 gl_context_ =
356 gl::init::CreateGLContext(nullptr, // share_group 358 gl::init::CreateGLContext(nullptr, // share_group
357 gl_surface_.get(), gl::PreferIntegratedGpu); 359 gl_surface_.get(), gl::GLContextAttribs());
358 360
359 make_current_.reset( 361 make_current_.reset(
360 new ui::ScopedMakeCurrent(gl_context_.get(), gl_surface_.get())); 362 new ui::ScopedMakeCurrent(gl_context_.get(), gl_surface_.get()));
363
361 wl_registry_listener registry_listener = {RegistryHandler, RegistryRemover}; 364 wl_registry_listener registry_listener = {RegistryHandler, RegistryRemover};
362 365
363 wl_registry* registry = wl_display_get_registry(display_.get()); 366 wl_registry* registry = wl_display_get_registry(display_.get());
364 wl_registry_add_listener(registry, &registry_listener, &globals_); 367 wl_registry_add_listener(registry, &registry_listener, &globals_);
365 368
366 wl_display_roundtrip(display_.get()); 369 wl_display_roundtrip(display_.get());
367 370
368 if (!globals_.compositor) { 371 if (!globals_.compositor) {
369 LOG(ERROR) << "Can't find compositor interface"; 372 LOG(ERROR) << "Can't find compositor interface";
370 return 1; 373 return 1;
371 } 374 }
372 if (!globals_.shm) { 375 if (!globals_.shm) {
373 LOG(ERROR) << "Can't find shm interface"; 376 LOG(ERROR) << "Can't find shm interface";
374 return 1; 377 return 1;
375 } 378 }
376 if (use_drm_ && !globals_.linux_dmabuf) { 379 if (use_drm_ && !globals_.linux_dmabuf) {
377 LOG(ERROR) << "Can't find linux_dmabuf interface"; 380 LOG(ERROR) << "Can't find linux_dmabuf interface";
378 return 1; 381 return 1;
379 } 382 }
380 if (!globals_.shell) { 383 if (!globals_.shell) {
381 LOG(ERROR) << "Can't find shell interface"; 384 LOG(ERROR) << "Can't find shell interface";
382 return 1; 385 return 1;
383 } 386 }
384 if (!globals_.seat) { 387 if (!globals_.seat) {
385 LOG(ERROR) << "Can't find seat interface"; 388 LOG(ERROR) << "Can't find seat interface";
386 return 1; 389 return 1;
387 } 390 }
388 391
392 EGLenum egl_sync_type = 0;
389 #if defined(OZONE_PLATFORM_GBM) 393 #if defined(OZONE_PLATFORM_GBM)
390 if (use_drm_) { 394 if (use_drm_) {
391 // Number of files to look for when discovering DRM devices. 395 // Number of files to look for when discovering DRM devices.
392 const uint32_t kDrmMaxMinor = 15; 396 const uint32_t kDrmMaxMinor = 15;
393 const uint32_t kRenderNodeStart = 128; 397 const uint32_t kRenderNodeStart = 128;
394 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor; 398 const uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor;
395 399
396 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { 400 for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) {
397 std::string dri_render_node( 401 std::string dri_render_node(
398 base::StringPrintf(kDriRenderNodeTemplate, i)); 402 base::StringPrintf(kDriRenderNodeTemplate, i));
(...skipping 24 matching lines...) Expand all
423 return 1; 427 return 1;
424 } 428 }
425 } 429 }
426 430
427 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface()); 431 sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface());
428 DCHECK(native_interface); 432 DCHECK(native_interface);
429 gr_context_ = sk_sp<GrContext>(GrContext::Create( 433 gr_context_ = sk_sp<GrContext>(GrContext::Create(
430 kOpenGL_GrBackend, 434 kOpenGL_GrBackend,
431 reinterpret_cast<GrBackendContext>(native_interface.get()))); 435 reinterpret_cast<GrBackendContext>(native_interface.get())));
432 DCHECK(gr_context_); 436 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 }
433 #endif 445 #endif
434 446
435 wl_buffer_listener buffer_listener = {BufferRelease}; 447 wl_buffer_listener buffer_listener = {BufferRelease};
436 448
437 for (size_t i = 0; i < kBuffers; ++i) { 449 for (size_t i = 0; i < kBuffers; ++i) {
438 if (!CreateBuffer(&buffers_[i])) 450 if (!CreateBuffer(&buffers_[i]))
439 return 1; 451 return 1;
440 } 452 }
441 wl_display_roundtrip(display_.get()); 453 wl_display_roundtrip(display_.get());
442 for (size_t i = 0; i < kBuffers; ++i) { 454 for (size_t i = 0; i < kBuffers; ++i) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 return 1; 516 return 1;
505 } 517 }
506 518
507 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion, 519 wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion,
508 TouchFrame, TouchCancel}; 520 TouchFrame, TouchCancel};
509 wl_touch_add_listener(touch.get(), &touch_listener, &event_times); 521 wl_touch_add_listener(touch.get(), &touch_listener, &event_times);
510 522
511 Frame frame; 523 Frame frame;
512 std::unique_ptr<wl_callback> frame_callback; 524 std::unique_ptr<wl_callback> frame_callback;
513 wl_callback_listener frame_listener = {FrameCallback}; 525 wl_callback_listener frame_listener = {FrameCallback};
526 std::deque<wl_buffer*> pending_frames;
514 527
515 uint32_t frames = 0; 528 uint32_t frames = 0;
516 base::TimeTicks benchmark_time = base::TimeTicks::Now(); 529 base::TimeTicks benchmark_time = base::TimeTicks::Now();
517 base::TimeDelta benchmark_interval = 530 base::TimeDelta benchmark_interval =
518 base::TimeDelta::FromSeconds(kBenchmarkInterval); 531 base::TimeDelta::FromSeconds(kBenchmarkInterval);
532 base::TimeDelta benchmark_wall_time;
533 base::TimeDelta benchmark_cpu_time;
519 534
535 int dispatch_status = 0;
520 do { 536 do {
521 if (frame.callback_pending) 537 bool enqueue_frame = frame.callback_pending
538 ? pending_frames.size() < max_frames_pending_
539 : pending_frames.empty();
540 if (enqueue_frame) {
541 Buffer* buffer =
542 std::find_if(std::begin(buffers_), std::end(buffers_),
543 [](const Buffer& buffer) { return !buffer.busy; });
544 if (buffer == std::end(buffers_)) {
545 LOG(ERROR) << "Can't find free buffer";
546 return 1;
547 }
548
549 base::TimeTicks wall_time_start = base::TimeTicks::Now();
550 if ((wall_time_start - benchmark_time) > benchmark_interval) {
551 // Print benchmark statistics for the frames produced.
552 // Note: frames produced is not necessarily the same as frames
553 // displayed.
554 std::cout << frames << " frames in " << benchmark_interval.InSeconds()
555 << " seconds: " << frames / benchmark_interval.InSecondsF()
556 << " fps (wall="
557 << benchmark_wall_time.InMillisecondsF() / frames
558 << " cpu=" << benchmark_cpu_time.InMillisecondsF() / frames
559 << ")" << std::endl;
560
561 frames = 0;
562 benchmark_time = wall_time_start;
563 benchmark_wall_time = base::TimeDelta();
564 benchmark_cpu_time = base::TimeDelta();
565 }
566
567 base::ThreadTicks cpu_time_start = base::ThreadTicks::Now();
568
569 SkCanvas* canvas = buffer->sk_surface->getCanvas();
570 canvas->save();
571
572 if (event_times.empty()) {
573 canvas->clear(SK_ColorBLACK);
574 } else {
575 // Split buffer into one horizontal rectangle for each event received
576 // since last frame. Latest event at the top.
577 int y = 0;
578 // Note: Rounding up to ensure we cover the whole canvas.
579 int h = (height_ + (event_times.size() / 2)) / event_times.size();
580 while (!event_times.empty()) {
581 SkIRect rect = SkIRect::MakeXYWH(0, y, width_, h);
582 SkPaint paint;
583 paint.setColor(SkColorSetRGB((event_times.back() & 0x0000ff) >> 0,
584 (event_times.back() & 0x00ff00) >> 8,
585 (event_times.back() & 0xff0000) >> 16));
586 canvas->drawIRect(rect, paint);
587 event_times.pop_back();
588 y += h;
589 }
590 }
591
592 // Draw rotating rects.
593 SkScalar half_width = SkScalarHalf(width_);
594 SkScalar half_height = SkScalarHalf(height_);
595 SkIRect rect = SkIRect::MakeXYWH(-SkScalarHalf(half_width),
596 -SkScalarHalf(half_height), half_width,
597 half_height);
598 SkScalar rotation = SkScalarMulDiv(frame.time, kRotationSpeed, 1000);
599 SkPaint paint;
600 canvas->translate(half_width, half_height);
601 for (size_t i = 0; i < num_rects_; ++i) {
602 const SkColor kColors[] = {SK_ColorBLUE, SK_ColorGREEN,
603 SK_ColorRED, SK_ColorYELLOW,
604 SK_ColorCYAN, SK_ColorMAGENTA};
605 paint.setColor(SkColorSetA(kColors[i % arraysize(kColors)], 0xA0));
606 canvas->rotate(rotation / num_rects_);
607 canvas->drawIRect(rect, paint);
608 }
609
610 canvas->restore();
611 if (gr_context_) {
612 gr_context_->flush();
613 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 }
625
626 buffer->busy = true;
627 pending_frames.push_back(buffer->buffer.get());
628
629 ++frames;
630 benchmark_wall_time += base::TimeTicks::Now() - wall_time_start;
631 benchmark_cpu_time += base::ThreadTicks::Now() - cpu_time_start;
522 continue; 632 continue;
523
524 Buffer* buffer =
525 std::find_if(std::begin(buffers_), std::end(buffers_),
526 [](const Buffer& buffer) { return !buffer.busy; });
527 if (buffer == std::end(buffers_))
528 continue;
529
530 base::TimeTicks current_time = base::TimeTicks::Now();
531 if ((current_time - benchmark_time) > benchmark_interval) {
532 std::cout << frames << " frames in " << benchmark_interval.InSeconds()
533 << " seconds: "
534 << static_cast<double>(frames) / benchmark_interval.InSeconds()
535 << " fps" << std::endl;
536 benchmark_time = current_time;
537 frames = 0;
538 } 633 }
539 634
540 SkCanvas* canvas = buffer->sk_surface->getCanvas(); 635 if (!frame.callback_pending) {
541 canvas->save(); 636 DCHECK_GT(pending_frames.size(), 0u);
637 wl_surface_set_buffer_scale(surface.get(), scale_);
638 wl_surface_attach(surface.get(), pending_frames.front(), 0, 0);
639 pending_frames.pop_front();
542 640
543 if (event_times.empty()) { 641 frame_callback.reset(wl_surface_frame(surface.get()));
544 canvas->clear(SK_ColorBLACK); 642 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame);
545 } else { 643 frame.callback_pending = true;
546 // Split buffer into one horizontal rectangle for each event received 644 wl_surface_commit(surface.get());
547 // since last frame. Latest event at the top. 645 wl_display_flush(display_.get());
548 int y = 0; 646 continue;
549 // Note: Rounding up to ensure we cover the whole canvas.
550 int h = (height_ + (event_times.size() / 2)) / event_times.size();
551 while (!event_times.empty()) {
552 SkIRect rect = SkIRect::MakeXYWH(0, y, width_, h);
553 SkPaint paint;
554 paint.setColor(SkColorSetRGB((event_times.back() & 0x0000ff) >> 0,
555 (event_times.back() & 0x00ff00) >> 8,
556 (event_times.back() & 0xff0000) >> 16));
557 canvas->drawIRect(rect, paint);
558 event_times.pop_back();
559 y += h;
560 }
561 } 647 }
562 648
563 // Draw rotating rects. 649 dispatch_status = wl_display_dispatch(display_.get());
564 SkScalar half_width = SkScalarHalf(width_); 650 } while (dispatch_status != -1);
565 SkScalar half_height = SkScalarHalf(height_);
566 SkIRect rect =
567 SkIRect::MakeXYWH(-SkScalarHalf(half_width), -SkScalarHalf(half_height),
568 half_width, half_height);
569 SkScalar rotation = SkScalarMulDiv(frame.time, kRotationSpeed, 1000);
570 SkPaint paint;
571 canvas->translate(half_width, half_height);
572 for (size_t i = 0; i < num_rects_; ++i) {
573 const SkColor kColors[] = {SK_ColorBLUE, SK_ColorGREEN,
574 SK_ColorRED, SK_ColorYELLOW,
575 SK_ColorCYAN, SK_ColorMAGENTA};
576 paint.setColor(SkColorSetA(kColors[i % arraysize(kColors)], 0xA0));
577 canvas->rotate(rotation / num_rects_);
578 canvas->drawIRect(rect, paint);
579 }
580 canvas->restore();
581 if (gr_context_) {
582 gr_context_->flush();
583 glFinish();
584 }
585 wl_surface_set_buffer_scale(surface.get(), scale_);
586 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0);
587 buffer->busy = true;
588
589 frame_callback.reset(wl_surface_frame(surface.get()));
590 wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame);
591 frame.callback_pending = true;
592
593 ++frames;
594
595 wl_surface_commit(surface.get());
596 } while (wl_display_dispatch(display_.get()) != -1);
597 651
598 return 0; 652 return 0;
599 } 653 }
600 654
601 bool MotionEvents::CreateBuffer(Buffer* buffer) { 655 bool MotionEvents::CreateBuffer(Buffer* buffer) {
602 #if defined(OZONE_PLATFORM_GBM) 656 #if defined(OZONE_PLATFORM_GBM)
603 if (use_drm_) { 657 if (use_drm_) {
604 buffer->bo.reset(gbm_bo_create(device_.get(), width_, height_, kDrmFormat, 658 buffer->bo.reset(gbm_bo_create(device_.get(), width_, height_, kDrmFormat,
605 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING)); 659 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING));
606 if (!buffer->bo) { 660 if (!buffer->bo) {
607 LOG(ERROR) << "Can't create gbm buffer"; 661 LOG(ERROR) << "Can't create gbm buffer";
608 return false; 662 return false;
609 } 663 }
610 base::ScopedFD fd(gbm_bo_get_plane_fd(buffer->bo.get(), 0)); 664 base::ScopedFD fd(gbm_bo_get_plane_fd(buffer->bo.get(), 0));
611 static const zwp_linux_buffer_params_v1_listener params_listener = { 665 static const zwp_linux_buffer_params_v1_listener params_listener = {
612 LinuxBufferParamsCreated, LinuxBufferParamsFailed}; 666 LinuxBufferParamsCreated, LinuxBufferParamsFailed};
613 667
614 buffer->params.reset( 668 buffer->params.reset(
615 zwp_linux_dmabuf_v1_create_params(globals_.linux_dmabuf.get())); 669 zwp_linux_dmabuf_v1_create_params(globals_.linux_dmabuf.get()));
616 zwp_linux_buffer_params_v1_add_listener(buffer->params.get(), 670 zwp_linux_buffer_params_v1_add_listener(buffer->params.get(),
617 &params_listener, buffer); 671 &params_listener, buffer);
618 zwp_linux_buffer_params_v1_add(buffer->params.get(), fd.get(), 0, 0, 672 uint32_t stride = gbm_bo_get_stride(buffer->bo.get());
619 stride(), 0, 0); 673 zwp_linux_buffer_params_v1_add(buffer->params.get(), fd.get(), 0, 0, stride,
674 0, 0);
620 zwp_linux_buffer_params_v1_create(buffer->params.get(), width_, height_, 675 zwp_linux_buffer_params_v1_create(buffer->params.get(), width_, height_,
621 kDrmFormat, 0); 676 kDrmFormat, 0);
622 677
623 EGLint khr_image_attrs[] = {EGL_DMA_BUF_PLANE0_FD_EXT, 678 EGLint khr_image_attrs[] = {EGL_DMA_BUF_PLANE0_FD_EXT,
624 fd.get(), 679 fd.get(),
625 EGL_WIDTH, 680 EGL_WIDTH,
626 width_, 681 width_,
627 EGL_HEIGHT, 682 EGL_HEIGHT,
628 height_, 683 height_,
629 EGL_LINUX_DRM_FOURCC_EXT, 684 EGL_LINUX_DRM_FOURCC_EXT,
630 kDrmFormat, 685 kDrmFormat,
631 EGL_DMA_BUF_PLANE0_PITCH_EXT, 686 EGL_DMA_BUF_PLANE0_PITCH_EXT,
632 stride(), 687 stride,
633 EGL_DMA_BUF_PLANE0_OFFSET_EXT, 688 EGL_DMA_BUF_PLANE0_OFFSET_EXT,
634 0, 689 0,
635 EGL_NONE}; 690 EGL_NONE};
636 EGLImageKHR image = eglCreateImageKHR( 691 EGLImageKHR image = eglCreateImageKHR(
637 eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, 692 eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
638 nullptr /* no client buffer */, khr_image_attrs); 693 nullptr /* no client buffer */, khr_image_attrs);
639 694
640 buffer->egl_image.reset(new ScopedEglImage(image)); 695 buffer->egl_image.reset(new ScopedEglImage(image));
641 GLuint texture = 0; 696 GLuint texture = 0;
642 glGenTextures(1, &texture); 697 glGenTextures(1, &texture);
(...skipping 13 matching lines...) Expand all
656 desc.fConfig = kGrPixelConfig; 711 desc.fConfig = kGrPixelConfig;
657 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 712 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
658 desc.fTextureHandle = reinterpret_cast<GrBackendObject>(&texture_info); 713 desc.fTextureHandle = reinterpret_cast<GrBackendObject>(&texture_info);
659 714
660 buffer->sk_surface = SkSurface::MakeFromBackendTextureAsRenderTarget( 715 buffer->sk_surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
661 gr_context_.get(), desc, nullptr); 716 gr_context_.get(), desc, nullptr);
662 DCHECK(buffer->sk_surface); 717 DCHECK(buffer->sk_surface);
663 return true; 718 return true;
664 } 719 }
665 #endif 720 #endif
666 buffer->shared_memory.CreateAndMapAnonymous(buffer_size()); 721
722 size_t stride = width_ * kBytesPerPixel;
723 buffer->shared_memory.CreateAndMapAnonymous(stride * height_);
667 buffer->shm_pool.reset( 724 buffer->shm_pool.reset(
668 wl_shm_create_pool(globals_.shm.get(), buffer->shared_memory.handle().fd, 725 wl_shm_create_pool(globals_.shm.get(), buffer->shared_memory.handle().fd,
669 buffer->shared_memory.requested_size())); 726 buffer->shared_memory.requested_size()));
670 727
671 buffer->buffer.reset(static_cast<wl_buffer*>(wl_shm_pool_create_buffer( 728 buffer->buffer.reset(static_cast<wl_buffer*>(wl_shm_pool_create_buffer(
672 buffer->shm_pool.get(), 0, width_, height_, stride(), kShmFormat))); 729 buffer->shm_pool.get(), 0, width_, height_, stride, kShmFormat)));
673 if (!buffer->buffer) { 730 if (!buffer->buffer) {
674 LOG(ERROR) << "Can't create buffer"; 731 LOG(ERROR) << "Can't create buffer";
675 return false; 732 return false;
676 } 733 }
677 734
678 buffer->sk_surface = SkSurface::MakeRasterDirect( 735 buffer->sk_surface = SkSurface::MakeRasterDirect(
679 SkImageInfo::Make(width_, height_, kColorType, kOpaque_SkAlphaType), 736 SkImageInfo::Make(width_, height_, kColorType, kOpaque_SkAlphaType),
680 static_cast<uint8_t*>(buffer->shared_memory.memory()), stride()); 737 static_cast<uint8_t*>(buffer->shared_memory.memory()), stride);
681 DCHECK(buffer->sk_surface); 738 DCHECK(buffer->sk_surface);
682 return true; 739 return true;
683 } 740 }
684 741
685 } // namespace clients 742 } // namespace clients
686 } // namespace wayland 743 } // namespace wayland
687 } // namespace exo 744 } // namespace exo
688 745
689 namespace switches { 746 namespace switches {
690 747
691 // Specifies the client buffer size. 748 // Specifies the client buffer size.
692 const char kSize[] = "size"; 749 const char kSize[] = "size";
693 750
694 // Specifies the client scale factor (ie. number of physical pixels per DIP). 751 // Specifies the client scale factor (ie. number of physical pixels per DIP).
695 const char kScale[] = "scale"; 752 const char kScale[] = "scale";
696 753
697 // Specifies the number of rotating rects to draw. 754 // Specifies the number of rotating rects to draw.
698 const char kNumRects[] = "num-rects"; 755 const char kNumRects[] = "num-rects";
699 756
757 // Specifies the maximum number of pending frames.
758 const char kMaxFramesPending[] = "max-frames-pending";
759
760 // Specifies if client should be fullscreen.
761 const char kFullscreen[] = "fullscreen";
762
700 // Use drm buffer instead of shared memory. 763 // Use drm buffer instead of shared memory.
701 const char kUseDrm[] = "use-drm"; 764 const char kUseDrm[] = "use-drm";
702 765
703 // Specifies if client should be fullscreen.
704 const char kFullscreen[] = "fullscreen";
705
706 } // namespace switches 766 } // namespace switches
707 767
708 int main(int argc, char* argv[]) { 768 int main(int argc, char* argv[]) {
709 base::AtExitManager exit_manager; 769 base::AtExitManager exit_manager;
710 base::CommandLine::Init(argc, argv); 770 base::CommandLine::Init(argc, argv);
711 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 771 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
712 772
713 int width = 256; 773 int width = 256;
714 int height = 256; 774 int height = 256;
715 if (command_line->HasSwitch(switches::kSize)) { 775 if (command_line->HasSwitch(switches::kSize)) {
(...skipping 13 matching lines...) Expand all
729 } 789 }
730 790
731 size_t num_rects = 1; 791 size_t num_rects = 1;
732 if (command_line->HasSwitch(switches::kNumRects) && 792 if (command_line->HasSwitch(switches::kNumRects) &&
733 !base::StringToSizeT( 793 !base::StringToSizeT(
734 command_line->GetSwitchValueASCII(switches::kNumRects), &num_rects)) { 794 command_line->GetSwitchValueASCII(switches::kNumRects), &num_rects)) {
735 LOG(ERROR) << "Invalid value for " << switches::kNumRects; 795 LOG(ERROR) << "Invalid value for " << switches::kNumRects;
736 return 1; 796 return 1;
737 } 797 }
738 798
799 size_t max_frames_pending = 0;
800 if (command_line->HasSwitch(switches::kMaxFramesPending) &&
801 (!base::StringToSizeT(
802 command_line->GetSwitchValueASCII(switches::kMaxFramesPending),
803 &max_frames_pending))) {
804 LOG(ERROR) << "Invalid value for " << switches::kMaxFramesPending;
805 return 1;
806 }
807
739 std::unique_ptr<std::string> use_drm; 808 std::unique_ptr<std::string> use_drm;
740 if (command_line->HasSwitch(switches::kUseDrm)) { 809 if (command_line->HasSwitch(switches::kUseDrm)) {
741 use_drm.reset( 810 use_drm.reset(
742 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm))); 811 new std::string(command_line->GetSwitchValueASCII(switches::kUseDrm)));
743 } 812 }
744 813
745 bool fullscreen = command_line->HasSwitch(switches::kFullscreen); 814 exo::wayland::clients::MotionEvents client(
746 815 width, height, scale, num_rects, max_frames_pending,
747 exo::wayland::clients::MotionEvents client(width, height, scale, num_rects, 816 command_line->HasSwitch(switches::kFullscreen), use_drm.get());
748 use_drm.get(), fullscreen);
749 return client.Run(); 817 return client.Run();
750 } 818 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698