github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/vbe/fb.go (about) 1 package vbe 2 3 import ( 4 "image" 5 "unsafe" 6 7 "github.com/icexin/eggos/drivers/multiboot" 8 "github.com/icexin/eggos/drivers/uart" 9 "github.com/icexin/eggos/kernel/mm" 10 ) 11 12 // framebufferInfo specifies the dimensions and DMA address of the VBE 13 // framebuffer. 14 type framebufferInfo struct { 15 // DMA address of the VBE framebuffer. 16 Addr uint64 17 // Pitch is the stride (in bytes) between vertically adjacent pixels. 18 Pitch uint32 19 // Width of frame buffer in pixels. 20 Width uint32 21 // Height of frame buffer in pixels. 22 Height uint32 23 } 24 25 var ( 26 // info specifies VBE framebuffer information. 27 info framebufferInfo 28 // buffer is an RGBA-buffer with the same pixel format and dimensions as 29 // fbbuf, used for double-buffering during rendering. 30 buffer []uint8 31 // fbbuf provides direct memory access to the VBE framebuffer. 32 fbbuf []uint8 33 34 // DefaultView is the default view used for rendering. 35 DefaultView *View 36 // currentView is the current view used for rendering. 37 currentView *View 38 ) 39 40 // bufcopy copies pixel data within the given rectangle from src to dst, based 41 // on the given stride and copy operation. 42 func bufcopy(dst, src []uint8, stride int, rect image.Rectangle, op func([]uint8, []uint8)) { 43 miny := rect.Min.Y 44 maxy := rect.Max.Y 45 minx := rect.Min.X * 4 46 maxx := rect.Max.X * 4 47 for j := miny; j < maxy; j++ { 48 srcline := src[j*stride : (j+1)*stride] 49 dstline := dst[j*stride : (j+1)*stride] 50 op(dstline[minx:maxx], srcline[minx:maxx]) 51 } 52 } 53 54 // SaveCurrView returns the current view. 55 func SaveCurrView() *View { 56 return currentView 57 } 58 59 // SetCurrView sets the current view, commiting pixel data to the framebuffer. 60 func SetCurrView(v *View) { 61 currentView = v 62 v.Commit() 63 } 64 65 // IsEnable reports whether the VBE framebuffer has been initialized. 66 func IsEnable() bool { 67 return fbbuf != nil 68 } 69 70 // Init initializes the VBE framebuffer based on the info data provided by 71 // multiboot. 72 func Init() { 73 bootInfo := &multiboot.BootInfo 74 if bootInfo.Flags&multiboot.FlagInfoVideoInfo == 0 { 75 uart.WriteString("[video] can't find video info from bootloader, video disabled\n") 76 return 77 } 78 if bootInfo.FramebufferType != 1 { 79 uart.WriteString("[video] framebuffer only support RGB color\n") 80 return 81 } 82 if bootInfo.FramebufferBPP != 32 { 83 uart.WriteString("[video] framebuffer only support 32 bit color\n") 84 return 85 } 86 87 info = framebufferInfo{ 88 Addr: bootInfo.FramebufferAddr, 89 Width: bootInfo.FramebufferWidth, 90 Height: bootInfo.FramebufferHeight, 91 Pitch: bootInfo.FramebufferPitch, 92 } 93 94 mm.SysFixedMmap(uintptr(info.Addr), uintptr(info.Addr), uintptr(info.Width*info.Height*4)) 95 fbbuf = (*[10 << 20]uint8)(unsafe.Pointer(uintptr(info.Addr)))[:info.Width*info.Height*4] 96 buffer = make([]uint8, len(fbbuf)) 97 DefaultView = NewView() 98 currentView = DefaultView 99 }