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

Unified Diff: components/exo/wayland/clients/motion_events.cc

Issue 2497173002: exo: Add explicit synchronization support to motion event client.
Patch Set: refactor 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/exo/wayland/BUILD.gn ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/wayland/clients/motion_events.cc
diff --git a/components/exo/wayland/clients/motion_events.cc b/components/exo/wayland/clients/motion_events.cc
index 6d913b4ae4e73f0e37166c904fccd34c7bd4f438..09535c26065aabeee55da3aed3b2d28f3083c9a8 100644
--- a/components/exo/wayland/clients/motion_events.cc
+++ b/components/exo/wayland/clients/motion_events.cc
@@ -8,6 +8,7 @@
#include <fcntl.h>
#include <linux-dmabuf-unstable-v1-client-protocol.h>
+#include <linux-explicit-synchronization-unstable-v1-client-protocol.h>
#include <wayland-client-core.h>
#include <wayland-client-protocol.h>
@@ -68,6 +69,9 @@ DEFAULT_DELETER(wl_seat, wl_seat_destroy)
DEFAULT_DELETER(wl_pointer, wl_pointer_destroy)
DEFAULT_DELETER(wl_touch, wl_touch_destroy)
DEFAULT_DELETER(wl_callback, wl_callback_destroy)
+DEFAULT_DELETER(zcr_linux_explicit_synchronization_v1,
+ zcr_linux_explicit_synchronization_v1_destroy)
+DEFAULT_DELETER(zcr_synchronization_v1, zcr_synchronization_v1_destroy)
DEFAULT_DELETER(zwp_linux_buffer_params_v1, zwp_linux_buffer_params_v1_destroy)
DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy)
@@ -110,6 +114,8 @@ const int kBenchmarkInterval = 5;
struct Globals {
std::unique_ptr<wl_compositor> compositor;
std::unique_ptr<wl_shm> shm;
+ std::unique_ptr<zcr_linux_explicit_synchronization_v1>
+ linux_explicit_synchronization;
std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf;
std::unique_ptr<wl_shell> shell;
std::unique_ptr<wl_seat> seat;
@@ -134,6 +140,11 @@ void RegistryHandler(void* data,
} else if (strcmp(interface, "wl_seat") == 0) {
globals->seat.reset(static_cast<wl_seat*>(
wl_registry_bind(registry, id, &wl_seat_interface, 5)));
+ } else if (strcmp(interface, "zcr_linux_explicit_synchronization_v1") == 0) {
+ globals->linux_explicit_synchronization.reset(
+ static_cast<zcr_linux_explicit_synchronization_v1*>(wl_registry_bind(
+ registry, id, &zcr_linux_explicit_synchronization_v1_interface,
+ 1)));
} else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>(
wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1)));
@@ -158,6 +169,14 @@ struct DeleteEglImageTraits {
}
};
using ScopedEglImage = base::ScopedGeneric<EGLImageKHR, DeleteEglImageTraits>;
+
+struct DeleteEglSyncTraits {
+ static EGLSyncKHR InvalidValue() { return 0; }
+ static void Free(EGLSyncKHR sync) {
+ eglDestroySyncKHR(eglGetCurrentDisplay(), sync);
+ }
+};
+using ScopedEglSync = base::ScopedGeneric<EGLSyncKHR, DeleteEglSyncTraits>;
#endif
struct Buffer {
@@ -166,6 +185,7 @@ struct Buffer {
#if defined(OZONE_PLATFORM_GBM)
std::unique_ptr<gbm_bo> bo;
std::unique_ptr<ScopedEglImage> egl_image;
+ std::unique_ptr<ScopedEglSync> egl_sync;
std::unique_ptr<ScopedTexture> texture;
#endif
std::unique_ptr<zwp_linux_buffer_params_v1> params;
@@ -303,6 +323,7 @@ class MotionEvents {
size_t num_rects,
size_t max_frames_pending,
bool fullscreen,
+ bool use_explicit_synchronization,
const std::string* use_drm)
: width_(width),
height_(height),
@@ -310,6 +331,7 @@ class MotionEvents {
num_rects_(num_rects),
max_frames_pending_(max_frames_pending),
fullscreen_(fullscreen),
+ use_explicit_synchronization_(use_explicit_synchronization),
use_drm_(use_drm) {}
// Initialize and run client main loop.
@@ -324,6 +346,7 @@ class MotionEvents {
const size_t num_rects_;
const size_t max_frames_pending_;
const bool fullscreen_;
+ const bool use_explicit_synchronization_;
const std::string* use_drm_;
Globals globals_;
@@ -376,6 +399,11 @@ int MotionEvents::Run() {
LOG(ERROR) << "Can't find shm interface";
return 1;
}
+ if (use_explicit_synchronization_ &&
+ !globals_.linux_explicit_synchronization) {
+ LOG(ERROR) << "Can't find linux_explicit_synchronization interface";
+ return 1;
+ }
if (use_drm_ && !globals_.linux_dmabuf) {
LOG(ERROR) << "Can't find linux_dmabuf interface";
return 1;
@@ -389,8 +417,8 @@ int MotionEvents::Run() {
return 1;
}
- EGLenum egl_sync_type = 0;
#if defined(OZONE_PLATFORM_GBM)
+ EGLenum egl_sync_type = 0;
if (use_drm_) {
// Number of files to look for when discovering DRM devices.
const uint32_t kDrmMaxMinor = 15;
@@ -426,6 +454,14 @@ int MotionEvents::Run() {
LOG(ERROR) << "Can't create gbm device";
return 1;
}
+
+ if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") ||
+ gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) {
+ egl_sync_type = EGL_SYNC_FENCE_KHR;
+ }
+ if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) {
+ egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID;
+ }
}
sk_sp<const GrGLInterface> native_interface(GrGLCreateNativeInterface());
@@ -434,14 +470,6 @@ int MotionEvents::Run() {
kOpenGL_GrBackend,
reinterpret_cast<GrBackendContext>(native_interface.get())));
DCHECK(gr_context_);
-
- if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") ||
- gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) {
- egl_sync_type = EGL_SYNC_FENCE_KHR;
- }
- if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) {
- egl_sync_type = EGL_SYNC_NATIVE_FENCE_ANDROID;
- }
#endif
wl_buffer_listener buffer_listener = {BufferRelease};
@@ -476,6 +504,17 @@ int MotionEvents::Run() {
wl_region_add(opaque_region.get(), 0, 0, width_, height_);
wl_surface_set_opaque_region(surface.get(), opaque_region.get());
+ std::unique_ptr<zcr_synchronization_v1> synchronization;
+ if (use_explicit_synchronization_) {
+ synchronization.reset(static_cast<zcr_synchronization_v1*>(
+ zcr_linux_explicit_synchronization_v1_get_synchronization(
+ globals_.linux_explicit_synchronization.get(), surface.get())));
+ if (!synchronization) {
+ LOG(ERROR) << "Can't get synchronization";
+ return 1;
+ }
+ }
+
std::unique_ptr<wl_shell_surface> shell_surface(
static_cast<wl_shell_surface*>(
wl_shell_get_shell_surface(globals_.shell.get(), surface.get())));
@@ -523,7 +562,7 @@ int MotionEvents::Run() {
Frame frame;
std::unique_ptr<wl_callback> frame_callback;
wl_callback_listener frame_listener = {FrameCallback};
- std::deque<wl_buffer*> pending_frames;
+ std::deque<Buffer*> pending_frames;
uint32_t frames = 0;
base::TimeTicks benchmark_time = base::TimeTicks::Now();
@@ -610,21 +649,20 @@ int MotionEvents::Run() {
canvas->restore();
if (gr_context_) {
gr_context_->flush();
- glFlush();
+#if defined(OZONE_PLATFORM_GBM)
if (egl_sync_type) {
- EGLSyncKHR sync =
- eglCreateSyncKHR(eglGetCurrentDisplay(), egl_sync_type, nullptr);
- DCHECK(sync != EGL_NO_SYNC_KHR);
- eglClientWaitSyncKHR(eglGetCurrentDisplay(), sync,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
- EGL_FOREVER_KHR);
- eglDestroySyncKHR(eglGetCurrentDisplay(), sync);
+ buffer->egl_sync.reset(new ScopedEglSync(eglCreateSyncKHR(
+ eglGetCurrentDisplay(), egl_sync_type, nullptr)));
+ DCHECK(buffer->egl_sync->is_valid());
}
+#endif
+
+ glFlush();
}
buffer->busy = true;
- pending_frames.push_back(buffer->buffer.get());
+ pending_frames.push_back(buffer);
++frames;
benchmark_wall_time += base::TimeTicks::Now() - wall_time_start;
@@ -634,10 +672,31 @@ int MotionEvents::Run() {
if (!frame.callback_pending) {
DCHECK_GT(pending_frames.size(), 0u);
- wl_surface_set_buffer_scale(surface.get(), scale_);
- wl_surface_attach(surface.get(), pending_frames.front(), 0, 0);
+ Buffer* buffer = pending_frames.front();
pending_frames.pop_front();
+ wl_surface_set_buffer_scale(surface.get(), scale_);
+ wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0);
+
+#if defined(OZONE_PLATFORM_GBM)
+ if (buffer->egl_sync->is_valid()) {
+ if (use_explicit_synchronization_) {
+ DCHECK_EQ(egl_sync_type,
+ static_cast<EGLenum>(EGL_SYNC_NATIVE_FENCE_ANDROID));
+ base::ScopedFD fence_fd(eglDupNativeFenceFDANDROID(
+ eglGetCurrentDisplay(), buffer->egl_sync->get()));
+ DCHECK(fence_fd.is_valid());
+ DCHECK(synchronization);
+ zcr_synchronization_v1_set_acquire_fence(synchronization.get(),
+ fence_fd.get());
+ } else {
+ eglClientWaitSyncKHR(eglGetCurrentDisplay(), buffer->egl_sync->get(),
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
+ EGL_FOREVER_KHR);
+ }
+ }
+#endif
+
frame_callback.reset(wl_surface_frame(surface.get()));
wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame);
frame.callback_pending = true;
@@ -760,6 +819,9 @@ const char kMaxFramesPending[] = "max-frames-pending";
// Specifies if client should be fullscreen.
const char kFullscreen[] = "fullscreen";
+// Specifies if client should be using explicit synchronization.
+const char kUseExplicitSynchronization[] = "use-explicit-synchronization";
+
// Use drm buffer instead of shared memory.
const char kUseDrm[] = "use-drm";
@@ -813,6 +875,8 @@ int main(int argc, char* argv[]) {
exo::wayland::clients::MotionEvents client(
width, height, scale, num_rects, max_frames_pending,
- command_line->HasSwitch(switches::kFullscreen), use_drm.get());
+ command_line->HasSwitch(switches::kFullscreen),
+ command_line->HasSwitch(switches::kUseExplicitSynchronization),
+ use_drm.get());
return client.Run();
}
« no previous file with comments | « components/exo/wayland/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698