summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErkki Seppälä <erkki.seppala@vincit.fi>2010-12-08 15:30:57 +0200
committerErkki Seppälä <erkki.seppala@vincit.fi>2012-04-18 12:36:25 +0300
commit3ba0decb4b55a1fd122d269e15b2b2da8ced8624 (patch)
tree338d2b298e2364ca5125b0ce6978334f75455b13
parentb8d0d19a6d410776b53a41e7cae90f68d4b22bb7 (diff)
dix: add a mechanism for iterating through all subresources
The mechanism allows iterating even through subresources that don't have specific XID's. When such 'resources' are iterated, the XID for them will be zero. A resource type can assign an iteration function for its subresources with SetResourceTypeFindSubResFunc; by default resources are assumed not to contain subresources. The purpose of this extension is to enable accurate accounting of the resources a resource consumes or uses. This patch provides the subresource iteration functions for Windows and GCs. Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi> Signed-off-by: Erkki Seppälä <erkki.seppala@vincit.fi>
-rw-r--r--dix/resource.c124
-rw-r--r--include/resource.h16
2 files changed, 139 insertions, 1 deletions
diff --git a/dix/resource.c b/dix/resource.c
index 89dfb5bb6..5691b1608 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -184,6 +184,7 @@ RESTYPE TypeMask;
struct ResourceType {
DeleteType deleteFunc;
SizeType sizeFunc;
+ FindTypeSubResources findSubResFunc;
int errorValue;
};
@@ -209,6 +210,25 @@ GetDefaultBytes(pointer value, XID id, ResourceSizePtr size)
}
/**
+ * Used by all resources that don't specify a function to iterate
+ * through subresources. Currently this is used for all resources with
+ * insignificant memory usage.
+ *
+ * @see FindSubResources, SetResourceTypeFindSubResFunc
+ *
+ * @param[in] value Pointer to resource object.
+ *
+ * @param[in] func Function to call for each subresource.
+
+ * @param[out] cdata Pointer to opaque data.
+ */
+static void
+DefaultFindSubRes(pointer value, FindAllRes func, pointer cdata)
+{
+ /* do nothing */
+}
+
+/**
* Calculate drawable size in bytes. Reference counting is not taken
* into account.
*
@@ -301,13 +321,45 @@ GetWindowBytes(pointer value, XID id, ResourceSizePtr size)
}
/**
+ * Iterate through subresources of a window. The purpose of this
+ * function is to gather accurate information on what resources
+ * a resource uses.
+ *
+ * @note Currently only sub-pixmaps are iterated
+ *
+ * @param[in] value Pointer to a window
+ *
+ * @param[in] func Function to call with each subresource
+ *
+ * @param[out] cdata Pointer to opaque data
+ */
+static void
+FindWindowSubRes(pointer value, FindAllRes func, pointer cdata)
+{
+ WindowPtr window = value;
+
+ /* Currently only pixmap subresources are reported to clients. */
+
+ if (window->backgroundState == BackgroundPixmap)
+ {
+ PixmapPtr pixmap = window->background.pixmap;
+ func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata);
+ }
+ if (window->border.pixmap && !window->borderIsPixel)
+ {
+ PixmapPtr pixmap = window->border.pixmap;
+ func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata);
+ }
+}
+
+/**
* Calculate graphics context size in bytes. The purpose of this
* function is to estimate memory usage that can be attributed to all
* pixmap references of the graphics context.
*
* @param[in] value Pointer to a graphics context.
*
- * @param[in] id Resource ID of graphics context.
+ * @param[in] id Resource ID of graphics context.
*
* @param[out] size Estimate of memory usage attributed to a all
* pixmap references of a graphics context.
@@ -338,57 +390,99 @@ GetGcBytes(pointer value, XID id, ResourceSizePtr size)
}
}
+/**
+ * Iterate through subresources of a graphics context. The purpose of
+ * this function is to gather accurate information on what resources a
+ * resource uses.
+ *
+ * @note Currently only sub-pixmaps are iterated
+ *
+ * @param[in] value Pointer to a window
+ *
+ * @param[in] func Function to call with each subresource
+ *
+ * @param[out] cdata Pointer to opaque data
+ */
+static void
+FindGCSubRes(pointer value, FindAllRes func, pointer cdata)
+{
+ GCPtr gc = value;
+
+ /* Currently only pixmap subresources are reported to clients. */
+
+ if (gc->stipple)
+ {
+ PixmapPtr pixmap = gc->stipple;
+ func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata);
+ }
+ if (gc->tile.pixmap && !gc->tileIsPixel)
+ {
+ PixmapPtr pixmap = gc->tile.pixmap;
+ func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata);
+ }
+}
+
static struct ResourceType *resourceTypes;
static const struct ResourceType predefTypes[] = {
[RT_NONE & (RC_LASTPREDEF - 1)] = {
.deleteFunc = (DeleteType) NoopDDA,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadValue,
},
[RT_WINDOW & (RC_LASTPREDEF - 1)] = {
.deleteFunc = DeleteWindow,
.sizeFunc = GetWindowBytes,
+ .findSubResFunc = FindWindowSubRes,
.errorValue = BadWindow,
},
[RT_PIXMAP & (RC_LASTPREDEF - 1)] = {
.deleteFunc = dixDestroyPixmap,
.sizeFunc = GetPixmapBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadPixmap,
},
[RT_GC & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeGC,
.sizeFunc = GetGcBytes,
+ .findSubResFunc = FindGCSubRes,
.errorValue = BadGC,
},
[RT_FONT & (RC_LASTPREDEF - 1)] = {
.deleteFunc = CloseFont,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadFont,
},
[RT_CURSOR & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeCursor,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadCursor,
},
[RT_COLORMAP & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeColormap,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadColor,
},
[RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeClientPixels,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadColor,
},
[RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = {
.deleteFunc = OtherClientGone,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadValue,
},
[RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = {
.deleteFunc = DeletePassiveGrab,
.sizeFunc = GetDefaultBytes,
+ .findSubResFunc = DefaultFindSubRes,
.errorValue = BadValue,
},
};
@@ -420,6 +514,7 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name)
resourceTypes = types;
resourceTypes[next].deleteFunc = deleteFunc;
resourceTypes[next].sizeFunc = GetDefaultBytes;
+ resourceTypes[next].findSubResFunc = DefaultFindSubRes;
resourceTypes[next].errorValue = BadValue;
/* Called even if name is NULL, to remove any previous entry */
@@ -461,6 +556,24 @@ SetResourceTypeSizeFunc(RESTYPE type, SizeType sizeFunc)
resourceTypes[type & TypeMask].sizeFunc = sizeFunc;
}
+/**
+ * Provide a function for iterating the subresources of a resource.
+ * This allows for example more accurate accounting of the (memory)
+ * resources consumed by a resource.
+ *
+ * @see FindSubResources
+ *
+ * @param[in] type Resource type used in size calculations.
+ *
+ * @param[in] sizeFunc Function to calculate the size of a single
+ * resource.
+ */
+void
+SetResourceTypeFindSubResFunc(RESTYPE type, FindTypeSubResources findFunc)
+{
+ resourceTypes[type & TypeMask].findSubResFunc = findFunc;
+}
+
void
SetResourceTypeErrorValue(RESTYPE type, int errorValue)
{
@@ -871,6 +984,15 @@ FindClientResourcesByType(ClientPtr client,
}
}
+void FindSubResources(pointer resource,
+ RESTYPE type,
+ FindAllRes func,
+ pointer cdata)
+{
+ struct ResourceType rtype = resourceTypes[type & TypeMask];
+ rtype.findSubResFunc(resource, func, cdata);
+}
+
void
FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata)
{
diff --git a/include/resource.h b/include/resource.h
index 8e58952aa..663fac4f6 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -171,12 +171,19 @@ typedef void (*SizeType)(pointer /*value*/,
extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType /*deleteFunc */ ,
const char * /*name */ );
+typedef void (*FindTypeSubResources)(pointer /* value */,
+ FindAllRes /* func */,
+ pointer /* cdata */);
+
extern _X_EXPORT void SetResourceTypeErrorValue(RESTYPE /*type */ ,
int /*errorValue */ );
extern _X_EXPORT SizeType GetResourceTypeSizeFunc(
RESTYPE /*type*/);
+extern _X_EXPORT void SetResourceTypeFindSubResFunc(
+ RESTYPE /*type*/, FindTypeSubResources /*findFunc*/);
+
extern _X_EXPORT void SetResourceTypeSizeFunc(
RESTYPE /*type*/, SizeType /*sizeFunc*/);
@@ -218,6 +225,15 @@ extern _X_EXPORT void FindAllClientResources(ClientPtr /*client */ ,
FindAllRes /*func */ ,
pointer /*cdata */ );
+/** @brief Iterate through all subresources of a resource.
+
+ @note The XID argument provided to the FindAllRes function
+ may be 0 for subresources that don't have an XID */
+extern _X_EXPORT void FindSubResources(pointer /*resource*/,
+ RESTYPE /*type*/,
+ FindAllRes /*func*/,
+ pointer /*cdata*/);
+
extern _X_EXPORT void FreeClientNeverRetainResources(ClientPtr /*client */ );
extern _X_EXPORT void FreeClientResources(ClientPtr /*client */ );