xserver-multidpi/hw/xfree86/xf8_32bpp/cfbscrinit.c
Eric Anholt e4d11e58ce Remove the PaintWindow optimization.
This was an attempt to avoid scratch gc creation and validation for paintwin
because that was expensive.  This is not the case in current servers, and the
danger of failure to implement it correctly (as seen in all previous
implementations) is high enough to justify removing it.  No performance
difference detected with x11perf -create -move -resize -circulate on Xvfb.
Leave the screen hooks for PaintWindow* in for now to avoid ABI change.
2007-09-13 00:08:53 +00:00

313 lines
8.4 KiB
C

#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <X11/X.h>
#include <X11/Xmd.h>
#include "misc.h"
#include "servermd.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "resource.h"
#include "colormap.h"
#include "colormapst.h"
#define PSZ 8
#include "cfb.h"
#undef PSZ
#include "cfb32.h"
#include "cfb8_32.h"
#include "mi.h"
#include "micmap.h"
#include "mistruct.h"
#include "dix.h"
#include "mibstore.h"
#include "mioverlay.h"
#include "xf86.h"
#include "xf86str.h"
#include "globals.h"
/* CAUTION: We require that cfb8 and cfb32 were NOT
compiled with CFB_NEED_SCREEN_PRIVATE */
int cfb8_32GCPrivateIndex;
int cfb8_32GetGCPrivateIndex(void) { return cfb8_32GCPrivateIndex; }
int cfb8_32ScreenPrivateIndex;
int cfb8_32GetScreenPrivateIndex(void) { return cfb8_32ScreenPrivateIndex; }
static unsigned long cfb8_32Generation = 0;
static Bool
cfb8_32AllocatePrivates(ScreenPtr pScreen)
{
cfb8_32ScreenPtr pScreenPriv;
if(cfb8_32Generation != serverGeneration) {
if(((cfb8_32GCPrivateIndex = AllocateGCPrivateIndex()) < 0) ||
((cfb8_32ScreenPrivateIndex = AllocateScreenPrivateIndex()) < 0))
return FALSE;
cfb8_32Generation = serverGeneration;
}
if (!(pScreenPriv = xalloc(sizeof(cfb8_32ScreenRec))))
return FALSE;
pScreen->devPrivates[cfb8_32ScreenPrivateIndex].ptr = (pointer)pScreenPriv;
/* All cfb will have the same GC and Window private indicies */
if(!mfbAllocatePrivates(pScreen, &cfbGCPrivateIndex))
return FALSE;
if(!AllocateGCPrivate(pScreen, cfbGCPrivateIndex, sizeof(cfbPrivGC)))
return FALSE;
if(!AllocateGCPrivate(pScreen, cfb8_32GCPrivateIndex, sizeof(cfb8_32GCRec)))
return FALSE;
return TRUE;
}
static void DestroyColormapNoop(
ColormapPtr pColormap)
{
/* NOOP */
}
static void StoreColorsNoop(
ColormapPtr pColormap,
int ndef,
xColorItem * pdef)
{
/* NOOP */
}
static Bool
cfb8_32SetupScreen(
ScreenPtr pScreen,
pointer pbits, /* pointer to screen bitmap */
int xsize, int ysize, /* in pixels */
int dpix, int dpiy, /* dots per inch */
int width /* pixel width of frame buffer */
){
if (!cfb8_32AllocatePrivates(pScreen))
return FALSE;
pScreen->defColormap = FakeClientID(0);
/* let CreateDefColormap do whatever it wants for pixels */
pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
pScreen->QueryBestSize = mfbQueryBestSize;
/* SaveScreen */
pScreen->GetImage = cfb8_32GetImage;
pScreen->GetSpans = cfb8_32GetSpans;
pScreen->CreateWindow = cfb8_32CreateWindow;
pScreen->DestroyWindow = cfb8_32DestroyWindow;
pScreen->PositionWindow = cfb8_32PositionWindow;
pScreen->ChangeWindowAttributes = cfb8_32ChangeWindowAttributes;
pScreen->RealizeWindow = cfb32MapWindow; /* OK */
pScreen->UnrealizeWindow = cfb32UnmapWindow; /* OK */
pScreen->CopyWindow = cfb8_32CopyWindow;
pScreen->CreatePixmap = cfb32CreatePixmap; /* OK */
pScreen->DestroyPixmap = cfb32DestroyPixmap; /* OK */
pScreen->RealizeFont = mfbRealizeFont;
pScreen->UnrealizeFont = mfbUnrealizeFont;
pScreen->CreateGC = cfb8_32CreateGC;
pScreen->CreateColormap = miInitializeColormap;
pScreen->DestroyColormap = DestroyColormapNoop;
pScreen->InstallColormap = miInstallColormap;
pScreen->UninstallColormap = miUninstallColormap;
pScreen->ListInstalledColormaps = miListInstalledColormaps;
pScreen->StoreColors = StoreColorsNoop;
pScreen->ResolveColor = miResolveColor;
pScreen->BitmapToRegion = mfbPixmapToRegion;
mfbRegisterCopyPlaneProc (pScreen, cfb8_32CopyPlane);
return TRUE;
}
typedef struct {
pointer pbits;
int width;
} miScreenInitParmsRec, *miScreenInitParmsPtr;
static Bool
cfb8_32CreateScreenResources(ScreenPtr pScreen)
{
miScreenInitParmsPtr pScrInitParms;
int pitch;
Bool retval;
/* get the pitch before mi destroys it */
pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
pitch = pScrInitParms->width << 2;
if((retval = miCreateScreenResources(pScreen))) {
/* fix the screen pixmap */
PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate;
pPix->drawable.bitsPerPixel = 32;
pPix->drawable.depth = 8;
pPix->devKind = pitch;
}
return retval;
}
static Bool
cfb8_32CloseScreen (int i, ScreenPtr pScreen)
{
cfb8_32ScreenPtr pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
if(pScreenPriv->visualData)
xfree(pScreenPriv->visualData);
xfree((pointer) pScreenPriv);
pScreen->devPrivates[cfb8_32ScreenPrivateIndex].ptr = NULL;
return(cfb32CloseScreen(i, pScreen));
}
static void
cfb8_32TransFunc(
ScreenPtr pScreen,
int nbox,
BoxPtr pbox
){
cfb8_32FillBoxSolid8(&(WindowTable[pScreen->myNum]->drawable),
nbox, pbox, xf86Screens[pScreen->myNum]->colorKey);
}
static Bool
cfb8_32InOverlayFunc(WindowPtr pWin)
{
return (pWin->drawable.depth == 8);
}
static Bool
cfb8_32FinishScreenInit(
ScreenPtr pScreen,
pointer pbits, /* pointer to screen bitmap */
int xsize, int ysize, /* in pixels */
int dpix, int dpiy, /* dots per inch */
int width /* pixel width of frame buffer */
){
VisualPtr visuals;
DepthPtr depths;
int nvisuals;
int ndepths;
int rootdepth;
VisualID defaultVisual;
rootdepth = 0;
if (!miInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
&defaultVisual,((unsigned long)1<<(32-1)), 8, -1))
return FALSE;
if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
rootdepth, ndepths, depths,
defaultVisual, nvisuals, visuals))
return FALSE;
pScreen->CreateScreenResources = cfb8_32CreateScreenResources;
pScreen->CloseScreen = cfb8_32CloseScreen;
pScreen->GetScreenPixmap = cfb32GetScreenPixmap; /* OK */
pScreen->SetScreenPixmap = cfb32SetScreenPixmap; /* OK */
if (! miInitOverlay(pScreen, cfb8_32InOverlayFunc, cfb8_32TransFunc))
return FALSE;
return TRUE;
}
static void
cfb8_32EnableDisableFBAccess (
int index,
Bool enable
){
ScreenPtr pScreen = screenInfo.screens[index];
cfb8_32ScreenPtr pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
miOverlaySetRootClip(pScreen, enable);
(*pScreenPriv->EnableDisableFBAccess) (index, enable);
}
static Atom overlayVisualsAtom;
typedef struct {
CARD32 overlay_visual;
CARD32 transparent_type;
CARD32 value;
CARD32 layer;
} overlayVisualRec;
static void
cfb8_32SetupVisuals (ScreenPtr pScreen)
{
cfb8_32ScreenPtr pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
char atomString[] = {"SERVER_OVERLAY_VISUALS"};
overlayVisualRec *overlayVisuals;
VisualID *visuals = NULL;
int numVisuals = 0;
DepthPtr pDepth = pScreen->allowedDepths;
int numDepths = pScreen->numDepths;
int i;
/* find depth 8 visuals */
for(i = 0; i < numDepths; i++, pDepth++) {
if(pDepth->depth == 8) {
numVisuals = pDepth->numVids;
visuals = pDepth->vids;
break;
}
}
if(!numVisuals || !visuals) {
ErrorF("No overlay visuals found!\n");
return;
}
if(!(overlayVisuals = xalloc(numVisuals * sizeof(overlayVisualRec))))
return;
for(i = 0; i < numVisuals; i++) {
overlayVisuals[i].overlay_visual = visuals[i];
overlayVisuals[i].transparent_type = 1; /* transparent pixel */
overlayVisuals[i].value = pScreenPriv->key;
overlayVisuals[i].layer = 1;
}
overlayVisualsAtom = MakeAtom(atomString, sizeof(atomString) - 1, TRUE);
xf86RegisterRootWindowProperty(pScreen->myNum, overlayVisualsAtom,
overlayVisualsAtom, 32, numVisuals * 4, overlayVisuals);
pScreenPriv->visualData = (pointer)overlayVisuals;
}
Bool
cfb8_32ScreenInit(
ScreenPtr pScreen,
pointer pbits, /* pointer to screen bitmap */
int xsize, int ysize, /* in pixels */
int dpix, int dpiy, /* dots per inch */
int w /* pixel width of frame buffer */
){
cfb8_32ScreenPtr pScreenPriv;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
if (!cfb8_32SetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, w))
return FALSE;
pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
pScreenPriv->key = pScrn->colorKey;
pScreenPriv->visualData = NULL;
pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
pScrn->EnableDisableFBAccess = cfb8_32EnableDisableFBAccess;
if(cfb8_32FinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, w))
{
cfb8_32SetupVisuals(pScreen);
return TRUE;
}
return FALSE;
}