summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-07-03 15:45:09 -0700
committerKeith Packard <keithp@keithp.com>2012-07-05 13:39:50 -0700
commit9d457f9c55f12106ba44c1c9db59d14f978f0ae8 (patch)
tree6b323ee38f55cdfd6d8b40b6e0ac40618c11430d /include
parented6daa15a7dcf8dba930f67401f4c1c8ca2e6fac (diff)
Add screen-specific privates.
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 <keithp@keithp.com> Reviewed-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/privates.h54
-rw-r--r--include/scrnintstr.h2
2 files changed, 55 insertions, 1 deletions
diff --git a/include/privates.h b/include/privates.h
index c34b9512c..a0874f697 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -66,6 +66,13 @@ typedef struct _DevPrivateKeyRec {
struct _DevPrivateKeyRec *next;
} DevPrivateKeyRec, *DevPrivateKey;
+typedef struct _DevPrivateSetRec {
+ DevPrivateKey key;
+ unsigned offset;
+ int created;
+ int allocated;
+} DevPrivateSetRec, *DevPrivateSetPtr;
+
typedef struct _DevScreenPrivateKeyRec {
DevPrivateKeyRec screenKey;
} DevScreenPrivateKeyRec, *DevScreenPrivateKey;
@@ -219,6 +226,51 @@ dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key,
}
/*
+ * These functions relate to allocations related to a specific screen;
+ * space will only be available for objects allocated for use on that
+ * screen. As such, only objects which are related directly to a specific
+ * screen are candidates for allocation this way, this includes
+ * windows, pixmaps, gcs, pictures and colormaps. This key is
+ * used just like any other key using dixGetPrivate and friends.
+ *
+ * This is distinctly different from the ScreenPrivateKeys above which
+ * allocate space in global objects like cursor bits for a specific
+ * screen, allowing multiple screen-related chunks of storage in a
+ * single global object.
+ */
+
+#define HAVE_SCREEN_SPECIFIC_PRIVATE_KEYS 1
+
+extern _X_EXPORT Bool
+dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
+ DevPrivateType type, unsigned size);
+
+/* Clean up screen-specific privates before CloseScreen */
+extern void
+dixFreeScreenSpecificPrivates(ScreenPtr pScreen);
+
+/* Initialize screen-specific privates in AddScreen */
+extern void
+dixInitScreenSpecificPrivates(ScreenPtr pScreen);
+
+extern _X_EXPORT void *
+_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
+ unsigned size,
+ unsigned clear,
+ unsigned offset,
+ DevPrivateType type);
+
+#define dixAllocateScreenObjectWithPrivates(s, t, type) _dixAllocateScreenObjectWithPrivates(s, sizeof(t), sizeof(t), offsetof(t, devPrivates), type)
+
+extern _X_EXPORT int
+dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type);
+
+extern _X_EXPORT void
+_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type);
+
+#define dixInitScreenPrivates(s, o, v, type) _dixInitScreenPrivates(s, &(o)->devPrivates, (v), type);
+
+/*
* Allocates private data separately from main object.
*
* For objects created during server initialization, this allows those
@@ -240,7 +292,7 @@ extern _X_EXPORT void
* Initialize privates by zeroing them
*/
extern _X_EXPORT void
- _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
+_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type);
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index c592d1ffe..7af2bf53f 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -367,6 +367,8 @@ typedef struct _Screen {
WindowPtr root;
ScreenSaverStuffRec screensaver;
+ DevPrivateSetRec screenSpecificPrivates[PRIVATE_LAST];
+
/* Random screen procedures */
CloseScreenProcPtr CloseScreen;