Implement framebuffer double buffering
All checks were successful
All checks were successful
This commit is contained in:
@@ -33,6 +33,9 @@ KAFFINITY HL::Cpu::ActiveProcessors;
|
|||||||
/* FrameBuffer information */
|
/* FrameBuffer information */
|
||||||
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
|
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
|
||||||
|
|
||||||
|
/* Pointer to the RAM shadow buffer used for double-buffered rendering */
|
||||||
|
PVOID HL::FrameBuffer::ScreenShadowBuffer;
|
||||||
|
|
||||||
/* Scroll region information */
|
/* Scroll region information */
|
||||||
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,9 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
||||||
{
|
{
|
||||||
ULONG PositionX, PositionY;
|
ULONG BackgroundColor, PositionY;
|
||||||
ULONG BackgroundColor;
|
PCHAR CurrentLine, TargetBuffer;
|
||||||
PCHAR CurrentLine;
|
UCHAR FillByte;
|
||||||
PULONG Pixel;
|
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -37,20 +36,29 @@ HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert background color and get pointer to frame buffer */
|
/* Convert background color */
|
||||||
BackgroundColor = GetRGBColor(Color);
|
BackgroundColor = GetRGBColor(Color);
|
||||||
CurrentLine = (PCHAR)FrameBufferData.Address;
|
|
||||||
|
/* Extract the lower byte for SetMemory */
|
||||||
|
FillByte = (UCHAR)(BackgroundColor & 0xFF);
|
||||||
|
|
||||||
|
/* Determine target buffer */
|
||||||
|
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
||||||
|
CurrentLine = TargetBuffer;
|
||||||
|
|
||||||
/* Fill the screen with the specified color */
|
/* Fill the screen with the specified color */
|
||||||
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
|
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
|
||||||
{
|
{
|
||||||
/* Fill the current line with the specified color */
|
/* Fill the current scanline with the background color byte */
|
||||||
Pixel = (PULONG)CurrentLine;
|
RTL::Memory::SetMemory(CurrentLine, FillByte, FrameBufferData.Width * FrameBufferData.BytesPerPixel);
|
||||||
for(PositionX = 0; PositionX < FrameBufferData.Width; PositionX++)
|
}
|
||||||
{
|
|
||||||
/* Set the color of the pixel */
|
/* Check if Shadow Buffer is active */
|
||||||
Pixel[PositionX] = BackgroundColor;
|
if(ScreenShadowBuffer != NULLPTR)
|
||||||
}
|
{
|
||||||
|
/* Flush changes to VRAM */
|
||||||
|
RTL::Memory::CopyMemory(FrameBufferData.Address, ScreenShadowBuffer,
|
||||||
|
FrameBufferData.Pitch * FrameBufferData.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +76,9 @@ XTCDECL
|
|||||||
XTSTATUS
|
XTSTATUS
|
||||||
HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||||
{
|
{
|
||||||
|
ULONG CharacterX, CharacterY;
|
||||||
PSSFN_FONT_HEADER FbFont;
|
PSSFN_FONT_HEADER FbFont;
|
||||||
|
BOOLEAN VisibleCharacter;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -80,6 +90,9 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
/* Get font information */
|
/* Get font information */
|
||||||
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
||||||
|
|
||||||
|
/* Assume invisible character */
|
||||||
|
VisibleCharacter = FALSE;
|
||||||
|
|
||||||
/* Handle special characters */
|
/* Handle special characters */
|
||||||
switch(Character)
|
switch(Character)
|
||||||
{
|
{
|
||||||
@@ -91,15 +104,20 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
case L'\t':
|
case L'\t':
|
||||||
/* Move cursor to the next tab stop */
|
/* Move cursor to the next tab stop */
|
||||||
ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
|
ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
|
||||||
if (ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
||||||
{
|
{
|
||||||
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
||||||
ScrollRegionData.CursorY += FbFont->Height;
|
ScrollRegionData.CursorY += FbFont->Height;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Draw the character */
|
/* Save cursor position */
|
||||||
DrawCharacter(ScrollRegionData.CursorX, ScrollRegionData.CursorY, ScrollRegionData.TextColor, Character);
|
CharacterX = ScrollRegionData.CursorX;
|
||||||
|
CharacterY = ScrollRegionData.CursorY;
|
||||||
|
|
||||||
|
/* Draw the character to RAM and mark it as visible */
|
||||||
|
DrawCharacter(CharacterX, CharacterY, ScrollRegionData.TextColor, Character);
|
||||||
|
VisibleCharacter = TRUE;
|
||||||
|
|
||||||
/* Advance cursor */
|
/* Advance cursor */
|
||||||
ScrollRegionData.CursorX += FbFont->Width;
|
ScrollRegionData.CursorX += FbFont->Width;
|
||||||
@@ -107,6 +125,7 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
/* Check if cursor reached end of line */
|
/* Check if cursor reached end of line */
|
||||||
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
||||||
{
|
{
|
||||||
|
/* Reset cursor to the left margin and advance to the next line */
|
||||||
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
||||||
ScrollRegionData.CursorY += FbFont->Height;
|
ScrollRegionData.CursorY += FbFont->Height;
|
||||||
}
|
}
|
||||||
@@ -120,6 +139,13 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
ScrollRegion();
|
ScrollRegion();
|
||||||
ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height;
|
ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height;
|
||||||
}
|
}
|
||||||
|
else if(VisibleCharacter == TRUE)
|
||||||
|
{
|
||||||
|
/* Flush visible character to VRAM */
|
||||||
|
UpdateScreenRegion(CharacterX, CharacterY,
|
||||||
|
CharacterX + FbFont->Width,
|
||||||
|
CharacterY + FbFont->Height);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@@ -153,9 +179,8 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
{
|
{
|
||||||
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
|
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
|
||||||
PUCHAR Character, CharacterMapping, Fragment;
|
PUCHAR Character, CharacterMapping, Fragment;
|
||||||
UINT_PTR GlyphPixel, Pixel;
|
ULONG FontColor, GlyphOffset, PixelOffset;
|
||||||
PSSFN_FONT_HEADER FbFont;
|
PSSFN_FONT_HEADER FbFont;
|
||||||
ULONG FontColor;
|
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -192,7 +217,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* There's a glyph for this character, check if it matches */
|
/* There is a glyph for this character, check if it matches */
|
||||||
if(Index == WideCharacter)
|
if(Index == WideCharacter)
|
||||||
{
|
{
|
||||||
/* Found the character, break loop */
|
/* Found the character, break loop */
|
||||||
@@ -213,8 +238,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find the glyph position on the frame buffer and set font color */
|
/* Find the glyph position on the frame buffer and set font color */
|
||||||
GlyphPixel = (UINT_PTR)FrameBufferData.Address + PositionY * FrameBufferData.Pitch +
|
GlyphOffset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
||||||
PositionX * FrameBufferData.BytesPerPixel;
|
|
||||||
FontColor = GetRGBColor(Color);
|
FontColor = GetRGBColor(Color);
|
||||||
|
|
||||||
/* Check all kerning fragments */
|
/* Check all kerning fragments */
|
||||||
@@ -243,7 +267,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get initial glyph line */
|
/* Get initial glyph line */
|
||||||
GlyphPixel += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
GlyphOffset += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
||||||
Mapping = CharacterMapping[1];
|
Mapping = CharacterMapping[1];
|
||||||
|
|
||||||
/* Extract glyph data from fragments table and advance */
|
/* Extract glyph data from fragments table and advance */
|
||||||
@@ -255,7 +279,8 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
CurrentFragment = 1;
|
CurrentFragment = 1;
|
||||||
while(GlyphLimit--)
|
while(GlyphLimit--)
|
||||||
{
|
{
|
||||||
Pixel = GlyphPixel;
|
/* Set the initial pixel offset for the current glyph fragment */
|
||||||
|
PixelOffset = GlyphOffset;
|
||||||
for(Line = 0; Line < Glyph; Line++)
|
for(Line = 0; Line < Glyph; Line++)
|
||||||
{
|
{
|
||||||
/* Decode compressed offsets */
|
/* Decode compressed offsets */
|
||||||
@@ -269,17 +294,26 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
/* Check if pixel should be drawn */
|
/* Check if pixel should be drawn */
|
||||||
if(*Fragment & CurrentFragment)
|
if(*Fragment & CurrentFragment)
|
||||||
{
|
{
|
||||||
/* Draw glyph pixel */
|
/* Route the pixel draw operation to the active buffer */
|
||||||
*((PULONG)Pixel) = FontColor;
|
if(ScreenShadowBuffer != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Draw glyph pixel to Shadow Buffer */
|
||||||
|
*((PULONG)((PCHAR)ScreenShadowBuffer + PixelOffset)) = FontColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Draw glyph pixel directly to VRAM */
|
||||||
|
*((PULONG)((PCHAR)FrameBufferData.Address + PixelOffset)) = FontColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance pixel pointer */
|
/* Advance pixel pointer */
|
||||||
Pixel += FrameBufferData.BytesPerPixel;
|
PixelOffset += FrameBufferData.BytesPerPixel;
|
||||||
CurrentFragment <<= 1;
|
CurrentFragment <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance to next line and increase mapping */
|
/* Advance to next line and increase mapping */
|
||||||
GlyphPixel += FrameBufferData.Pitch;
|
GlyphOffset += FrameBufferData.Pitch;
|
||||||
Mapping++;
|
Mapping++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +344,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
|||||||
IN ULONG PositionY,
|
IN ULONG PositionY,
|
||||||
IN ULONG Color)
|
IN ULONG Color)
|
||||||
{
|
{
|
||||||
PCHAR PixelAddress;
|
ULONG Offset;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -327,11 +361,67 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the address of the pixel in the frame buffer memory */
|
/* Calculate the address of the pixel in the frame buffer memory */
|
||||||
PixelAddress = (PCHAR)FrameBufferData.Address + (PositionY * FrameBufferData.Pitch) +
|
Offset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
||||||
(PositionX * FrameBufferData.BytesPerPixel);
|
|
||||||
|
|
||||||
/* Set the color of the pixel by writing to the corresponding memory location */
|
/* Route the pixel draw operation to the active buffer */
|
||||||
*((PULONG)PixelAddress) = GetRGBColor(Color);
|
if(ScreenShadowBuffer != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Set the color of the pixel by writing to the corresponding memory location (RAM) */
|
||||||
|
*((PULONG)((PCHAR)ScreenShadowBuffer + Offset)) = GetRGBColor(Color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Set the color of the pixel by writing to the corresponding memory location (VRAM) */
|
||||||
|
*((PULONG)((PCHAR)FrameBufferData.Address + Offset)) = GetRGBColor(Color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the Shadow Buffer (Double Buffering) for high-performance rendering.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
XTSTATUS
|
||||||
|
HL::FrameBuffer::EnableShadowBuffer(VOID)
|
||||||
|
{
|
||||||
|
ULONG FrameBufferSize;
|
||||||
|
XTSTATUS Status;
|
||||||
|
|
||||||
|
/* Check if the shadow buffer is already enabled */
|
||||||
|
if(ScreenShadowBuffer != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Nothing to do, return success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure frame buffer is already initialized */
|
||||||
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
|
{
|
||||||
|
/* Unable to operate on non-initialized frame buffer */
|
||||||
|
return STATUS_DEVICE_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the total size of the framebuffer */
|
||||||
|
FrameBufferSize = FrameBufferData.Pitch * FrameBufferData.Height;
|
||||||
|
|
||||||
|
/* Allocate non-paged memory for the shadow buffer */
|
||||||
|
Status = MM::Allocator::AllocatePool(NonPagedPool, FrameBufferSize,
|
||||||
|
&ScreenShadowBuffer, SIGNATURE32('F', 'B', 'U', 'F'));
|
||||||
|
if(Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Allocation failed, return status code */
|
||||||
|
ScreenShadowBuffer = NULLPTR;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Synchronize the newly allocated shadow buffer with the current on-screen contents */
|
||||||
|
RTL::Memory::CopyMemory(ScreenShadowBuffer, FrameBufferData.Address, FrameBufferSize);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,10 +634,9 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
HL::FrameBuffer::ScrollRegion(VOID)
|
HL::FrameBuffer::ScrollRegion(VOID)
|
||||||
{
|
{
|
||||||
PCHAR Destination, Source;
|
PCHAR TargetBuffer, Destination, Source;
|
||||||
|
ULONG Line, PositionX, LineBytes;
|
||||||
PSSFN_FONT_HEADER FbFont;
|
PSSFN_FONT_HEADER FbFont;
|
||||||
ULONG Line, PositionX;
|
|
||||||
ULONG LineBytes;
|
|
||||||
PULONG Pixel;
|
PULONG Pixel;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
@@ -557,37 +646,132 @@ HL::FrameBuffer::ScrollRegion(VOID)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get font information */
|
/* Retrieve font metrics and calculate line properties for the scroll operation */
|
||||||
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
||||||
|
|
||||||
/* Calculate bytes per line in the scroll region */
|
|
||||||
LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;
|
LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;
|
||||||
|
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
||||||
|
|
||||||
/* Scroll up each scan line in the scroll region */
|
/* Process every line in the scroll region */
|
||||||
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom - FbFont->Height; Line++)
|
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom; Line++)
|
||||||
{
|
{
|
||||||
Destination = (PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
|
/* Calculate destination address for the current line */
|
||||||
ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
|
Destination = TargetBuffer + (Line * FrameBufferData.Pitch) +
|
||||||
|
(ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
|
||||||
|
|
||||||
/* The source is one full text line (FbFont->Height) below the destination */
|
/* Check if the current line needs to be copied from below or cleared */
|
||||||
Source = (PCHAR)FrameBufferData.Address + (Line + FbFont->Height) * FrameBufferData.Pitch +
|
if(Line < ScrollRegionData.Bottom - FbFont->Height)
|
||||||
ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
|
|
||||||
|
|
||||||
/* Move each scan line in the scroll region up */
|
|
||||||
RTL::Memory::MoveMemory(Destination, Source, LineBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the last text line */
|
|
||||||
for(Line = ScrollRegionData.Bottom - FbFont->Height; Line < ScrollRegionData.Bottom; Line++)
|
|
||||||
{
|
|
||||||
/* Get pointer to the start of the scan line to clear */
|
|
||||||
Pixel = (PULONG)((PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
|
|
||||||
ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
|
|
||||||
|
|
||||||
/* Clear each pixel in the scan line with the background color */
|
|
||||||
for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++)
|
|
||||||
{
|
{
|
||||||
Pixel[PositionX] = ScrollRegionData.BackgroundColor;
|
/* Copy the line from below */
|
||||||
|
Source = Destination + (FbFont->Height * FrameBufferData.Pitch);
|
||||||
|
RTL::Memory::CopyMemory(Destination, Source, LineBytes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fill the bottom line(s) with the background color */
|
||||||
|
Pixel = (PULONG)Destination;
|
||||||
|
for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++)
|
||||||
|
{
|
||||||
|
/* Overwrite the pixel with the background color */
|
||||||
|
Pixel[PositionX] = ScrollRegionData.BackgroundColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flush changes to VRAM if Shadow Buffer was used */
|
||||||
|
if(ScreenShadowBuffer != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Flush the updated scroll region to VRAM */
|
||||||
|
UpdateScreenRegion(ScrollRegionData.Left,
|
||||||
|
ScrollRegionData.Top,
|
||||||
|
ScrollRegionData.Right,
|
||||||
|
ScrollRegionData.Bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes the current content of the Shadow Buffer to the visible FrameBuffer (VRAM).
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::FrameBuffer::UpdateScreen(VOID)
|
||||||
|
{
|
||||||
|
/* Make sure framebuffer is already initialized and shadow buffer is ready */
|
||||||
|
if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)
|
||||||
|
{
|
||||||
|
/* Unable to operate on non-initialized frame buffer */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush RAM to VRAM */
|
||||||
|
RTL::Memory::CopyMemory(FrameBufferData.Address,
|
||||||
|
ScreenShadowBuffer,
|
||||||
|
FrameBufferData.Pitch * FrameBufferData.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes a specific rectangular region from the Shadow Buffer to the visible FrameBuffer (VRAM).
|
||||||
|
*
|
||||||
|
* @param Left
|
||||||
|
* Supplies the left pixel coordinate of the region to update.
|
||||||
|
*
|
||||||
|
* @param Top
|
||||||
|
* Supplies the top pixel coordinate of the region to update.
|
||||||
|
*
|
||||||
|
* @param Right
|
||||||
|
* Supplies the right pixel coordinate of the region to update.
|
||||||
|
*
|
||||||
|
* @param Bottom
|
||||||
|
* Supplies the bottom pixel coordinate of the region to update.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::FrameBuffer::UpdateScreenRegion(IN ULONG Left,
|
||||||
|
IN ULONG Top,
|
||||||
|
IN ULONG Right,
|
||||||
|
IN ULONG Bottom)
|
||||||
|
{
|
||||||
|
ULONG Line, LineBytes;
|
||||||
|
PCHAR Source, Destination;
|
||||||
|
|
||||||
|
/* Make sure framebuffer is already initialized and shadow buffer is ready */
|
||||||
|
if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)
|
||||||
|
{
|
||||||
|
/* Unable to operate on non-initialized frame buffer */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure parameters are valid to prevent memory corruption */
|
||||||
|
if(Left >= Right || Top >= Bottom || Right > FrameBufferData.Width || Bottom > FrameBufferData.Height)
|
||||||
|
{
|
||||||
|
/* Invalid region coordinates provided */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the width of the region */
|
||||||
|
LineBytes = (Right - Left) * FrameBufferData.BytesPerPixel;
|
||||||
|
|
||||||
|
/* Copy the specified region line by line */
|
||||||
|
for(Line = Top; Line < Bottom; Line++)
|
||||||
|
{
|
||||||
|
/* Calculate the source address in the shadow buffer */
|
||||||
|
Source = (PCHAR)ScreenShadowBuffer +
|
||||||
|
(Line * FrameBufferData.Pitch) +
|
||||||
|
(Left * FrameBufferData.BytesPerPixel);
|
||||||
|
|
||||||
|
/* Calculate the destination address in the VRAM */
|
||||||
|
Destination = (PCHAR)FrameBufferData.Address +
|
||||||
|
(Line * FrameBufferData.Pitch) +
|
||||||
|
(Left * FrameBufferData.BytesPerPixel);
|
||||||
|
|
||||||
|
/* Flush RAM to VRAM */
|
||||||
|
RTL::Memory::CopyMemory(Destination, Source, LineBytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ namespace HL
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
STATIC HL_FRAMEBUFFER_DATA FrameBufferData;
|
STATIC HL_FRAMEBUFFER_DATA FrameBufferData;
|
||||||
|
STATIC PVOID ScreenShadowBuffer;
|
||||||
STATIC HL_SCROLL_REGION_DATA ScrollRegionData;
|
STATIC HL_SCROLL_REGION_DATA ScrollRegionData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI VOID ClearScreen(IN ULONG Color);
|
STATIC XTAPI VOID ClearScreen(IN ULONG Color);
|
||||||
STATIC XTCDECL XTSTATUS DisplayCharacter(IN WCHAR Character);
|
STATIC XTCDECL XTSTATUS DisplayCharacter(IN WCHAR Character);
|
||||||
|
STATIC XTAPI XTSTATUS EnableShadowBuffer(VOID);
|
||||||
STATIC XTAPI VOID GetFrameBufferResolution(OUT PULONG Width,
|
STATIC XTAPI VOID GetFrameBufferResolution(OUT PULONG Width,
|
||||||
OUT PULONG Height);
|
OUT PULONG Height);
|
||||||
STATIC XTAPI XTSTATUS InitializeFrameBuffer(VOID);
|
STATIC XTAPI XTSTATUS InitializeFrameBuffer(VOID);
|
||||||
@@ -32,7 +34,11 @@ namespace HL
|
|||||||
IN ULONG Right,
|
IN ULONG Right,
|
||||||
IN ULONG Bottom,
|
IN ULONG Bottom,
|
||||||
IN ULONG FontColor);
|
IN ULONG FontColor);
|
||||||
|
STATIC XTAPI VOID UpdateScreen(VOID);
|
||||||
|
STATIC XTAPI VOID UpdateScreenRegion(IN ULONG Left,
|
||||||
|
IN ULONG Top,
|
||||||
|
IN ULONG Right,
|
||||||
|
IN ULONG Bottom);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTAPI VOID DrawCharacter(IN ULONG PositionX,
|
STATIC XTAPI VOID DrawCharacter(IN ULONG PositionX,
|
||||||
|
|||||||
@@ -118,6 +118,9 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
/* Initialize Memory Manager */
|
/* Initialize Memory Manager */
|
||||||
MM::Manager::InitializeMemoryManager();
|
MM::Manager::InitializeMemoryManager();
|
||||||
|
|
||||||
|
/* Enable shadow buffer for framebuffer */
|
||||||
|
HL::FrameBuffer::EnableShadowBuffer();
|
||||||
|
|
||||||
/* Enter infinite loop */
|
/* Enter infinite loop */
|
||||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||||
KE::Crash::HaltSystem();
|
KE::Crash::HaltSystem();
|
||||||
|
|||||||
@@ -118,6 +118,9 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
/* Initialize Memory Manager */
|
/* Initialize Memory Manager */
|
||||||
MM::Manager::InitializeMemoryManager();
|
MM::Manager::InitializeMemoryManager();
|
||||||
|
|
||||||
|
/* Enable shadow buffer for framebuffer */
|
||||||
|
HL::FrameBuffer::EnableShadowBuffer();
|
||||||
|
|
||||||
/* Enter infinite loop */
|
/* Enter infinite loop */
|
||||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||||
KE::Crash::HaltSystem();
|
KE::Crash::HaltSystem();
|
||||||
|
|||||||
Reference in New Issue
Block a user