diff options
author | Erkki Seppälä <erkki.seppala@vincit.fi> | 2010-12-08 15:30:57 +0200 |
---|---|---|
committer | Erkki Seppälä <erkki.seppala@vincit.fi> | 2012-04-18 12:36:25 +0300 |
commit | 3ba0decb4b55a1fd122d269e15b2b2da8ced8624 (patch) | |
tree | 338d2b298e2364ca5125b0ce6978334f75455b13 | |
parent | b8d0d19a6d410776b53a41e7cae90f68d4b22bb7 (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.c | 124 | ||||
-rw-r--r-- | include/resource.h | 16 |
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 */ ); |