aboutsummaryrefslogtreecommitdiff
path: root/src/graphics/lfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/lfb.c')
-rw-r--r--src/graphics/lfb.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/graphics/lfb.c b/src/graphics/lfb.c
new file mode 100644
index 0000000..682f719
--- /dev/null
+++ b/src/graphics/lfb.c
@@ -0,0 +1,91 @@
+#include "../drivers/uart.h"
+#include "../graphics/mbox.h"
+#include "../graphics/homer.h"
+
+unsigned int width, height, pitch, isrgb; /* dimensions and channel order */
+unsigned char *lfb; /* raw frame buffer address */
+
+/**
+ * Set screen resolution to 1024x768
+ */
+void lfb_init()
+{
+ mbox[0] = 35*4;
+ mbox[1] = MBOX_REQUEST;
+
+ mbox[2] = 0x48003; //set phy wh
+ mbox[3] = 8;
+ mbox[4] = 8;
+ mbox[5] = 1024; //FrameBufferInfo.width
+ mbox[6] = 768; //FrameBufferInfo.height
+
+ mbox[7] = 0x48004; //set virt wh
+ mbox[8] = 8;
+ mbox[9] = 8;
+ mbox[10] = 1024; //FrameBufferInfo.virtual_width
+ mbox[11] = 768; //FrameBufferInfo.virtual_height
+
+ mbox[12] = 0x48009; //set virt offset
+ mbox[13] = 8;
+ mbox[14] = 8;
+ mbox[15] = 0; //FrameBufferInfo.x_offset
+ mbox[16] = 0; //FrameBufferInfo.y.offset
+
+ mbox[17] = 0x48005; //set depth
+ mbox[18] = 4;
+ mbox[19] = 4;
+ mbox[20] = 32; //FrameBufferInfo.depth
+
+ mbox[21] = 0x48006; //set pixel order
+ mbox[22] = 4;
+ mbox[23] = 4;
+ mbox[24] = 1; //RGB, not BGR preferably
+
+ mbox[25] = 0x40001; //get framebuffer, gets alignment on request
+ mbox[26] = 8;
+ mbox[27] = 8;
+ mbox[28] = 4096; //FrameBufferInfo.pointer
+ mbox[29] = 0; //FrameBufferInfo.size
+
+ mbox[30] = 0x40008; //get pitch
+ mbox[31] = 4;
+ mbox[32] = 4;
+ mbox[33] = 0; //FrameBufferInfo.pitch
+
+ mbox[34] = MBOX_TAG_LAST;
+
+ //this might not return exactly what we asked for, could be
+ //the closest supported resolution instead
+ if(mbox_call(MBOX_CH_PROP) && mbox[20]==32 && mbox[28]!=0) {
+ mbox[28]&=0x3FFFFFFF; //convert GPU address to ARM address
+ width=mbox[5]; //get actual physical width
+ height=mbox[6]; //get actual physical height
+ pitch=mbox[33]; //get number of bytes per line
+ isrgb=mbox[24]; //get the actual channel order
+ lfb=(void*)((unsigned long)mbox[28]);
+ } else {
+ uart_string("Unable to set screen resolution to 1024x768x32\n");
+ }
+}
+
+/**
+ * Show a picture
+ */
+void lfb_showpicture()
+{
+ unsigned int x,y;
+ unsigned char *ptr=lfb;
+ char *data=homer_data, pixel[4];
+
+ ptr += (height-homer_height)/2*pitch + (width-homer_width)*2;
+ for(y=0;y<homer_height;y++) {
+ for(x=0;x<homer_width;x++) {
+ HEADER_PIXEL(data, pixel);
+ // the image is in RGB. So if we have an RGB framebuffer, we can copy the pixels
+ // directly, but for BGR we must swap R (pixel[0]) and B (pixel[2]) channels.
+ *((unsigned int*)ptr)=isrgb ? *((unsigned int *)&pixel) : (unsigned int)(pixel[0]<<16 | pixel[1]<<8 | pixel[2]);
+ ptr+=4;
+ }
+ ptr+=pitch-homer_width*4;
+ }
+}