[all] provide conditional path optimization hints to the compiler

This commit is contained in:
Geoffrey McRae 2023-11-12 18:26:08 +11:00
parent 7bea919352
commit 929e88b9d3
8 changed files with 117 additions and 94 deletions

View File

@ -382,9 +382,9 @@ bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format)
bool egl_desktopUpdate(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd, bool egl_desktopUpdate(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd,
const FrameDamageRect * damageRects, int damageRectsCount) const FrameDamageRect * damageRects, int damageRectsCount)
{ {
if (desktop->useDMA && dmaFd >= 0) if (likely(desktop->useDMA && dmaFd >= 0))
{ {
if (egl_textureUpdateFromDMA(desktop->texture, frame, dmaFd)) if (likely(egl_textureUpdateFromDMA(desktop->texture, frame, dmaFd)))
{ {
atomic_store(&desktop->processFrame, true); atomic_store(&desktop->processFrame, true);
return true; return true;
@ -420,8 +420,8 @@ bool egl_desktopUpdate(EGL_Desktop * desktop, const FrameBuffer * frame, int dma
return false; return false;
} }
if (egl_textureUpdateFromFrame(desktop->texture, frame, if (likely(egl_textureUpdateFromFrame(desktop->texture, frame,
damageRects, damageRectsCount)) damageRects, damageRectsCount)))
{ {
atomic_store(&desktop->processFrame, true); atomic_store(&desktop->processFrame, true);
return true; return true;
@ -443,7 +443,7 @@ bool egl_desktopRender(EGL_Desktop * desktop, unsigned int outputWidth,
EGL_Texture * tex; EGL_Texture * tex;
int width, height; int width, height;
if (desktop->useSpice) if (unlikely(desktop->useSpice))
{ {
tex = desktop->spiceTexture; tex = desktop->spiceTexture;
width = desktop->spiceWidth; width = desktop->spiceWidth;
@ -456,11 +456,11 @@ bool egl_desktopRender(EGL_Desktop * desktop, unsigned int outputWidth,
height = desktop->height; height = desktop->height;
} }
if (outputWidth == 0 && outputHeight == 0) if (unlikely(outputWidth == 0 && outputHeight == 0))
DEBUG_FATAL("outputWidth || outputHeight == 0"); DEBUG_FATAL("outputWidth || outputHeight == 0");
enum EGL_TexStatus status; enum EGL_TexStatus status;
if ((status = egl_textureProcess(tex)) != EGL_TEX_STATUS_OK) if (unlikely((status = egl_textureProcess(tex)) != EGL_TEX_STATUS_OK))
{ {
if (status != EGL_TEX_STATUS_NOTREADY) if (status != EGL_TEX_STATUS_NOTREADY)
DEBUG_ERROR("Failed to process the desktop texture"); DEBUG_ERROR("Failed to process the desktop texture");

View File

@ -296,7 +296,7 @@ bool egl_screenToDesktop(struct FrameDamageRect * output, const double matrix[6]
void egl_desktopRectsRender(EGL_DesktopRects * rects) void egl_desktopRectsRender(EGL_DesktopRects * rects)
{ {
if (!rects->count) if (unlikely(!rects->count))
return; return;
glBindVertexArray(rects->vao); glBindVertexArray(rects->vao);

View File

@ -20,6 +20,7 @@
#include "interface/renderer.h" #include "interface/renderer.h"
#include "common/util.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/KVMFR.h" #include "common/KVMFR.h"
#include "common/option.h" #include "common/option.h"
@ -580,7 +581,7 @@ static bool egl_onFrameFormat(LG_Renderer * renderer, const LG_RendererFormat fo
this->formatValid = true; this->formatValid = true;
/* this event runs in a second thread so we need to init it here */ /* this event runs in a second thread so we need to init it here */
if (!this->frameContext) if (unlikely(!this->frameContext))
{ {
static EGLint attrs[] = { static EGLint attrs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_CLIENT_VERSION, 2,
@ -600,7 +601,7 @@ static bool egl_onFrameFormat(LG_Renderer * renderer, const LG_RendererFormat fo
} }
} }
if (this->scalePointer) if (likely(this->scalePointer))
{ {
float scale = max(1.0f, (float)format.screenWidth / this->width); float scale = max(1.0f, (float)format.screenWidth / this->width);
egl_cursorSetScale(this->cursor, scale); egl_cursorSetScale(this->cursor, scale);
@ -623,7 +624,8 @@ static bool egl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, int d
struct Inst * this = UPCAST(struct Inst, renderer); struct Inst * this = UPCAST(struct Inst, renderer);
uint64_t start = nanotime(); uint64_t start = nanotime();
if (!egl_desktopUpdate(this->desktop, frame, dmaFd, damageRects, damageRectsCount)) if (unlikely(!egl_desktopUpdate(
this->desktop, frame, dmaFd, damageRects, damageRectsCount)))
{ {
DEBUG_INFO("Failed to to update the desktop"); DEBUG_INFO("Failed to to update the desktop");
return false; return false;
@ -632,12 +634,17 @@ static bool egl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, int d
INTERLOCKED_SECTION(this->desktopDamageLock, { INTERLOCKED_SECTION(this->desktopDamageLock, {
struct DesktopDamage * damage = this->desktopDamage + this->desktopDamageIdx; struct DesktopDamage * damage = this->desktopDamage + this->desktopDamageIdx;
if (damage->count == -1 || damageRectsCount == 0 || if (unlikely(
damage->count + damageRectsCount >= KVMFR_MAX_DAMAGE_RECTS) damage->count == -1 ||
damageRectsCount == 0 ||
damage->count + damageRectsCount >= KVMFR_MAX_DAMAGE_RECTS))
{
damage->count = -1; damage->count = -1;
}
else else
{ {
memcpy(damage->rects + damage->count, damageRects, damageRectsCount * sizeof(FrameDamageRect)); memcpy(damage->rects + damage->count, damageRects,
damageRectsCount * sizeof(FrameDamageRect));
damage->count += damageRectsCount; damage->count += damageRectsCount;
} }
}); });
@ -1056,14 +1063,14 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
accumulated->count = 0; accumulated->count = 0;
INTERLOCKED_SECTION(this->desktopDamageLock, { INTERLOCKED_SECTION(this->desktopDamageLock, {
if (!renderAll) if (likely(!renderAll))
{ {
for (int i = 0; i < bufferAge; ++i) for (int i = 0; i < bufferAge; ++i)
{ {
struct DesktopDamage * damage = this->desktopDamage + struct DesktopDamage * damage = this->desktopDamage +
IDX_AGO(this->desktopDamageIdx, i, DESKTOP_DAMAGE_COUNT); IDX_AGO(this->desktopDamageIdx, i, DESKTOP_DAMAGE_COUNT);
if (damage->count < 0) if (unlikely(damage->count < 0))
{ {
renderAll = true; renderAll = true;
break; break;
@ -1087,7 +1094,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
this->desktopDamage[this->desktopDamageIdx].count = 0; this->desktopDamage[this->desktopDamageIdx].count = 0;
}); });
if (!renderAll) if (likely(!renderAll))
{ {
double matrix[6]; double matrix[6];
egl_screenToDesktopMatrix(matrix, egl_screenToDesktopMatrix(matrix,
@ -1101,7 +1108,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
int count = this->overlayHistoryCount[idx]; int count = this->overlayHistoryCount[idx];
struct Rect * damage = this->overlayHistory[idx]; struct Rect * damage = this->overlayHistory[idx];
if (count < 0) if (unlikely(count < 0))
{ {
renderAll = true; renderAll = true;
break; break;
@ -1114,11 +1121,12 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
); );
} }
accumulated->count = rectsMergeOverlapping(accumulated->rects, accumulated->count); accumulated->count = rectsMergeOverlapping(accumulated->rects,
accumulated->count);
} }
++this->overlayHistoryIdx; ++this->overlayHistoryIdx;
if (this->destRect.w > 0 && this->destRect.h > 0) if (likely(this->destRect.w > 0 && this->destRect.h > 0))
{ {
if (egl_desktopRender(this->desktop, if (egl_desktopRender(this->desktop,
this->destRect.w, this->destRect.h, this->destRect.w, this->destRect.h,
@ -1136,20 +1144,17 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
renderLetterBox(this); renderLetterBox(this);
hasOverlay |= egl_damageRender(this->damage, rotate, newFrame ? desktopDamage : NULL); hasOverlay |=
hasOverlay |= invalidateWindow; egl_damageRender(this->damage, rotate, newFrame ? desktopDamage : NULL) |
invalidateWindow;
struct Rect damage[KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2]; struct Rect damage[KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2];
int damageIdx = app_renderOverlay(damage, MAX_OVERLAY_RECTS); int damageIdx = app_renderOverlay(damage, MAX_OVERLAY_RECTS);
if (unlikely(damageIdx != 0))
switch (damageIdx)
{ {
case 0: // no overlay if (damageIdx == -1)
break;
case -1: // full damage
hasOverlay = true; hasOverlay = true;
// fallthrough
default:
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
@ -1157,20 +1162,21 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
damage[i].y = this->height - damage[i].y - damage[i].h; damage[i].y = this->height - damage[i].y - damage[i].h;
} }
if (damageIdx >= 0 && cursorState.visible) if (likely(damageIdx >= 0 && cursorState.visible))
damage[damageIdx++] = cursorState.rect; damage[damageIdx++] = cursorState.rect;
int overlayHistoryIdx = this->overlayHistoryIdx % DESKTOP_DAMAGE_COUNT; int overlayHistoryIdx = this->overlayHistoryIdx % DESKTOP_DAMAGE_COUNT;
if (hasOverlay) if (unlikely(hasOverlay))
this->overlayHistoryCount[overlayHistoryIdx] = -1; this->overlayHistoryCount[overlayHistoryIdx] = -1;
else else
{ {
if (damageIdx > 0) if (unlikely(damageIdx > 0))
memcpy(this->overlayHistory[overlayHistoryIdx], damage, damageIdx * sizeof(struct Rect)); memcpy(this->overlayHistory[overlayHistoryIdx],
damage, damageIdx * sizeof(struct Rect));
this->overlayHistoryCount[overlayHistoryIdx] = damageIdx; this->overlayHistoryCount[overlayHistoryIdx] = damageIdx;
} }
if (!hasOverlay && !this->hadOverlay) if (unlikely(!hasOverlay && !this->hadOverlay))
{ {
if (this->cursorLast.visible) if (this->cursorLast.visible)
damage[damageIdx++] = this->cursorLast.rect; damage[damageIdx++] = this->cursorLast.rect;
@ -1197,7 +1203,9 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
this->cursorLast = cursorState; this->cursorLast = cursorState;
preSwap(udata); preSwap(udata);
app_eglSwapBuffers(this->display, this->surface, damage, this->noSwapDamage ? 0 : damageIdx); app_eglSwapBuffers(this->display, this->surface, damage,
this->noSwapDamage ? 0 : damageIdx);
return true; return true;
} }

View File

@ -157,7 +157,7 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
break; break;
} }
if (image == EGL_NO_IMAGE) if (unlikely(image == EGL_NO_IMAGE))
{ {
const uint64_t modifier = DRM_FORMAT_MOD_LINEAR; const uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
EGLAttrib attribs[] = EGLAttrib attribs[] =
@ -184,16 +184,16 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
(EGLClientBuffer)NULL, (EGLClientBuffer)NULL,
attribs); attribs);
if (image == EGL_NO_IMAGE) if (unlikely(image == EGL_NO_IMAGE))
{ {
DEBUG_EGL_ERROR("Failed to create EGLImage for DMA transfer"); DEBUG_EGL_ERROR("Failed to create EGLImage for DMA transfer");
return false; return false;
} }
if (!vector_push(&this->images, &(struct FdImage) { if (unlikely(!vector_push(&this->images, &(struct FdImage) {
.fd = update->dmaFD, .fd = update->dmaFD,
.image = image, .image = image,
})) })))
{ {
DEBUG_ERROR("Failed to store EGLImage"); DEBUG_ERROR("Failed to store EGLImage");
g_egl_dynProcs.eglDestroyImage(this->display, image); g_egl_dynProcs.eglDestroyImage(this->display, image);
@ -206,7 +206,7 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
glBindTexture(GL_TEXTURE_EXTERNAL_OES, parent->tex[parent->bufIndex]); glBindTexture(GL_TEXTURE_EXTERNAL_OES, parent->tex[parent->bufIndex]);
g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image); g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
if (parent->sync) if (likely(parent->sync))
glDeleteSync(parent->sync); glDeleteSync(parent->sync);
parent->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); parent->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

View File

@ -209,17 +209,16 @@ static int renderThread(void * unused)
struct timespec time; struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time); clock_gettime(CLOCK_MONOTONIC, &time);
while(g_state.state != APP_STATE_SHUTDOWN) while(likely(g_state.state != APP_STATE_SHUTDOWN))
{ {
bool forceRender = false;
if (g_state.jitRender) if (g_state.jitRender)
forceRender = g_state.ds->waitFrame(); {
const bool forceRender = g_state.ds->waitFrame();
app_handleRenderEvent(microtime()); app_handleRenderEvent(microtime());
if (g_state.jitRender)
{
const uint64_t pending = const uint64_t pending =
atomic_load_explicit(&g_state.pendingCount, memory_order_acquire); atomic_load_explicit(&g_state.pendingCount, memory_order_acquire);
if (!lgResetEvent(g_state.frameEvent) if (!lgResetEvent(g_state.frameEvent)
&& !forceRender && !forceRender
&& !pending && !pending
@ -235,9 +234,13 @@ static int renderThread(void * unused)
} }
else if (g_params.fpsMin != 0) else if (g_params.fpsMin != 0)
{ {
app_handleRenderEvent(microtime());
float ups = atomic_load_explicit(&g_state.ups, memory_order_relaxed); float ups = atomic_load_explicit(&g_state.ups, memory_order_relaxed);
if (!lgWaitEventAbs(g_state.frameEvent, &time) || ups > g_params.fpsMin) if (unlikely(
!lgWaitEventAbs(g_state.frameEvent, &time) ||
ups > g_params.fpsMin))
{ {
/* only update the time if we woke up early */ /* only update the time if we woke up early */
clock_gettime(CLOCK_MONOTONIC, &time); clock_gettime(CLOCK_MONOTONIC, &time);
@ -247,7 +250,7 @@ static int renderThread(void * unused)
} }
int resize = atomic_load(&g_state.lgrResize); int resize = atomic_load(&g_state.lgrResize);
if (resize) if (unlikely(resize))
{ {
g_state.io->DisplaySize = (ImVec2) { g_state.io->DisplaySize = (ImVec2) {
.x = g_state.windowW, .x = g_state.windowW,
@ -286,8 +289,8 @@ static int renderThread(void * unused)
renderQueue_process(); renderQueue_process();
if (!RENDERER(render, g_params.winRotate, newFrame, invalidate, if (unlikely(!RENDERER(render, g_params.winRotate, newFrame, invalidate,
preSwapCallback, (void *)&renderStart)) preSwapCallback, (void *)&renderStart)))
{ {
LG_UNLOCK(g_state.lgrLock); LG_UNLOCK(g_state.lgrLock);
break; break;
@ -300,7 +303,7 @@ static int renderThread(void * unused)
g_state.lastRenderTime = t; g_state.lastRenderTime = t;
atomic_fetch_add_explicit(&g_state.renderCount, 1, memory_order_relaxed); atomic_fetch_add_explicit(&g_state.renderCount, 1, memory_order_relaxed);
if (g_state.lastRenderTimeValid) if (likely(g_state.lastRenderTimeValid))
{ {
const float fdelta = (float)delta / 1e6f; const float fdelta = (float)delta / 1e6f;
ringbuffer_push(g_state.renderTimings, &fdelta); ringbuffer_push(g_state.renderTimings, &fdelta);
@ -308,7 +311,9 @@ static int renderThread(void * unused)
g_state.lastRenderTimeValid = true; g_state.lastRenderTimeValid = true;
const uint64_t now = microtime(); const uint64_t now = microtime();
if (!g_state.resizeDone && g_state.resizeTimeout < now) if (unlikely(
!g_state.resizeDone &&
g_state.resizeTimeout < now))
{ {
if (g_params.autoResize) if (g_params.autoResize)
{ {
@ -1739,9 +1744,9 @@ restart:
return -1; return -1;
} }
while(g_state.state == APP_STATE_RUNNING) while(likely(g_state.state == APP_STATE_RUNNING))
{ {
if (!lgmpClientSessionValid(g_state.lgmp)) if (unlikely(!lgmpClientSessionValid(g_state.lgmp)))
{ {
g_state.lgHostConnected = false; g_state.lgHostConnected = false;
DEBUG_INFO("Waiting for the host to restart..."); DEBUG_INFO("Waiting for the host to restart...");

View File

@ -40,4 +40,7 @@
#define ALIGN_TO(value, align) (((value) + (align) - 1) & -(align)) #define ALIGN_TO(value, align) (((value) + (align) - 1) & -(align))
#define unlikely(expr) __builtin_expect(!!(expr), 0)
#define likely(expr) __builtin_expect(!!(expr), 1)
#endif #endif

View File

@ -457,7 +457,7 @@ static CaptureResult nvfbc_capture(void)
unsigned int width, height; unsigned int width, height;
getDesktopSize(&width, &height); getDesktopSize(&width, &height);
if (this->width != width || this->height != height) if (unlikely(this->width != width || this->height != height))
{ {
this->resChanged = true; this->resChanged = true;
this->width = width; this->width = width;
@ -476,7 +476,7 @@ static CaptureResult nvfbc_capture(void)
&grabInfo &grabInfo
); );
if (result != CAPTURE_RESULT_OK) if (unlikely(result != CAPTURE_RESULT_OK))
return result; return result;
bool changed = false; bool changed = false;
@ -651,15 +651,15 @@ done:
static CaptureResult nvfbc_waitFrame(CaptureFrame * frame, static CaptureResult nvfbc_waitFrame(CaptureFrame * frame,
const size_t maxFrameSize) const size_t maxFrameSize)
{ {
if (this->stop) if (unlikely(this->stop))
return CAPTURE_RESULT_REINIT; return CAPTURE_RESULT_REINIT;
if ( if (unlikely(
this->grabInfo.dwWidth != this->grabWidth || this->grabInfo.dwWidth != this->grabWidth ||
this->grabInfo.dwHeight != this->grabHeight || this->grabInfo.dwHeight != this->grabHeight ||
this->grabInfo.dwBufferWidth != this->grabStride || this->grabInfo.dwBufferWidth != this->grabStride ||
this->grabInfo.bIsHDR != this->isHDR || this->grabInfo.bIsHDR != this->isHDR ||
this->resChanged) this->resChanged))
{ {
this->grabWidth = this->grabInfo.dwWidth; this->grabWidth = this->grabInfo.dwWidth;
this->grabHeight = this->grabInfo.dwHeight; this->grabHeight = this->grabInfo.dwHeight;
@ -820,11 +820,11 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame, int frameIndex)
static int pointerThread(void * unused) static int pointerThread(void * unused)
{ {
while (!this->stop) while (likely(!this->stop))
{ {
lgWaitEvent(this->cursorEvent, TIMEOUT_INFINITE); lgWaitEvent(this->cursorEvent, TIMEOUT_INFINITE);
if (this->stop) if (unlikely(this->stop))
break; break;
CaptureResult result; CaptureResult result;
@ -832,14 +832,14 @@ static int pointerThread(void * unused)
void * data; void * data;
uint32_t size; uint32_t size;
if (!this->getPointerBufferFn(&data, &size)) if (unlikely(!this->getPointerBufferFn(&data, &size)))
{ {
DEBUG_WARN("failed to get a pointer buffer"); DEBUG_WARN("failed to get a pointer buffer");
continue; continue;
} }
result = NvFBCToSysGetCursor(this->nvfbc, &pointer, data, size); result = NvFBCToSysGetCursor(this->nvfbc, &pointer, data, size);
if (result != CAPTURE_RESULT_OK) if (unlikely(result != CAPTURE_RESULT_OK))
{ {
DEBUG_WARN("NvFBCToSysGetCursor failed"); DEBUG_WARN("NvFBCToSysGetCursor failed");
continue; continue;

View File

@ -927,14 +927,16 @@ int app_main(int argc, char * argv[])
} }
} }
while(app.state != APP_STATE_SHUTDOWN && ( while(likely(app.state != APP_STATE_SHUTDOWN && (
lgmpHostQueueHasSubs(app.pointerQueue) || lgmpHostQueueHasSubs(app.pointerQueue) ||
lgmpHostQueueHasSubs(app.frameQueue))) lgmpHostQueueHasSubs(app.frameQueue))))
{ {
if (app.state == APP_STATE_RESTART || app.state == APP_STATE_REINIT) if (unlikely(
app.state == APP_STATE_RESTART ||
app.state == APP_STATE_REINIT))
break; break;
if (lgmpHostQueueNewSubs(app.pointerQueue) > 0) if (unlikely(lgmpHostQueueNewSubs(app.pointerQueue) > 0))
{ {
LG_LOCK(app.pointerLock); LG_LOCK(app.pointerLock);
sendPointer(true); sendPointer(true);
@ -951,24 +953,25 @@ int app_main(int argc, char * argv[])
} }
const uint64_t captureStart = microtime(); const uint64_t captureStart = microtime();
switch(app.iface->capture()) const CaptureResult result = app.iface->capture();
{ if (likely(result == CAPTURE_RESULT_OK))
case CAPTURE_RESULT_OK:
previousFrameTime = captureStart; previousFrameTime = captureStart;
break; else if (likely(result == CAPTURE_RESULT_TIMEOUT))
{
case CAPTURE_RESULT_TIMEOUT:
if (!app.iface->asyncCapture) if (!app.iface->asyncCapture)
if (app.frameValid && lgmpHostQueueNewSubs(app.frameQueue) > 0) if (unlikely(app.frameValid &&
lgmpHostQueueNewSubs(app.frameQueue) > 0))
{ {
LGMP_STATUS status; LGMP_STATUS status;
if ((status = lgmpHostQueuePost(app.frameQueue, 0, if ((status = lgmpHostQueuePost(app.frameQueue, 0,
app.frameMemory[app.frameIndex])) != LGMP_OK) app.frameMemory[app.frameIndex])) != LGMP_OK)
DEBUG_ERROR("%s", lgmpStatusString(status)); DEBUG_ERROR("%s", lgmpStatusString(status));
} }
}
continue; else
{
switch(result)
{
case CAPTURE_RESULT_REINIT: case CAPTURE_RESULT_REINIT:
app.state = APP_STATE_RESTART; app.state = APP_STATE_RESTART;
continue; continue;
@ -977,6 +980,10 @@ int app_main(int argc, char * argv[])
DEBUG_ERROR("Capture interface reported a fatal error"); DEBUG_ERROR("Capture interface reported a fatal error");
exitcode = LG_HOST_EXIT_FAILED; exitcode = LG_HOST_EXIT_FAILED;
goto fail_capture; goto fail_capture;
default:
DEBUG_ASSERT("Invalid capture result");
}
} }
if (!app.iface->asyncCapture) if (!app.iface->asyncCapture)