GOP: Difference between revisions

330 bytes added ,  3 years ago
m
minor fixups
[unchecked revision][unchecked revision]
m (minor fixups)
Line 1:
This is the new standard for UEFI that superseded [[VESA]] (BIOS) and UGA (EFI 1.0).
 
== GraphicGraphics Output Protocol ==
It has basicly the same functions as VESA, you can query the modes, set the modes. You also have an efficient BitBlitter function, which you can't use from your OS unfortunately. GOP is an EFI Boot Time Service, meaning you can't access it after you call ExitBootServices().
 
Line 16:
PrintLn(L"Unable to locate GOP");
</source>
GOP is the default protocol, so you should be able to locate it on all UEFI firmware. It can probably only fail if you're on an old EFI (pre-UEFI) machine, like and old iMac or intel Macbook perhaps.
 
=== Get the Current Mode ===
In order to get the mode code for the current video mode, you must set the mode firstas well to circumvent some buggy UEFI firmware. ThisOtherwise this is done using the QueryMode function, and then gop->Mode->Mode will contain the code (this is a perfect example how badly designed UEFI is. Look: gop->Mode is a struct, while gop->Mode->Mode is a UINTN)., Seeyet exactly the QueryModesame example belowname).
 
=== Query Available Video Modes ===
Similarly to VESA, there's no standard mode codes, rather you have a function to query the available modes with video card specific mode codes.
<source lang="c">
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
Line 32 ⟶ 30:
if(EFI_ERROR(status)) {
PrintLn(L"Unable to get native mode");
} else {
return status;
nativeMode = gop->Mode->Mode;
numModes = gop->Mode->MaxMode;
}
nativeMode = gop->Mode->Mode;
numModes = gop->Mode->MaxMode;
</source>
 
Now you know how many modes there are, and which one is currently set. You can iterate on the modes and query the information structure for each:
=== Query Available Video Modes ===
Similarly to VESA, there's no standard mode codes, rather you have a function to query the available modes. Now you know how many modes there are (numModes above), and which one is currently set (nativeMode). You can iterate on the modes and query the information structure for each:
<source lang="c">
for (i = 0; i < numModes; i++) {
Line 57:
if(EFI_ERROR(status)) {
PrintLn(L"Unable to set mode %03d", mode);
} else {
return status;
// get framebuffer
PrintLn(L"Framebuffer address %x size %d, width %d height %d pixelperlinepixelsperline %d",
gop->Mode->FrameBufferBase,
gop->Mode->FrameBufferSize,
gop->Mode->Info->HorizontalResolution,
gop->Mode->Info->VerticalResolution,
gop->Mode->Info->PixelsPerScanLine
);
}
// get framebuffer
PrintLn(L"Framebuffer address %x size %d, width %d height %d pixelperline %d",
gop->Mode->FrameBufferBase,
gop->Mode->FrameBufferSize,
gop->Mode->Info->HorizontalResolution,
gop->Mode->Info->VerticalResolution,
gop->Mode->Info->PixelsPerScanLine
);
</source>
To get the same value as scanline in VESA (also called commonly pitch in many graphics libraries), you have to multiply PixelsPerScanLine by the number of bytes per pixel. That can be detected by examining the gop->Mode->Info->PixelFormat field. For example with 32 bit packed pixel formats,
Line 75:
=== Plotting Pixels ===
{{Main|Drawing In Protected Mode}}
Now you can use the returned framebuffer exactly the same way as you would with VESA, there's absolutely no difference.
To calculate the offset for an (X,Y) coordinate on screen, do pitch*Y+pixelbytes*X. For example for 32 bit true-color (where pixelbytes is 4):
<source lang="c">
static inline void PlotPixel_32bpp(int x, int y, uint32_t pixel)
Line 83:
}
</source>
For drawing characters, you can use the same method described in [[VGA Fonts]].
 
=== Don't Read From Video Memory ===
 
Reading from the video memory is slooow! Use [[Double Buffering|double buffering]] instead.
 
Anonymous user