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

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

Issue 2477043002: exo: Add drm support to motion_events. (Closed)
Patch Set: Rebase on master. 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
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>
10 #include <linux-dmabuf-unstable-v1-client-protocol.h>
9 #include <wayland-client-core.h> 11 #include <wayland-client-core.h>
10 #include <wayland-client-protocol.h> 12 #include <wayland-client-protocol.h>
11 13
14 #include "base/at_exit.h"
15 #include "base/command_line.h"
12 #include "base/logging.h" 16 #include "base/logging.h"
13 #include "base/memory/shared_memory.h" 17 #include "base/memory/shared_memory.h"
18 #include "ui/gl/gl_bindings.h"
19 #include "ui/gl/gl_context.h"
20 #include "ui/gl/gl_enums.h"
21 #include "ui/gl/gl_surface.h"
22 #include "ui/gl/gl_surface_egl.h"
23 #include "ui/gl/init/gl_factory.h"
24 #include "ui/gl/scoped_make_current.h"
25
26 #if defined(OZONE_PLATFORM_GBM)
27 #include <drm_fourcc.h>
28 #include <gbm.h>
29 #endif
14 30
15 // Convenient macro that is used to define default deleters for wayland object 31 // Convenient macro that is used to define default deleters for wayland object
16 // types allowing them to be used with std::unique_ptr. 32 // types allowing them to be used with std::unique_ptr.
17 #define DEFAULT_DELETER(TypeName, DeleteFunction) \ 33 #define DEFAULT_DELETER(TypeName, DeleteFunction) \
18 namespace std { \ 34 namespace std { \
19 template <> \ 35 template <> \
20 struct default_delete<TypeName> { \ 36 struct default_delete<TypeName> { \
21 void operator()(TypeName* ptr) { DeleteFunction(ptr); } \ 37 void operator()(TypeName* ptr) { DeleteFunction(ptr); } \
22 }; \ 38 }; \
23 } 39 }
24 40
41 #if defined(OZONE_PLATFORM_GBM)
42 DEFAULT_DELETER(gbm_device, gbm_device_destroy)
43 DEFAULT_DELETER(gbm_bo, gbm_bo_destroy)
44 #endif
45
25 DEFAULT_DELETER(wl_display, wl_display_disconnect) 46 DEFAULT_DELETER(wl_display, wl_display_disconnect)
26 DEFAULT_DELETER(wl_compositor, wl_compositor_destroy) 47 DEFAULT_DELETER(wl_compositor, wl_compositor_destroy)
27 DEFAULT_DELETER(wl_shm, wl_shm_destroy) 48 DEFAULT_DELETER(wl_shm, wl_shm_destroy)
28 DEFAULT_DELETER(wl_shm_pool, wl_shm_pool_destroy) 49 DEFAULT_DELETER(wl_shm_pool, wl_shm_pool_destroy)
29 DEFAULT_DELETER(wl_buffer, wl_buffer_destroy) 50 DEFAULT_DELETER(wl_buffer, wl_buffer_destroy)
30 DEFAULT_DELETER(wl_surface, wl_surface_destroy) 51 DEFAULT_DELETER(wl_surface, wl_surface_destroy)
31 DEFAULT_DELETER(wl_region, wl_region_destroy) 52 DEFAULT_DELETER(wl_region, wl_region_destroy)
32 DEFAULT_DELETER(wl_shell, wl_shell_destroy) 53 DEFAULT_DELETER(wl_shell, wl_shell_destroy)
33 DEFAULT_DELETER(wl_shell_surface, wl_shell_surface_destroy) 54 DEFAULT_DELETER(wl_shell_surface, wl_shell_surface_destroy)
34 DEFAULT_DELETER(wl_seat, wl_seat_destroy) 55 DEFAULT_DELETER(wl_seat, wl_seat_destroy)
35 DEFAULT_DELETER(wl_pointer, wl_pointer_destroy) 56 DEFAULT_DELETER(wl_pointer, wl_pointer_destroy)
36 DEFAULT_DELETER(wl_touch, wl_touch_destroy) 57 DEFAULT_DELETER(wl_touch, wl_touch_destroy)
37 DEFAULT_DELETER(wl_callback, wl_callback_destroy) 58 DEFAULT_DELETER(wl_callback, wl_callback_destroy)
59 DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy)
38 60
39 namespace exo { 61 namespace exo {
40 namespace wayland { 62 namespace wayland {
41 namespace clients { 63 namespace clients {
42 namespace { 64 namespace {
43 65
44 // Window size. 66 // Window size.
45 const size_t kWidth = 256; 67 const size_t kWidth = 256;
46 const size_t kHeight = 256; 68 const size_t kHeight = 256;
47 69
48 // Buffer format. 70 // Buffer format.
49 const int32_t kFormat = WL_SHM_FORMAT_ABGR8888; 71 const int32_t kShmFormat = WL_SHM_FORMAT_ABGR8888;
72 #if defined(OZONE_PLATFORM_GBM)
73 const int32_t kDrmFormat = DRM_FORMAT_ABGR8888;
74 #endif
50 const size_t kBytesPerPixel = 4; 75 const size_t kBytesPerPixel = 4;
51 76
52 // Number of buffers. 77 // Number of buffers.
53 const size_t kBuffers = 2; 78 const size_t kBuffers = 2;
54 79
55 // Helper constants. 80 // Helper constants.
56 const size_t kStride = kWidth * kBytesPerPixel; 81 const size_t kStride = kWidth * kBytesPerPixel;
57 const size_t kBufferSize = kHeight * kStride; 82 const size_t kBufferSize = kHeight * kStride;
58 const size_t kMemorySize = kBufferSize * kBuffers; 83 const size_t kMemorySize = kBufferSize * kBuffers;
59 84
60 struct Globals { 85 struct Globals {
61 std::unique_ptr<wl_compositor> compositor; 86 std::unique_ptr<wl_compositor> compositor;
62 std::unique_ptr<wl_shm> shm; 87 std::unique_ptr<wl_shm> shm;
88 std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf;
63 std::unique_ptr<wl_shell> shell; 89 std::unique_ptr<wl_shell> shell;
64 std::unique_ptr<wl_seat> seat; 90 std::unique_ptr<wl_seat> seat;
65 }; 91 };
66 92
67 void RegistryHandler(void* data, 93 void RegistryHandler(void* data,
68 wl_registry* registry, 94 wl_registry* registry,
69 uint32_t id, 95 uint32_t id,
70 const char* interface, 96 const char* interface,
71 uint32_t version) { 97 uint32_t version) {
72 Globals* globals = static_cast<Globals*>(data); 98 Globals* globals = static_cast<Globals*>(data);
73 99
74 if (strcmp(interface, "wl_compositor") == 0) { 100 if (strcmp(interface, "wl_compositor") == 0) {
75 globals->compositor.reset(static_cast<wl_compositor*>( 101 globals->compositor.reset(static_cast<wl_compositor*>(
76 wl_registry_bind(registry, id, &wl_compositor_interface, 3))); 102 wl_registry_bind(registry, id, &wl_compositor_interface, 3)));
77 } else if (strcmp(interface, "wl_shm") == 0) { 103 } else if (strcmp(interface, "wl_shm") == 0) {
78 globals->shm.reset(static_cast<wl_shm*>( 104 globals->shm.reset(static_cast<wl_shm*>(
79 wl_registry_bind(registry, id, &wl_shm_interface, 1))); 105 wl_registry_bind(registry, id, &wl_shm_interface, 1)));
80 } else if (strcmp(interface, "wl_shell") == 0) { 106 } else if (strcmp(interface, "wl_shell") == 0) {
81 globals->shell.reset(static_cast<wl_shell*>( 107 globals->shell.reset(static_cast<wl_shell*>(
82 wl_registry_bind(registry, id, &wl_shell_interface, 1))); 108 wl_registry_bind(registry, id, &wl_shell_interface, 1)));
83 } else if (strcmp(interface, "wl_seat") == 0) { 109 } else if (strcmp(interface, "wl_seat") == 0) {
84 globals->seat.reset(static_cast<wl_seat*>( 110 globals->seat.reset(static_cast<wl_seat*>(
85 wl_registry_bind(registry, id, &wl_seat_interface, 5))); 111 wl_registry_bind(registry, id, &wl_seat_interface, 5)));
112 } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
113 globals->linux_dmabuf.reset(static_cast<zwp_linux_dmabuf_v1*>(
114 wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1)));
86 } 115 }
87 } 116 }
88 117
89 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) { 118 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) {
90 LOG(WARNING) << "Got a registry losing event for " << id; 119 LOG(WARNING) << "Got a registry losing event for " << id;
91 } 120 }
92 121
93 struct BufferState { 122 struct BufferState {
94 std::unique_ptr<wl_buffer> buffer; 123 std::unique_ptr<wl_buffer> buffer;
95 uint8_t* data = nullptr; 124 uint8_t* data = nullptr;
96 bool busy = false; 125 bool busy = false;
126 // dmabuf
127 #if defined(OZONE_PLATFORM_GBM)
128 std::unique_ptr<gbm_bo> bo = nullptr;
reveman 2016/11/04 22:34:14 remove " = nullptr"
Daniele Castagna 2016/11/05 21:05:12 Done.
129 #endif
130 EGLImageKHR egl_image = 0;
reveman 2016/11/04 22:34:15 can we have a unique_ptr for this too?
Daniele Castagna 2016/11/05 21:05:11 Added a ScopedEglImage that is slightly nicer than
131 unsigned gl_texture = 0;
reveman 2016/11/04 22:34:14 s/gl_texture/texture/ can we use GLuint instead o
Daniele Castagna 2016/11/05 21:05:11 Done.
132 unsigned fb = 0;
reveman 2016/11/04 22:34:14 s/fb/framebuffer/ and GLuint + ScopedFramebuffer
Daniele Castagna 2016/11/05 21:05:12 This is gone now that we're using skia.
97 }; 133 };
98 134
99 void BufferRelease(void* data, wl_buffer* buffer) { 135 void BufferRelease(void* data, wl_buffer* buffer) {
100 BufferState* state = static_cast<BufferState*>(data); 136 BufferState* state = static_cast<BufferState*>(data);
101 137
102 state->busy = false; 138 state->busy = false;
103 } 139 }
104 140
105 struct MainLoopContext { 141 struct MainLoopContext {
106 uint32_t color = 0xffffffff; 142 uint32_t color = 0xffffffff;
107 bool needs_redraw = true; 143 bool needs_redraw = true;
108 bool shutdown = false; 144 bool shutdown = false;
109 bool throttled = false; 145 bool throttled = false;
146 base::SharedMemory shared_memory;
147 std::unique_ptr<wl_shm_pool> shm_pool;
148
149 #if defined(OZONE_PLATFORM_GBM)
150 std::unique_ptr<gbm_device> device;
151 #endif
110 }; 152 };
111 153
112 void PointerEnter(void* data, 154 void PointerEnter(void* data,
113 wl_pointer* pointer, 155 wl_pointer* pointer,
114 uint32_t serial, 156 uint32_t serial,
115 wl_surface* surface, 157 wl_surface* surface,
116 wl_fixed_t x, 158 wl_fixed_t x,
117 wl_fixed_t y) {} 159 wl_fixed_t y) {}
118 160
119 void PointerLeave(void* data, 161 void PointerLeave(void* data,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 void TouchFrame(void* data, wl_touch* touch) {} 238 void TouchFrame(void* data, wl_touch* touch) {}
197 239
198 void TouchCancel(void* data, wl_touch* touch) {} 240 void TouchCancel(void* data, wl_touch* touch) {}
199 241
200 void FrameCallback(void* data, wl_callback* callback, uint32_t time) { 242 void FrameCallback(void* data, wl_callback* callback, uint32_t time) {
201 MainLoopContext* context = static_cast<MainLoopContext*>(data); 243 MainLoopContext* context = static_cast<MainLoopContext*>(data);
202 244
203 context->throttled = false; 245 context->throttled = false;
204 } 246 }
205 247
248 #if defined(OZONE_PLATFORM_GBM)
249 void LinuxBufferParamsCreated(void* data,
250 zwp_linux_buffer_params_v1* params,
251 wl_buffer* buffer) {
252 std::unique_ptr<wl_buffer>* out_buffer =
253 static_cast<std::unique_ptr<wl_buffer>*>(data);
reveman 2016/11/04 22:34:14 nit: maybe cleaner to just pass BufferState* as da
Daniele Castagna 2016/11/05 21:05:12 Done.
254 out_buffer->reset(buffer);
255 }
256
257 void LinuxBufferParamsFailed(void* data, zwp_linux_buffer_params_v1* params) {
258 LOG(ERROR) << "Linux buffer params failed callback";
reveman 2016/11/04 22:34:14 nit: s/failed callback/failed/
Daniele Castagna 2016/11/05 21:05:11 Done.
259 }
260 #endif
261
262 bool CreateBuffer(MainLoopContext* context,
263 Globals* globals,
264 wl_display* display,
265 size_t index,
266 BufferState* buffer_state) {
267 if (base::CommandLine::ForCurrentProcess()->HasSwitch("linux_dmabuf_v1")) {
reveman 2016/11/04 22:34:14 s/linux_dmabuf_v1/use-drm/ and move the string to
Daniele Castagna 2016/11/05 21:05:12 Done.
268 #if defined(OZONE_PLATFORM_GBM)
reveman 2016/11/04 22:34:14 move the switch check into this ifdef and just sil
Daniele Castagna 2016/11/05 21:05:11 Done.
269 buffer_state->bo.reset(
270 gbm_bo_create(context->device.get(), kWidth, kHeight, kDrmFormat,
271 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING));
272 if (!buffer_state->bo) {
273 LOG(ERROR) << "Can't create gbm buffer.";
274 return false;
275 }
276 base::ScopedFD fd(gbm_bo_get_plane_fd(buffer_state->bo.get(), 0));
277 zwp_linux_buffer_params_v1_listener params_listener = {
278 LinuxBufferParamsCreated, LinuxBufferParamsFailed};
279
280 zwp_linux_buffer_params_v1* params =
reveman 2016/11/04 22:34:14 are we leaking this object?
Daniele Castagna 2016/11/05 21:05:11 Fixed.
281 zwp_linux_dmabuf_v1_create_params(globals->linux_dmabuf.get());
282 zwp_linux_buffer_params_v1_add_listener(params, &params_listener,
283 &buffer_state->buffer);
284 zwp_linux_buffer_params_v1_add(params, fd.get(), 0, 0, kStride, 0, 0);
285 zwp_linux_buffer_params_v1_create(params, kWidth, kHeight, kDrmFormat, 0);
286 wl_display_dispatch(display);
287 wl_display_roundtrip(display);
reveman 2016/11/04 22:34:14 please move this round trip so we only do it once
Daniele Castagna 2016/11/05 21:05:12 Done.
288
289 if (!buffer_state->buffer) {
290 LOG(ERROR) << "Can't create linux dmabuf";
291 return false;
292 }
293
294 const EGLint khr_image_attrs[] = {EGL_DMA_BUF_PLANE0_FD_EXT,
reveman 2016/11/04 22:34:14 nit: not sure about 'const' here
Daniele Castagna 2016/11/05 21:05:12 Removed.
295 fd.get(),
296 EGL_WIDTH,
297 kWidth,
298 EGL_HEIGHT,
299 kHeight,
300 EGL_LINUX_DRM_FOURCC_EXT,
301 kDrmFormat,
302 EGL_DMA_BUF_PLANE0_PITCH_EXT,
303 kStride,
304 EGL_DMA_BUF_PLANE0_OFFSET_EXT,
305 0,
306 EGL_NONE};
307
308 buffer_state->egl_image = eglCreateImageKHR(
309 eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
310 NULL /* no client buffer */, khr_image_attrs);
reveman 2016/11/04 22:34:15 s/NULL/nullptr/
311 glGenTextures(1, &buffer_state->gl_texture);
312 glBindTexture(GL_TEXTURE_2D, buffer_state->gl_texture);
313
314 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
315 (GLeglImageOES)buffer_state->egl_image);
reveman 2016/11/04 22:34:14 static_cast
Daniele Castagna 2016/11/05 21:05:12 Done.
316 glBindTexture(GL_TEXTURE_2D, 0);
317 glGenFramebuffersEXT(1, &buffer_state->fb);
318 glBindFramebufferEXT(GL_FRAMEBUFFER, buffer_state->fb);
319 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
320 GL_TEXTURE_2D, buffer_state->gl_texture, 0);
321 CHECK(GL_FRAMEBUFFER_COMPLETE ==
322 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
323 #else
324 LOG(ERROR) << "Ozone GBM is necessary to use --linux_dmabuf_v1 flag";
325 return false;
326 #endif
327 } else {
328 buffer_state->buffer.reset(static_cast<wl_buffer*>(
329 wl_shm_pool_create_buffer(context->shm_pool.get(), index * kBufferSize,
330 kWidth, kHeight, kStride, kShmFormat)));
331 if (!buffer_state->buffer) {
332 LOG(ERROR) << "Can't create buffer";
333 return false;
334 }
335 buffer_state->data =
336 static_cast<uint8_t*>(context->shared_memory.memory()) +
337 kBufferSize * index;
338 }
339 return true;
340 }
341
206 } // namespace 342 } // namespace
207 343
208 int MotionEventsMain() { 344 int MotionEventsMain() {
345 bool use_dmabuf =
reveman 2016/11/04 22:34:14 use_drm and maybe a good idea to add this to the m
Daniele Castagna 2016/11/05 21:05:11 Done.
346 base::CommandLine::ForCurrentProcess()->HasSwitch("linux_dmabuf_v1");
209 std::unique_ptr<wl_display> display(wl_display_connect(nullptr)); 347 std::unique_ptr<wl_display> display(wl_display_connect(nullptr));
210 if (!display) { 348 if (!display) {
211 LOG(ERROR) << "wl_display_connect failed"; 349 LOG(ERROR) << "wl_display_connect failed";
212 return 1; 350 return 1;
213 } 351 }
214 352
353 bool gl_initialized = gl::init::InitializeGLOneOff();
354 DCHECK(gl_initialized);
355 scoped_refptr<gl::GLSurface> gl_surface =
356 gl::init::CreateOffscreenGLSurface(gfx::Size());
357 scoped_refptr<gl::GLContext> gl_context =
358 gl::init::CreateGLContext(nullptr, // share_group
359 gl_surface.get(), gl::PreferIntegratedGpu);
360 ui::ScopedMakeCurrent smc(gl_context.get(), gl_surface.get());
361
215 wl_registry_listener registry_listener = {RegistryHandler, RegistryRemover}; 362 wl_registry_listener registry_listener = {RegistryHandler, RegistryRemover};
216 363
217 Globals globals; 364 Globals globals;
218 wl_registry* registry = wl_display_get_registry(display.get()); 365 wl_registry* registry = wl_display_get_registry(display.get());
219 wl_registry_add_listener(registry, &registry_listener, &globals); 366 wl_registry_add_listener(registry, &registry_listener, &globals);
220 367
221 wl_display_dispatch(display.get()); 368 wl_display_dispatch(display.get());
222 wl_display_roundtrip(display.get()); 369 wl_display_roundtrip(display.get());
223 370
224 if (!globals.compositor) { 371 if (!globals.compositor) {
225 LOG(ERROR) << "Can't find compositor interface"; 372 LOG(ERROR) << "Can't find compositor interface";
226 return 1; 373 return 1;
227 } 374 }
228 if (!globals.shm) { 375 if (!globals.shm) {
229 LOG(ERROR) << "Can't find shm interface"; 376 LOG(ERROR) << "Can't find shm interface";
230 return 1; 377 return 1;
231 } 378 }
379
380 if (use_dmabuf && !globals.linux_dmabuf) {
381 LOG(ERROR) << "Can't find linux_dmabuf interface";
382 return 1;
383 }
384
232 if (!globals.shell) { 385 if (!globals.shell) {
233 LOG(ERROR) << "Can't find shell interface"; 386 LOG(ERROR) << "Can't find shell interface";
234 return 1; 387 return 1;
235 } 388 }
236 if (!globals.seat) { 389 if (!globals.seat) {
237 LOG(ERROR) << "Can't find seat interface"; 390 LOG(ERROR) << "Can't find seat interface";
238 return 1; 391 return 1;
239 } 392 }
393 MainLoopContext context;
394 base::ScopedFD fd(open("/dev/dri/renderD128", O_RDWR));
reveman 2016/11/04 22:34:14 lets move "/dev/dri/renderD128" to a constant at t
Daniele Castagna 2016/11/05 21:05:12 Done.
395 if (fd.get() < 0) {
reveman 2016/11/04 22:34:14 we probably want this in the GBM ifdef below or it
Daniele Castagna 2016/11/05 21:05:12 Done.
396 LOG(ERROR) << "Can't open drm device '/dev/dri/renderD128'";
397 return 1;
398 }
399 #if defined(OZONE_PLATFORM_GBM)
400 context.device.reset(gbm_create_device(fd.get()));
401 if (!context.device) {
402 LOG(ERROR) << "Can't create gbm device.";
403 return 1;
404 }
405 #endif
240 406
241 wl_buffer_listener buffer_listener = {BufferRelease}; 407 wl_buffer_listener buffer_listener = {BufferRelease};
242 408
243 BufferState buffers[kBuffers]; 409 BufferState buffers[kBuffers];
244 base::SharedMemory shared_memory; 410 context.shared_memory.CreateAndMapAnonymous(kMemorySize);
245 shared_memory.CreateAndMapAnonymous(kMemorySize); 411 context.shm_pool.reset(
246 std::unique_ptr<wl_shm_pool> shm_pool( 412 wl_shm_create_pool(globals.shm.get(), context.shared_memory.handle().fd,
247 wl_shm_create_pool(globals.shm.get(), shared_memory.handle().fd, 413 context.shared_memory.requested_size()));
248 shared_memory.requested_size()));
249 for (size_t i = 0; i < kBuffers; ++i) { 414 for (size_t i = 0; i < kBuffers; ++i) {
250 buffers[i].buffer.reset(static_cast<wl_buffer*>(wl_shm_pool_create_buffer( 415 if (!CreateBuffer(&context, &globals, display.get(), i, &buffers[i])) {
251 shm_pool.get(), i * kBufferSize, kWidth, kHeight, kStride, kFormat)));
252 if (!buffers[i].buffer) {
253 LOG(ERROR) << "Can't create buffer";
254 return 1; 416 return 1;
255 } 417 }
256 buffers[i].data =
257 static_cast<uint8_t*>(shared_memory.memory()) + kBufferSize * i;
258 wl_buffer_add_listener(buffers[i].buffer.get(), &buffer_listener, 418 wl_buffer_add_listener(buffers[i].buffer.get(), &buffer_listener,
259 &buffers[i]); 419 &buffers[i]);
260 } 420 }
261 421
262 std::unique_ptr<wl_surface> surface(static_cast<wl_surface*>( 422 std::unique_ptr<wl_surface> surface(static_cast<wl_surface*>(
263 wl_compositor_create_surface(globals.compositor.get()))); 423 wl_compositor_create_surface(globals.compositor.get())));
264 if (!surface) { 424 if (!surface) {
265 LOG(ERROR) << "Can't create surface"; 425 LOG(ERROR) << "Can't create surface";
266 return 1; 426 return 1;
267 } 427 }
(...skipping 12 matching lines...) Expand all
280 static_cast<wl_shell_surface*>( 440 static_cast<wl_shell_surface*>(
281 wl_shell_get_shell_surface(globals.shell.get(), surface.get()))); 441 wl_shell_get_shell_surface(globals.shell.get(), surface.get())));
282 if (!shell_surface) { 442 if (!shell_surface) {
283 LOG(ERROR) << "Can't get shell surface"; 443 LOG(ERROR) << "Can't get shell surface";
284 return 1; 444 return 1;
285 } 445 }
286 446
287 wl_shell_surface_set_title(shell_surface.get(), "Test Client"); 447 wl_shell_surface_set_title(shell_surface.get(), "Test Client");
288 wl_shell_surface_set_toplevel(shell_surface.get()); 448 wl_shell_surface_set_toplevel(shell_surface.get());
289 449
290 MainLoopContext context;
291
292 std::unique_ptr<wl_pointer> pointer( 450 std::unique_ptr<wl_pointer> pointer(
293 static_cast<wl_pointer*>(wl_seat_get_pointer(globals.seat.get()))); 451 static_cast<wl_pointer*>(wl_seat_get_pointer(globals.seat.get())));
294 if (!pointer) { 452 if (!pointer) {
295 LOG(ERROR) << "Can't get pointer"; 453 LOG(ERROR) << "Can't get pointer";
296 return 1; 454 return 1;
297 } 455 }
298 456
299 wl_pointer_listener pointer_listener = { 457 wl_pointer_listener pointer_listener = {
300 PointerEnter, PointerLeave, PointerMotion, 458 PointerEnter, PointerLeave, PointerMotion,
301 PointerButton, PointerAxis, PointerFrame, 459 PointerButton, PointerAxis, PointerFrame,
(...skipping 25 matching lines...) Expand all
327 continue; 485 continue;
328 486
329 BufferState* buffer = 487 BufferState* buffer =
330 std::find_if(std::begin(buffers), std::end(buffers), 488 std::find_if(std::begin(buffers), std::end(buffers),
331 [](const BufferState& buffer) { return !buffer.busy; }); 489 [](const BufferState& buffer) { return !buffer.busy; });
332 if (buffer == std::end(buffers)) 490 if (buffer == std::end(buffers))
333 continue; 491 continue;
334 492
335 context.needs_redraw = false; 493 context.needs_redraw = false;
336 494
337 static_assert(sizeof(uint32_t) == kBytesPerPixel, 495 if (use_dmabuf) {
338 "uint32_t must be same size as kBytesPerPixel"); 496 glBindFramebufferEXT(GL_FRAMEBUFFER, buffer->fb);
339 for (size_t y = 0; y < kHeight; y++) { 497 glViewport(0, 0, kWidth, kHeight);
340 uint32_t* pixel = reinterpret_cast<uint32_t*>(buffer->data + y * kStride); 498 const float toUnitRatio = 1.f / 255.f;
341 for (size_t x = 0; x < kWidth; x++) 499 glClearColor(toUnitRatio * (context.color & 0xFF),
342 *pixel++ = context.color; 500 toUnitRatio * ((context.color & 0xFF00) >> 8),
501 toUnitRatio * ((context.color & 0xFF0000) >> 16), 1.0f);
502 glClear(GL_COLOR_BUFFER_BIT);
503 glFinish();
504 } else {
505 static_assert(sizeof(uint32_t) == kBytesPerPixel,
506 "uint32_t must be same size as kBytesPerPixel");
507 for (size_t y = 0; y < kHeight; y++) {
508 uint32_t* pixel =
509 reinterpret_cast<uint32_t*>(buffer->data + y * kStride);
510 for (size_t x = 0; x < kWidth; x++)
511 *pixel++ = context.color;
512 }
343 } 513 }
344 514
345 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0); 515 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0);
346 buffer->busy = true; 516 buffer->busy = true;
347 517
348 frame_callback.reset(wl_surface_frame(surface.get())); 518 frame_callback.reset(wl_surface_frame(surface.get()));
349 wl_callback_add_listener(frame_callback.get(), &frame_listener, &context); 519 wl_callback_add_listener(frame_callback.get(), &frame_listener, &context);
350 context.throttled = true; 520 context.throttled = true;
351 521
352 wl_surface_commit(surface.get()); 522 wl_surface_commit(surface.get());
353 wl_display_flush(display.get()); 523 wl_display_flush(display.get());
354 } while (wl_display_dispatch(display.get()) != -1); 524 } while (wl_display_dispatch(display.get()) != -1);
355 525
526 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
527 for (uint32_t i = 0; i < kBuffers; ++i) {
528 BufferState& buffer = buffers[i];
529 glDeleteFramebuffersEXT(1, &buffer.fb);
530 glDeleteTextures(1, &buffer.gl_texture);
531 eglDestroyImageKHR(eglGetCurrentDisplay(), buffer.egl_image);
532 }
533
356 return 0; 534 return 0;
357 } 535 }
358 536
359 } // namespace clients 537 } // namespace clients
360 } // namespace wayland 538 } // namespace wayland
361 } // namespace exo 539 } // namespace exo
362 540
363 int main() { 541 int main(int argc, char* argv[]) {
542 base::AtExitManager exit_manager;
543 base::CommandLine::Init(argc, argv);
364 return exo::wayland::clients::MotionEventsMain(); 544 return exo::wayland::clients::MotionEventsMain();
365 } 545 }
OLDNEW
« components/exo/wayland/BUILD.gn ('K') | « components/exo/wayland/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698