mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
dispd: Wait for console rendering to finish.
This prevents a race condition where the console may still be rendering, but the process may be able to get data on the screen faster, which results in visual corruption as the two race.
This commit is contained in:
parent
ca7ad9709f
commit
ef53864d36
7 changed files with 45 additions and 2 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <sys/display.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -121,5 +122,19 @@ bool dispd_session_setup_game_rgba(struct dispd_session* session)
|
|||
perror(chvideomode);
|
||||
exit(127);
|
||||
}
|
||||
|
||||
// TODO: HACK: The console may be rendered asynchronously and it is still
|
||||
// rendering to the framebuffer, but this process may be able to write to
|
||||
// the framebuffer before it is done. We need to wait for the console to
|
||||
// finish to fix this race condition.
|
||||
int ttyfd = open("/dev/tty", O_WRONLY);
|
||||
if ( 0 <= ttyfd )
|
||||
{
|
||||
// TODO: There is no fsync system call yet! Whoops! However, closing a
|
||||
// file descriptor also happens to sync it, so this actually works.
|
||||
//fsync(ttyfd);
|
||||
close(ttyfd);
|
||||
}
|
||||
|
||||
return session->is_rgba = true;
|
||||
}
|
||||
|
|
|
@ -35,11 +35,13 @@ namespace Sortix
|
|||
extern size_t (*deviceCallback)(void*, const char*, size_t);
|
||||
extern size_t (*deviceWidth)(void*);
|
||||
extern size_t (*deviceHeight)(void*);
|
||||
extern bool (*deviceSync)(void*);
|
||||
extern void* devicePointer;
|
||||
|
||||
void Init(size_t (*callback)(void*, const char*, size_t),
|
||||
size_t (*widthfunc)(void*),
|
||||
size_t (*heightfunc)(void*),
|
||||
bool (*syncfunc)(void*),
|
||||
void* user);
|
||||
|
||||
inline void Flush()
|
||||
|
@ -57,6 +59,11 @@ namespace Sortix
|
|||
return deviceHeight(devicePointer);
|
||||
}
|
||||
|
||||
inline bool Sync()
|
||||
{
|
||||
return deviceSync(devicePointer);
|
||||
}
|
||||
|
||||
inline size_t Print(const char* str)
|
||||
{
|
||||
if ( !deviceCallback ) { return 0; }
|
||||
|
|
|
@ -135,6 +135,11 @@ static size_t TextTermHeight(void* user)
|
|||
return ((TextTerminal*) user)->Height();
|
||||
}
|
||||
|
||||
static bool TextTermSync(void* user)
|
||||
{
|
||||
return ((TextTerminal*) user)->Sync();
|
||||
}
|
||||
|
||||
addr_t initrd;
|
||||
size_t initrdsize;
|
||||
Ref<TextBufferHandle> textbufhandle;
|
||||
|
@ -166,7 +171,8 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
|
|||
TextTerminal textterm(textbufhandle);
|
||||
|
||||
// Register the text terminal as the kernel log and initialize it.
|
||||
Log::Init(PrintToTextTerminal, TextTermWidth, TextTermHeight, &textterm);
|
||||
Log::Init(PrintToTextTerminal, TextTermWidth, TextTermHeight, TextTermSync,
|
||||
&textterm);
|
||||
|
||||
// Display the boot welcome screen.
|
||||
DoWelcome();
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Sortix
|
|||
size_t (*deviceCallback)(void*, const char*, size_t) = NULL;
|
||||
size_t (*deviceWidth)(void*) = NULL;
|
||||
size_t (*deviceHeight)(void*) = NULL;
|
||||
bool (*deviceSync)(void*) = NULL;
|
||||
void* devicePointer = NULL;
|
||||
|
||||
size_t SysPrintString(const char* str)
|
||||
|
@ -47,11 +48,13 @@ namespace Sortix
|
|||
void Init(size_t (*callback)(void*, const char*, size_t),
|
||||
size_t (*widthfunc)(void*),
|
||||
size_t (*heightfunc)(void*),
|
||||
bool (*syncfunc)(void*),
|
||||
void* user)
|
||||
{
|
||||
deviceCallback = callback;
|
||||
deviceWidth = widthfunc;
|
||||
deviceHeight = heightfunc;
|
||||
deviceSync = syncfunc;
|
||||
devicePointer = user;
|
||||
|
||||
Syscall::Register(SYSCALL_PRINT_STRING, (void*) SysPrintString);
|
||||
|
|
|
@ -125,7 +125,7 @@ int LogTerminal::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
|
|||
|
||||
int LogTerminal::sync(ioctx_t* /*ctx*/)
|
||||
{
|
||||
return 0; // Not needed.
|
||||
return Log::Sync() ? 0 : -1;
|
||||
}
|
||||
|
||||
void LogTerminal::OnKeystroke(Keyboard* kb, void* /*user*/)
|
||||
|
|
|
@ -89,6 +89,17 @@ size_t TextTerminal::Height() const
|
|||
return height;
|
||||
}
|
||||
|
||||
bool TextTerminal::Sync()
|
||||
{
|
||||
// Reading something from the textbuffer may cause it to block while
|
||||
// finishing rendering, effectively synchronizing with it.
|
||||
ScopedLock lock(&termlock);
|
||||
TextBuffer* textbuf = textbufhandle->Acquire();
|
||||
textbuf->GetCursorPos();
|
||||
textbufhandle->Release(textbuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextTerminal::PutChar(TextBuffer* textbuf, char c)
|
||||
{
|
||||
if ( ansimode )
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
size_t Print(const char* string, size_t stringlen);
|
||||
size_t Width() const;
|
||||
size_t Height() const;
|
||||
bool Sync();
|
||||
|
||||
private:
|
||||
void PutChar(TextBuffer* textbuf, char c);
|
||||
|
|
Loading…
Reference in a new issue