Schedule full console redraw after user-space framebuffer write.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-05-10 20:28:33 +02:00
parent dad5c57f33
commit af9cc8ed05
10 changed files with 53 additions and 4 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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;
} }
} }

View File

@ -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;
}; };

View File

@ -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.

View File

@ -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

View File

@ -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();

View File

@ -196,6 +196,10 @@ void VGATextBuffer::SpawnThreads()
{ {
} }
void VGATextBuffer::Invalidate()
{
}
bool VGATextBuffer::EmergencyIsImpaired() bool VGATextBuffer::EmergencyIsImpaired()
{ {
return false; return false;

View File

@ -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();

View File

@ -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;
} }