From af9cc8ed05f72e281e23d75e4313d0d3eceffe9a Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 10 May 2015 20:28:33 +0200 Subject: [PATCH] Schedule full console redraw after user-space framebuffer write. --- kernel/include/sortix/kernel/log.h | 6 ++++++ kernel/include/sortix/kernel/textbuffer.h | 1 + kernel/lfbtextbuffer.cpp | 23 +++++++++++++++++++---- kernel/lfbtextbuffer.h | 3 +++ kernel/log.cpp | 7 +++++++ kernel/textterminal.cpp | 9 +++++++++ kernel/textterminal.h | 1 + kernel/vgatextbuffer.cpp | 4 ++++ kernel/vgatextbuffer.h | 1 + kernel/video.cpp | 2 ++ 10 files changed, 53 insertions(+), 4 deletions(-) diff --git a/kernel/include/sortix/kernel/log.h b/kernel/include/sortix/kernel/log.h index e2036759..00ca5ba7 100644 --- a/kernel/include/sortix/kernel/log.h +++ b/kernel/include/sortix/kernel/log.h @@ -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)); diff --git a/kernel/include/sortix/kernel/textbuffer.h b/kernel/include/sortix/kernel/textbuffer.h index e289ecff..b37eaa70 100644 --- a/kernel/include/sortix/kernel/textbuffer.h +++ b/kernel/include/sortix/kernel/textbuffer.h @@ -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; diff --git a/kernel/lfbtextbuffer.cpp b/kernel/lfbtextbuffer.cpp index 19296e96..5fcbea16 100644 --- a/kernel/lfbtextbuffer.cpp +++ b/kernel/lfbtextbuffer.cpp @@ -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; } } diff --git a/kernel/lfbtextbuffer.h b/kernel/lfbtextbuffer.h index 4c06c4e1..5d90fe8d 100644 --- a/kernel/lfbtextbuffer.h +++ b/kernel/lfbtextbuffer.h @@ -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; }; diff --git a/kernel/log.cpp b/kernel/log.cpp index 2ae51f55..f537efd0 100644 --- a/kernel/log.cpp +++ b/kernel/log.cpp @@ -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. diff --git a/kernel/textterminal.cpp b/kernel/textterminal.cpp index 3f862b27..ce10a837 100644 --- a/kernel/textterminal.cpp +++ b/kernel/textterminal.cpp @@ -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 diff --git a/kernel/textterminal.h b/kernel/textterminal.h index a5d7b9de..74310c1a 100644 --- a/kernel/textterminal.h +++ b/kernel/textterminal.h @@ -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(); diff --git a/kernel/vgatextbuffer.cpp b/kernel/vgatextbuffer.cpp index 6a7c93ea..9b47b7d1 100644 --- a/kernel/vgatextbuffer.cpp +++ b/kernel/vgatextbuffer.cpp @@ -196,6 +196,10 @@ void VGATextBuffer::SpawnThreads() { } +void VGATextBuffer::Invalidate() +{ +} + bool VGATextBuffer::EmergencyIsImpaired() { return false; diff --git a/kernel/vgatextbuffer.h b/kernel/vgatextbuffer.h index b1adfa3e..f7ad5a38 100644 --- a/kernel/vgatextbuffer.h +++ b/kernel/vgatextbuffer.h @@ -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(); diff --git a/kernel/video.cpp b/kernel/video.cpp index 702ec94c..6f14e7ad 100644 --- a/kernel/video.cpp +++ b/kernel/video.cpp @@ -482,6 +482,8 @@ static int WriteMemory(void* ptr, size_t size) return errno = ENODEV, -1; } + Log::Invalidate(); + return 0; }