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;
+	}
+    }
+}