comparison Samples/Sdl/RtViewer/RtViewerSdl.cpp @ 1434:c6bfcc105414

Rewrite of the event loop to compact all refresh events. HUGE speedup when using the trackers, especially in Debug mode.
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 19 May 2020 13:24:04 +0200
parents 1eaf19af15bf
children 15173a383a00
comparison
equal deleted inserted replaced
1433:8635b333fa5b 1434:c6bfcc105414
257 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); 257 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
258 258
259 bool stop = false; 259 bool stop = false;
260 while (!stop) 260 while (!stop)
261 { 261 {
262 bool paint = false; 262 std::vector<SDL_Event> sdlEvents;
263 SDL_Event event; 263 std::map<Uint32,SDL_Event> userEventsMap;
264 while (SDL_PollEvent(&event)) 264 SDL_Event sdlEvent;
265
266 // FIRST: collect all pending events
267 while (SDL_PollEvent(&sdlEvent) != 0)
265 { 268 {
266 if (event.type == SDL_QUIT) 269 if ( (sdlEvent.type >= SDL_USEREVENT) &&
270 (sdlEvent.type < SDL_LASTEVENT) )
271 {
272 // we don't want to have multiple refresh events ,
273 // and since every refresh event is a user event with a special type,
274 // we use a map
275 userEventsMap[sdlEvent.type] = sdlEvent;
276 }
277 else
278 {
279 sdlEvents.push_back(sdlEvent);
280 }
281 }
282
283 // SECOND: add all user events to sdlEvents
284 for (std::map<Uint32,SDL_Event>::const_iterator it = userEventsMap.begin(); it != userEventsMap.end(); ++it)
285 sdlEvents.push_back(it->second);
286
287 // now process the events
288 for (std::vector<SDL_Event>::const_iterator it = sdlEvents.begin(); it != sdlEvents.end(); ++it)
289 {
290 const SDL_Event& sdlEvent = *it;
291
292 if (sdlEvent.type == SDL_QUIT)
267 { 293 {
268 stop = true; 294 stop = true;
269 break; 295 break;
270 } 296 }
271 else if (event.type == SDL_WINDOWEVENT && 297 else if (sdlEvent.type == SDL_WINDOWEVENT &&
272 (event.window.event == SDL_WINDOWEVENT_RESIZED || 298 (sdlEvent.window.event == SDL_WINDOWEVENT_RESIZED ||
273 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)) 299 sdlEvent.window.event == SDL_WINDOWEVENT_SIZE_CHANGED))
274 { 300 {
275 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( 301 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
276 views, event.window.windowID); 302 views, sdlEvent.window.windowID);
277 303
278 boost::shared_ptr<SdlViewport> sdlViewport = 304 boost::shared_ptr<SdlViewport> sdlViewport =
279 boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport()); 305 boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport());
280 306
281 sdlViewport->UpdateSize(event.window.data1, event.window.data2); 307 sdlViewport->UpdateSize(sdlEvent.window.data1, sdlEvent.window.data2);
282 } 308 }
283 else if (event.type == SDL_WINDOWEVENT && 309 else if (sdlEvent.type == SDL_WINDOWEVENT &&
284 (event.window.event == SDL_WINDOWEVENT_SHOWN || 310 (sdlEvent.window.event == SDL_WINDOWEVENT_SHOWN ||
285 event.window.event == SDL_WINDOWEVENT_EXPOSED)) 311 sdlEvent.window.event == SDL_WINDOWEVENT_EXPOSED))
286 { 312 {
287 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( 313 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
288 views, event.window.windowID); 314 views, sdlEvent.window.windowID);
289 boost::shared_ptr<SdlViewport> sdlViewport = 315 boost::shared_ptr<SdlViewport> sdlViewport =
290 boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport()); 316 boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport());
291 sdlViewport->Paint(); 317 sdlViewport->Paint();
292 } 318 }
293 else if (event.type == SDL_KEYDOWN && 319 else if (sdlEvent.type == SDL_KEYDOWN &&
294 event.key.repeat == 0 /* Ignore key bounce */) 320 sdlEvent.key.repeat == 0 /* Ignore key bounce */)
295 { 321 {
296 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( 322 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
297 views, event.window.windowID); 323 views, sdlEvent.window.windowID);
298 324
299 switch (event.key.keysym.sym) 325 switch (sdlEvent.key.keysym.sym)
300 { 326 {
301 case SDLK_f: 327 case SDLK_f:
302 { 328 {
303 boost::shared_ptr<SdlViewport> sdlViewport = 329 boost::shared_ptr<SdlViewport> sdlViewport =
304 boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport()); 330 boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport());
320 346
321 default: 347 default:
322 break; 348 break;
323 } 349 }
324 } 350 }
325 else if (event.type == SDL_MOUSEBUTTONDOWN || 351 else if (sdlEvent.type == SDL_MOUSEBUTTONDOWN ||
326 event.type == SDL_MOUSEMOTION || 352 sdlEvent.type == SDL_MOUSEMOTION ||
327 event.type == SDL_MOUSEBUTTONUP) 353 sdlEvent.type == SDL_MOUSEBUTTONUP)
328 { 354 {
329 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( 355 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
330 views, event.window.windowID); 356 views, sdlEvent.window.windowID);
331 357
332 std::auto_ptr<OrthancStone::IViewport::ILock> lock(view->GetViewport()->Lock()); 358 std::auto_ptr<OrthancStone::IViewport::ILock> lock(view->GetViewport()->Lock());
333 if (lock->HasCompositor()) 359 if (lock->HasCompositor())
334 { 360 {
335 OrthancStone::PointerEvent p; 361 OrthancStone::PointerEvent p;
336 OrthancStoneHelpers::GetPointerEvent(p, lock->GetCompositor(), 362 OrthancStoneHelpers::GetPointerEvent(p, lock->GetCompositor(),
337 event, keyboardState, scancodeCount); 363 sdlEvent, keyboardState, scancodeCount);
338 364
339 switch (event.type) 365 switch (sdlEvent.type)
340 { 366 {
341 case SDL_MOUSEBUTTONDOWN: 367 case SDL_MOUSEBUTTONDOWN:
342 lock->GetController().HandleMousePress(interactor, p, 368 lock->GetController().HandleMousePress(interactor, p,
343 lock->GetCompositor().GetCanvasWidth(), 369 lock->GetCompositor().GetCanvasWidth(),
344 lock->GetCompositor().GetCanvasHeight()); 370 lock->GetCompositor().GetCanvasHeight());
360 default: 386 default:
361 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 387 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
362 } 388 }
363 } 389 }
364 } 390 }
365 else if (event.type == SDL_MOUSEWHEEL) 391 else if (sdlEvent.type == SDL_MOUSEWHEEL)
366 { 392 {
367 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( 393 boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
368 views, event.window.windowID); 394 views, sdlEvent.window.windowID);
369 395
370 int delta = 0; 396 int delta = 0;
371 if (event.wheel.y < 0) 397 if (sdlEvent.wheel.y < 0)
372 delta = -1; 398 delta = -1;
373 if (event.wheel.y > 0) 399 if (sdlEvent.wheel.y > 0)
374 delta = 1; 400 delta = 1;
375 401
376 view->Scroll(delta); 402 view->Scroll(delta);
377 } 403 }
378 else 404 else
379 { 405 {
380 for (size_t i = 0; i < views.size(); ++i) 406 for (size_t i = 0; i < views.size(); ++i)
381 { 407 {
382 boost::shared_ptr<SdlViewport> sdlViewport = 408 boost::shared_ptr<SdlViewport> sdlViewport =
383 boost::dynamic_pointer_cast<SdlViewport>(views[i]->GetViewport()); 409 boost::dynamic_pointer_cast<SdlViewport>(views[i]->GetViewport());
384 if (sdlViewport->IsRefreshEvent(event)) 410 if (sdlViewport->IsRefreshEvent(sdlEvent))
411 {
385 sdlViewport->Paint(); 412 sdlViewport->Paint();
413 }
386 } 414 }
387 } 415 }
388 } 416 }
389 // Small delay to avoid using 100% of CPU 417 // Small delay to avoid using 100% of CPU
390 SDL_Delay(1); 418 SDL_Delay(1);