#include "gamma_context.h"
#include "gamma_vb.h"
#include "context.h"
#include "matrix.h"
#include "glint_dri.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "array_cache/acache.h"
static GLboolean
gammaInitDriver(__DRIscreenPrivate *sPriv)
{
sPriv->private = (void *) gammaCreateScreen( sPriv );
if (!sPriv->private) {
gammaDestroyScreen( sPriv );
return GL_FALSE;
}
return GL_TRUE;
}
static void
gammaDestroyContext(__DRIcontextPrivate *driContextPriv)
{
gammaContextPtr gmesa = (gammaContextPtr)driContextPriv->driverPrivate;
if (gmesa) {
_swsetup_DestroyContext( gmesa->glCtx );
_tnl_DestroyContext( gmesa->glCtx );
_ac_DestroyContext( gmesa->glCtx );
_swrast_DestroyContext( gmesa->glCtx );
gammaFreeVB( gmesa->glCtx );
gmesa->glCtx->DriverCtx = NULL;
_mesa_destroy_context(gmesa->glCtx);
Xfree(gmesa);
driContextPriv->driverPrivate = NULL;
}
}
static GLboolean
gammaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
if (isPixmap) {
return GL_FALSE;
}
else {
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer(mesaVis,
GL_FALSE,
mesaVis->stencilBits > 0,
mesaVis->accumRedBits > 0,
mesaVis->alphaBits > 0
);
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
gammaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
}
static void
gammaSwapBuffers( __DRIdrawablePrivate *dPriv )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
gammaContextPtr gmesa;
__DRIscreenPrivate *driScrnPriv;
GLcontext *ctx;
gmesa = (gammaContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = gmesa->glCtx;
driScrnPriv = gmesa->driScreen;
_mesa_notifySwapBuffers(ctx);
VALIDATE_DRAWABLE_INFO(gmesa);
FLUSH_DMA_BUFFER(gmesa);
DRM_SPINLOCK(&driScrnPriv->pSAREA->drawable_lock,
driScrnPriv->drawLockID);
VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER) {
int src, dst, x0, y0, x1, h;
int i;
int nRect = dPriv->numClipRects;
XF86DRIClipRectPtr pRect = dPriv->pClipRects;
__DRIscreenPrivate *driScrnPriv = gmesa->driScreen;
GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;
CHECK_DMA_BUFFER(gmesa, 2);
WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
FBReadSrcEnable));
WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);
for (i = 0; i < nRect; i++, pRect++) {
x0 = pRect->x1;
x1 = pRect->x2;
h = pRect->y2 - pRect->y1;
y0 = driScrnPriv->fbHeight - (pRect->y1+h);
if (gDRIPriv->numMultiDevices == 2)
src = (y0/2)*driScrnPriv->fbWidth+x0;
else
src = y0*driScrnPriv->fbWidth+x0;
y0 += driScrnPriv->fbHeight;
if (gDRIPriv->numMultiDevices == 2)
dst = (y0/2)*driScrnPriv->fbWidth+x0;
else
dst = y0*driScrnPriv->fbWidth+x0;
CHECK_DMA_BUFFER(gmesa, 9);
WRITE(gmesa->buf, StartXDom, x0<<16);
WRITE(gmesa->buf, StartY, y0<<16);
WRITE(gmesa->buf, StartXSub, x1<<16);
WRITE(gmesa->buf, GLINTCount, h);
WRITE(gmesa->buf, dY, 1<<16);
WRITE(gmesa->buf, dXDom, 0<<16);
WRITE(gmesa->buf, dXSub, 0<<16);
WRITE(gmesa->buf, FBSourceOffset, (dst-src));
WRITE(gmesa->buf, Render, 0x00040048);
}
CHECK_DMA_BUFFER(gmesa, 2);
WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
gmesa->AB_FBReadMode));
WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
}
if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
DRM_SPINUNLOCK(&driScrnPriv->pSAREA->drawable_lock,
driScrnPriv->drawLockID);
VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
} else {
_mesa_problem(NULL, "gammaSwapBuffers: drawable has no context!\n");
}
}
static GLboolean
gammaMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
if (driContextPriv) {
GET_CURRENT_CONTEXT(ctx);
gammaContextPtr oldGammaCtx = ctx ? GAMMA_CONTEXT(ctx) : NULL;
gammaContextPtr newGammaCtx = (gammaContextPtr) driContextPriv->driverPrivate;
if ( newGammaCtx != oldGammaCtx ) {
newGammaCtx->dirty = ~0;
}
if (newGammaCtx->driDrawable != driDrawPriv) {
newGammaCtx->driDrawable = driDrawPriv;
gammaUpdateWindow ( newGammaCtx->glCtx );
gammaUpdateViewportOffset( newGammaCtx->glCtx );
}
#if 0
newGammaCtx->Window &= ~W_GIDMask;
newGammaCtx->Window |= (driDrawPriv->index << 5);
CHECK_DMA_BUFFER(newGammaCtx,1);
WRITE(newGammaCtx->buf, GLINTWindow, newGammaCtx->Window);
#endif
newGammaCtx->new_state |= GAMMA_NEW_WINDOW;
_mesa_make_current2( newGammaCtx->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );
if (!newGammaCtx->glCtx->Viewport.Width) {
_mesa_set_viewport(newGammaCtx->glCtx, 0, 0,
driDrawPriv->w, driDrawPriv->h);
}
} else {
_mesa_make_current( 0, 0 );
}
return GL_TRUE;
}
static GLboolean
gammaUnbindContext( __DRIcontextPrivate *driContextPriv )
{
return GL_TRUE;
}
static GLboolean
gammaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
static GLboolean
gammaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
static struct __DriverAPIRec gammaAPI = {
gammaInitDriver,
gammaDestroyScreen,
gammaCreateContext,
gammaDestroyContext,
gammaCreateBuffer,
gammaDestroyBuffer,
gammaSwapBuffers,
gammaMakeCurrent,
gammaUnbindContext,
gammaOpenFullScreen,
gammaCloseFullScreen
};
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &gammaAPI);
return (void *) psp;
}