Re: [PATCH 1/3] Add screen-specific privates.

2012-07-05 Thread Keith Packard
Keith Packard kei...@keithp.com writes:

 Screen-specific privates areas are only allocated for objects related
 to the target screen; objects allocated for other screens will not
 have the private space reserved. This saves memory in these objects
 while also allowing hot-plug screens to have additional private
 allocation space beyond what the core screens are using.

 Drivers are encouraged to switch to this mechanism as it will reduce
 memory usage in multi-GPU environments, but it is only required for
 drivers which will be loaded after the server starts, like
 modesetting.

 Objects providing screen-specific privates *must* be managed by the
 screen-specific private API when allocating or initializing privates
 so that the per-screen area can be initialized properly.

 The objects which support screen-specific privates are:

   Windows
   Pixmaps
   GCs
   Pictures

 Extending this list to include Colormaps would be possible, but
 require slightly more work as the default colormap is created before
 all colormap privates are allocated during server startup, and hence
 gets a bunch of special treatment.

 Of particular note, glyphs are *not* capable of supporting
 screen-specific privates as they are global objects, not allocated on
 a screen-specific basis, and so each driver must be able to see their
 privates within the glyph.

 Signed-off-by: Keith Packard kei...@keithp.com

This sequence, including some patches to fix up midispcur to support GPU
hotplug has been

Merged, with Reviewed-by: Dave Airlie airl...@redhat.com:
   ed6daa1..9e4b8b7  master - master

-- 
keith.pack...@intel.com


pgpLDLZ5knNwL.pgp
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

[PATCH 1/3] Add screen-specific privates.

2012-07-03 Thread Keith Packard
Screen-specific privates areas are only allocated for objects related
to the target screen; objects allocated for other screens will not
have the private space reserved. This saves memory in these objects
while also allowing hot-plug screens to have additional private
allocation space beyond what the core screens are using.

Drivers are encouraged to switch to this mechanism as it will reduce
memory usage in multi-GPU environments, but it is only required for
drivers which will be loaded after the server starts, like
modesetting.

Objects providing screen-specific privates *must* be managed by the
screen-specific private API when allocating or initializing privates
so that the per-screen area can be initialized properly.

The objects which support screen-specific privates are:

Windows
Pixmaps
GCs
Pictures

Extending this list to include Colormaps would be possible, but
require slightly more work as the default colormap is created before
all colormap privates are allocated during server startup, and hence
gets a bunch of special treatment.

Of particular note, glyphs are *not* capable of supporting
screen-specific privates as they are global objects, not allocated on
a screen-specific basis, and so each driver must be able to see their
privates within the glyph.

Signed-off-by: Keith Packard kei...@keithp.com
---
 dix/dispatch.c   |3 +
 dix/gc.c |2 +-
 dix/main.c   |1 +
 dix/pixmap.c |4 +-
 dix/privates.c   |  381 +++---
 dix/window.c |4 +-
 doc/Xserver-spec.xml |   26 +++-
 include/privates.h   |   54 ++-
 include/scrnintstr.h |2 +
 render/picture.c |5 +-
 10 files changed, 395 insertions(+), 87 deletions(-)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index b88f974..7d2d3b7 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3743,6 +3743,8 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
 if (!pScreen)
 return -1;
 
+dixInitScreenSpecificPrivates(pScreen);
+
 if (!dixAllocatePrivates(pScreen-devPrivates, PRIVATE_SCREEN)) {
 free(pScreen);
 return -1;
@@ -3794,6 +3796,7 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
 screenInfo.screens[i] = pScreen;
 screenInfo.numScreens++;
 if (!(*pfnInit) (pScreen, argc, argv)) {
+dixFreeScreenSpecificPrivates(pScreen);
 dixFreePrivates(pScreen-devPrivates, PRIVATE_SCREEN);
 free(pScreen);
 screenInfo.numScreens--;
diff --git a/dix/gc.c b/dix/gc.c
index ac67643..60f54ec 100644
--- a/dix/gc.c
+++ b/dix/gc.c
@@ -463,7 +463,7 @@ NewGCObject(ScreenPtr pScreen, int depth)
 {
 GCPtr pGC;
 
-pGC = dixAllocateObjectWithPrivates(GC, PRIVATE_GC);
+pGC = dixAllocateScreenObjectWithPrivates(pScreen, GC, PRIVATE_GC);
 if (!pGC) {
 return (GCPtr) NULL;
 }
diff --git a/dix/main.c b/dix/main.c
index e95ca1c..9524189 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -329,6 +329,7 @@ main(int argc, char *argv[], char *envp[])
 FreeScratchPixmapsForScreen(screenInfo.screens[i]);
 FreeGCperDepth(i);
 FreeDefaultStipple(i);
+dixFreeScreenSpecificPrivates(screenInfo.screens[i]);
 (*screenInfo.screens[i]-CloseScreen) (screenInfo.screens[i]);
 dixFreePrivates(screenInfo.screens[i]-devPrivates, 
PRIVATE_SCREEN);
 free(screenInfo.screens[i]);
diff --git a/dix/pixmap.c b/dix/pixmap.c
index 545ff54..0c85c3f 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -88,7 +88,7 @@ CreateScratchPixmapsForScreen(ScreenPtr pScreen)
 {
 unsigned int pixmap_size;
 
-pixmap_size = sizeof(PixmapRec) + dixPrivatesSize(PRIVATE_PIXMAP);
+pixmap_size = sizeof(PixmapRec) + dixScreenSpecificPrivatesSize(pScreen, 
PRIVATE_PIXMAP);
 pScreen-totalPixmapSize =
 BitmapBytePad(pixmap_size * 8);
 
@@ -118,7 +118,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
 if (!pPixmap)
 return NullPixmap;
 
-dixInitPrivates(pPixmap, pPixmap + 1, PRIVATE_PIXMAP);
+dixInitScreenPrivates(pScreen, pPixmap, pPixmap + 1, PRIVATE_PIXMAP);
 return pPixmap;
 }
 
diff --git a/dix/privates.c b/dix/privates.c
index 15fbf75..0948325 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -63,12 +63,7 @@ from The Open Group.
 #include scrnintstr.h
 #include extnsionst.h
 
-static struct {
-DevPrivateKey key;
-unsigned offset;
-int created;
-int allocated;
-} keys[PRIVATE_LAST];
+static DevPrivateSetRec global_keys[PRIVATE_LAST];
 
 static const Bool xselinux_private[PRIVATE_LAST] = {
 [PRIVATE_SCREEN] = TRUE,
@@ -86,8 +81,57 @@ static const Bool xselinux_private[PRIVATE_LAST] = {
 [PRIVATE_GLYPHSET] = TRUE,
 };
 
+static const char *key_names[PRIVATE_LAST] = {
+/* XSELinux uses the same private keys for numerous objects */
+[PRIVATE_XSELINUX] = XSELINUX,
+
+/* Otherwise, you get a private in just the requested