Mercurial > hg > Members > kono > Cerium
diff old/simple_render/viewer.cpp @ 507:735f76483bb2
Reorganization..
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 12 Oct 2009 09:39:35 +0900 |
parents | TaskManager/Test/simple_render/viewer.cpp@5c194c71eca8 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/old/simple_render/viewer.cpp Mon Oct 12 09:39:35 2009 +0900 @@ -0,0 +1,473 @@ +#include <iostream> +#include <SDL.h> +#include "polygon.h" +#include "viewer.h" +#include "sys.h" +#include "SpuSpan.h" +#include "Func.h" +#include "error.h" +#include "fb.h" +using namespace std; + +int Viewer::width; +int Viewer::height; +int Viewer::bpp; +int Viewer::spe_num; + +#define redMask 0x00ff0000 +#define greenMask 0x0000ff00 +#define blueMask 0x000000ff +#define alphaMask 0 + +extern int create_sgp(Polygon *sg, SceneGraphPack *sgp); + +#if 0 + #define MEMORY_ALLOCATION(dest, align, size) \ + posix_memalign((void**)(dest), (align), (size)) + //void posix_memalign(void** dest, size_t align, size_t size){ + //*dest = malloc(size); + //} +#else + #define MEMORY_ALLOCATION(dest, align, size) \ + *((void**)dest) = malloc((size)) +#endif + + + + +Viewer::Viewer(int b, int w, int h) +{ + bpp = b; + width = w; + height = h; + spe_num = 1; +} + +Viewer::Viewer(int b, int w, int h, int _num) +{ + bpp = b; + width = w; + height = h; + spe_num = _num; +} + +unsigned int fbdev_addr; + +void Viewer::sdl_init() +{ + if (SDL_Init( SDL_INIT_VIDEO ) < 0) { + fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError()); + exit( 1 ); + } + +#ifndef _DEBUG + screen = SDL_SetVideoMode( width, height, bpp, SDL_HWSURFACE); + if (screen == NULL) { + fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + fbdev_addr = (uint32)screen->pixels; +#else + fbdev_addr = get_fbdev_addr(); + if (fbdev_addr == 0) { + fbdev_addr = (unsigned int)(new Uint32[width*height*32/8]); + } + screen = SDL_CreateRGBSurfaceFrom((void*)fbdev_addr, width, height, 32, + width*4, redMask, greenMask, + blueMask, alphaMask); +#endif +} + + +int Viewer::get_ticks() +{ + int time; + time = SDL_GetTicks(); + return time; +} + +bool Viewer::quit_check() +{ + bool quit = false; + SDL_Event event; + while(SDL_PollEvent(&event)) + { + if(event.type==SDL_QUIT) + { + quit = true; + return quit; + } + } + return quit; +} + +void Viewer::quit() +{ + SDL_Quit(); +} + + +void Viewer::swap_buffers() +{ + SDL_GL_SwapBuffers(); +} + + +void +Viewer::write_pixel(int x, int y,float z, Uint32 rgb) +{ + x += width/2; + y += height/2; + + if (z < zRow[x][y]) { + if (x < width && x > 0 && y > 0 && y < height) { + zRow[x][y] = z; + y = height - y; + pixels[width*y + x] = rgb; + } + } +} + +void +Viewer::write_line(float x1, float y1, float x2, float y2, Uint32 rgb) +{ + if (x1 > x2) { + float x=0; + float y=0; + x=x1; + y=y1; + x1 = x2; + y1 = y2; + x2 = x; + y2 = y; + } + + float s = y1; + + if ((int)x1 == (int)x2) { + if (y1 > y2) { + float y=0; + y = y1; + y1 = y2; + y2 = y; + } + + for (float i=y1; i<y2; i++) { + //write_pixel((int)x1,(int)i); + write_pixel((int)x1,(int)i,0,rgb); + } + } else { + float t = (y2 - y1)/(x2 - x1); + if (t < -1) { + float f = 0; + for (float i=x1; i<x2; i++) { + for (float a=(int)t; a<0; a++) { + write_pixel((int)i,(int)s,0,rgb); + s--; + } + + f += t-(int)t; + + if (f <= -1) { + write_pixel((int)i,(int)s,0,rgb); + f = 0; + s--; + } + } + } else if (t <= 1) { + for(float i=x1; i<x2; i++) { + //write_pixel((int)i,(int)s); + write_pixel((int)i,(int)s,0,rgb); + s += t; + } + } else { + float f = 0; + for (float i=x1; i<x2; i++) { + for (float a=0; a<(int)t; a++) { + write_pixel((int)i,(int)s,0,rgb); + s++; + } + + f += t-(int)t; + + if (f >= 1) { + write_pixel((int)i,(int)s,0,rgb); + f = 0; + s++; + } + } + } + } +} + +void Viewer::write_triangle(float x1, float y1, float x2, float y2, float x3, float y3, Uint32 rgb) +{ + write_line(x1,y1,x2,y2,rgb); + write_line(x2,y2,x3,y3,rgb); + write_line(x3,y3,x1,y1,rgb); +} + +void Viewer::clean_pixels() +{ +#if 0 + for(int i=0; i<width*height; i++) + { + pixels[i] = 0x00; + } +#else + bzero(pixels, sizeof(int)*width*height); +#endif +} + +void Viewer::graph_line() +{ + int xl = width*height/2; + int yl = width/2; + for(int i=0; i<width; i++) + { + for(int t=0; t<height; t+=20) + { + pixels[width*t+i] = 0x5a; + } + pixels[xl +i] = 0xff; + } + for(int i=0; i<height; i++) + { + for(int t=0; t<width; t+=20) + { + pixels[i*width+t] = 0x5a; + } + pixels[i*width+yl] = 0xff; + } +} + +int start_time; +int this_time; +int frames; +SDL_Surface *bitmap; +SDL_PixelFormat *pixelFormat; +Uint32 background; +Polygon *polygon; +SceneGraphPack *sgp; +PolygonPack *pp; +SpuSpan *ssl; + +//SpanPack send_pack[6][10] __attribute__((aligned(16))); +SpanPack send_pack[SPE_NUM_MAX][MAX_SIZE_SPAN_PACK] __attribute__((aligned(16))); + +void *__texture; + +void +Viewer::run_init(char *xml) +{ + HTaskPtr task; + + start_time = get_ticks(); + this_time = 0; + frames = 0; + + pixelFormat = screen->format; + background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); + //polygon = new Polygon; + //polygon->set_data(xml); + polygon = Polygon::createFromXMLfile(xml); + polygon->viewer = this; + + // TaskManager 側で + // allocate API を作っておいた方がいい。 + // もしくは configure ?微妙か + //posix_memalign((void**)&sgp, 16, sizeof(SceneGraphPack)); + //posix_memalign((void**)&pp, 16, sizeof(PolygonPack)); + //posix_memalign((void**)&ssl, 16, sizeof(SpuSpan)); + //sgp = new SceneGraphPack; + //pp = new PolygonPack; + //ssl = new SpuSpan; + MEMORY_ALLOCATION( &sgp, 16, sizeof(SceneGraphPack)); + MEMORY_ALLOCATION( &pp, 16, sizeof(PolygonPack)); + MEMORY_ALLOCATION( &ssl, 16, sizeof(SpuSpan)); + create_sgp(polygon, sgp); + sgp->ssl = ssl; + + //pixels = new Uint32[width*height]; + pixels = (Uint32*)fbdev_addr; + //fbdev_addr = (Uint32)pixels; + //graph_line(); + + bitmap = SDL_CreateRGBSurfaceFrom((void *)pixels, width, height, 32, + width*4, redMask, greenMask, + blueMask, alphaMask); + + task = manager->create_task(VIEWER_RUN_LOOP, 0, 0, 0, NULL); + task->spawn(); + + //posix_memalign((void**)&__texture, 16, 128*128*3); + //__texture = malloc(128*128*3); + MEMORY_ALLOCATION( &__texture, 16, 128*128*3); + memcpy(__texture, polygon->texture_image->pixels, 128*128*3); + HTaskPtr task_init_tex; + + for (int i = 0; i < spe_num; i++) { + task_init_tex + = manager->create_task(TASK_INIT_TEXTURE, 0, + (uint32)__texture, 0, NULL); + //task_init_tex->set_cpu(CPU_SPE); + task_init_tex->set_cpu((CPU_TYPE)(i + SPE_0)); + task_init_tex->spawn(); + } +} + +void +Viewer::run_loop(void) +{ + HTaskPtr task_update_sgp = NULL; + HTaskPtr task_create_pp = NULL; + HTaskPtr task_create_sp = NULL; + HTaskPtr task_finish = NULL; + + HTaskPtr task; + bool quit_flg; + + quit_flg = quit_check(); + + SDL_BlitSurface(bitmap, NULL, screen, NULL); + SDL_UpdateRect(screen, 0, 0, 0, 0); + + if (quit_flg == true) { + this_time = get_ticks(); + task_finish = manager->create_task(VIEWER_RUN_FINISH, 0, 0, 0, NULL); + task_finish->spawn(); + return; + } + + // clean_pixels や zRow_init は、 + // spe で fb に draw する時は必要ない。 + // ppe 側で draw する時にだけ呼ぶべき。 + //clean_pixels(); + //zRow_init(); + + // これ自身、一つのタスクとして回す方がよいか + //graph_line(); + + task_update_sgp + = manager->create_task(TASK_UPDATE_SGP, sizeof(SceneGraphPack), + (uint32)sgp, (uint32)sgp, NULL); + task_create_pp + = manager->create_task(TASK_CREATE_PP, sizeof(SceneGraphPack), + (uint32)sgp, (uint32)pp, NULL); + task_create_sp + = manager->create_task(TASK_CREATE_SPAN, sizeof(PolygonPack), + (uint32)pp, 0, NULL); + + task = manager->create_task(VIEWER_RUN_DRAW, 0, 0, 0, NULL); + + task->wait_for(task_update_sgp); + task->wait_for(task_create_pp); + task->wait_for(task_create_sp); + task_create_sp->wait_for(task_create_pp); + + //task_update_sgp->set_cpu(CPU_SPE); + //task_create_pp->set_cpu(CPU_SPE); + + task_update_sgp->spawn(); + task_create_pp->spawn(); + task_create_sp->spawn(); + task->spawn(); +} + +/** + * 本当はタスクとして TestDraw を選ぶ + */ +//#define DRAW_POLYGON +#define DRAW_SPANPACK +//#define DRAW_SPUSPAN +void +Viewer::run_draw(void) +{ + HTaskPtr task_loop; + HTaskPtr task_draw; + + task_loop = manager->create_task(VIEWER_RUN_LOOP, 0, 0, 0, NULL); + +#if 1 + for (int j = 0; j < SPE_NUM_MAX; j++) { + for (int i = 0; i < MAX_SIZE_SPAN_PACK; i++) { + if (ssl->list[j].packs[i].info.size == 0) continue; + // memcpy はもちろんだめ。だけど。。。 + // SPUSPAN->ss は配列で、各要素がアライメントとれてないと駄目。 +#if 1 + memcpy(&send_pack[j][i], &ssl->list[j].packs[i], sizeof(SpanPack)); + task_draw + = manager->create_task(TASK_DRAW, sizeof(SpanPack), + (uint32)&send_pack[j][i], fbdev_addr, NULL); +#else + task_draw + = manager->create_task(TASK_DRAW, sizeof(SpanPack), + (uint32)&ssl->list[j].packs[i], + fbdev_addr, NULL); +#endif + //task_draw->set_cpu(CPU_SPE); + // もう少し良い選び方があってもいいはずだ + // てか ANY にすればいいんじゃね + task_draw->set_cpu((CPU_TYPE)(((i+j)%spe_num) + SPE_0)); + //task_draw->set_cpu(CPU_PPE); + task_loop->wait_for(task_draw); + task_draw->spawn(); + } + } +#endif + task_loop->spawn(); + frames++; + + return; + +#ifdef DRAW_POLYGON + //polygon->draw(pp); // test draw of PolygonPack + polygon->draw(sgp); // test draw of PolygonPack +#else +# ifdef DRAW_SPANPACK // test draw of SpanPack + for (int j = 0; j < SPE_NUM_MAX; j++) { + for (int i = 0; i < MAX_SIZE_SPAN_PACK; i++) { + if (ssl->list[j].packs[i].info.size < 1) continue; + polygon->draw(&ssl->list[j].packs[i]); + } + } +# else + polygon->draw(&ssl->ss[0]); + polygon->draw(&ssl->ss[1]); + polygon->draw(&ssl->ss[2]); + polygon->draw(&ssl->ss[3]); + polygon->draw(&ssl->ss[4]); + polygon->draw(&ssl->ss[5]); +# endif +#endif + + SDL_BlitSurface(bitmap, NULL, screen, NULL); + SDL_UpdateRect(screen, 0, 0, 0, 0); +} + +void +Viewer::run_finish(void) +{ + if (this_time != start_time) { + cout<< (((float)frames)/(this_time-start_time))*1000.0 << " FPS\n"; + } + + SDL_FreeSurface(bitmap); + //delete [] pixels; + polygon->delete_data(); + delete polygon; + + free(__texture); + quit(); +} + +void +Viewer::zRow_init() +{ + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + zRow[i][j] = 65535; + } + } +}