PDA

Ver la versión completa : [Ayuda] Scaler1.5x: color RGB343. ¿Cómo usar RGB565?



hi-ban
23/10/2011, 19:22
Mi problema es el siguiente:

El Ohboy usa un scaler (1.5x) que, por lo visto, utiliza como source color RGB343, y la salida es en RGB565.
Lo que pasa es que, al usar paletas de colores con ese scaler, los colores finales en pantalla no se ven como deberían, sino ligéramente cambiados.
Esto me supongo que es debido a que, al estar las paletas en color RGB565(16bit) y pasarlas a RGB343(10bit) hay una "pérdida de tonos" que luego no se recupera.

La unica solución sería hacer que el scaler utilice como source y como salida RGB565.

Alguna ayuda? El codigo es el siguiente:



static un16 buffer[3][240];

/*
** Appears to expect source/dest framebuffer pixels to be 16bpp
** But expects source to be in RGB343 format. Looks like it may expect dest to be RGB565.
** 1.5 scaler with "smoothing", i.e. 160x144 -> 239x215 BUT centered/centred in a 320x240 screen.
** It looks like it does a 2 pass conversion:
** 1) increase 3x
** 2) decrease by 2x
*/
void ohb_scale3x(){

un16 *dst = buffer[0];
un16 *src = (un16*)fb.ptr;
un16 *base = (un16*)vid_fb.ptr + 3880;
int x,y;

un16 A,B,C,D,E,F,G,H,I;

memset(buffer,0,480*3);

// Top-left
SCALE3X(0,1,0,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
// Top
for(x=1; x<159; x+=2){
SCALE3X(-1,1,0,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,0,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
}
// Top-Right
SCALE3X(-1,0,0,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;

for(y=1; y<142; y+=2){
// left
SCALE3X(0,1,-160,160,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
// middle
for(x=1; x<159; x+=2){
SCALE3X(-1,1,-160,160,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,-160,160,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
}
// right
SCALE3X(-1,0,-160,160,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;

memcpy(base,buffer[0],480);
memcpy(base+320,buffer[1],480);
memcpy(base+640,buffer[2],480);
dst=(un16*)buffer;
base += 960;

memset(buffer,0,480*3);
// left
SCALE3X(0,1,-160,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
// middle
for(x=1; x<159; x+=2){
SCALE3X(-1,1,-160,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,-160,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
}
// right
SCALE3X(-1,0,-160,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
}

// left
SCALE3X(0,1,-160,0,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
// middle
for(x=1; x<159; x+=2){
SCALE3X(-1,1,-160,0,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,-160,0,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
}
// right
SCALE3X(-1,0,-160,0,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;

memcpy(base,buffer[0],480);
memcpy(base+320,buffer[1],480);
memcpy(base+640,buffer[2],480);
}

/*
** Appears to expect source/dest framebuffer pixels to be 16bpp
** But expects source to be in RGB343 format. Looks like it may expect dest to be RGB565.
** 1.5 scaler, i.e. 160x144 -> 239x215 BUT centered/centred in a 320x240 screen.
*/
void ohb_render(){

fb.cc[0].r = screen->format->Rloss+2;
fb.cc[1].r = screen->format->Gloss+2;
fb.cc[2].r = screen->format->Bloss+2;
vid_fb.dirty = 0;
pal_dirty();

un16 *mix, *buf;

un16 *src = (un16*)fb.ptr;
un16 *dst = (un16*)vid_fb.ptr + 3880;
int x,y;

for(y=0; y<144; y+=2){
mix = buffer[0];
for(x=0; x<160; x+=2){
*(dst++) = (*(mix++) = (*src<<1))<<1;
*mix = *(src++);
*(dst++) = (*(mix++) += *src)<<1;
*(dst++) = (*(mix++) = (*(src++)<<1))<<1;
}
dst += 80;
mix = buffer[0];
buf = buffer[1];
for(x=0; x<160; x+=2){
*(dst++) = *(mix++) + ((*(buf++) = (*src<<2))>>1);
*buf = *(src++)<<1;
*(dst++) = *(mix++) + ((*(buf++) += (*src<<1))>>1);
*(dst++) = *(mix++) + ((*(buf++) = (*(src++)<<2))>>1);
}
dst += 80;
memcpy(dst, buffer[1], 480);
dst += 320;
}
}


y luego (case 1 y 2):



void scaler_init(int scaler_number){
switch (upscaler){
case 1: /* 1.5 scaler */
case 2: /* 1.5 scaler with some smoothing ala scale3x / scale2x */
/* RGB343 */
fb.cc[0].r = screen->format->Rloss+2;
fb.cc[1].r = screen->format->Gloss+2;
fb.cc[2].r = screen->format->Bloss+2;
break;
case 3: /* Ayla full screen 320x240 (no aspect ration preservation) */
case 0: /* no scale, that is, native */
default:
/* RGB565 */
fb.cc[0].r = screen->format->Rloss;
fb.cc[1].r = screen->format->Gloss;
fb.cc[2].r = screen->format->Bloss;
//ohb_ayla_dingoo_scale();
break;
}
vid_fb.dirty = 1;
pal_dirty();
}



EDIT: Solucionado usando un scaler diferente. Se puede cerrar ya este hilo.