shithub: riscv

Download patch

ref: 99e004c72e5a95a37a5060d273c3c1ce99bed6ec
parent: 6aa6e9fc8b27850769899f23f4462c7eaf1da3d4
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Oct 18 14:48:56 EDT 2014

efi: convert pixel format to bootscreen color channel

--- a/sys/src/boot/efi/efi.c
+++ b/sys/src/boot/efi/efi.c
@@ -199,6 +199,87 @@
 	}
 }
 
+static int
+topbit(ulong mask)
+{
+	int bit;
+
+	for(bit=1; bit < 32 && (mask >> bit) != 0; bit++)
+		;
+	return bit;
+}
+
+static int
+lowbit(ulong mask)
+{
+	int bit;
+
+	for(bit=0; bit < 32 && (mask & (1<<bit)) == 0; bit++)
+		;
+	return bit;
+}
+
+static char*
+modeinfostr(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info, char *s)
+{
+	ulong mr, mg, mb, mx, mc;
+	int n, depth;
+
+	switch(info->PixelFormat){
+	default:
+		return nil;	/* unsupported */
+
+	case PixelRedGreenBlueReserved8BitPerColor:
+		mr = 0x000000ff;
+		mg = 0x0000ff00;
+		mb = 0x00ff0000;
+		mx = 0xff000000;
+		break;
+	case PixelBlueGreenRedReserved8BitPerColor:
+		mb = 0x000000ff;
+		mg = 0x0000ff00;
+		mr = 0x00ff0000;
+		mx = 0xff000000;
+		break;
+	case PixelBitMask:
+		mr = info->PixelInformation.RedMask;
+		mg = info->PixelInformation.GreenMask;
+		mb = info->PixelInformation.BlueMask;
+		mx = info->PixelInformation.ReservedMask;
+		break;
+	}
+
+	depth = topbit(mr | mg | mb | mx);
+
+	s = decfmt(s, 0, info->PixelsPerScanLine), *s++ = 'x';
+	s = decfmt(s, 0, info->VerticalResolution), *s++ = 'x';
+	s = decfmt(s, 0, depth), *s++ = ' ';
+
+	while(depth > 0){
+		if(depth == topbit(mr)){
+			mc = mr;
+			*s++ = 'r';
+		} else if(depth == topbit(mg)){
+			mc = mg;
+			*s++ = 'g';
+		} else if(depth == topbit(mb)){
+			mc = mb;
+			*s++ = 'b';
+		} else if(depth == topbit(mx)){
+			mc = mx;
+			*s++ = 'x';
+		} else {
+			break;
+		}
+		n = depth - lowbit(mc);
+		s = decfmt(s, 0, n);
+		depth -= n;
+	}
+	*s = '\0';
+
+	return s;
+}
+
 static void
 screenconf(char **cfg)
 {
@@ -210,14 +291,11 @@
 
 	s = *cfg;
 	memmove(s, "*bootscreen=", 12), s += 12;
-
-	s = decfmt(s, 0, gop->Mode->Info->PixelsPerScanLine), *s++ = 'x';
-	s = decfmt(s, 0, gop->Mode->Info->VerticalResolution), *s++ = 'x';
-	s = decfmt(s, 0, 32), *s++ = ' ';
-
-	memmove(s, "x8r8g8b8", 8), s += 8;
+	if((s = modeinfostr(gop->Mode->Info, s)) == nil){
+		**cfg = '\0';
+		return;
+	}
 	*s++ = ' ';
-
 	*s++ = '0', *s++ = 'x';
 	s = hexfmt(s, 0, gop->Mode->FrameBufferBase), *s++ = '\n';
 	*s = '\0';
@@ -224,18 +302,6 @@
 
 	print(*cfg);
 	*cfg = s;
-
-/*
-	Print(" Width="), Printi(gop->Mode->Info->HorizontalResolution), Print("\r\n");
-	Print(" Height="), Printi(gop->Mode->Info->VerticalResolution), Print("\r\n");
-	Print(" Stride="), Printi(gop->Mode->Info->PixelsPerScanLine), Print("\r\n");
-	Print(" PixelFormat="), Printi(gop->Mode->Info->PixelFormat), Print("\r\n");
-	Print(" RedMask="), Printi(gop->Mode->Info->PixelInformation.RedMask), Print("\r\n");
-	Print(" GreenMask="), Printi(gop->Mode->Info->PixelInformation.GreenMask), Print("\r\n");
-	Print(" BlueMask="), Printi(gop->Mode->Info->PixelInformation.BlueMask), Print("\r\n");
-	Print(" FrameBufferBase="), Printi(gop->Mode->FrameBufferBase), Print("\r\n");
-	Print(" FrameBufferSize="), Printi(gop->Mode->FrameBufferSize), Print("\r\n");
-*/
 }
 
 void
--- a/sys/src/boot/efi/efi.h
+++ b/sys/src/boot/efi/efi.h
@@ -48,6 +48,14 @@
 	UINT32		ReservedMask;
 } EFI_PIXEL_BITMASK;
 
+enum {
+	PixelRedGreenBlueReserved8BitPerColor,
+	PixelBlueGreenRedReserved8BitPerColor,
+	PixelBitMask,
+	PixelBltOnly,
+	PixelFormatMax,
+};
+
 typedef struct {
 	UINT32		Version;
 	UINT32		HorizontalResolution;