UEFI Unable to write correctly to the screen with GOP buffer
Posted: Fri Aug 19, 2022 9:16 am
Hello, I have a problem that i don't know how to resolve. I'm trying to draw some icon to the screen using the BMP format in my UEFI boot loader using the base address of the GOP buffer. The problem is that the results are completely incoherent on a particular resolution (1366x768) my code is completely dynamic depending on the resolutions and work perfectly fine on other resolutions. Does anyone have an idea on what the problem could be?
Code: Select all
VOID RenderBitmapImage(IN GRAPHICS_INFO* GraphicsInfo, IN BITMAP_IMAGE* Image, UINT32 x, UINT32 y) {
// Some pointer verifications to prevent any fault
if (GraphicsInfo == NULL)
return;
if (Image == NULL)
return;
if (Image->Header == NULL || Image->Info == NULL || Image->PixelData == NULL)
return;
// Check if x and y are in the buffer
if (x > GraphicsInfo->PixelsPerScanLine)
return;
if (y > GraphicsInfo->VerticalResolution)
return;
// Safer and easier to use typed pointers
BITMAP_PIXEL_DATA_32BPP* ImagePixelData = (BITMAP_PIXEL_DATA_32BPP*)Image->PixelData;
UINT8* FrameBufferAddr = (UINT8*)GraphicsInfo->BufferBaseAddress;
UINT8* FremeBufferMaxAddr =FrameBufferAddr + GraphicsInfo->BufferSize;
//Offsetting address at the x and y position
//Don't be confused it's only algebraic distribution of PixelSize
FrameBufferAddr += GraphicsInfo->PixelSize * (x + (y * GraphicsInfo->PixelsPerScanLine));
//Offsetting address so the image is drawn from bottom to top
FrameBufferAddr += Image->Info->Height * GraphicsInfo->PixelsPerScanLine * GraphicsInfo->PixelSize;
//Use of local variable to enhance performances
UINT8 PixelFormat = GraphicsInfo->PixelFormat;
// for each line of pixels in the image, every pixel in the line is converted to the correct PixelFormat and drawn to the screen
for (UINT32 h = 0; h < Image->Info->Height; h++) {
for (UINT32 w = 0; w < Image->Info->Width; w++, ImagePixelData++, FrameBufferAddr += GraphicsInfo->PixelSize) {
if (FrameBufferAddr > FremeBufferMaxAddr) {
break;
}
if (PixelFormat == 1) { // Format is RedGreenBlueReserved 8bit per color
PIXEL_32BPP_RGBReserved* FrameBufferPixelData = (PIXEL_32BPP_RGBReserved*)FrameBufferAddr;
FrameBufferPixelData->Red = ImagePixelData->Red;
FrameBufferPixelData->Green = ImagePixelData->Green;
FrameBufferPixelData->Blue = ImagePixelData->Blue;
} else if (PixelFormat == 2) { // Format is BlueGreenRedReserved 8bit per color
PIXEL_32BPP_BGRReserved* FrameBufferPixelData = (PIXEL_32BPP_BGRReserved*)FrameBufferAddr;
FrameBufferPixelData->Red = ImagePixelData->Red;
FrameBufferPixelData->Green = ImagePixelData->Green;
FrameBufferPixelData->Blue = ImagePixelData->Blue;
}
}
FrameBufferAddr -= Image->Info->Width * GraphicsInfo->PixelSize;
FrameBufferAddr -= GraphicsInfo->PixelsPerScanLine * GraphicsInfo->PixelSize;
}