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 void (*device_get_cursor)(void*, size_t*, size_t*);
extern bool (*device_sync)(void*);
extern void (*device_invalidate)(void*);
extern void* device_pointer;
extern bool (*emergency_device_is_impaired)(void*);
extern bool (*emergency_device_recoup)(void*);
@ -90,6 +91,11 @@ inline bool Sync()
return device_sync(device_pointer);
}
inline void Invalidate()
{
return device_invalidate(device_pointer);
}
inline size_t Print(const char* str)
{
return device_callback(device_pointer, str, strlen(str));

View File

@ -88,6 +88,7 @@ public:
virtual TextPos GetCursorPos() const = 0;
virtual void SetCursorPos(TextPos cursorpos) = 0;
virtual void SpawnThreads() = 0;
virtual void Invalidate() = 0;
virtual bool EmergencyIsImpaired() = 0;
virtual bool EmergencyRecoup() = 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++ )
memset(lfb + scansize * y, 0, lfbformat/8UL * xres);
ret->emergency_state = false;
ret->invalidated = false;
if ( !kernel_process )
return ret;
@ -288,7 +289,6 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
{
from = CropPosition(from);
to = CropPosition(to);
#if !defined(HAS_FAST_VIDEO_MEMORY)
uint8_t* orig_lfb = lfb;
bool backbuffered = from.y != to.y;
if ( backbuffered )
@ -297,7 +297,6 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
from.x = 0;
to.x = columns - 1;
}
#endif
TextPos i = from;
RenderChar(chars[i.y * columns + i.x], i.x, i.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);
RenderChar(chars[i.y * columns + i.x], i.x, i.y);
}
#if !defined(HAS_FAST_VIDEO_MEMORY)
if ( backbuffered )
{
lfb = orig_lfb;
@ -319,11 +317,17 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
memcpy(lfb + offset, backbuf + offset, pixelsx * sizeof(uint32_t));
}
}
#endif
}
void LFBTextBuffer::IssueCommand(TextBufferCmd* cmd)
{
if ( invalidated )
{
invalidated = false;
TextBufferCmd newcmd;
newcmd.type = TEXTBUFCMD_REDRAW;
IssueCommand(&newcmd);
}
if ( !queue_thread || emergency_state )
{
bool exit_requested = false;
@ -446,6 +450,11 @@ void LFBTextBuffer::SetCursorPos(TextPos newcursorpos)
IssueCommand(&cmd);
}
void LFBTextBuffer::Invalidate()
{
invalidated = true;
}
size_t LFBTextBuffer::OffsetOfPos(TextPos pos) const
{
return pos.y * columns + pos.x;
@ -545,6 +554,7 @@ bool LFBTextBuffer::IsCommandIdempotent(const TextBufferCmd* cmd) const
case TEXTBUFCMD_MOVE: return false;
case TEXTBUFCMD_FILL: return true;
case TEXTBUFCMD_SCROLL: return false;
case TEXTBUFCMD_REDRAW: return true;
default: return false;
}
}
@ -636,6 +646,11 @@ void LFBTextBuffer::ExecuteCommand(TextBufferCmd* cmd,
render_from = {0, 0};
render_to = {columns-1, rows-1};
} 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_FILL,
TEXTBUFCMD_SCROLL,
TEXTBUFCMD_REDRAW,
};
struct TextBufferCmd
@ -84,6 +85,7 @@ public:
virtual TextPos GetCursorPos() const;
virtual void SetCursorPos(TextPos newcursorpos);
virtual void SpawnThreads();
virtual void Invalidate();
virtual bool EmergencyIsImpaired();
virtual bool EmergencyRecoup();
virtual void EmergencyReset();
@ -144,6 +146,7 @@ private:
bool cursorenabled;
TextPos cursorpos;
bool emergency_state;
bool invalidated;
size_t execute_amount;
};

View File

@ -53,6 +53,7 @@ size_t (*device_width)(void*) = NULL;
size_t (*device_height)(void*) = NULL;
void (*device_get_cursor)(void*, size_t*, size_t*) = NULL;
bool (*device_sync)(void*) = NULL;
void (*device_invalidate)(void*) = NULL;
void* device_pointer = NULL;
bool (*emergency_device_is_impaired)(void*) = NULL;
bool (*emergency_device_recoup)(void*) = NULL;
@ -89,6 +90,11 @@ static bool TextTermSync(void* user)
return ((TextTerminal*) user)->Sync();
}
static void TextTermInvalidate(void* user)
{
((TextTerminal*) user)->Invalidate();
}
static bool EmergencyTextTermIsImpaired(void* user)
{
return ((TextTerminal*) user)->EmergencyIsImpaired();
@ -196,6 +202,7 @@ void Init(multiboot_info_t* bootinfo)
Log::device_height = TextTermHeight;
Log::device_get_cursor = TextTermGetCursor;
Log::device_sync = TextTermSync;
Log::device_invalidate = TextTermInvalidate;
Log::device_pointer = textterm;
// Register the emergency kernel log.

View File

@ -114,6 +114,15 @@ bool TextTerminal::Sync()
return true;
}
bool TextTerminal::Invalidate()
{
ScopedLock lock(&termlock);
TextBuffer* textbuf = textbufhandle->Acquire();
textbuf->Invalidate();
textbufhandle->Release(textbuf);
return true;
}
bool TextTerminal::EmergencyIsImpaired()
{
// This is during a kernel emergency where preemption has been disabled and

View File

@ -44,6 +44,7 @@ public:
size_t Height() const;
void GetCursor(size_t* column, size_t* row) const;
bool Sync();
bool Invalidate();
bool EmergencyIsImpaired();
bool EmergencyRecoup();
void EmergencyReset();

View File

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

View File

@ -49,6 +49,7 @@ public:
virtual TextPos GetCursorPos() const;
virtual void SetCursorPos(TextPos cursorpos);
virtual void SpawnThreads();
virtual void Invalidate();
virtual bool EmergencyIsImpaired();
virtual bool EmergencyRecoup();
virtual void EmergencyReset();

View File

@ -482,6 +482,8 @@ static int WriteMemory(void* ptr, size_t size)
return errno = ENODEV, -1;
}
Log::Invalidate();
return 0;
}