View Single Post
Posts: 88 | Thanked: 411 times | Joined on Mar 2010 @ southern Italy
#7
N900 framebuffer memory map it's a bit weird.

cat /dev/fb0 outputs 1966080 bytes, that is 480 scanlines * 4096 bytes.

Only the first 1600 bytes (800 pixels, 16 bits each) are relevant; the following bytes overflow on next scanlines (that is: only 800*480*2=768000 bytes are the actual display image; the remaining 1198080 bytes are wasted duplicates).

Also, the /dev/fb0 format is 5-6-5 (5 bits red, 6 bits green, 5 bits blue), but is packed as 5-5-6 in big-endian (that is: first byte is bbbbbrrr, second byte is rrgggggg: green is in the 6 less significant bits of the 16-bit pixel value, blue is in the 5 high significant bits of the 16-bit pixel).

The following Ruby program fills the screen by only writing on /dev/fb0 (note: any video-related event causing Xorg refresh will redraw screen areas).
Code:
#!/usr/bin/env ruby

def rgb565 r, g, b
  r >>= 3    # shift to skip unused bits
  g >>= 2
  b >>= 3
  [ (r<<6) | g | (b<<11) ].pack('n')  # build & pack to 16 bits
end

samples = [ rgb565(255,0,0), rgb565(0,255,0), rgb565(0,0,255),
            rgb565(50,0,0), rgb565(0,50,0), rgb565(0,0,50),
            rgb565(0,255,255), rgb565(255,255,0) ]

File.open("/dev/fb0", "w") do |fp|    # open framebuffer for write
  480.times do |sl|                   # for every scanline:
    fp.seek sl*4096                   # update framebuffer pointer
    samples.each do |color|           # eight color samples:
      100.times { fp.write color }    # 100 pixels wide column
    end
  end
end
 

The Following 3 Users Say Thank You to alfmar For This Useful Post: