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. Signed-off-by: Erkki Seppälä <[email protected]> Reviewed-by: Rami Ylimäki <[email protected]> --- dix/resource.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++- include/resource.h | 18 +++++++ 2 files changed, 142 insertions(+), 1 deletions(-) diff --git a/dix/resource.c b/dix/resource.c index 7c8a31e..7184ead 100644 --- a/dix/resource.c +++ b/dix/resource.c @@ -187,6 +187,7 @@ RESTYPE TypeMask; struct ResourceType { DeleteType deleteFunc; SizeType sizeFunc; + FindTypeSubResources findSubResFunc; int errorValue; }; @@ -212,6 +213,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. * @@ -304,13 +324,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. @@ -341,56 +393,98 @@ 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, } }; @@ -422,6 +516,7 @@ CreateNewResourceType(DeleteType deleteFunc, 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 */ @@ -463,6 +558,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) { @@ -906,6 +1019,16 @@ FindClientResourcesByType( } } +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, diff --git a/include/resource.h b/include/resource.h index 406d74a..aea617c 100644 --- a/include/resource.h +++ b/include/resource.h @@ -166,6 +166,11 @@ typedef void (*FindAllRes)( RESTYPE /*type*/, pointer /*cdata*/); +typedef void (*FindTypeSubResources)( + pointer /* value */, + FindAllRes /* func */, + pointer /* cdata */); + typedef Bool (*FindComplexResType)( pointer /*value*/, XID /*id*/, @@ -177,6 +182,9 @@ extern _X_EXPORT RESTYPE CreateNewResourceType( 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*/); @@ -221,6 +229,16 @@ extern _X_EXPORT void FindClientResourcesByType( FindResType /*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 FindAllClientResources( ClientPtr /*client*/, FindAllRes /*func*/, -- 1.7.0.4 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
