Dexter's patch didn't make as much difference as I'd hoped. Probably gcc sucks. A few extra FPS is still welcome, though :)
Vegac, as you rightly pointed out on #nekochan, the YCrCb extension doesn't work with glTexSubImage2D() so one can't have hardware colourspace conversion && textured zooming on O2... but actually you can, with some messing about with UMA. If you know the PBuffer-as-texture trick then disregard this, otherwise this is ripped wholesale from something else I'm writing so it should work, ish:
Obviously... link with -ldmedia too.
Code:
#include <dmedia.h>
Make and init a texture, nothing new here, move along...
Code:
int tex;
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
Make a DMbufferpool suitable for GL with just one buffer in it:
Code:
DMparams *texPoolParams, *texImageParams;
DMbufferpool texPool;
DMbuffer texDMBuffer;
dmParamsCreate(&texImageParams);
dmSetImageDefaults(texImageParams, 1024, 1024, DM_IMAGE_PACKING_RGBA);
dmParamsSetEnum(texImageParams, DM_IMAGE_LAYOUT, DM_IMAGE_LAYOUT_GRAPHICS);
dmParamsCreate(&texPoolParams);
dmBufferSetPoolDefaults(texPoolParams, 1, 1024 * 1024 * 4, DM_FALSE, DM_FALSE);
dmBufferGetGLPoolParams(texImageParams, texPoolParams);
dmBufferCreatePool(texPoolParams, &texPool);
dmBufferAllocate(texPool, texDMBuffer);
Make a PBuffer:
Code:
GLXFBConfig *fbConfigs;
GLXPbuffer texPBuffer;
int configCount;
int fbAttrs[] = {GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
GLX_DOUBLEBUFFER, False,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
None};
int pbAttrs[] = {GLX_PBUFFER_WIDTH, 1024,
GLX_PBUFFER_HEIGHT, 1024,
GLX_PRESERVED_CONTENTS, True,
GLX_DIGITAL_MEDIA_PBUFFER_SGIX, True,
None};
fbConfigs = glXChooseFBConfig(xDisplay, DefaultScreen(xDisplay), fbAttrs,
&configCount);
texPBuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbAttrs);
Associate the PBuffer with the DMBuffer. The glTexSubImage2D() copies by reference (hurrah!) if everything above has worked, so you only need to do it once. Thereafter drawing into the PBuffer draws straight into the texture.
Code:
glXAssociateDMPbufferSGIX(xDisplay, texPBuffer, texImageParams, texDMBuffer);
glXMakeContextCurrent(xDisplay, glxPBuffer, glxPBuffer, glxContext);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1024, 1024);
Now on each frame, you draw into the texture, then draw a textured quad as big as you like, keeping aspect would be a good plan:
Code:
glXMakeContextCurrent(xDisplay, texPBuffer, texPBuffer, glxContext);
glRasterPos2i(0, height);
glPixelZoom(1.0, -1.0);
glDrawPixels(width, height, GL_YCRCB_422_SGIX, GL_UNSIGNED_BYTE, pixels);
glXMakeContextCurrent(xDisplay, glxWindow, glxWindow, glxContext);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2i(0, 0);
glTexCoord2f(0.0, (float)height/1024.0);
glVertex2i(0, 1024);
glTexCoord2f((float)width/1024.0, (float)height/1024.0);
glVertex2i(1280, 1024);
glTexCoord2f((float)width/1024.0, 0.0);
glVertex2i(1280, 0);
glEnd();
glXSwapBuffers(xDisplay, glxWin);
I'm sure you get the idea... some checking of return vales and liberal use of XFree() might be wise :) Crime can handle the fill rates up to PAL sizes. Should go at about the same speed as using glTexSubImage2D() on every frame in the normal textured-zooming manner. Wouldn't cope with zooming PAL up to 1600x1024, perhaps, that would be about 51MPixels/sec, probably not achievable on mips4 O2s and surely not on the broken 175Mhz R10k.
Enjoy...