Seri Bedah Kode RezaOS — Bagian 4: Ekstraksi Metadata Grafis dan Manajemen Memori Video

Setelah berhasil memperoleh akses ke Graphics Output Protocol (GOP) pada bagian sebelumnya, langkah selanjutnya yang dilakukan oleh RezaOS adalah membaca properti teknis dari perangkat keras grafis tersebut. Data ini sangat vital karena tanpa mengetahui alamat memori video dan resolusi layar yang tepat, kode kita tidak akan bisa menggambar apa pun secara akurat.

Bagian ini akan membedah proses ekstraksi informasi dari struktur data GOP, memahami konsep pemetaan memori video, serta mengungkap rahasia di balik variabel PixelsPerScanLine.


1. Struktur Data GOP Mode

Dalam spesifikasi UEFI, informasi mengenai status grafik saat ini disimpan di dalam sebuah struktur bernama Gop->Mode. Struktur ini bertindak sebagai pusat informasi yang diperbarui secara otomatis oleh firmware. Kode kita mengakses data tersebut melalui baris-baris berikut:

// 2. Ambil Info Layar & Buffer
UINT32 *VideoBuffer = (UINT32*)(UINTN)Gop->Mode->FrameBufferBase;
UINT32 Width = Gop->Mode->Info->HorizontalResolution;
UINT32 Height = Gop->Mode->Info->VerticalResolution;
UINT32 PixelsPerScanLine = Gop->Mode->Info->PixelsPerScanLine;


2. Memahami VideoBuffer: Jendela ke Alamat Fisik

Baris pertama melakukan operasi yang sangat teknis:

UINT32 *VideoBuffer = (UINT32*)(UINTN)Gop->Mode->FrameBufferBase;

Analisis Teknis:

  • FrameBufferBase: Ini adalah alamat memori fisik (Physical Address) di mana kartu grafis memetakan piksel-piksel layar. Di alamat inilah data warna disimpan.
  • *Casting (UINTN) & (UINT32)**:
    • UINTN adalah tipe data integer yang lebarnya menyesuaikan dengan arsitektur CPU (64-bit pada sistem x64). Kita mengubah alamat dasar menjadi angka terlebih dahulu.
    • Kemudian, kita mengubahnya menjadi pointer UINT32*. Mengapa UINT32? Karena pada standar UEFI modern, setiap piksel diwakili oleh 32-bit (4 byte). Format yang umum digunakan adalah BGRR (8-bit Blue, 8-bit Green, 8-bit Red, dan 8-bit Reserved).
  • Linear Framebuffer: Dengan baris ini, kita telah mendapatkan akses langsung ke memori video. Menulis data ke alamat ini sama saja dengan mengubah warna di layar secara instan tanpa bantuan fungsi sistem apa pun.

3. Dimensi Layar: Horizontal vs Vertical Resolution

Dua baris berikutnya mengambil dimensi layar yang sedang aktif:

UINT32 Width = Gop->Mode->Info->HorizontalResolution;

UINT32 Height = Gop->Mode->Info->VerticalResolution;

UEFI secara otomatis mendeteksi resolusi terbaik (native) dari monitor Anda melalui protokol komunikasi EDID (Extended Display Identification Data). Jika layar Anda adalah Full HD, maka Width akan bernilai 1920 dan Height akan bernilai 1080. Data ini nantinya digunakan untuk membatasi area gambar agar kode tidak menulis data di luar batas memori yang disediakan (yang bisa menyebabkan sistem crash).


4. Teka-teki PixelsPerScanLine

Variabel terakhir sering kali membingungkan pengembang pemula:

UINT32 PixelsPerScanLine = Gop->Mode->Info->PixelsPerScanLine;

Banyak yang bertanya: “Bukankah PixelsPerScanLine nilainya sama dengan Width?”

Jawabannya: Belum tentu.

Analisis Teknis:

Dalam arsitektur hardware, memori video sering kali memiliki “padding” atau ruang kosong tambahan di akhir setiap baris untuk tujuan optimasi performa (alignment).

  • Width: Adalah jumlah piksel yang benar-benar terlihat di layar.
  • PixelsPerScanLine: Adalah jumlah piksel (termasuk ruang kosong tersembunyi) yang ada di satu baris memori fisik.

Jika kita hanya menggunakan Width untuk menghitung posisi baris berikutnya, gambar di layar mungkin akan terlihat miring atau hancur karena ada pergeseran memori (memory misalignment).


5. Rumus Matematika Penentuan Posisi Piksel

Dengan empat variabel di atas, kita kini memiliki semua bahan untuk membuat rumus pemetaan piksel. Karena memori bersifat linear (satu baris panjang), sedangkan layar bersifat dua dimensi (X dan Y), kita butuh rumus konversi:

Indeks_Piksel = (Koordinat_Y * PixelsPerScanLine) + Koordinat_X

Misalnya, jika Anda ingin mewarnai piksel pada baris ke-10 dan kolom ke-5:

  1. Kalikan koordinat Y (10) dengan lebar total memori per baris (PixelsPerScanLine).
  2. Tambahkan koordinat X (5).
  3. Hasilnya adalah lokasi urutan ke-berapa piksel tersebut di dalam array VideoBuffer.

Kesimpulan Bagian 4

Pada tahap ini, RezaOS sudah “melek” terhadap lingkungan fisiknya. Ia sudah tahu di mana alamat memori videonya, seberapa luas layarnya, dan bagaimana cara menghitung posisi piksel dengan akurat tanpa merusak tata letak memori. Fondasi ini mutlak diperlukan sebelum kita mengeksekusi perintah menggambar yang sebenarnya pada bagian-bagian selanjutnya.


Langkah Selanjutnya:

Pada bagian kelima, kita akan membedah logika iterasi untuk Mengisi Layar dengan Warna Hitam. Kita akan melihat bagaimana loop for bekerja sama dengan pointer memori untuk menciptakan tampilan yang bersih dan profesional.