void run(void) { int i; fbx_struct stressfb; memset(&stressfb, 0, sizeof(stressfb)); try { int mywidth, myheight, myx=0, myy=0; if(myrank<2) {mywidth=width/2; myx=0;} else {mywidth=width-width/2; myx=width/2;} if(myrank%2==0) {myheight=height/2; myy=0;} else {myheight=height-height/2; myy=height/2;} fbx(fbx_init(&stressfb, wh, mywidth, myheight, useshm)); if(useshm && !stressfb.shm) _throw("MIT-SHM not available"); initbuf(myx, myy, mywidth, stressfb.pitch, myheight, stressfb.format, (unsigned char *)stressfb.bits); for (i=0; i<iter; i++) fbx(fbx_write(&stressfb, 0, 0, myx, myy, mywidth, myheight)); } catch(...) {fbx_term(&stressfb); throw;} }
void run(void) { fbx_struct stressfb; memset(&stressfb, 0, sizeof(stressfb)); try { int i, mywidth, myheight, myx=0, myy=0; if(myrank<2) {mywidth=width/2; myx=0;} else {mywidth=width-width/2; myx=width/2;} if(myrank%2==0) {myheight=height/2; myy=0;} else {myheight=height-height/2; myy=height/2;} fbx(fbx_init(&stressfb, wh, mywidth, myheight, useshm)); if(useshm && !stressfb.shm) _throw("MIT-SHM not available"); int ps=fbx_ps[stressfb.format]; memset(stressfb.bits, 0, mywidth*myheight*ps); for(i=0; i<iter; i++) fbx(fbx_read(&stressfb, myx, myy)); if(!cmpbuf(myx, myy, mywidth, stressfb.pitch, myheight, stressfb.format, (unsigned char *)stressfb.bits)) _throw("ERROR: Bogus data read back."); } catch(...) {fbx_term(&stressfb); throw;} }
// Platform-specific readback test void nativeread(int useshm) { fbx_struct s; int n, i; double rbtime; memset(&s, 0, sizeof(s)); try { fbx(fbx_init(&s, wh, 0, 0, useshm)); int ps=fbx_ps[s.format]; if(useshm && !s.shm) _throw("MIT-SHM not available"); if(s.width!=width || s.height!=height) _throw("The benchmark window lost input focus or was obscured.\nSkipping native read test\n"); if(useshm) fprintf(stderr, "FBX read [SHM]: "); else fprintf(stderr, "FBX read: "); memset(s.bits, 0, width*height*ps); n=N; do { n+=n; timer.start(); for(i=0; i<n; i++) { fbx(fbx_read(&s, 0, 0)); } rbtime=timer.elapsed(); if(!cmpbuf(0, 0, width, s.pitch, height, s.format, (unsigned char *)s.bits)) _throw("ERROR: Bogus data read back."); } while (rbtime<1.); fprintf(stderr, "%f Mpixels/sec\n", (double)n*(double)(width*height)/((double)1000000.*rbtime)); } catch(rrerror &e) {fprintf(stderr, "%s\n", e.getMessage());} fbx_term(&s); }
int fbx_init(fbx_struct *fb, fbx_wh wh, int width_, int height_, int useShm) { int width, height; int rmask, gmask, bmask, ps, i; #ifdef _WIN32 BMINFO bminfo; HBITMAP hmembmp=0; RECT rect; HDC hdc=NULL; #else XWindowAttributes xwa; int shmok=1, alphaFirst, pixmap=0; #endif if(!fb) _throw("Invalid argument"); #ifdef _WIN32 if(!wh) _throw("Invalid argument"); _w32(GetClientRect(wh, &rect)); if(width_>0) width=width_; else { width=rect.right-rect.left; if(width<=0) width=MINWIDTH; } if(height_>0) height=height_; else { height=rect.bottom-rect.top; if(height<=0) height=MINHEIGHT; } if(fb->wh==wh) { if(width==fb->width && height==fb->height && fb->hmdc && fb->hdib && fb->bits) return 0; else if(fbx_term(fb)==-1) return -1; } memset(fb, 0, sizeof(fbx_struct)); fb->wh=wh; _w32(hdc=GetDC(fb->wh)); _w32(fb->hmdc=CreateCompatibleDC(hdc)); _w32(hmembmp=CreateCompatibleBitmap(hdc, width, height)); _w32(GetDeviceCaps(hdc, RASTERCAPS)&RC_BITBLT); _w32(GetDeviceCaps(fb->hmdc, RASTERCAPS)&RC_DI_BITMAP); bminfo.bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bminfo.bmi.bmiHeader.biBitCount=0; _w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS)); _w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS)); _w32(DeleteObject(hmembmp)); hmembmp=0; /* (we only needed it to get the screen properties) */ ps=bminfo.bmi.bmiHeader.biBitCount/8; if(width>0) bminfo.bmi.bmiHeader.biWidth=width; if(height>0) bminfo.bmi.bmiHeader.biHeight=height; fb->width=bminfo.bmi.bmiHeader.biWidth; fb->height=bminfo.bmi.bmiHeader.biHeight; if(ps<3) { /* Make the buffer BGRA */ bminfo.bmi.bmiHeader.biCompression=BI_BITFIELDS; bminfo.bmi.bmiHeader.biBitCount=32; ps=4; (*(DWORD *)&bminfo.bmi.bmiColors[0])=0xFF0000; (*(DWORD *)&bminfo.bmi.bmiColors[1])=0xFF00; (*(DWORD *)&bminfo.bmi.bmiColors[2])=0xFF; } fb->pitch=BMPPAD(fb->width*ps); /* Windoze bitmaps are always padded */ if(bminfo.bmi.bmiHeader.biCompression==BI_BITFIELDS) { rmask=(*(DWORD *)&bminfo.bmi.bmiColors[0]); gmask=(*(DWORD *)&bminfo.bmi.bmiColors[1]); bmask=(*(DWORD *)&bminfo.bmi.bmiColors[2]); } else { rmask=0xFF0000; gmask=0xFF00; bmask=0xFF; } fb->format=-1; for(i=0; i<FBX_FORMATS; i++) if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i] && ps==fbx_ps[i] && fbx_alphafirst[i]==0) fb->format=i; if(fb->format==-1) _throw("Display has unsupported pixel format"); bminfo.bmi.bmiHeader.biHeight=-bminfo.bmi.bmiHeader.biHeight; /* (our convention is top-down) */ _w32(fb->hdib=CreateDIBSection(hdc, &bminfo.bmi, DIB_RGB_COLORS, (void **)&fb->bits, NULL, 0)); _w32(SelectObject(fb->hmdc, fb->hdib)); ReleaseDC(fb->wh, hdc); return 0; finally: if(hmembmp) DeleteObject(hmembmp); if(hdc) ReleaseDC(fb->wh, hdc); #else if(!wh.dpy || !wh.d) _throw("Invalid argument"); if(wh.v) { _x11(XGetGeometry(wh.dpy, wh.d, &xwa.root, &xwa.x, &xwa.y, (unsigned int *)&xwa.width, (unsigned int *)&xwa.height, (unsigned int *)&xwa.border_width, (unsigned int *)&xwa.depth)); xwa.visual=wh.v; useShm=0; pixmap=1; } else { _x11(XGetWindowAttributes(wh.dpy, wh.d, &xwa)); } if(width_>0) width=width_; else width=xwa.width; if(height_>0) height=height_; else height=xwa.height; if(fb->wh.dpy==wh.dpy && fb->wh.d==wh.d) { if(width==fb->width && height==fb->height && fb->xi && fb->xgc && fb->bits) return 0; else if(fbx_term(fb)==-1) return -1; } memset(fb, 0, sizeof(fbx_struct)); fb->wh.dpy=wh.dpy; fb->wh.d=wh.d; #ifdef USESHM if(!useShm) { static int alreadyWarned=0; if(!alreadyWarned && warningFile) { fprintf(warningFile, "[FBX] Disabling shared memory blitting\n"); alreadyWarned=1; } } if(useShm && XShmQueryExtension(fb->wh.dpy)) { static int alreadyWarned=0; fb->shminfo.shmid=-1; if(!(fb->xi=XShmCreateImage(fb->wh.dpy, xwa.visual, xwa.depth, ZPixmap, NULL, &fb->shminfo, width, height))) { useShm=0; goto noshm; } if((fb->shminfo.shmid=shmget(IPC_PRIVATE, fb->xi->bytes_per_line*fb->xi->height+1, IPC_CREAT|0777))==-1) { useShm=0; XDestroyImage(fb->xi); goto noshm; } if((fb->shminfo.shmaddr=fb->xi->data =(char *)shmat(fb->shminfo.shmid, 0, 0))==(char *)-1) { useShm=0; XDestroyImage(fb->xi); shmctl(fb->shminfo.shmid, IPC_RMID, 0); goto noshm; } fb->shminfo.readOnly=False; XLockDisplay(fb->wh.dpy); XSync(fb->wh.dpy, False); prevHandler=XSetErrorHandler(xhandler); extok=1; serial=NextRequest(fb->wh.dpy); XShmAttach(fb->wh.dpy, &fb->shminfo); XSync(fb->wh.dpy, False); XSetErrorHandler(prevHandler); shmok=extok; if(!alreadyWarned && !shmok && warningFile) { fprintf(warningFile, "[FBX] WARNING: MIT-SHM extension failed to initialize (this is normal on a\n"); fprintf(warningFile, "[FBX] remote connection.) Will use X Pixmap drawing instead.\n"); alreadyWarned=1; } XUnlockDisplay(fb->wh.dpy); if(shmok) { char *env=getenv("FBX_USESHMPIXMAPS"); if(env && !strcmp(env, "1")) { static int alreadyWarned=0; if(!alreadyWarned && warningFile) { fprintf(warningFile, "[FBX] Using MIT-SHM pixmaps\n"); alreadyWarned=1; } fb->pm=XShmCreatePixmap(fb->wh.dpy, fb->wh.d, fb->shminfo.shmaddr, &fb->shminfo, width, height, xwa.depth); if(!fb->pm) shmok=0; } } shmctl(fb->shminfo.shmid, IPC_RMID, 0); if(!shmok) { useShm=0; XDestroyImage(fb->xi); shmdt(fb->shminfo.shmaddr); shmctl(fb->shminfo.shmid, IPC_RMID, 0); goto noshm; } fb->xattach=1; fb->shm=1; } else if(useShm) { static int alreadyWarned=0; if(!alreadyWarned && warningFile) { fprintf(warningFile, "[FBX] WARNING: MIT-SHM extension not available. Will use X pixmap\n"); fprintf(warningFile, "[FBX] drawing instead.\n"); alreadyWarned=1; } useShm=0; } noshm: if(!useShm) #endif { if(!pixmap) _x11(fb->pm=XCreatePixmap(fb->wh.dpy, fb->wh.d, width, height, xwa.depth)); _x11(fb->xi=XCreateImage(fb->wh.dpy, xwa.visual, xwa.depth, ZPixmap, 0, NULL, width, height, 8, 0)); if((fb->xi->data=(char *)malloc(fb->xi->bytes_per_line*fb->xi->height+1)) ==NULL) _throw("Memory allocation error"); } ps=fb->xi->bits_per_pixel/8; fb->width=fb->xi->width; fb->height=fb->xi->height; fb->pitch=fb->xi->bytes_per_line; if(fb->width!=width || fb->height!=height) _throw("Bitmap returned does not match requested size"); rmask=fb->xi->red_mask; gmask=fb->xi->green_mask; bmask=fb->xi->blue_mask; alphaFirst=0; if(fb->xi->byte_order==MSBFirst) { if(ps<4) { rmask=fb->xi->blue_mask; gmask=fb->xi->green_mask; bmask=fb->xi->red_mask; } else alphaFirst=1; } fb->format=-1; for(i=0; i<FBX_FORMATS; i++) if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i] && ps==fbx_ps[i] && fbx_alphafirst[i]==alphaFirst) fb->format=i; if(fb->format==-1) _throw("Display has unsupported pixel format"); fb->bits=fb->xi->data; fb->pixmap=pixmap; _x11(fb->xgc=XCreateGC(fb->wh.dpy, fb->pm? fb->pm:fb->wh.d, 0, NULL)); return 0; finally: #endif fbx_term(fb); return -1; }
// Platform-specific write test void nativewrite(int useshm) { fbx_struct s; int n, i; double rbtime; memset(&s, 0, sizeof(s)); try { fbx(fbx_init(&s, wh, 0, 0, useshm)); if(useshm && !s.shm) _throw("MIT-SHM not available"); fprintf(stderr, "Native Pixel Format: %s", fbx_formatname(s.format)); fprintf(stderr, "\n"); if(s.width!=width || s.height!=height) _throw("The benchmark window lost input focus or was obscured.\nSkipping native write test\n"); clearfb(); initbuf(0, 0, width, s.pitch, height, s.format, (unsigned char *)s.bits); if(useshm) fprintf(stderr, "FBX bottom-up write [SHM]: "); else fprintf(stderr, "FBX bottom-up write: "); n=N; do { n+=n; timer.start(); for (i=0; i<n; i++) { if(checkdb) { memset(s.bits, 255, s.pitch*s.height); fbx(fbx_awrite(&s, 0, 0, 0, 0, 0, 0)); initbuf(0, 0, width, s.pitch, height, s.format, (unsigned char *)s.bits); } fbx(fbx_flip(&s, 0, 0, 0, 0)); fbx(fbx_write(&s, 0, 0, 0, 0, 0, 0)); } rbtime=timer.elapsed(); } while(rbtime<1.); fprintf(stderr, "%f Mpixels/sec\n", (double)n*(double)(width*height)/((double)1000000.*rbtime)); clearfb(); if(useshm) fprintf(stderr, "FBX top-down write [SHM]: "); else fprintf(stderr, "FBX top-down write: "); n=N; do { n+=n; timer.start(); for (i=0; i<n; i++) { if(checkdb) { memset(s.bits, 255, s.pitch*s.height); fbx(fbx_awrite(&s, 0, 0, 0, 0, 0, 0)); initbuf(0, 0, width, s.pitch, height, s.format, (unsigned char *)s.bits); } fbx(fbx_write(&s, 0, 0, 0, 0, 0, 0)); } rbtime=timer.elapsed(); } while(rbtime<1.); fprintf(stderr, "%f Mpixels/sec\n", (double)n*(double)(width*height)/((double)1000000.*rbtime)); } catch(rrerror &e) {fprintf(stderr, "%s\n", e.getMessage());} fbx_term(&s); }