diff options
Diffstat (limited to 'src/ui/window.c')
-rw-r--r-- | src/ui/window.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/ui/window.c b/src/ui/window.c index 13abc5fa..47abf878 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -539,10 +539,19 @@ void deinit_Window(iWindow *d) { | |||
539 | void init_MainWindow(iMainWindow *d, iRect rect) { | 539 | void init_MainWindow(iMainWindow *d, iRect rect) { |
540 | theWindow_ = &d->base; | 540 | theWindow_ = &d->base; |
541 | theMainWindow_ = d; | 541 | theMainWindow_ = d; |
542 | d->enableBackBuf = iFalse; | ||
542 | uint32_t flags = 0; | 543 | uint32_t flags = 0; |
543 | #if defined (iPlatformAppleDesktop) | 544 | #if defined (iPlatformAppleDesktop) |
544 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, shouldDefaultToMetalRenderer_MacOS() ? "metal" : "opengl"); | 545 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, shouldDefaultToMetalRenderer_MacOS() ? "metal" : "opengl"); |
545 | flags |= shouldDefaultToMetalRenderer_MacOS() ? SDL_WINDOW_METAL : SDL_WINDOW_OPENGL; | 546 | flags |= shouldDefaultToMetalRenderer_MacOS() ? SDL_WINDOW_METAL : SDL_WINDOW_OPENGL; |
547 | if (flags & SDL_WINDOW_METAL) { | ||
548 | /* There are some really odd refresh glitches that only occur with the Metal | ||
549 | backend. It's perhaps related to it not expecting refresh to stop intermittently | ||
550 | to wait for input events. If forcing constant refreshing at full frame rate, the | ||
551 | problems seem to go away... Rendering everything to a separate render target | ||
552 | appears to sidestep some of the glitches. */ | ||
553 | d->enableBackBuf = iTrue; | ||
554 | } | ||
546 | #elif defined (iPlatformAppleMobile) | 555 | #elif defined (iPlatformAppleMobile) |
547 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); | 556 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); |
548 | flags |= SDL_WINDOW_METAL; | 557 | flags |= SDL_WINDOW_METAL; |
@@ -566,6 +575,7 @@ void init_MainWindow(iMainWindow *d, iRect rect) { | |||
566 | d->place.lastNotifiedSize = zero_I2(); | 575 | d->place.lastNotifiedSize = zero_I2(); |
567 | d->place.snap = 0; | 576 | d->place.snap = 0; |
568 | d->keyboardHeight = 0; | 577 | d->keyboardHeight = 0; |
578 | d->backBuf = NULL; | ||
569 | #if defined(iPlatformMobile) | 579 | #if defined(iPlatformMobile) |
570 | const iInt2 minSize = zero_I2(); /* windows aren't independently resizable */ | 580 | const iInt2 minSize = zero_I2(); /* windows aren't independently resizable */ |
571 | #else | 581 | #else |
@@ -637,6 +647,9 @@ void init_MainWindow(iMainWindow *d, iRect rect) { | |||
637 | } | 647 | } |
638 | 648 | ||
639 | void deinit_MainWindow(iMainWindow *d) { | 649 | void deinit_MainWindow(iMainWindow *d) { |
650 | if (d->backBuf) { | ||
651 | SDL_DestroyTexture(d->backBuf); | ||
652 | } | ||
640 | deinitRoots_Window_(as_Window(d)); | 653 | deinitRoots_Window_(as_Window(d)); |
641 | if (theWindow_ == as_Window(d)) { | 654 | if (theWindow_ == as_Window(d)) { |
642 | theWindow_ = NULL; | 655 | theWindow_ = NULL; |
@@ -682,6 +695,10 @@ iRoot *otherRoot_Window(const iWindow *d, iRoot *root) { | |||
682 | static void invalidate_MainWindow_(iMainWindow *d, iBool forced) { | 695 | static void invalidate_MainWindow_(iMainWindow *d, iBool forced) { |
683 | if (d && (!d->base.isInvalidated || forced)) { | 696 | if (d && (!d->base.isInvalidated || forced)) { |
684 | d->base.isInvalidated = iTrue; | 697 | d->base.isInvalidated = iTrue; |
698 | if (d->enableBackBuf && d->backBuf) { | ||
699 | SDL_DestroyTexture(d->backBuf); | ||
700 | d->backBuf = NULL; | ||
701 | } | ||
685 | resetFonts_Text(text_Window(d)); | 702 | resetFonts_Text(text_Window(d)); |
686 | postCommand_App("theme.changed auto:1"); /* forces UI invalidation */ | 703 | postCommand_App("theme.changed auto:1"); /* forces UI invalidation */ |
687 | } | 704 | } |
@@ -1272,11 +1289,28 @@ void draw_MainWindow(iMainWindow *d) { | |||
1272 | d->maxDrawableHeight = renderSize.y; | 1289 | d->maxDrawableHeight = renderSize.y; |
1273 | } | 1290 | } |
1274 | } | 1291 | } |
1292 | if (d->enableBackBuf) { | ||
1293 | /* Possible resize the backing buffer. */ | ||
1294 | if (!d->backBuf || !isEqual_I2(size_SDLTexture(d->backBuf), renderSize)) { | ||
1295 | if (d->backBuf) { | ||
1296 | SDL_DestroyTexture(d->backBuf); | ||
1297 | } | ||
1298 | d->backBuf = SDL_CreateTexture(d->base.render, | ||
1299 | SDL_PIXELFORMAT_RGB888, | ||
1300 | SDL_TEXTUREACCESS_TARGET, | ||
1301 | renderSize.x, | ||
1302 | renderSize.y); | ||
1303 | // printf("NEW BACKING: %dx%d %p\n", renderSize.x, renderSize.y, d->backBuf); fflush(stdout); | ||
1304 | } | ||
1305 | } | ||
1275 | } | 1306 | } |
1276 | const int winFlags = SDL_GetWindowFlags(d->base.win); | 1307 | const int winFlags = SDL_GetWindowFlags(d->base.win); |
1277 | const iBool gotFocus = (winFlags & SDL_WINDOW_INPUT_FOCUS) != 0; | 1308 | const iBool gotFocus = (winFlags & SDL_WINDOW_INPUT_FOCUS) != 0; |
1278 | iPaint p; | 1309 | iPaint p; |
1279 | init_Paint(&p); | 1310 | init_Paint(&p); |
1311 | if (d->backBuf) { | ||
1312 | SDL_SetRenderTarget(d->base.render, d->backBuf); | ||
1313 | } | ||
1280 | /* Clear the window. The clear color is visible as a border around the window | 1314 | /* Clear the window. The clear color is visible as a border around the window |
1281 | when the custom frame is being used. */ { | 1315 | when the custom frame is being used. */ { |
1282 | setCurrent_Root(w->roots[0]); | 1316 | setCurrent_Root(w->roots[0]); |
@@ -1359,6 +1393,10 @@ void draw_MainWindow(iMainWindow *d) { | |||
1359 | drawCount_ = 0; | 1393 | drawCount_ = 0; |
1360 | #endif | 1394 | #endif |
1361 | } | 1395 | } |
1396 | if (d->backBuf) { | ||
1397 | SDL_SetRenderTarget(d->base.render, NULL); | ||
1398 | SDL_RenderCopy(d->base.render, d->backBuf, NULL, NULL); | ||
1399 | } | ||
1362 | #if 0 | 1400 | #if 0 |
1363 | /* Text cache debugging. */ { | 1401 | /* Text cache debugging. */ { |
1364 | SDL_Rect rect = { d->roots[0]->widget->rect.size.x - 640, 0, 640, 2.5 * 640 }; | 1402 | SDL_Rect rect = { d->roots[0]->widget->rect.size.x - 640, 0, 640, 2.5 * 640 }; |