Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /** Color Cell Encoder, Inner Function
- * src: source framebuffer, current frame
- * lsrc: scratch framebuffer, to detect/skip unchanging blocks.
- * rdsta: first part of destination
- * rdstb: second part of destination
- * Note: that rdsta and rdstb need not be adjacent.
- * Note: also that screen width is hard-coded in this version.
- */
- void VID_ConGfx_EncBlock16P(u16 *src, u16 *lsrc, u32 *rdsta, u32 *rdstb)
- {
- u16 *cs, *ct;
- int cmin, cmax;
- register int cavg, calo, cahi;
- int clra, clrb;
- u32 px2;
- u32 dxa, dxb;
- u64 lpx0, lpx1, lpx2, lpx3, lpx4;
- register int k0, k1;
- int i, j, k;
- //NOTE: BGBCC Codegen Hint.
- //Hints register allocator to enable use of all 32 GPRs.
- __hint_use_egpr();
- //Note: BGBCC is kinda stupid, so branches result in spilling most of the registers...
- //Detect if pixels haven't changed
- ct=lsrc; cs=src; i=0;
- lpx0=*(u64 *)cs; lpx4=*(u64 *)ct;
- cs+=BASEWIDTH; ct+=BASEWIDTH;
- i|=(lpx0!=lpx4);
- lpx1=*(u64 *)cs; lpx4=*(u64 *)ct;
- cs+=BASEWIDTH; ct+=BASEWIDTH;
- i|=(lpx1!=lpx4);
- lpx2=*(u64 *)cs; lpx4=*(u64 *)ct;
- cs+=BASEWIDTH; ct+=BASEWIDTH;
- i|=(lpx2!=lpx4);
- lpx3=*(u64 *)cs; lpx4=*(u64 *)ct;
- i|=(lpx3!=lpx4);
- if(!i) return; //Hasn't changed, do nothing
- //Save new pixels to scratch buffer
- ct=lsrc;
- *(u64 *)ct=lpx0; ct+=BASEWIDTH;
- *(u64 *)ct=lpx1; ct+=BASEWIDTH;
- *(u64 *)ct=lpx2; ct+=BASEWIDTH;
- *(u64 *)ct=lpx3;
- calo=65536; cahi=-1;
- //NOTE: BGBCC: __int_min() and __int_max() are intrinsics wrapping the CSELT instruction.
- //Find the lightest and darkest pixels:
- k0=(u16)(lpx0 ); k1=(u16)(lpx0>>16);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- k0=(u16)(lpx0>>32);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k1=(u16)(lpx0>>48);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k0=(u16)(lpx1 ); k1=(u16)(lpx1>>16);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- k0=(u16)(lpx1>>32);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k1=(u16)(lpx1>>48);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k0=(u16)(lpx2 ); k1=(u16)(lpx2>>16);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- k0=(u16)(lpx2>>32);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k1=(u16)(lpx2>>48);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k0=(u16)(lpx3 ); k1=(u16)(lpx3>>16);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- k0=(u16)(lpx3>>32);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- k1=(u16)(lpx3>>48);
- calo=__int_min(calo, k0); cahi=__int_max(cahi, k0);
- calo=__int_min(calo, k1); cahi=__int_max(cahi, k1);
- //OK, we have range, calc average, lower, and upper threshold:
- cmin=calo; cmax=cahi;
- cavg=(cmin+cmax)>>1;
- calo=(cmin+cavg)>>1;
- cahi=(cmax+cavg)>>1;
- //Find pixel bits; Note that MUL, DIV, and mem-access are expensive in BJX2
- //Especially don't want DIV, because DIV is implemented in software (hidden C runtime call; 100s of cycles).
- //But, what we do have, is 32 GPRs and a fairly cheap 'a>b' operator...
- px2=0;
- k0=(u16)(lpx0 ); k1=(u16)(lpx0>>16);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- k0=(u16)(lpx0>>32);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k1=(u16)(lpx0>>48);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k0=(u16)(lpx1 ); k1=(u16)(lpx1>>16);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- k0=(u16)(lpx1>>32);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k1=(u16)(lpx1>>48);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k0=(u16)(lpx2 ); k1=(u16)(lpx2>>16);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- k0=(u16)(lpx2>>32);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k1=(u16)(lpx2>>48);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k0=(u16)(lpx3 ); k1=(u16)(lpx3>>16);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- k0=(u16)(lpx3>>32);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- k1=(u16)(lpx3>>48);
- px2=(px2<<2)|((k0>cavg)<<1); px2|=(k0>cahi)|(calo>k0);
- px2=(px2<<2)|((k1>cavg)<<1); px2|=(k1>cahi)|(calo>k1);
- px2=px2^((~(px2>>1))&0x55555555);
- clrb=cmin>>1; clra=cmax>>1;
- dxa=0xC0000000|(clrb<<15)|clra; dxb=px2;
- *rdsta=dxa; *rdstb=dxb;
- }
Add Comment
Please, Sign In to add comment