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  }