diff options
| author | Miguel <m.i@gmx.at> | 2018-10-19 23:17:00 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-10-19 23:17:00 +0200 |
| commit | dffe2aa65968b66329a83a0411c7ca97b1c57493 (patch) | |
| tree | eba9e132dda6238d47664bdd985208e218690eb1 /video | |
| parent | c9c26727a11c37f61bc51662c3ca498737ce523f (diff) | |
struggling with our compositor....
Diffstat (limited to 'video')
| -rw-r--r-- | video/compositor.c | 476 |
1 files changed, 275 insertions, 201 deletions
diff --git a/video/compositor.c b/video/compositor.c index 4a7a5cc..5b188a5 100644 --- a/video/compositor.c +++ b/video/compositor.c @@ -21,7 +21,7 @@ #define MAX_WINDOWS 50 #define MAX_PID 200 -#define MAX_INVAL 100 // max pending invalidation rectangles per process +#define MAX_INVALID 100 // max pending invalidation rectangles per process #define MAX_ICONS 50 void load_bmp(uint8_t *dst,char *filename); @@ -64,15 +64,18 @@ struct window // set on init bool borderless; // never show borders bool fixed; // can not be moved + bool no_close; // can not be moved + struct pdirectory *vmem; // retreive from task manager? }; static uint16_t next_window=0; +struct window bbwindow; struct window windows[MAX_WINDOWS]; struct window *pid_to_win[MAX_PID]; -struct inval invalid[MAX_PID]; -uint8_t invalid_cnt[MAX_PID]; +struct inval invalid[MAX_PID][MAX_INVALID]; +uint16_t invalid_cnt[MAX_PID]; // fraembuffer info static uint16_t vesa_width; @@ -175,111 +178,129 @@ static void cpy_rect(uint8_t *src, uint16_t src_pitch, uint16_t src_x, uint16 } } -static void put_win(uint8_t *dst, struct window *win) +static void put_win(uint8_t *dst, struct window *win,bool alpha) { + bool no_smartass=false; struct pdirectory* mydir; + if(win->vmem) + { + mydir=x86_get_page_directory(); + x86_set_page_directory(win->vmem); + } - //x86_cli();// do not reschedule us til ready! - mydir=x86_get_page_directory(); - x86_set_page_directory(win->vmem); + for(int i=0;i<next_window;i++) + { + if(no_smartass) + { + cpy_rect(win->fb,win->width*4, + 0,0, // from + dst,vesa_pitch, + win->posx,win->posy, + win->width,win->height, + false, + 0, 0, // scaling not implemented yet anyway, not sure how to use them :P + true, // transparency color key + 0xff00ff // color key of transp + ,true + ); + } + else + { + uint32_t pid=windows[i].pid; -cpy_rect(win->fb,win->width*4,0,0, // from - dst,vesa_pitch,win->posx,win->posy, // to - win->width,win->height, // icon dimensions - false, - 0, 0, // scaling not implemented yet anyway, not sure how to use them :P - true, // transparency color key - 0xff00ff // color key of transp - ,true - ); + // if too many areas invalidated refresh whole window + if(invalid_cnt[pid]>=MAX_INVALID) + { + invalid[pid][0].x=win->posx; + invalid[pid][0].y=win->posy; + invalid[pid][0].w=win->width; + invalid[pid][0].h=win->height; + invalid_cnt[pid]=1; + } -int iconx=X_icon_lx; -int icony=X_icon_ly; -if(win->on_close) -{ - iconx=X_icon_active_lx; - icony=X_icon_active_ly; -} + for(int j=0;j<invalid_cnt[pid];j++) + { + // invalidated area is in screen coords + struct inval *inv=&invalid[pid][j]; -cpy_rect(icon_data,vesa_pitch,iconx,icony, // from - dst, vesa_pitch,win->posx+win->width-X_icon_width,win->posy, // to - X_icon_width,X_icon_height, // icon dimensions - false, - 0, 0, // scaling not implemented yet anyway, not sure how to use them :P - true, // transparency color key - 0xff00ff // color key of transp - ,true - ); + int from_x=inv->x-win->posx; + int from_y=inv->y-win->posy; - // iterate over invalidated rects - -//// while(ringbuffer_has(win->invl)) -//// { -//// int ry=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl); -//// int rx=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl); -//// int rh=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl); -//// int rw=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl); -//// if(!win->draw_meat)continue; -//// -//// uint32_t userx=rx; -//// uint32_t usery=ry; -//// -//// // iterate over rect area -//// for(uint16_t x=win->posx+rx;x<win->posx+rx+rw;x++) -//// { -//// usery=ry; -//// for(uint16_t y=win->posy+ry;y<win->posy+ry+rh;y++) -//// { -//// // blending non-active windows (TODO: costly?) -//// if(!win->active && option_blending) -//// { -//// /* -//// uint8_t dst_b=backbuffer[y*vesa_width+x]&0xff; -//// uint8_t dst_g=(backbuffer[y*vesa_width+x]&0xff00)>>8; -//// uint8_t dst_r=(backbuffer[y*vesa_width+x]&0xff0000)>>16; -//// -//// uint16_t a; -//// -//// uint32_t col=0xff0000; -//// col=user_vmem[userx+usery*640]; -//// uint8_t src_b=col&0xff; -//// uint8_t src_g=(col&0xff00)>>8; -//// uint8_t src_r=(col&0xff0000)>>16; -//// a=0x44; -//// -//// -//// uint8_t out_r=((src_r*(0xff-a))>>8)+((a*dst_r)>>8); -//// uint8_t out_g=((src_g*(0xff-a))>>8)+((a*dst_g)>>8); -//// uint8_t out_b=((src_b*(0xff-a))>>8)+((a*dst_b)>>8); -//// -//// backbuffer[y*vesa_width+x]=(out_r<<16)+(out_g<<8)+out_b; -//// */ -//// -//// put_pixel_alpha(dst,x,y,(user_vmem[userx+usery*640])); -//// } -//// else -//// { -//// put_pixel(dst,x,y,(user_vmem[userx+usery*640])); -//// } -//// -//// usery++; -//// } -//// userx++; -//// } -//// } - //if(win->vmem) - //{ - x86_set_page_directory(mydir); -// x86_sti(); - //} + int to_x=inv->x; + int width=inv->w; + int to_y=inv->y; + int height=inv->h; + + if(from_x<0) + { + to_x=inv->x-from_x; + width=inv->w+from_x; + from_x=0; + } + + if(from_y<0) + { + to_y=inv->y-from_y; + height=inv->h+from_y; + from_y=0; + } - //draw boundaries - if(option_win_borders&&win->draw_border) + if(win->width<width+from_x)width=win->width-from_x; + if(win->height<height+from_y)height=win->height-from_y; + + //klog("rep from %d %d , to %d %d , size %d %d",from_x,from_y,to_x,to_y,width,height); + + if(width>0&&height>0) + cpy_rect(win->fb,win->width*4, + from_x,from_y, // from + dst,vesa_pitch, + to_x,to_y, + width,height, + false, + 0, 0, // scaling not implemented yet anyway, not sure how to use them :P + true, // transparency color key + 0xff00ff // color key of transp + ,alpha + ); + } + } + } + + if(win->vmem) + { + x86_set_page_directory(mydir); + } + + // CLOSE ICON // + if(!win->no_close) + { + int iconx=X_icon_lx; + int icony=X_icon_ly; + + if(win->on_close) + { + iconx=X_icon_active_lx; + icony=X_icon_active_ly; + } + + cpy_rect(icon_data,vesa_pitch,iconx,icony, // from + dst, vesa_pitch,win->posx+win->width-X_icon_width,win->posy, // to + X_icon_width,X_icon_height, // icon dimensions + false, + 0, 0, // scaling not implemented yet anyway, not sure how to use them :P + true, // transparency color key + 0xff00ff // color key of transp + ,true + ); + } + + // BORDERS // + if(option_win_borders&&!win->borderless) { uint32_t border_col=0x002b36; if(win->active)border_col=0xfdfd6e3; -//TODO win->draw_border=false; + for(uint16_t x=win->posx;x<win->posx+win->width;x++) { put_pixel(dst,x,win->posy,border_col,vesa_pitch,vesa_depth,false); //TOP @@ -294,20 +315,17 @@ cpy_rect(icon_data,vesa_pitch,iconx,icony, // from // } -static void put_bg(uint8_t *dst) + +static void invalidate_all() { - cpy_rect(wallpaper,vesa_pitch,0,0 , // from - dst,vesa_pitch,0,0, // to - vesa_width,vesa_height, // icon dimensions - false, - 0, 0, // scaling not implemented yet anyway, not sure how to use them :P - false, // transparency color key - 0xffffff // color key of transp - ,false - ); + invalid[0][invalid_cnt[0]].x=0; + invalid[0][invalid_cnt[0]].y=0; + invalid[0][invalid_cnt[0]].w=vesa_width; + invalid[0][invalid_cnt[0]].h=vesa_height; + invalid_cnt[0]++; } -static void put_mouse(uint8_t *dst) +static void put_mouse(uint8_t *dst,bool inval) { static int last_put_mouse_x=0; @@ -325,6 +343,18 @@ if(mouse_k&1) last_put_mouse_x=mouse_x; last_put_mouse_y=mouse_y; +invalid[0][invalid_cnt[0]].x=mouse_x; +invalid[0][invalid_cnt[0]].y=mouse_y; +invalid[0][invalid_cnt[0]].w=mouse_icon_width; +invalid[0][invalid_cnt[0]].h=mouse_icon_height; + +invalid_cnt[0]++; + +if(inval) +{ +return; +} + cpy_rect(icon_data,vesa_pitch,iconx,icony, // from dst, vesa_pitch,mouse_x,mouse_y, // to mouse_icon_width,mouse_icon_height, // icon dimensions @@ -334,7 +364,6 @@ cpy_rect(icon_data,vesa_pitch,iconx,icony, // from 0xff00ff // color key of transp ,true ); - } void compositor_del_window(uint32_t addr) @@ -372,6 +401,33 @@ void compositor_init(uint16_t width, uint16_t height,uint16_t depth, uint16_t pi load_bmp(wallpaper,"/home/miguel/wallpaper.bmp"); load_bmp(icon_data,"/home/miguel/ico.bmp"); + // window holding background + windows[0].pid=0; + windows[0].vmem=0; + windows[0].fb=wallpaper; + windows[0].posx=0; + windows[0].posy=0; + windows[0].height=vesa_height; + windows[0].width=vesa_width; + windows[0].fixed=true; + windows[0].borderless=true; + windows[0].no_close=true; + next_window++; + + // fake window holding backbuffer + bbwindow.pid=0; + bbwindow.vmem=0; + bbwindow.fb=backbuffer; + bbwindow.posx=0; + bbwindow.posy=0; + bbwindow.height=vesa_height; + bbwindow.width=vesa_width; + bbwindow.fixed=true; + bbwindow.borderless=true; + bbwindow.no_close=true; + + invalidate_all(); + klog("initialized composing window manager to %d x %d x %d" ,width,height,depth); } @@ -382,6 +438,7 @@ void compositor_wake() void compositor_paint() { + // forced max rate if(skip_render)return; skip_render=true; @@ -398,19 +455,29 @@ void compositor_paint() last=now; frames=0; } - - //wallpaper - //put_bg(backbuffer); - for(int i=next_window-1;i>=0;i--) + for(int i=0;i<next_window;i++) { - put_win(backbuffer,&windows[i]); + x86_cli(); + put_win(backbuffer,&windows[i],true); + x86_sti(); } - put_mouse(backbuffer); + put_mouse(backbuffer,false); + + // TODO: only rects too! + //memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_pitch*vesa_height); + put_win(VMEM_FRAMEBUFFER,&bbwindow,false); + + // reset counts + for(int i=next_window-1;i>=0;i--) + { + uint32_t pid=windows[i].pid; + invalid_cnt[pid]=0; + } + + put_mouse(backbuffer,true);//invalidate only - // TODO: only rects - memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_pitch*vesa_height); } void check_win_pos(struct window *w) @@ -449,10 +516,8 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key) mouse_y+=diff_y; mouse_k=key; - if(mouse_x<0)mouse_x=0; if(mouse_y<0)mouse_y=0; - if(mouse_x>=vesa_width-mouse_icon_width)mouse_x=vesa_width-1-mouse_icon_width; if(mouse_y>=vesa_height-mouse_icon_height)mouse_y=vesa_height-1-mouse_icon_height; @@ -465,63 +530,68 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key) int active=-1; bool active_win=false; - for(int i=0;i<next_window;i++) + // top most window first + for(int i=next_window;i>=0;i--) { struct window *w=&windows[i]; w->on_close=false; - if(active==-1&&mouse_x>w->posx&&mouse_x<w->posx+w->width&&mouse_y>w->posy&&mouse_y<w->posy+w->height) - { - if(key&1) - { - - w->draw_meat=false; - uint32_t xy=(w->posx<<16)|(w->posy); - uint32_t wh=(640<<16)|(400); - - /* - ringbuffer_put(&bg_invl,xy&0x000000ff); - ringbuffer_put(&bg_invl,(xy&0x0000ff00)>>8); - ringbuffer_put(&bg_invl,(xy&0x00ff0000)>>16); - ringbuffer_put(&bg_invl,(xy&0xff000000)>>24); - - ringbuffer_put(&bg_invl,wh&0x000000ff); - ringbuffer_put(&bg_invl,(wh&0x0000ff00)>>8); - ringbuffer_put(&bg_invl,(wh&0x00ff0000)>>16); - ringbuffer_put(&bg_invl,(wh&0xff000000)>>24); - */ - - w->posx-=last_mouse_x-mouse_x; - last_mouse_x=mouse_x; - - w->posy-=last_mouse_y-mouse_y; - last_mouse_y=mouse_y; - check_win_pos(w); + if(w->fixed)continue; - w->draw_border=true; - - } - else - { - w->draw_meat=true; - if(lastkey&1) - { - w->draw_border=true; - uint32_t xy=(0<<16)|(0); - uint32_t wh=(640<<16)|(400); - -/// ringbuffer_put(w->invl,xy&0x000000ff); -/// ringbuffer_put(w->invl,(xy&0x0000ff00)>>8); -/// ringbuffer_put(w->invl,(xy&0x00ff0000)>>16); -/// ringbuffer_put(w->invl,(xy&0xff000000)>>24); -/// -/// ringbuffer_put(w->invl,wh&0x000000ff); -/// ringbuffer_put(w->invl,(wh&0x0000ff00)>>8); -/// ringbuffer_put(w->invl,(wh&0x00ff0000)>>16); -/// ringbuffer_put(w->invl,(wh&0xff000000)>>24); - } - - } + if(active==-1&&mouse_x>w->posx&&mouse_x<w->posx+w->width&&mouse_y>w->posy&&mouse_y<w->posy+w->height) + { + +//// if(key&1) +//// { +//// +//// w->draw_meat=false; +//// uint32_t xy=(w->posx<<16)|(w->posy); +//// uint32_t wh=(640<<16)|(400); +//// +//// /* +//// ringbuffer_put(&bg_invl,xy&0x000000ff); +//// ringbuffer_put(&bg_invl,(xy&0x0000ff00)>>8); +//// ringbuffer_put(&bg_invl,(xy&0x00ff0000)>>16); +//// ringbuffer_put(&bg_invl,(xy&0xff000000)>>24); +//// +//// ringbuffer_put(&bg_invl,wh&0x000000ff); +//// ringbuffer_put(&bg_invl,(wh&0x0000ff00)>>8); +//// ringbuffer_put(&bg_invl,(wh&0x00ff0000)>>16); +//// ringbuffer_put(&bg_invl,(wh&0xff000000)>>24); +//// */ +//// +//// w->posx-=last_mouse_x-mouse_x; +//// last_mouse_x=mouse_x; +//// +//// w->posy-=last_mouse_y-mouse_y; +//// last_mouse_y=mouse_y; +//// +//// check_win_pos(w); +//// +//// w->draw_border=true; +//// +//// } +//// else +//// { +//// w->draw_meat=true; +//// if(lastkey&1) +//// { +//// w->draw_border=true; +//// uint32_t xy=(0<<16)|(0); +//// uint32_t wh=(640<<16)|(400); +//// +/////// ringbuffer_put(w->invl,xy&0x000000ff); +/////// ringbuffer_put(w->invl,(xy&0x0000ff00)>>8); +/////// ringbuffer_put(w->invl,(xy&0x00ff0000)>>16); +/////// ringbuffer_put(w->invl,(xy&0xff000000)>>24); +/////// +/////// ringbuffer_put(w->invl,wh&0x000000ff); +/////// ringbuffer_put(w->invl,(wh&0x0000ff00)>>8); +/////// ringbuffer_put(w->invl,(wh&0x00ff0000)>>16); +/////// ringbuffer_put(w->invl,(wh&0xff000000)>>24); +//// } +//// +//// } w->active=true; active_win=true; @@ -530,12 +600,11 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key) } else { - - - w->active=false; + w->active=false; } } + /* if(active_win&&active!=-1&&active!=0&&(key&1)) { struct window temp; @@ -545,8 +614,9 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key) pid_to_win[windows[0].pid]=&windows[active]; windows[0]=temp; - pid_to_win[windows[0].pid]=&windows[0]; + pid_to_win[windows[0].pid]=&windows[0]; } + */ lastkey=key; } @@ -603,16 +673,20 @@ void load_bmp(uint8_t *dst,char *filename) void compositor_invalidate(uint32_t pid,uint16_t x, uint16_t y, uint16_t w, uint16_t h,uint32_t *fb) { -// klog("pid %d invalidating %dx%d rect at %d %d with fb addr 0x%08x",pid,w,h,x,y,fb); + + // klog("pid %d invalidating %dx%d rect at %d %d with fb addr 0x%08x",pid,w,h,x,y,fb); if(fb!=0)pid_to_win[pid]->fb=fb; - if(invalid_cnt[pid]>=MAX_INVAL)return;//invalidation buffer is full. + if(invalid_cnt[pid]>=MAX_INVALID){ +// klog("compositor: invalidation buffer is full for pid: %d",pid); + return;//invalidation buffer is full. - invalid[invalid_cnt[pid]].x=x; - invalid[invalid_cnt[pid]].y=y; - invalid[invalid_cnt[pid]].w=w; - invalid[invalid_cnt[pid]].h=h; - invalid_cnt[pid]++; + } + invalid[pid][invalid_cnt[pid]].x=x+pid_to_win[pid]->posx; + invalid[pid][invalid_cnt[pid]].y=y+pid_to_win[pid]->posy; + invalid[pid][invalid_cnt[pid]].w=w; + invalid[pid][invalid_cnt[pid]].h=h; + invalid_cnt[pid]++; } int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint16_t h,uint16_t flags) @@ -620,43 +694,43 @@ int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint klog("pid %d creating %dx%d win at %d %d with flags 0x%02x",pid,w,h,x,y,flags); if (next_window>=MAX_WINDOWS)kpanic("max number of windows reached. increase MAX_WINDOWS"); - windows[next_window]=windows[0]; - pid_to_win[windows[0].pid]=&windows[next_window]; + int idx=next_window; // auto position if(x==0xffff&&y==0xffff) { - windows[0].posx=mouse_x-(w/2); - windows[0].posy=mouse_y-(h/2); + windows[idx].posx=mouse_x-(w/2); + windows[idx].posy=mouse_y-(h/2); } else { - windows[0].posx=x; - windows[0].posy=y; + windows[idx].posx=x; + windows[idx].posy=y; } - windows[0].width=w; - windows[0].height=h; + windows[idx].width=w; + windows[idx].height=h; - check_win_pos(&windows[0]); + check_win_pos(&windows[idx]); - windows[0].active=0; + windows[idx].active=0; - windows[0].fb=0; - windows[0].vmem=scheduler_get_vmem(pid); - windows[0].pid=pid; + windows[idx].fb=0; + windows[idx].vmem=scheduler_get_vmem(pid); + windows[idx].pid=pid; - windows[0].draw_border=true; - windows[0].draw_meat=true; + windows[idx].draw_border=true; + windows[idx].draw_meat=true; - windows[0].on_close=false; - windows[0].borderless=flags&1; - windows[0].fixed=flags&2; + windows[idx].on_close=false; + windows[idx].borderless=flags&1; + windows[idx].fixed=flags&2; + windows[idx].borderless=flags&1; + windows[idx].no_close=false; - pid_to_win[windows[0].pid]=&windows[0]; + pid_to_win[pid]=&windows[idx]; next_window++; - //compositor_mouse_handle(0,0,0); return 0;// ok } |
