mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-02 02:49:15 +00:00
Merge remote-tracking branch 'Kernel/master'
This commit is contained in:
166
Kernel/core/video/display.cpp
Normal file
166
Kernel/core/video/display.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <display.hpp>
|
||||
#include <lock.hpp>
|
||||
#include <uart.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
NewLock(PrintLock);
|
||||
|
||||
namespace Video
|
||||
{
|
||||
uint16_t Display::GetBitsPerPixel() { return this->framebuffer.BitsPerPixel; }
|
||||
size_t Display::GetPitch() { return this->framebuffer.Pitch; }
|
||||
|
||||
void Display::ClearBuffer()
|
||||
{
|
||||
memset(this->Buffer, 0, this->Size);
|
||||
// std::fill(this->DirtyMap.begin(), this->DirtyMap.end(), true);
|
||||
}
|
||||
|
||||
__no_sanitize("undefined") void Display::SetPixel(uint32_t X,
|
||||
uint32_t Y,
|
||||
uint32_t Color)
|
||||
{
|
||||
if (unlikely(X >= this->Width))
|
||||
X = this->Width - 1;
|
||||
|
||||
if (unlikely(Y >= this->Height))
|
||||
Y = this->Height - 1;
|
||||
|
||||
uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffer + (Y * this->Width + X) * (this->framebuffer.BitsPerPixel / 8));
|
||||
*Pixel = Color;
|
||||
// MarkRegionDirty(Y / RegionHeight, X / RegionWidth);
|
||||
}
|
||||
|
||||
__no_sanitize("undefined") uint32_t Display::GetPixel(uint32_t X,
|
||||
uint32_t Y)
|
||||
{
|
||||
if (unlikely(X >= this->Width))
|
||||
X = this->Width - 1;
|
||||
|
||||
if (unlikely(Y >= this->Height))
|
||||
Y = this->Height - 1;
|
||||
|
||||
uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffer + (Y * this->Width + X) * (this->framebuffer.BitsPerPixel / 8));
|
||||
return *Pixel;
|
||||
}
|
||||
|
||||
__no_sanitize("undefined") void Display::DrawRectangle(uint32_t X,
|
||||
uint32_t Y,
|
||||
uint32_t Width,
|
||||
uint32_t Height,
|
||||
uint32_t Color)
|
||||
{
|
||||
for (uint32_t i = 0; i < Width; i++)
|
||||
{
|
||||
for (uint32_t j = 0; j < Height; j++)
|
||||
{
|
||||
uint32_t *Pixel =
|
||||
(uint32_t *)((uintptr_t)this->Buffer + ((Y + j) *
|
||||
this->Width +
|
||||
(X + i)) *
|
||||
(this->framebuffer.BitsPerPixel / 8));
|
||||
*Pixel = Color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Display::UpdateBuffer()
|
||||
{
|
||||
if (!DirectWrite)
|
||||
memcpy(this->framebuffer.BaseAddress, this->Buffer, this->Size);
|
||||
|
||||
// for (size_t i = 0; i < DirtyMap.size(); ++i)
|
||||
// {
|
||||
// if (DirtyMap[i])
|
||||
// {
|
||||
// size_t rRow = i / (framebuffer.Width / RegionWidth);
|
||||
// size_t rCol = i % (framebuffer.Width / RegionWidth);
|
||||
// UpdateRegion(rRow, rCol);
|
||||
// DirtyMap[i] = false;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void Display::UpdateRegion(size_t RegionRow, size_t RegionColumn)
|
||||
{
|
||||
size_t startRow = RegionRow * RegionHeight;
|
||||
size_t endRow = startRow + RegionHeight;
|
||||
size_t startCol = RegionColumn * RegionWidth;
|
||||
size_t endCol = startCol + RegionWidth;
|
||||
|
||||
uint8_t *framebufferPtr = (uint8_t *)framebuffer.BaseAddress;
|
||||
uint8_t *bufferPtr = (uint8_t *)Buffer;
|
||||
|
||||
for (size_t row = startRow; row < endRow; ++row)
|
||||
{
|
||||
uint8_t *framebufferRowPtr = framebufferPtr + (row % framebuffer.Height) * framebuffer.Width * (framebuffer.BitsPerPixel / 8);
|
||||
uint8_t *bufferRowPtr = bufferPtr + row * framebuffer.Width * (framebuffer.BitsPerPixel / 8);
|
||||
|
||||
for (size_t col = startCol; col < endCol; ++col)
|
||||
{
|
||||
uint8_t *framebufferPixelPtr = framebufferRowPtr + (col % framebuffer.Width) * (framebuffer.BitsPerPixel / 8);
|
||||
uint8_t *bufferPixelPtr = bufferRowPtr + col * (framebuffer.BitsPerPixel / 8);
|
||||
|
||||
memcpy(framebufferPixelPtr, bufferPixelPtr, framebuffer.BitsPerPixel / 8);
|
||||
}
|
||||
}
|
||||
/*
|
||||
size_t startRow = RegionRow * RegionHeight;
|
||||
size_t endRow = startRow + RegionHeight;
|
||||
size_t startCol = RegionColumn * RegionWidth;
|
||||
size_t endCol = startCol + RegionWidth;
|
||||
|
||||
for (size_t row = startRow; row < endRow; ++row)
|
||||
{
|
||||
for (size_t col = startCol; col < endCol; ++col)
|
||||
{
|
||||
size_t bufferIndex = row * framebuffer.Width + col;
|
||||
size_t framebufferIndex = (row % framebuffer.Height) * framebuffer.Width + (col % framebuffer.Width);
|
||||
memcpy((uint8_t *)framebuffer.BaseAddress + framebufferIndex * (framebuffer.BitsPerPixel / 8),
|
||||
(uint8_t *)Buffer + bufferIndex * (framebuffer.BitsPerPixel / 8),
|
||||
framebuffer.BitsPerPixel / 8);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Display::MarkRegionDirty(size_t RegionRow, size_t RegionCol)
|
||||
{
|
||||
size_t index = RegionRow * (framebuffer.Width / RegionWidth) + RegionCol;
|
||||
DirtyMap[index] = true;
|
||||
}
|
||||
|
||||
Display::Display(BootInfo::FramebufferInfo Info,
|
||||
bool _DirectWrite)
|
||||
: framebuffer(Info), DirectWrite(_DirectWrite)
|
||||
{
|
||||
Width = Info.Width;
|
||||
Height = Info.Height;
|
||||
Size = this->framebuffer.Pitch * Height;
|
||||
if (DirectWrite)
|
||||
Buffer = (void *)this->framebuffer.BaseAddress;
|
||||
else
|
||||
Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||
|
||||
// DirtyMap.resize((Width / RegionWidth) * (Height / RegionHeight), false);
|
||||
}
|
||||
|
||||
Display::~Display() {}
|
||||
}
|
80
Kernel/core/video/font.cpp
Normal file
80
Kernel/core/video/font.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <display.hpp>
|
||||
#include <debug.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
Font::Font(uintptr_t *Start, uintptr_t *End, FontType Type)
|
||||
{
|
||||
trace("Initializing font with start %#lx and end %#lx Type: %d", Start, End, Type);
|
||||
this->Info.StartAddress = Start;
|
||||
this->Info.EndAddress = End;
|
||||
this->Info.Type = Type;
|
||||
size_t FontDataLength = End - Start;
|
||||
|
||||
if (Type == FontType::PCScreenFont2)
|
||||
{
|
||||
this->Info.PSF2Font = new PSF2_FONT;
|
||||
|
||||
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(TO_PAGES(FontDataLength + 1));
|
||||
memcpy((void *)font2, Start, FontDataLength);
|
||||
|
||||
Memory::Virtual().Map((void *)font2, (void *)font2,
|
||||
FontDataLength, Memory::PTFlag::RW);
|
||||
|
||||
if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 ||
|
||||
font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3)
|
||||
{
|
||||
error("Font2 magic mismatch.");
|
||||
KernelAllocator.FreePages((void *)font2, TO_PAGES(FontDataLength + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
this->Info.PSF2Font->Header = font2;
|
||||
this->Info.PSF2Font->GlyphBuffer =
|
||||
r_cst(void *, r_cst(uintptr_t, Start) + sizeof(PSF2_HEADER));
|
||||
this->Info.Width = font2->width;
|
||||
this->Info.Height = font2->height;
|
||||
}
|
||||
else if (Type == FontType::PCScreenFont1)
|
||||
{
|
||||
this->Info.PSF1Font = new PSF1_FONT;
|
||||
PSF1_HEADER *font1 = (PSF1_HEADER *)Start;
|
||||
if (font1->magic[0] != PSF1_MAGIC0 || font1->magic[1] != PSF1_MAGIC1)
|
||||
error("Font1 magic mismatch.");
|
||||
uint32_t glyphBufferSize = font1->charsize * 256;
|
||||
if (font1->mode == 1) // 512 glyph mode
|
||||
glyphBufferSize = font1->charsize * 512;
|
||||
void *glyphBuffer =
|
||||
r_cst(void *, r_cst(uintptr_t, Start) + sizeof(PSF1_HEADER));
|
||||
this->Info.PSF1Font->Header = font1;
|
||||
this->Info.PSF1Font->GlyphBuffer = glyphBuffer;
|
||||
UNUSED(glyphBufferSize); // TODO: Use this in the future?
|
||||
|
||||
// TODO: Get font size.
|
||||
this->Info.Width = 16;
|
||||
this->Info.Height = 8;
|
||||
}
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user