Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Readers > Amazon Kindle > Kindle Developer's Corner

Notices

Reply
 
Thread Tools Search this Thread
Old 04-22-2012, 02:27 PM   #31
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
UPDATE 2: Another complication... When I copy a raw 600x800 image to the framebuffer with dd, which was saved from a JPG image using IrfanView, it displays CORRECTLY on my K5(touch) using this command:
PHP Code:
for i in $(seq 0 1 799);do dd if=barn.raw of=/dev/fb0 bs=1 count=600 skip=$((i*600)) seek=$((i*608)) 2>/dev/null;done;eips '' 
When I write to the framebuffer with a C program, although the framebuffer contains an 8-bit image that I can copy out and view, the eink screen only shows 16 colors. The only possible explanation I have is that perhaps this image is only USING 16 colors and is already dithered from 256 to 16 colors. Hmm...

UPDATE 3: Okay, I just ran the "hoser" demo below, then I used the above command copying from /tmp/wbo instead of from barn.raw, and the result was ONLY 16 COLORS on the eink display (even though the original was a full color JPEG, and it was converted directly to 8-bit grayscale with IrfanView). That means that IrfanView MUST HAVE dithered it down to 16-colors even though I selected 256 color. The wb0 screenshot below shows that it really does contain 256 different shades of gray when viewed on a CRT/LCD display. Hmm... Does this really need to be this complicated?
I just loaded barn.raw into Irfanview and did its histogram function -- 16 spikes showing it only has 16 colors. Hmm... But it looks pretty darned good for 16 colors (amazing how well dithering works when you have tiny little pixels like on these eink displays).


To test K4(mini) and K5(touch) 8-bit framebuffers, I just changed my paldemo program to put the 0-255 color values directly into the framebuffer, and although a SCREENSHOT of the resulting framebuffer shows all 256 shades of gray, the eink display only show 16 shades of gray.

Worse, they are not balanced: values 0-17 display as pure black, but ONLY value 255 displays as pure white.

And what is VERY STRANGE, by viewing the eink screen in a bright light with magnification, you can CLEARLY see that those shades of gray are created by the eink drivers with an ordered dither between two adjacent shades of 4-bit gray.

Now that really begs the question: IF the kindle hardware can only do 16 shades of gray AND the eink drivers use an ordered dither to get JUST THE RIGHT shade of gray, then WHY did they not just dither ALL 256 shades of gray?

This lack of REAL 8-bit support astounds and befuddles me.

Here is a screenshot copied from the framebuffer, and a photo of the K5(Touch) eink display (differences are most visible on the bottom "white" row due to CRT/LCD display gamma):

Spoiler:
Screenshot copied from /dev/fb0 (all 256 grays visible):



Photo of K5(Touch) eink screen (only 16 grays visible):

What you cannot see in the photo shown above is that those 16-shades of gray in the photo use an ordered dither to get those exact shades of gray, so why not dither to 256 shades of gray? What you CAN see is noisy interference between the eink dither pattern and JPEG encoding.

Now it looks like we have to dither to get 256 shades of gray ourselves, but that gives a complication of the eink drivers dithering our dithered output, which can cause nasty Moiré pattern interference where it is NOT WANTED (unlike the spoxbrane and cosmegg demos where it IS wanted ).

This will be quite complicated to work around two layers of dithering. Not nice!

EDIT: Because each of the 16 driver shades of gray is made from two adjacent hardware shades of gray, if we dither two of those "driver grays", our dither interference pattern will contain THREE hardware shades of gray.

UPDATE: I just tested this on a K4 booted from main (with the old eink drivers). It acts differently from a K3 and from a K5 (not unexpected). Each line of the displayed palette is a solid color, so the color quantizing is balanced, but it has ANOTHER problem. The rows for 4-bit colors 11 and 12 are identical, so it can only do 15 shades of gray, not 16. However, I see no dithering, so it appears to be using the shades of gray provided directly by the hardware, with no color or gamma correction like the newer eink drivers appear to be doing. The K4 also displays the palette "upside down" with the whites at the top (values 0-15) and the blacks at the bottom (values 240-255). This just keeps getting more "interesting". Normally, these details are hidden from us inside eips and the Xorg color management layers. Direct hardware access (or at lease low-level framebuffer access) often has these complications, but there is real personal satisfaction obtained by overcoming them.


Last edited by geekmaster; 04-23-2012 at 09:39 PM.
geekmaster is offline   Reply With Quote
Old 04-23-2012, 12:59 PM   #32
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
hoser-2.0 - eink demo, all-new dither, K3 speed++

MAJOR UPDATE:This version adds the eink update method used in sparkle-1.0 (which is WHY it was so fast). On a K3 there is such a HUGE speed increase, it deserved a major version number upgrade. K3 owners - rejoice!

All new eink dither routines based on total redesign to support hybrid K4 main boot eink mode (K3 eink drivers but 8-bit framebuffer). These dither routines are optimized to dither an entire framebuffer (not just a moving object), so every time you see any movement on the display, that was just the result of an entire screen of dithered pixels being created from the image in /tmp/wb0.

This demo runs full throttle with no delays, so it shows some eink artifacts ("ball in tube" after-images on newer kindles), but it is an interesting effect. The older "non-Pearl" eink display on the DX shows a DIFFERENT "ball in tube" artifact that leaves a white spot ghosted on the surface of the hoses (caused by a sudden black-to-white transition). The speed of this demo is limited ONLY by the system eink update logic. The dither routines can go a lot faster than the eink display.

EDIT: The K5(touch) is MUCH faster than the K4(booted from main), and the K3 is much slower than the K4 (UPDATE: hoser-2.0 runs about the same speed on the K3 and K4), and the DX is even slower than that. You really should see it hustle on the K5(touch).


This program writes all updates to an 8-bit virtual framebuffer using 256 shades of gray. While it is running, you can use dd to copy 256-color screenshots from /tmp/wb0, or you can copy dither screenshots from /dev/fb0. The virtual framebuffer (wb0 work buffer) is updated as fast as the program can fill it, but this will be speed-limited in future code.

The screenshots:
Spoiler:

Hoser /dev/fb0:


Hoser /tmp/wb0:

The source code:
Spoiler:
PHP Code:
//====================================================
// hoser 2.0 - eink demo with all-new dither design
// (yet another "dithermation" demo by geekmaster)
// Copyright (C) 2012 by geekmaster, with MIT license:
// http://www.opensource.org/licenses/mit-license.php
//----------------------------------------------------
// This version adds the eink update method used in
// sparkle-1.0 (which is WHY it was so fast). On a K3
// there is such a HUGE speed increase, it deserved a
// major version number upgrade. K3 owners - rejoice!
// This was tested on DX,DXG,K3,K4(Mini),K5(Touch).
//----------------------------------------------------

#include <stdio.h>      // printf
#include <stdlib.h>    // malloc, free
#include <string.h>   // memset, memcpy
#include <unistd.h>  // usleep
#include <fcntl.h>  // open, close, write
#include <time.h>  // time
#include <sys/mman.h>   // mmap, munmap
#include <sys/ioctl.h> // ioctl
#include <linux/fb.h> // screeninfo

#define FBIO_EINK_UPDATE_DISPLAY_AREA 0x46dd
enum GMLIB_op GMLIB_INIT,GMLIB_CLOSE,GMLIB_UPDATE };
typedef unsigned char u8;
typedef unsigned int u32;
    
// function prototypes
void circle(int,int,int);
int gmlib(int);
inline void setpx(int,int,int);
void d4w(void);
void d8w(void);
void d8b(void);

// gmlib global vars
static u8 dt[64] = {
    
3,129,34,160,10,136,42,168,192,66,223,97,200,73,231,105,50,
    
176,18,144,58,184,26,152,239,113,207,81,247,121,215,89,14,
    
140,46,180,7,133,38,164,203,77,235,109,196,70,227,101,62,188,
    
30,156,54,180,22,148,251,125,219,93,243,117,211,85 }; // 0-255 dither table
u8 *fb0=NULL;       // framebuffer pointer
u8 *wb=NULL;       // workbuffer pointer
u32 mpu=100;      // msec/update
int fdFB=0;      // fb0 file descriptor
int fdWB=0;     // wb file descriptor
u32 fs=0;      // fb0 stride
u32 MX=0;     // xres (visible)
u32 MY=0;    // yres (visible)
u8 blk=0;   // black
u8 msk=0;  // black mask
u8 ppb=0// pixels per byte

//===============================================
// hoser - eink demo showing all-new dither design
// This works on all kindle eink models.   Enjoy!
//-----------------------------------------------
void hoser(void) {
    
u32 x,y,c,px1,py1,vx1,vy1,dx,dy,cc,cu,cl;
    
gmlib(GMLIB_INIT);      // init geekmaster functions
    
c=0,px1=MX/2,py1=MY/2,vx1=1,vy1=5,cc=31,cl=16;
    for (
cu=0;cu<20000;cu++) {
        if (
0==cu%3000) { // periodic background display
          
for (y=0y<=MY/2y++) for (x=0x<=MX/2x++) {
            
dx=MX/2-xdy=MY/2-yc=255-(dx*dx+dy*dy)*255/(MX*220);
            
setpx(x,y,c); setpx(MX-x,y,c);
            
setpx(x,MY-y,c); setpx(MX-x,MY-y,c);
          }
        }
        
circle(px1,py1,30); circle(px1,py1,31); circle(px1,py1,32);
        
circle(px1,py1,29); circle(px1,py1,28); circle(px1,py1,27);
        
circle(px1,py1,26); circle(px1,py1,25); circle(px1,py1,24);
        
circle(px1,py1,23); circle(px1,py1,22); circle(px1,py1,21);
        
circle(px1,py1,20); circle(px1,py1,19); circle(px1,py1,18);
        
circle(px1,py1,17); circle(px1,py1,16); circle(px1,py1,15);
        
circle(px1,py1,14); circle(px1,py1,13); circle(px1,py1,12);
        
px1+=vx1py1+=vy1;
        if (
px1>MX-40 || px1<40vx1=-vx1;
        if (
py1<40) { py1=40vy1=-vy1; }
        if (
py1>MY-40) { py1=MY-40vy1=-vy1; }
        if (
0==cu%cl) { vy1++;
            
gmlib(GMLIB_UPDATE); // update display
        
}
        
cc=(cc+4)%256// cycle big box color
    
}

// cleanup - close and free resources
    
gmlib(GMLIB_CLOSE); // close geekmaster functions
}

//====================================
// gmlib - geekmaster function library
// op (init, update, close)
//------------------------------------
int gmlib(int op) {
    
struct update_area_t int x1,y1,x2,y2,fxu8 *buffer; } ua;
    
struct fb_var_screeninfo screeninfo;
    static 
int fdUpdate=-1;
    if (
GMLIB_INIT==op) {
        
fdWB=open("/tmp/wb0",O_RDWR|O_CREAT); // work framebuffer
        
fdFB=open("/dev/fb0",O_RDWR);        // eink framebuffer
        
ioctl(fdFB,FBIOGET_VSCREENINFO,&screeninfo);
        
ppb=8/screeninfo.bits_per_pixel// pixels per byte
        
fs=screeninfo.xres_virtual/ppb// fb0 stride
        
blk=screeninfo.rotate-1;       // black
        
MX=screeninfo.xres;           // max X+1
        
MY=screeninfo.yres;          // max Y+1
        
msk=1/ppb-1;                // black mask (4-bit=255,8-bit=0)
        
fb0=(u8 *)mmap(0,MY*fs,PROT_READ|PROT_WRITE,MAP_SHARED,fdFB,0); // map fb0
        
lseek(fdWB,MY*MX-1,SEEK_SET); write(fdWB,"",1); // create work buffer file
        
wb=(u8 *)mmap(0,MY*MX,PROT_READ|PROT_WRITE,MAP_SHARED,fdWB,0); // map wb
        
fdUpdate=open("/proc/eink_fb/update_display",O_WRONLY);
    } else if (
GMLIB_CLOSE==op) {
        
gmlib(GMLIB_UPDATE); // update display
        
munmap(fb0,MY*fs);  // unmap fb0
        
munmap(wb,MY*MX);  // unmap wb
        
close(fdUpdate);  // close update proc
        
close(fdFB);     // close fb0
        
close(fdWB);    // close wb
    
} else if (GMLIB_UPDATE==op) {
        if (
ppb/2) { d4w();
            
ua.x1=0ua.y1=0ua.x2=MXua.y2=MYua.fx=0ua.buffer=NULL;
            
ioctl(fdFBFBIO_EINK_UPDATE_DISPLAY_AREA, &ua); // fx_update_partial
        
}
        else if (
blk) { d8w(); write(fdUpdate,"1\n",2); }
        else { 
d8b(); system("eips ''");  }
    } else { return -
1; }
    return 
fdUpdate;
}

//========================================
// setpx - draw pixel to 8-bit work buffer
// x,y:screen coordinates, c:color(0-255).
//----------------------------------------
inline void setpx(int x,int y,int c) {
    
wb[y*MX+x]=c;
}

//===========================
// d8b - dither 8-bit black 0
//---------------------------
void d8b(void) {
    
u8 *pi,*point x,y;
    
pi=wbpo=fb0;
    for (
y=0;y<MY;y++) {
        for (
x=0;x<MX;x++) { *po++=dt[(y&7)*8|x&7]-*pi++>>8; }
        
po+=(fs-MX);
    }
}

//===========================
// d8w - dither 8-bit white 0
//---------------------------
void d8w(void) {
    
u8 *pi,*point x,y;
    
pi=wbpo=fb0;
    for (
y=0;y<MY;y++) {
        for (
x=0;x<MX;x++) { *po++=~(dt[(y&7)*8|x&7]-*pi++>>8); }
        
po+=(fs-MX);
    }
}

//===========================
// d4w - dither 4-bit white 0
//---------------------------
void d4w(void) {
    
u8 *pi,*point x,y,ys;
    
pi=wbpo=fb0;
    for (
y=0;y<MY;y++) { ys=(y&7)*8;
        for (
x=0;x<MX;x+=8) {
             *
po++=(~(dt[ys]-*pi++>>8)|15)&(~(dt[ys+1]-*pi++>>8)|240);
             *
po++=(~(dt[ys+2]-*pi++>>8)|15)&(~(dt[ys+3]-*pi++>>8)|240);
             *
po++=(~(dt[ys+4]-*pi++>>8)|15)&(~(dt[ys+5]-*pi++>>8)|240);
             *
po++=(~(dt[ys+6]-*pi++>>8)|15)&(~(dt[ys+7]-*pi++>>8)|240);
        }
    }
}

//==============================================
// circle - optimized midpoint circle algorithm
//----------------------------------------------
void circle(int cx,int cy,int r) {
    
int e=-r,x=r,y=0;
    while (
x>y) {
        
setpx(cx+y,cy-x,255); setpx(cx+x,cy-y,159);
        
setpx(cx+x,cy+y,95); setpx(cx+y,cy+x,31);
        
setpx(cx-y,cy+x,0); setpx(cx-x,cy+y,63);
        
setpx(cx-x,cy-y,127); setpx(cx-y,cy-x,191);
        
e+=yy++; e+=y;
        if (
e>0) { e-=xx-=1e-=x; }
    }
}

//==================
// main - start here
//------------------
int main(int argc,char **argv) {
    if (
argc>1) { mpu=atoi(argv[1]); }
    
hoser(); // do the hoser demo :D
    
return 0;


Enjoy and learn!

EDIT: This demo really needs to be viewed on a K5(Touch) to appreciate the speed of my new dither routines. Somebody should post a youtube video showing it running on a K5. I will give a bunch karma points for a youtube link.

NOTE: I just realized that the gmlib CLOSE function should probably delete the workbuffer file from RAMdisk (rm /tmp/wb0). It is consuming nearly 1MB of RAM on a 1200x824 DX or DXG, and they only have 128MB of RAM. Newer kindles use a smaller workbuffer and have more RAM, so not much of a problem. Oh well, the next version will do that if I do not forget... ...But if the hoser program *had* deleted that file, then I would not have been able to get that "last frame" screenshot shown in the screenshots spoiler above. I could have gotten an "in progress" image while it was running though.

EDIT: I just decided to give you a little bonus golden nugget of knowledge. I will let you in on a "little secret" about how I derived such simple dither logic formulas that work for all eink kindles including the weird hybrid K4 main boot mode. The "magic sauce" has TWO names: Karnaugh Maps, and DeMorgan's Theorems (and a weekend of intense perseverence and little sleep).


Attached Files
File Type: gz hoser-1.0.tar.gz (9.0 KB, 207 views)
File Type: gz hoser-2.0.tar.gz (8.7 KB, 242 views)

Last edited by geekmaster; 04-24-2012 at 02:22 AM.
geekmaster is offline   Reply With Quote
Advert
Old 04-23-2012, 04:50 PM   #33
jmseight
Zealot
jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'
 
Posts: 130
Karma: 10000
Join Date: Mar 2012
Device: Kindle 3G, Kindle Touch 3G, iRiver Story HD, Sony Reader
Hi,

This looks really cool. I only have K3 but it is pretty fast.

So the speed is completely limited by full screen update, correct?

Now you can play videos easily if you put successive frames in the image buffer, correct?

Thanks,
James
jmseight is offline   Reply With Quote
Old 04-23-2012, 04:53 PM   #34
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Perhaps the reason that I like dithered eink images is that I am a big fan of charcoal drawings on textured paper. That is my favorite artistic medium, closely followed by eink.
geekmaster is offline   Reply With Quote
Old 04-23-2012, 05:03 PM   #35
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by jmseight View Post
Hi,

This looks really cool. I only have K3 but it is pretty fast.

So the speed is completely limited by full screen update, correct?

Now you can play videos easily if you put successive frames in the image buffer, correct?

Thanks,
James
Yes. We can dither the images MANY time faster than the K3 can return from writing to the update port, or calling eips. But the K3 is capable of faster updates using ioctl() calls, if you limit the "active" part of the screen to a smaller area.

I got about 5 FPS fullscreen, or 12 FPS updating only a 640x360 rectangle (the size of old DivX movies). For "talking heads" video (mostly dialog, like TV talk shows), you just need to update mostly the face area at high speed.

Also, you can pre-filter the video to smooth any changes in time and space (averaging successive frames in a "long persistence" way), and other video filter tricks such as "deshaking". That makes it a LOT more eink-friendly. The key is to minimize (or ignore) unimportant changing areas on the screen, so the eink drivers do not fall behind the video causing nasty (self-correcting over time) display artifacts.

On the K5, you can update as fast as you want, but if you do it too fast the eink drivers can just shut down for your process (white screen). Opening another SSH session and doing eips '' commands shows that the framebuffer is changing, because the NEW process still gets eink requests honored.

It appears that the eink drivers detect "abusive" eink updates and start ignoring requests from that process. So we need to add delays before eink update requests, in some cases.

Last edited by geekmaster; 11-25-2012 at 11:01 PM.
geekmaster is offline   Reply With Quote
Advert
Old 04-24-2012, 12:01 AM   #36
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow sparkle 2.0 - geekmaster's FIRST kindle program! (updated)

UPDATE: The demo kernel from the original sparkle-1.0 was added to the "dithermation" framework used by other demos in this thread. Now it works on all the eink kindles! On the K4(touch) the trail of ghosts is as long as on the old DX (but moving much faster).

Here we have a little piece of geekmaster history, dusted off and polished up a bit (a bunch of commented-out code removed). It is relevant now because it broke the bounds of what many still believe is even possible on a Kindle 3. Check out the frame rate.

This program was created in 2011 November, when geekmaster got his first kindle. It was his first kindle program (after the traditional "Hello World!" program to test the build tools). It formed the basis of his eink opinions expressed in mobileread forums since the beginning.

This demo uses spatiotemporal random dithering. The "temporal" aspect appears as "sparkle" on the eink display.

This method was abandoned for displaying live video because of significant display artifacts, which are very interesting from an "eye candy" point of view, so it is being presented for public viewing here and now.

This predates the newer kindles with 8-bit framebuffers (K4 and K5), but it works great on the DX, DXG, and K3. UPDATE: the "new and improved" version 2.0 now supports ALL eink kindles!

The interesting effect here is that on newer Pearl eink displays, the moving objects have a "snake-like" trail of alternating light and dark ghosts following them, taking two seconds to fade out. On the DX with the older eink technology, the trail of alternating fading ghosts gets so long it occupies much of the display, making a rather dazzling (but unintended) visual effect.

sparkle-2.0 source code:
Spoiler:
PHP Code:
//====================================================
// sparkle 2.0 - animation demo for all eink kindles
// Copyright (C) 2012 by geekmaster, with MIT license:
// http://www.opensource.org/licenses/mit-license.php
//----------------------------------------------------
// This demo contains the code kernel of sparkle 1.0
// This was tested on DX,DXG,K3,K4(Mini),K5(Touch).
//----------------------------------------------------

#include <stdio.h>      // printf
#include <stdlib.h>    // malloc, free
#include <string.h>   // memset, memcpy
#include <unistd.h>  // usleep
#include <fcntl.h>  // open, close, write
#include <time.h>  // time
#include <sys/mman.h>   // mmap, munmap
#include <sys/ioctl.h> // ioctl
#include <linux/fb.h> // screeninfo

#define FBIO_EINK_UPDATE_DISPLAY_AREA 0x46dd
enum GMLIB_op GMLIB_INIT,GMLIB_CLOSE,GMLIB_UPDATE };
typedef unsigned char u8;
typedef unsigned int u32;

// function prototypes
void circle(int,int,int);
int gmlib(int);
inline void setpx(int,int,int);
void d4w(void);
void d8w(void);
void d8b(void);

// gmlib global vars
static u8 dt[64] = {
    
3,129,34,160,10,136,42,168,192,66,223,97,200,73,231,105,50,
    
176,18,144,58,184,26,152,239,113,207,81,247,121,215,89,14,
    
140,46,180,7,133,38,164,203,77,235,109,196,70,227,101,62,188,
    
30,156,54,180,22,148,251,125,219,93,243,117,211,85 }; // 0-255 dither table
u8 *pbuff=NULL;      // screensave pointer
u8 *fb0=NULL;       // framebuffer pointer
u8 *wb=NULL;       // workbuffer pointer
u32 mpu=100;      // msec/update
int fdFB=0;      // fb0 file descriptor
int fdWB=0;     // wb file descriptor
u32 fs=0;      // fb0 stride
u32 MX=0;     // xres (visible)
u32 MY=0;    // yres (visible)
u8 blk=0;   // black
u8 msk=0;  // black mask
u8 ppb=0// pixels per byte

//===============================================
// hoser - eink demo showing all-new dither design
// This works on all kindle eink models.   Enjoy!
//-----------------------------------------------
void hoser(void) {
    
u32 x,y,c,px1,py1,vx1,vy1,dx,dy,cc,cu,cl;
    
int i,j,n,d,wbytes,wb2,fdin,wdin,rc,once=0;
    
__u8 *start,*end,*half,*pbyte,*psave,*pln;

    
gmlib(GMLIB_INIT);      // init geekmaster functions

    // save original screen
    
pbuff=fb0psave=malloc(wbytes*MY); memcpy(psave,fb0,wbytes*MY);
    
start=pbuff+wbytes*40half=pbuff+wbytes*(MY/2); end=pbuff+wbytes*(MY-33);

    
int yoff=40,xoff=60,bbx=xoff+10,bby=50,bbvx=7,bbvy=3;
    
int wbx=xoff+480-80,wby=200,wbvx=-6,wbvy=-4;

    for (
y=0;y<240;y++) for (x=0;x<480;x++) setpx(x+xoff,y+yoff,255);

    for (
i=0;i<800;i++) {

//### fill screen with grays
        
for (y=0;y<80;y++) for (x=0;x<480;x++) {
            if (
rand()%480<x/2setpx(x+xoff,y+yoff,0); else setpx(x+xoff,y+yoff,255);
        }
        for (
y=80;y<160;y++) for (x=0;x<480;x++) {
            if (
rand()%480<x/2setpx(x+xoff,y+yoff,0); else setpx(x+xoff,y+yoff,255);
        }
        for (
y=160;y<240;y++) for (x=0;x<480;x++) {
            if (
rand()%480>xsetpx(x+xoff,y+yoff,0); else setpx(x+xoff,y+yoff,255);
        }
        if (!
once) { once=1;
            
gmlib(GMLIB_UPDATE); // update display
        
}

//### black box
        
for (y=bby;y<bby+33;y++) for (x=bbx;x<bbx+100;x++) setpx(x,y,0);
        for (
y=bby+33;y<bby+66;y++) {
            for (
x=bbx;x<bbx+33;x++) setpx(x,y,0);
            for (
x=bbx+66;x<bbx+100;x++) setpx(x,y,0);
        }
        for (
y=bby+66;y<bby+100;y++) for (x=bbx;x<bbx+100;x++) setpx(x,y,0);

//### white box
        
for (y=wby;y<wby+25;y++) for (x=wbx;x<wbx+25;x++) setpx(x,y,255);

//### animate
        
bbx += bbvxbby += bbvywbx += wbvxwby += wbvy;
        if (
bbx>xoff+380) { bbx=xoff+380bbvx=-bbvx; }
        if (
bbx<xoff) { bbx=xoffbbvx=-bbvx; }
        if (
bby>140+yoff) { bby=140+yoffbbvy=-bbvy; }
        if (
bby<40) { bby=40bbvy=-bbvy; }
        if (
wbx>xoff+405) { wbx=xoff+405wbvx=-wbvx; }
        if (
wbx<xoff) { wbx=xoffwbvx=-wbvx; }
        if (
wby>215+yoff) { wby=215+yoffwbvy=-wbvy; }
        if (
wby<40) { wby=40wbvy=-wbvy; }
        
gmlib(GMLIB_UPDATE); // update display
    
}

// cleanup - close and free resources
    
memcpy(fb0,psave,wbytes*MY); // restore display
    
gmlib(GMLIB_CLOSE); // close geekmaster functions
    
free (psave);
}

//====================================
// gmlib - geekmaster function library
// op (init, update, close)
//------------------------------------
int gmlib(int op) {
    
struct update_area_t int x1,y1,x2,y2,fxu8 *buffer; } ua;
    
struct fb_var_screeninfo screeninfo;
    static 
int fdUpdate=-1;
    if (
GMLIB_INIT==op) {
        
fdWB=open("/tmp/wb0",O_RDWR|O_CREAT); // work framebuffer
        
fdFB=open("/dev/fb0",O_RDWR);        // eink framebuffer
        
ioctl(fdFB,FBIOGET_VSCREENINFO,&screeninfo);
        
ppb=8/screeninfo.bits_per_pixel// pixels per byte
        
fs=screeninfo.xres_virtual/ppb// fb0 stride
        
blk=screeninfo.rotate-1;       // black
        
MX=screeninfo.xres;           // max X+1
        
MY=screeninfo.yres;          // max Y+1
        
msk=1/ppb-1;                // black mask (4-bit=255,8-bit=0)
        
fb0=(u8 *)mmap(0,MY*fs,PROT_READ|PROT_WRITE,MAP_SHARED,fdFB,0); // map fb0
        
lseek(fdWB,MY*MX-1,SEEK_SET); write(fdWB,"",1); // create work buffer file
        
wb=(u8 *)mmap(0,MY*MX,PROT_READ|PROT_WRITE,MAP_SHARED,fdWB,0); // map wb
        
fdUpdate=open("/proc/eink_fb/update_display",O_WRONLY);
    } else if (
GMLIB_CLOSE==op) {
        
gmlib(GMLIB_UPDATE); // update display
        
munmap(fb0,MY*fs);  // unmap fb0
        
munmap(wb,MY*MX);  // unmap wb
        
close(fdUpdate);  // close update proc
        
close(fdFB);     // close fb0
        
close(fdWB);    // close wb
    
} else if (GMLIB_UPDATE==op) {
        if (
ppb/2) { d4w();
            
ua.x1=0ua.y1=0ua.x2=MXua.y2=MYua.fx=0ua.buffer=NULL;
            
ioctl(fdFBFBIO_EINK_UPDATE_DISPLAY_AREA, &ua); // fx_update_partial
        
}
        else if (
blk) { d8w();
            
ua.x1=0ua.y1=0ua.x2=MXua.y2=MYua.fx=0ua.buffer=NULL;
            
ioctl(fdFBFBIO_EINK_UPDATE_DISPLAY_AREA, &ua); // fx_update_partial
        
}
        else { 
d8b(); system("eips ''");  }
    } else { return -
1; }
    return 
fdUpdate;
}

//========================================
// setpx - draw pixel to 8-bit work buffer
// x,y:screen coordinates, c:color(0-255).
//----------------------------------------
inline void setpx(int x,int y,int c) {
    
wb[y*MX+x]=c;
}

//===========================
// d8b - dither 8-bit black 0
//---------------------------
void d8b(void) {
    
u8 *pi,*point x,y;
    
pi=wbpo=fb0;
    for (
y=0;y<MY;y++) {
        for (
x=0;x<MX;x++) { *po++=dt[(y&7)*8|x&7]-*pi++>>8; }
        
po+=(fs-MX);
    }
}

//===========================
// d8w - dither 8-bit white 0
//---------------------------
void d8w(void) {
    
u8 *pi,*point x,y;
    
pi=wbpo=fb0;
    for (
y=0;y<MY;y++) {
        for (
x=0;x<MX;x++) { *po++=~(dt[(y&7)*8|x&7]-*pi++>>8); }
        
po+=(fs-MX);
    }
}

//===========================
// d4w - dither 4-bit white 0
//---------------------------
void d4w(void) {
    
u8 *pi,*point x,y,ys;
    
pi=wbpo=fb0;
    for (
y=0;y<MY;y++) { ys=(y&7)*8;
        for (
x=0;x<MX;x+=8) {
             *
po++=(~(dt[ys]-*pi++>>8)|15)&(~(dt[ys+1]-*pi++>>8)|240);
             *
po++=(~(dt[ys+2]-*pi++>>8)|15)&(~(dt[ys+3]-*pi++>>8)|240);
             *
po++=(~(dt[ys+4]-*pi++>>8)|15)&(~(dt[ys+5]-*pi++>>8)|240);
             *
po++=(~(dt[ys+6]-*pi++>>8)|15)&(~(dt[ys+7]-*pi++>>8)|240);
        }
    }
}

//==============================================
// circle - optimized midpoint circle algorithm
//----------------------------------------------
void circle(int cx,int cy,int r) {
    
int e=-r,x=r,y=0;
    while (
x>y) {
        
setpx(cx+y,cy-x,255); setpx(cx+x,cy-y,159);
        
setpx(cx+x,cy+y,95); setpx(cx+y,cy+x,31);
        
setpx(cx-y,cy+x,0); setpx(cx-x,cy+y,63);
        
setpx(cx-x,cy-y,127); setpx(cx-y,cy-x,191);
        
e+=yy++; e+=y;
        if (
e>0) { e-=xx-=1e-=x; }
    }
}

//==================
// main - start here
//------------------
int main(int argc,char **argv) {
    if (
argc>1) { mpu=atoi(argv[1]); }
    
hoser(); // do the hoser demo :D
    
return 0;


sparkle-1.0 source code:
Spoiler:
PHP Code:
//====================================================
// sparkle 1.0 - eink animation demo for DX/DXG/K3
// Copyright (C) 2012 by geekmaster, with MIT license:
// http://www.opensource.org/licenses/mit-license.php
// Copyright (C) 2011 by geekmaster
//----------------------------------------------------
// This program was created in 2011 November, when
// geekmaster got his first kindle. It was his first
// kindle program (after traditional "Hello World!").
// It formed the basis of his eink opinions expressed
// in mobileread forums since the beginning.    Enjoy!
//----------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#define FBIO_MAGIC_NUMBER 'F'
#define FBIO_EINK_UPDATE_DISPLAY_AREA _IO(FBIO_MAGIC_NUMBER,0xdd) // 0x46dd (update_area_t *)

#define pxwht(x,y) if ((x)&1) { fb0[(y)*MX+(x)>>1]&=0xF0; } else { fb0[(y)*MX+(x)>>1]&=0x0F; }
#define pxblk(x,y) if ((x)&1) { fb0[(y)*MX+(x)>>1]|=0x0F; } else { fb0[(y)*MX+(x)>>1]|=0xF0; }

struct update_area_t {
    
int x1,y1,x2,y2,which_fx;
    
__u8 *buffer// NULL=framebuffer
};
typedef struct update_area_t update_area_t;

int MX=0,MY=0;
__u8 *fb0=NULL,*pbuff=NULL;
update_area_t ua;

int main(int argc,char** argv) {
    
int i,j,n,x,y,d,wbytes,wb2,fdin,wdin,rc,once=0;
    
__u8 *start,*end,*half,*pbyte,*psave,*pln;
    
struct fb_var_screeninfo screeninfo;

    
int fdFB=open("/dev/fb0",O_RDWR);
    
ioctl(fdFB,FBIOGET_VSCREENINFO,&screeninfo);
    
MX=screeninfo.xresMY=screeninfo.yreswbytes=MX/2wb2=wbytes/2;
    
fb0=(__u8*)mmap(0,MY*wbytes,PROT_READ|PROT_WRITE,MAP_SHARED,fdFB,0); // map fb0

    // save original screen
    
pbuff=fb0psave=malloc(wbytes*MY); memcpy(psave,fb0,wbytes*MY);
    
start=pbuff+wbytes*40half=pbuff+wbytes*(MY/2); end=pbuff+wbytes*(MY-33);

    
int yoff=40,xoff=60,bbx=xoff+10,bby=50,bbvx=7,bbvy=3
    
int wbx=xoff+480-80,wby=200,wbvx=-6,wbvy=-4

    
ua.buffer=NULL;
    for (
y=0y<240y++) for (x=0x<480x++) pxwht(x+xoff,y+yoff);


    for (
i=0i<800i++) {

//### fill screen with grays
        
for (y=0y<80y++) for (x=0x<480x++) {
            if (
rand()%480<x/2pxblk(x+xoff,y+yoff) else pxwht(x+xoff,y+yoff);
        }
        for (
y=80y<160y++) for (x=0x<480x++) {
            if (
rand()%480<x/2pxwht(x+xoff,y+yoff) else pxblk(x+xoff,y+yoff);
        }
        for (
y=160y<240y++) for (x=0x<480x++) {
            if (
rand()%480>xpxblk(x+xoff,y+yoff) else pxwht(x+xoff,y+yoff);
        }
        if (!
once) { once=1;
            
ua.x1=xoffua.y1=yoffua.x2=xoff+481ua.y2=yoff+241;
            
ua.which_fx=0// fx_update_partial
            
ioctl(fdFB,FBIO_EINK_UPDATE_DISPLAY_AREA,&ua);
        }

//### black box
        
for (y=bbyy<bby+33y++) for (x=bbxx<bbx+100x++) pxblk(x,y);
        for (
y=bby+33y<bby+66y++) {
            for (
x=bbxx<bbx+33x++) pxblk(x,y);
            for (
x=bbx+66x<bbx+100x++) pxblk(x,y);
        } 
        for (
y=bby+66y<bby+100y++) for (x=bbxx<bbx+100x++) pxblk(x,y);
        
//### white box
        
for (y=wbyy<wby+25y++) for (x=wbxx<wbx+25x++) pxwht(x,y);

//### animate
        
bbx += bbvxbby += bbvywbx += wbvxwby += wbvy;
        if (
bbx>xoff+380) { bbx=xoff+380bbvx=-bbvx; }
        if (
bbx<xoff) { bbx=xoffbbvx=-bbvx; }
        if (
bby>140+yoff) { bby=140+yoffbbvy=-bbvy; }
        if (
bby<40) { bby=40bbvy=-bbvy; }
        if (
wbx>xoff+405) { wbx=xoff+405wbvx=-wbvx; }
        if (
wbx<xoff) { wbx=xoffwbvx=-wbvx; }
        if (
wby>215+yoff) { wby=215+yoffwbvy=-wbvy; }
        if (
wby<40) { wby=40wbvy=-wbvy; }

        
ua.x1=xoffua.y1=yoffua.x2=xoff+481ua.y2=yoff+241;
        
ua.which_fx=0// fx_update_partial
        
ioctl(fdFB,FBIO_EINK_UPDATE_DISPLAY_AREA,&ua);
    }

    
memcpy(fb0,psave,wbytes*MY); // restore display
    
ua.x1=0ua.y1=0ua.x2=600ua.y2=800;
    
ua.which_fx=2// fx_update
    
ioctl(fdFB,FBIO_EINK_UPDATE_DISPLAY_AREA,&ua);

    
free (psave);
    
munmap(fb0,MX*MY/2);
    
close(fdFB);


Enjoy and learn!

Attached Files
File Type: gz sparkle-1.0.tar.gz (5.9 KB, 183 views)
File Type: gz sparkle-2.0.tar.gz (9.4 KB, 174 views)

Last edited by geekmaster; 04-24-2012 at 02:07 AM.
geekmaster is offline   Reply With Quote
Old 04-24-2012, 12:12 AM   #37
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow Major Update for K3 Owners!

MAJOR UPDATE for K3 owners!

The "partial area" updates used in Sparkle-1.0 (for which the source code had been lost and was recently found), are MUCH faster on a K3 than using eips, and much faster than using the /proc update interface.

After replacing the eink update method for 4-bit screens (DX, DXG, K3), hoser-2.0 is many times faster on a K3, EVEN THOUGH it is not recommended for FULL SCREEN updates like this. That means that it will be EVEN FASTER if we use it to only update known changed (dirty) areas of the screen.

It does not make the DX or DXG run any faster though -- they use older 2.x firmware. Perhaps it would be faster on a DXG that was updated to 3.x firmware.

If you have a K3, go get hoser-2.0 now! Soon, I will update all the old demos to run MUCH faster on the K3. Things will only get BETTER with this new change in update method.

Enjoy!


Last edited by geekmaster; 04-24-2012 at 01:19 AM.
geekmaster is offline   Reply With Quote
Old 04-24-2012, 01:52 AM   #38
kiri87
Member
kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.
 
Posts: 16
Karma: 25544
Join Date: Feb 2012
Device: Kindle 3
This is awesome on so many levels. After running sparkle-1.0, I was impressed, but after running hoser-2.0 on my K3, my mind blown . Thank you for this fantastic piece of code (even though it's still beyond my ability to understand) and for motivating other people to start learning.
kiri87 is offline   Reply With Quote
Old 04-24-2012, 01:55 AM   #39
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Okay, now sparkle-1.0 has been updated to use the "dithermation framework" so it supports ALL the eink kindles (see sparkle-2.0 above). Now you can see that cool K3 eye-candy on all the kindles. On the K4, there are almost no ghost trails though -- just the sparkle.

We need to update the old demos to 2.0 version just like I did for hoser -- just a few lines of code in a couple of places. Use a version comparison tool to see the changes in hoser-1.0 and hoser-2.0, then do those to the other demos too.

I will be away most of the next day or so. I hope to see 2.0 versions of ALL the demos posted here when I get back.

Remember, this huge speed increase only affects the K3. I *LIKE* where this code is headed. Remember, *demos* are just toys to show what this code can do and how to do it, but the real purpose of this code is to use it in *tools*.



Last edited by geekmaster; 04-24-2012 at 02:02 AM.
geekmaster is offline   Reply With Quote
Old 04-24-2012, 02:32 AM   #40
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
When are we going to see some youtube videos of these things running? Screenshots are a very poor substitute for the DITHERMATION demos. Dithered animation is just too cool -- it is just like seeing a charcoal drawing come alive!

Let's see something like this, except videos of the "Dithermation" demos from this thread:


By the way, the reason that the face is being drawn upside-down in the above video is to bypass the facial-recognition filters in the artist's visual processing centers, so that fine detail can be seen and reproduced, which is normally well below a human's conscious level of awareness. The end result is a much more accurate representation containing much more subtle accurate detail that is well below conscious awareness but which greatly increases image fidelity, as can be seen in the final image.


Last edited by geekmaster; 04-24-2012 at 09:44 AM.
geekmaster is offline   Reply With Quote
Old 04-24-2012, 03:29 AM   #41
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by kiri87 View Post
This is awesome on so many levels. After running sparkle-1.0, I was impressed, but after running hoser-2.0 on my K3, my mind blown . Thank you for this fantastic piece of code (even though it's still beyond my ability to understand) and for motivating other people to start learning.
Thank you for thanking me! It is nice to get some feedback so I know at least *somebody* appreciates my efforts here.

I actually tried this partial update method now used in hoser-2.0 awhile ago on older animation code and it was SLOWER than eips and the /proc interface.

It could be that to use it effectively for full screen updates, you may need to double-buffer by using a virtual framebuffer like I did in hoser (/tmp/wb0) where all the changes are written, and then when time to update the eink it gets dithered to the real framebuffer (/dev/fb0).

I also thought of another potential speedup by relieving even more contention between my code and the system eink drivers when using the same /dev/fb0 buffer at the same time. I could use a second virtual framebuffer with identical dimensions to the real framebuffer, then just before an eink update I would dither to that second virtual buffer instead of to /dev/fb0, and only at the last instant do a fast COPY of the entire dithered virtual buffer to the real /dev/fb0 framebuffer.

At least, I *think* that should make it all faster, and faster is better, right?


Last edited by geekmaster; 04-24-2012 at 03:32 AM.
geekmaster is offline   Reply With Quote
Old 04-24-2012, 08:19 AM   #42
Tanga
Zealot
Tanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toysTanga shares his or her toys
 
Posts: 128
Karma: 5792
Join Date: Mar 2011
Location: Australia
Device: Kindle 3
I'm a total noob. What do these things do and can I play with them on my K3?
Tanga is offline   Reply With Quote
Old 04-24-2012, 08:56 AM   #43
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by Tanga View Post
I'm a total noob. What do these things do and can I play with them on my K3?
What they REALLY do is show you how to write programs to do cool things on kindles.

The individual demos themselves just draw pixels on the eink display, so they are safe to run. They draw cool things with animated effects. Just download the attachment and run the executable (the file without the ".c" on the end of the filename) on your kindles. And watch what they do. Usually they are named in a way that hints at effect they will show you. Some of them have a screenshot that shows a sample of what you see at some time during the demo.

Be sure to click the "Show" buttons in these posts to see what is hidden behind them.

If you read the comments in the first few lines of source code for each demo program, they say that they work on ALL eink kindles. Many of them also say that in their posting. You should read the posts first, then scan the code for any comments that may give a clue, then run the program on your kindle (or just skip the reading and run the program to enjoy the unfolding surprise).

Each demo has custom code that is contained in a function called from main(). The demo function calls functions provided by my library code that does the "heavy lifting" to give you simple access to all eink kindles.

The organizing of my function library is evolving. I call the whole package of dithered animation support "Dithermation". The library of all of geekmaster's function is called "gmlib" and that includes a larger code base for everything, not just eink support.

What else can I say?


Last edited by geekmaster; 04-24-2012 at 09:28 AM.
geekmaster is offline   Reply With Quote
Old 05-10-2012, 08:12 PM   #44
Dweia
Junior Member
Dweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with othersDweia plays well with others
 
Posts: 7
Karma: 2614
Join Date: May 2012
Device: Kindle Touch
Interesting Side-effect of your algorithms: I ran first the Hoser demo on Kindle Touch, and after that tried the Sparkle demo. Wenn running the second, the lower part of the screen still showed the rest of the "Hoser" image - one could leaf through a book and see for a short moment the page and then again the lower part was overwritten with the Hoser image and the top part contionued to scribble the Sparkles...

Impressive speed!
Dweia is offline   Reply With Quote
Old 05-10-2012, 08:33 PM   #45
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by Dweia View Post
Interesting Side-effect of your algorithms: I ran first the Hoser demo on Kindle Touch, and after that tried the Sparkle demo. Wenn running the second, the lower part of the screen still showed the rest of the "Hoser" image - one could leaf through a book and see for a short moment the page and then again the lower part was overwritten with the Hoser image and the top part contionued to scribble the Sparkles...

Impressive speed!
You should see how fast and smooth the videos play using a lot of the same code (except evolved to a whole new level, such as very fast dithering without a dither table, and all updates done using ioctl() system calls instead of eips ''). And the new code can be used in the older demos too. It could even be backported to the "eink algorithmic art shell scripting" demos.
geekmaster is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Troubleshooting Kindle and math formula DrShakalu Amazon Kindle 12 12-11-2011 07:25 AM
Formula Plots PuxyYunm General Discussions 9 05-15-2011 04:19 AM
Demo: Jetbook mini official demo bookwarm Ectaco jetBook 36 09-21-2010 12:18 PM


All times are GMT -4. The time now is 07:25 PM.


MobileRead.com is a privately owned, operated and funded community.