Schedule full console redraw after user-space framebuffer write.
This commit is contained in:
parent
dad5c57f33
commit
af9cc8ed05
|
@ -54,6 +54,7 @@ extern size_t (*device_width)(void*);
|
||||||
extern size_t (*device_height)(void*);
|
extern size_t (*device_height)(void*);
|
||||||
extern void (*device_get_cursor)(void*, size_t*, size_t*);
|
extern void (*device_get_cursor)(void*, size_t*, size_t*);
|
||||||
extern bool (*device_sync)(void*);
|
extern bool (*device_sync)(void*);
|
||||||
|
extern void (*device_invalidate)(void*);
|
||||||
extern void* device_pointer;
|
extern void* device_pointer;
|
||||||
extern bool (*emergency_device_is_impaired)(void*);
|
extern bool (*emergency_device_is_impaired)(void*);
|
||||||
extern bool (*emergency_device_recoup)(void*);
|
extern bool (*emergency_device_recoup)(void*);
|
||||||
|
@ -90,6 +91,11 @@ inline bool Sync()
|
||||||
return device_sync(device_pointer);
|
return device_sync(device_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Invalidate()
|
||||||
|
{
|
||||||
|
return device_invalidate(device_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
inline size_t Print(const char* str)
|
inline size_t Print(const char* str)
|
||||||
{
|
{
|
||||||
return device_callback(device_pointer, str, strlen(str));
|
return device_callback(device_pointer, str, strlen(str));
|
||||||
|
|
|
@ -88,6 +88,7 @@ public:
|
||||||
virtual TextPos GetCursorPos() const = 0;
|
virtual TextPos GetCursorPos() const = 0;
|
||||||
virtual void SetCursorPos(TextPos cursorpos) = 0;
|
virtual void SetCursorPos(TextPos cursorpos) = 0;
|
||||||
virtual void SpawnThreads() = 0;
|
virtual void SpawnThreads() = 0;
|
||||||
|
virtual void Invalidate() = 0;
|
||||||
virtual bool EmergencyIsImpaired() = 0;
|
virtual bool EmergencyIsImpaired() = 0;
|
||||||
virtual bool EmergencyRecoup() = 0;
|
virtual bool EmergencyRecoup() = 0;
|
||||||
virtual void EmergencyReset() = 0;
|
virtual void EmergencyReset() = 0;
|
||||||
|
|
|
@ -122,6 +122,7 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
|
||||||
for ( size_t y = 0; y < yres; y++ )
|
for ( size_t y = 0; y < yres; y++ )
|
||||||
memset(lfb + scansize * y, 0, lfbformat/8UL * xres);
|
memset(lfb + scansize * y, 0, lfbformat/8UL * xres);
|
||||||
ret->emergency_state = false;
|
ret->emergency_state = false;
|
||||||
|
ret->invalidated = false;
|
||||||
|
|
||||||
if ( !kernel_process )
|
if ( !kernel_process )
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -288,7 +289,6 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
|
||||||
{
|
{
|
||||||
from = CropPosition(from);
|
from = CropPosition(from);
|
||||||
to = CropPosition(to);
|
to = CropPosition(to);
|
||||||
#if !defined(HAS_FAST_VIDEO_MEMORY)
|
|
||||||
uint8_t* orig_lfb = lfb;
|
uint8_t* orig_lfb = lfb;
|
||||||
bool backbuffered = from.y != to.y;
|
bool backbuffered = from.y != to.y;
|
||||||
if ( backbuffered )
|
if ( backbuffered )
|
||||||
|
@ -297,7 +297,6 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
|
||||||
from.x = 0;
|
from.x = 0;
|
||||||
to.x = columns - 1;
|
to.x = columns - 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
TextPos i = from;
|
TextPos i = from;
|
||||||
RenderChar(chars[i.y * columns + i.x], i.x, i.y);
|
RenderChar(chars[i.y * columns + i.x], i.x, i.y);
|
||||||
while ( !(i.x==to.x && i.y==to.y) )
|
while ( !(i.x==to.x && i.y==to.y) )
|
||||||
|
@ -305,7 +304,6 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
|
||||||
i = AddToPosition(i, 1);
|
i = AddToPosition(i, 1);
|
||||||
RenderChar(chars[i.y * columns + i.x], i.x, i.y);
|
RenderChar(chars[i.y * columns + i.x], i.x, i.y);
|
||||||
}
|
}
|
||||||
#if !defined(HAS_FAST_VIDEO_MEMORY)
|
|
||||||
if ( backbuffered )
|
if ( backbuffered )
|
||||||
{
|
{
|
||||||
lfb = orig_lfb;
|
lfb = orig_lfb;
|
||||||
|
@ -319,11 +317,17 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
|
||||||
memcpy(lfb + offset, backbuf + offset, pixelsx * sizeof(uint32_t));
|
memcpy(lfb + offset, backbuf + offset, pixelsx * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LFBTextBuffer::IssueCommand(TextBufferCmd* cmd)
|
void LFBTextBuffer::IssueCommand(TextBufferCmd* cmd)
|
||||||
{
|
{
|
||||||
|
if ( invalidated )
|
||||||
|
{
|
||||||
|
invalidated = false;
|
||||||
|
TextBufferCmd newcmd;
|
||||||
|
newcmd.type = TEXTBUFCMD_REDRAW;
|
||||||
|
IssueCommand(&newcmd);
|
||||||
|
}
|
||||||
if ( !queue_thread || emergency_state )
|
if ( !queue_thread || emergency_state )
|
||||||
{
|
{
|
||||||
bool exit_requested = false;
|
bool exit_requested = false;
|
||||||
|
@ -446,6 +450,11 @@ void LFBTextBuffer::SetCursorPos(TextPos newcursorpos)
|
||||||
IssueCommand(&cmd);
|
IssueCommand(&cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LFBTextBuffer::Invalidate()
|
||||||
|
{
|
||||||
|
invalidated = true;
|
||||||
|
}
|
||||||
|
|
||||||
size_t LFBTextBuffer::OffsetOfPos(TextPos pos) const
|
size_t LFBTextBuffer::OffsetOfPos(TextPos pos) const
|
||||||
{
|
{
|
||||||
return pos.y * columns + pos.x;
|
return pos.y * columns + pos.x;
|
||||||
|
@ -545,6 +554,7 @@ bool LFBTextBuffer::IsCommandIdempotent(const TextBufferCmd* cmd) const
|
||||||
case TEXTBUFCMD_MOVE: return false;
|
case TEXTBUFCMD_MOVE: return false;
|
||||||
case TEXTBUFCMD_FILL: return true;
|
case TEXTBUFCMD_FILL: return true;
|
||||||
case TEXTBUFCMD_SCROLL: return false;
|
case TEXTBUFCMD_SCROLL: return false;
|
||||||
|
case TEXTBUFCMD_REDRAW: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,6 +646,11 @@ void LFBTextBuffer::ExecuteCommand(TextBufferCmd* cmd,
|
||||||
render_from = {0, 0};
|
render_from = {0, 0};
|
||||||
render_to = {columns-1, rows-1};
|
render_to = {columns-1, rows-1};
|
||||||
} break;
|
} break;
|
||||||
|
case TEXTBUFCMD_REDRAW:
|
||||||
|
{
|
||||||
|
render_from = {0, 0};
|
||||||
|
render_to = {columns-1, rows-1};
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum TextBufferCmdType
|
||||||
TEXTBUFCMD_MOVE,
|
TEXTBUFCMD_MOVE,
|
||||||
TEXTBUFCMD_FILL,
|
TEXTBUFCMD_FILL,
|
||||||
TEXTBUFCMD_SCROLL,
|
TEXTBUFCMD_SCROLL,
|
||||||
|
TEXTBUFCMD_REDRAW,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextBufferCmd
|
struct TextBufferCmd
|
||||||
|
@ -84,6 +85,7 @@ public:
|
||||||
virtual TextPos GetCursorPos() const;
|
virtual TextPos GetCursorPos() const;
|
||||||
virtual void SetCursorPos(TextPos newcursorpos);
|
virtual void SetCursorPos(TextPos newcursorpos);
|
||||||
virtual void SpawnThreads();
|
virtual void SpawnThreads();
|
||||||
|
virtual void Invalidate();
|
||||||
virtual bool EmergencyIsImpaired();
|
virtual bool EmergencyIsImpaired();
|
||||||
virtual bool EmergencyRecoup();
|
virtual bool EmergencyRecoup();
|
||||||
virtual void EmergencyReset();
|
virtual void EmergencyReset();
|
||||||
|
@ -144,6 +146,7 @@ private:
|
||||||
bool cursorenabled;
|
bool cursorenabled;
|
||||||
TextPos cursorpos;
|
TextPos cursorpos;
|
||||||
bool emergency_state;
|
bool emergency_state;
|
||||||
|
bool invalidated;
|
||||||
size_t execute_amount;
|
size_t execute_amount;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,6 +53,7 @@ size_t (*device_width)(void*) = NULL;
|
||||||
size_t (*device_height)(void*) = NULL;
|
size_t (*device_height)(void*) = NULL;
|
||||||
void (*device_get_cursor)(void*, size_t*, size_t*) = NULL;
|
void (*device_get_cursor)(void*, size_t*, size_t*) = NULL;
|
||||||
bool (*device_sync)(void*) = NULL;
|
bool (*device_sync)(void*) = NULL;
|
||||||
|
void (*device_invalidate)(void*) = NULL;
|
||||||
void* device_pointer = NULL;
|
void* device_pointer = NULL;
|
||||||
bool (*emergency_device_is_impaired)(void*) = NULL;
|
bool (*emergency_device_is_impaired)(void*) = NULL;
|
||||||
bool (*emergency_device_recoup)(void*) = NULL;
|
bool (*emergency_device_recoup)(void*) = NULL;
|
||||||
|
@ -89,6 +90,11 @@ static bool TextTermSync(void* user)
|
||||||
return ((TextTerminal*) user)->Sync();
|
return ((TextTerminal*) user)->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TextTermInvalidate(void* user)
|
||||||
|
{
|
||||||
|
((TextTerminal*) user)->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
static bool EmergencyTextTermIsImpaired(void* user)
|
static bool EmergencyTextTermIsImpaired(void* user)
|
||||||
{
|
{
|
||||||
return ((TextTerminal*) user)->EmergencyIsImpaired();
|
return ((TextTerminal*) user)->EmergencyIsImpaired();
|
||||||
|
@ -196,6 +202,7 @@ void Init(multiboot_info_t* bootinfo)
|
||||||
Log::device_height = TextTermHeight;
|
Log::device_height = TextTermHeight;
|
||||||
Log::device_get_cursor = TextTermGetCursor;
|
Log::device_get_cursor = TextTermGetCursor;
|
||||||
Log::device_sync = TextTermSync;
|
Log::device_sync = TextTermSync;
|
||||||
|
Log::device_invalidate = TextTermInvalidate;
|
||||||
Log::device_pointer = textterm;
|
Log::device_pointer = textterm;
|
||||||
|
|
||||||
// Register the emergency kernel log.
|
// Register the emergency kernel log.
|
||||||
|
|
|
@ -114,6 +114,15 @@ bool TextTerminal::Sync()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextTerminal::Invalidate()
|
||||||
|
{
|
||||||
|
ScopedLock lock(&termlock);
|
||||||
|
TextBuffer* textbuf = textbufhandle->Acquire();
|
||||||
|
textbuf->Invalidate();
|
||||||
|
textbufhandle->Release(textbuf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool TextTerminal::EmergencyIsImpaired()
|
bool TextTerminal::EmergencyIsImpaired()
|
||||||
{
|
{
|
||||||
// This is during a kernel emergency where preemption has been disabled and
|
// This is during a kernel emergency where preemption has been disabled and
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
size_t Height() const;
|
size_t Height() const;
|
||||||
void GetCursor(size_t* column, size_t* row) const;
|
void GetCursor(size_t* column, size_t* row) const;
|
||||||
bool Sync();
|
bool Sync();
|
||||||
|
bool Invalidate();
|
||||||
bool EmergencyIsImpaired();
|
bool EmergencyIsImpaired();
|
||||||
bool EmergencyRecoup();
|
bool EmergencyRecoup();
|
||||||
void EmergencyReset();
|
void EmergencyReset();
|
||||||
|
|
|
@ -196,6 +196,10 @@ void VGATextBuffer::SpawnThreads()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VGATextBuffer::Invalidate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool VGATextBuffer::EmergencyIsImpaired()
|
bool VGATextBuffer::EmergencyIsImpaired()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
virtual TextPos GetCursorPos() const;
|
virtual TextPos GetCursorPos() const;
|
||||||
virtual void SetCursorPos(TextPos cursorpos);
|
virtual void SetCursorPos(TextPos cursorpos);
|
||||||
virtual void SpawnThreads();
|
virtual void SpawnThreads();
|
||||||
|
virtual void Invalidate();
|
||||||
virtual bool EmergencyIsImpaired();
|
virtual bool EmergencyIsImpaired();
|
||||||
virtual bool EmergencyRecoup();
|
virtual bool EmergencyRecoup();
|
||||||
virtual void EmergencyReset();
|
virtual void EmergencyReset();
|
||||||
|
|
|
@ -482,6 +482,8 @@ static int WriteMemory(void* ptr, size_t size)
|
||||||
return errno = ENODEV, -1;
|
return errno = ENODEV, -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log::Invalidate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue