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

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

Issue 2478403002: exo: Add continuous drawing using skia to motion event client. (Closed)
Patch Set: 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 | « components/exo/wayland/BUILD.gn ('k') | 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 <wayland-client-core.h> 9 #include <wayland-client-core.h>
10 #include <wayland-client-protocol.h> 10 #include <wayland-client-protocol.h>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkRefCnt.h"
16 #include "third_party/skia/include/core/SkSurface.h"
14 17
15 // Convenient macro that is used to define default deleters for wayland object 18 // Convenient macro that is used to define default deleters for wayland object
16 // types allowing them to be used with std::unique_ptr. 19 // types allowing them to be used with std::unique_ptr.
17 #define DEFAULT_DELETER(TypeName, DeleteFunction) \ 20 #define DEFAULT_DELETER(TypeName, DeleteFunction) \
18 namespace std { \ 21 namespace std { \
19 template <> \ 22 template <> \
20 struct default_delete<TypeName> { \ 23 struct default_delete<TypeName> { \
21 void operator()(TypeName* ptr) { DeleteFunction(ptr); } \ 24 void operator()(TypeName* ptr) { DeleteFunction(ptr); } \
22 }; \ 25 }; \
23 } 26 }
(...skipping 15 matching lines...) Expand all
39 namespace exo { 42 namespace exo {
40 namespace wayland { 43 namespace wayland {
41 namespace clients { 44 namespace clients {
42 namespace { 45 namespace {
43 46
44 // Window size. 47 // Window size.
45 const size_t kWidth = 256; 48 const size_t kWidth = 256;
46 const size_t kHeight = 256; 49 const size_t kHeight = 256;
47 50
48 // Buffer format. 51 // Buffer format.
49 const int32_t kFormat = WL_SHM_FORMAT_ABGR8888; 52 const int32_t kFormat = WL_SHM_FORMAT_ARGB8888;
53 const SkColorType kColorType = kBGRA_8888_SkColorType;
50 const size_t kBytesPerPixel = 4; 54 const size_t kBytesPerPixel = 4;
51 55
52 // Number of buffers. 56 // Number of buffers.
53 const size_t kBuffers = 2; 57 const size_t kBuffers = 2;
54 58
59 // Rotation speed (degrees/second).
60 const double kRotationSpeed = 360.0;
61
55 // Helper constants. 62 // Helper constants.
56 const size_t kStride = kWidth * kBytesPerPixel; 63 const size_t kStride = kWidth * kBytesPerPixel;
57 const size_t kBufferSize = kHeight * kStride; 64 const size_t kBufferSize = kHeight * kStride;
58 const size_t kMemorySize = kBufferSize * kBuffers; 65 const size_t kMemorySize = kBufferSize * kBuffers;
59 66
60 struct Globals { 67 struct Globals {
61 std::unique_ptr<wl_compositor> compositor; 68 std::unique_ptr<wl_compositor> compositor;
62 std::unique_ptr<wl_shm> shm; 69 std::unique_ptr<wl_shm> shm;
63 std::unique_ptr<wl_shell> shell; 70 std::unique_ptr<wl_shell> shell;
64 std::unique_ptr<wl_seat> seat; 71 std::unique_ptr<wl_seat> seat;
(...skipping 20 matching lines...) Expand all
85 wl_registry_bind(registry, id, &wl_seat_interface, 5))); 92 wl_registry_bind(registry, id, &wl_seat_interface, 5)));
86 } 93 }
87 } 94 }
88 95
89 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) { 96 void RegistryRemover(void* data, wl_registry* registry, uint32_t id) {
90 LOG(WARNING) << "Got a registry losing event for " << id; 97 LOG(WARNING) << "Got a registry losing event for " << id;
91 } 98 }
92 99
93 struct BufferState { 100 struct BufferState {
94 std::unique_ptr<wl_buffer> buffer; 101 std::unique_ptr<wl_buffer> buffer;
95 uint8_t* data = nullptr; 102 sk_sp<SkSurface> sk_surface;
96 bool busy = false; 103 bool busy = false;
97 }; 104 };
98 105
99 void BufferRelease(void* data, wl_buffer* buffer) { 106 void BufferRelease(void* data, wl_buffer* buffer) {
100 BufferState* state = static_cast<BufferState*>(data); 107 BufferState* state = static_cast<BufferState*>(data);
101 108
102 state->busy = false; 109 state->busy = false;
103 } 110 }
104 111
105 struct MainLoopContext { 112 struct MainLoopContext {
106 uint32_t color = 0xffffffff;
107 bool needs_redraw = true;
108 bool shutdown = false; 113 bool shutdown = false;
109 bool throttled = false; 114 uint32_t last_event_time = 0;
115 bool frame_callback_pending = false;
116 double rotation = 0.0;
110 }; 117 };
111 118
112 void PointerEnter(void* data, 119 void PointerEnter(void* data,
113 wl_pointer* pointer, 120 wl_pointer* pointer,
114 uint32_t serial, 121 uint32_t serial,
115 wl_surface* surface, 122 wl_surface* surface,
116 wl_fixed_t x, 123 wl_fixed_t x,
117 wl_fixed_t y) {} 124 wl_fixed_t y) {}
118 125
119 void PointerLeave(void* data, 126 void PointerLeave(void* data,
120 wl_pointer* pointer, 127 wl_pointer* pointer,
121 uint32_t serial, 128 uint32_t serial,
122 wl_surface* surface) {} 129 wl_surface* surface) {}
123 130
124 void PointerMotion(void* data, 131 void PointerMotion(void* data,
125 wl_pointer* pointer, 132 wl_pointer* pointer,
126 uint32_t time, 133 uint32_t time,
127 wl_fixed_t x, 134 wl_fixed_t x,
128 wl_fixed_t y) { 135 wl_fixed_t y) {
129 MainLoopContext* context = static_cast<MainLoopContext*>(data); 136 MainLoopContext* context = static_cast<MainLoopContext*>(data);
130 137
131 context->color = 0xff000000 | time; 138 context->last_event_time = time;
132 } 139 }
133 140
134 void PointerButton(void* data, 141 void PointerButton(void* data,
135 wl_pointer* pointer, 142 wl_pointer* pointer,
136 uint32_t serial, 143 uint32_t serial,
137 uint32_t time, 144 uint32_t time,
138 uint32_t button, 145 uint32_t button,
139 uint32_t state) { 146 uint32_t state) {
140 MainLoopContext* context = static_cast<MainLoopContext*>(data); 147 MainLoopContext* context = static_cast<MainLoopContext*>(data);
141 148
(...skipping 11 matching lines...) Expand all
153 void PointerAxisStop(void* data, 160 void PointerAxisStop(void* data,
154 wl_pointer* pointer, 161 wl_pointer* pointer,
155 uint32_t time, 162 uint32_t time,
156 uint32_t axis) {} 163 uint32_t axis) {}
157 164
158 void PointerDiscrete(void* data, 165 void PointerDiscrete(void* data,
159 wl_pointer* pointer, 166 wl_pointer* pointer,
160 uint32_t axis, 167 uint32_t axis,
161 int32_t discrete) {} 168 int32_t discrete) {}
162 169
163 void PointerFrame(void* data, wl_pointer* pointer) { 170 void PointerFrame(void* data, wl_pointer* pointer) {}
164 MainLoopContext* context = static_cast<MainLoopContext*>(data);
165
166 context->needs_redraw = true;
167 }
168 171
169 void TouchDown(void* data, 172 void TouchDown(void* data,
170 wl_touch* touch, 173 wl_touch* touch,
171 uint32_t serial, 174 uint32_t serial,
172 uint32_t time, 175 uint32_t time,
173 wl_surface* surface, 176 wl_surface* surface,
174 int32_t id, 177 int32_t id,
175 wl_fixed_t x, 178 wl_fixed_t x,
176 wl_fixed_t y) {} 179 wl_fixed_t y) {}
177 180
178 void TouchUp(void* data, 181 void TouchUp(void* data,
179 wl_touch* touch, 182 wl_touch* touch,
180 uint32_t serial, 183 uint32_t serial,
181 uint32_t time, 184 uint32_t time,
182 int32_t id) {} 185 int32_t id) {}
183 186
184 void TouchMotion(void* data, 187 void TouchMotion(void* data,
185 wl_touch* touch, 188 wl_touch* touch,
186 uint32_t time, 189 uint32_t time,
187 int32_t id, 190 int32_t id,
188 wl_fixed_t x, 191 wl_fixed_t x,
189 wl_fixed_t y) { 192 wl_fixed_t y) {
190 MainLoopContext* context = static_cast<MainLoopContext*>(data); 193 MainLoopContext* context = static_cast<MainLoopContext*>(data);
191 194
192 context->color = 0xff000000 | time; 195 context->last_event_time = time;
193 context->needs_redraw = true;
194 } 196 }
195 197
196 void TouchFrame(void* data, wl_touch* touch) {} 198 void TouchFrame(void* data, wl_touch* touch) {}
197 199
198 void TouchCancel(void* data, wl_touch* touch) {} 200 void TouchCancel(void* data, wl_touch* touch) {}
199 201
200 void FrameCallback(void* data, wl_callback* callback, uint32_t time) { 202 void FrameCallback(void* data, wl_callback* callback, uint32_t time) {
201 MainLoopContext* context = static_cast<MainLoopContext*>(data); 203 MainLoopContext* context = static_cast<MainLoopContext*>(data);
202 204
203 context->throttled = false; 205 static uint32_t initial_time = time;
206 context->rotation = ((time - initial_time) / 1000.0) * kRotationSpeed;
207 context->frame_callback_pending = false;
204 } 208 }
205 209
206 } // namespace 210 } // namespace
207 211
208 int MotionEventsMain() { 212 int MotionEventsMain() {
209 std::unique_ptr<wl_display> display(wl_display_connect(nullptr)); 213 std::unique_ptr<wl_display> display(wl_display_connect(nullptr));
210 if (!display) { 214 if (!display) {
211 LOG(ERROR) << "wl_display_connect failed"; 215 LOG(ERROR) << "wl_display_connect failed";
212 return 1; 216 return 1;
213 } 217 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 std::unique_ptr<wl_shm_pool> shm_pool( 250 std::unique_ptr<wl_shm_pool> shm_pool(
247 wl_shm_create_pool(globals.shm.get(), shared_memory.handle().fd, 251 wl_shm_create_pool(globals.shm.get(), shared_memory.handle().fd,
248 shared_memory.requested_size())); 252 shared_memory.requested_size()));
249 for (size_t i = 0; i < kBuffers; ++i) { 253 for (size_t i = 0; i < kBuffers; ++i) {
250 buffers[i].buffer.reset(static_cast<wl_buffer*>(wl_shm_pool_create_buffer( 254 buffers[i].buffer.reset(static_cast<wl_buffer*>(wl_shm_pool_create_buffer(
251 shm_pool.get(), i * kBufferSize, kWidth, kHeight, kStride, kFormat))); 255 shm_pool.get(), i * kBufferSize, kWidth, kHeight, kStride, kFormat)));
252 if (!buffers[i].buffer) { 256 if (!buffers[i].buffer) {
253 LOG(ERROR) << "Can't create buffer"; 257 LOG(ERROR) << "Can't create buffer";
254 return 1; 258 return 1;
255 } 259 }
256 buffers[i].data = 260 buffers[i].sk_surface = SkSurface::MakeRasterDirect(
257 static_cast<uint8_t*>(shared_memory.memory()) + kBufferSize * i; 261 SkImageInfo::Make(kWidth, kHeight, kColorType, kUnpremul_SkAlphaType),
262 static_cast<uint8_t*>(shared_memory.memory()) + kBufferSize * i,
263 kStride);
264 if (!buffers[i].sk_surface) {
265 LOG(ERROR) << "Can't create SkSurface";
266 return 1;
267 }
258 wl_buffer_add_listener(buffers[i].buffer.get(), &buffer_listener, 268 wl_buffer_add_listener(buffers[i].buffer.get(), &buffer_listener,
259 &buffers[i]); 269 &buffers[i]);
260 } 270 }
261 271
262 std::unique_ptr<wl_surface> surface(static_cast<wl_surface*>( 272 std::unique_ptr<wl_surface> surface(static_cast<wl_surface*>(
263 wl_compositor_create_surface(globals.compositor.get()))); 273 wl_compositor_create_surface(globals.compositor.get())));
264 if (!surface) { 274 if (!surface) {
265 LOG(ERROR) << "Can't create surface"; 275 LOG(ERROR) << "Can't create surface";
266 return 1; 276 return 1;
267 } 277 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 TouchFrame, TouchCancel}; 323 TouchFrame, TouchCancel};
314 wl_touch_add_listener(touch.get(), &touch_listener, &context); 324 wl_touch_add_listener(touch.get(), &touch_listener, &context);
315 325
316 std::unique_ptr<wl_callback> frame_callback; 326 std::unique_ptr<wl_callback> frame_callback;
317 wl_callback_listener frame_listener = {FrameCallback}; 327 wl_callback_listener frame_listener = {FrameCallback};
318 328
319 do { 329 do {
320 if (context.shutdown) 330 if (context.shutdown)
321 break; 331 break;
322 332
323 if (!context.needs_redraw) 333 if (context.frame_callback_pending)
324 continue;
325
326 if (context.throttled)
327 continue; 334 continue;
328 335
329 BufferState* buffer = 336 BufferState* buffer =
330 std::find_if(std::begin(buffers), std::end(buffers), 337 std::find_if(std::begin(buffers), std::end(buffers),
331 [](const BufferState& buffer) { return !buffer.busy; }); 338 [](const BufferState& buffer) { return !buffer.busy; });
332 if (buffer == std::end(buffers)) 339 if (buffer == std::end(buffers))
333 continue; 340 continue;
334 341
335 context.needs_redraw = false; 342 SkCanvas* canvas = buffer->sk_surface->getCanvas();
336 343 canvas->save();
337 static_assert(sizeof(uint32_t) == kBytesPerPixel, 344 canvas->clear(SkColorSetRGB((context.last_event_time & 0x0000ff) >> 0,
338 "uint32_t must be same size as kBytesPerPixel"); 345 (context.last_event_time & 0x00ff00) >> 8,
339 for (size_t y = 0; y < kHeight; y++) { 346 (context.last_event_time & 0xff0000) >> 16));
340 uint32_t* pixel = reinterpret_cast<uint32_t*>(buffer->data + y * kStride); 347 canvas->translate(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2));
341 for (size_t x = 0; x < kWidth; x++) 348 canvas->rotate(SkDoubleToScalar(context.rotation));
342 *pixel++ = context.color; 349 SkRect rect = SkRect::MakeXYWH(-(kWidth / 4.0f), -(kHeight / 4.0f),
343 } 350 kWidth / 2.0f, kHeight / 2.0f);
351 SkPaint paint;
352 paint.setColor(SK_ColorBLUE);
353 canvas->drawRect(rect, paint);
354 canvas->restore();
344 355
345 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0); 356 wl_surface_attach(surface.get(), buffer->buffer.get(), 0, 0);
346 buffer->busy = true; 357 buffer->busy = true;
347 358
348 frame_callback.reset(wl_surface_frame(surface.get())); 359 frame_callback.reset(wl_surface_frame(surface.get()));
349 wl_callback_add_listener(frame_callback.get(), &frame_listener, &context); 360 wl_callback_add_listener(frame_callback.get(), &frame_listener, &context);
350 context.throttled = true; 361 context.frame_callback_pending = true;
351 362
352 wl_surface_commit(surface.get()); 363 wl_surface_commit(surface.get());
353 wl_display_flush(display.get()); 364 wl_display_flush(display.get());
354 } while (wl_display_dispatch(display.get()) != -1); 365 } while (wl_display_dispatch(display.get()) != -1);
355 366
356 return 0; 367 return 0;
357 } 368 }
358 369
359 } // namespace clients 370 } // namespace clients
360 } // namespace wayland 371 } // namespace wayland
361 } // namespace exo 372 } // namespace exo
362 373
363 int main() { 374 int main() {
364 return exo::wayland::clients::MotionEventsMain(); 375 return exo::wayland::clients::MotionEventsMain();
365 } 376 }
OLDNEW
« 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