Re: Thousands of leaked CGContext ?
Hi, CGDataProviderRef provider = CGDataProviderCreateDirect( mps, sizeof(mps), callbacks ); NSWindow* window = (NSWindow*)Window(); What does this line do? It's just a global function which returns the (only) window. For crossplatform compatibility reasons (our app runs on MacOSX, Linux, Windows and Android) it returns a void*, that's why the cast is needed. This one : CGImageRef image = CGImageCreate( size_t(mDirtyRect.W()), size_t(mDirtyRect.H()), 8, 32, size_t(mBlock-Width()*4), [[window colorSpace] CGColorSpace], kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst, provider, NULL, false, kCGRenderingIntentRelativeColorimetric ); It creates a CGImage which will use the CGDataProvider for a source of the pixels. The size is the same as the 'dirty' rect to refresh, 8 bits/component, 32 bits/pixel, w*4 bytes/row, the windows colorspace, the pixel 'description' (integer, no useful data in alpha channel), my data provider, NULL(decode array), no interpolation (it's anyway a 1to1 mapping of the pixels), rendering intent. The data provider just copies the pixels or returns a pointer to the correct byte : struct MyProviderStruct { ::nImage8::cRGBABlock* mBlock; int mX, mY; }; static const void* MyProviderGetBytePointer( void* iInfo ) { MyProviderStruct* mps = (MyProviderStruct*) iInfo; return mps-mBlock-Pixels( mps-mX, mps-mY ); // this returns a pointer to that pixel } static void MyProviderReleaseBytePointer( void* iInfo, const void* iPointer ) {} static size_t MyProviderGetBytesAtPosition( void* iInfo, void* oBuffer, off_t iPosition, size_t iCount ) { MyProviderStruct* mps = (MyProviderStruct*) iInfo; ::nMemoryUtils::Copy( oBuffer, (uint8*)(mps-mBlock-Pixels()) + iPosition, uint32(iCount) ); return iCount; } static void MyProviderReleaseInfo( void* iInfo ) {} Except for the leaked memory, it works as expected. Thanks -- Keep intel OUTSIDE my Mac ! Hiii !!! I can see Intel chips creeping around my G5 ! Eric M. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Thousands of leaked CGContext ?
On Apr 20, 2015, at 12:05 AM, Eric Matecki eml...@wanadoo.fr wrote: Hi, CGDataProviderRef provider = CGDataProviderCreateDirect( mps, sizeof(mps), callbacks ); NSWindow* window = (NSWindow*)Window(); What does this line do? It's just a global function which returns the (only) window. For crossplatform compatibility reasons (our app runs on MacOSX, Linux, Windows and Android) it returns a void*, that's why the cast is needed. Sure, but of all the code you’ve presented, nothing seems to indicate a leak, except for the single call to Window(). My hope would be that it isn’t doing something with side effects that ultimately causes this. This one : CGImageRef image = CGImageCreate( size_t(mDirtyRect.W()), size_t(mDirtyRect.H()), 8, 32, size_t(mBlock-Width()*4), [[window colorSpace] CGColorSpace], kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst, provider, NULL, false, kCGRenderingIntentRelativeColorimetric ); It creates a CGImage which will use the CGDataProvider for a source of the pixels. The size is the same as the 'dirty' rect to refresh, 8 bits/component, 32 bits/pixel, w*4 bytes/row, the windows colorspace, the pixel 'description' (integer, no useful data in alpha channel), my data provider, NULL(decode array), no interpolation (it's anyway a 1to1 mapping of the pixels), rendering intent. The data provider just copies the pixels or returns a pointer to the correct byte : struct MyProviderStruct { ::nImage8::cRGBABlock* mBlock; int mX, mY; }; static const void* MyProviderGetBytePointer( void* iInfo ) { MyProviderStruct* mps = (MyProviderStruct*) iInfo; return mps-mBlock-Pixels( mps-mX, mps-mY ); // this returns a pointer to that pixel } static void MyProviderReleaseBytePointer( void* iInfo, const void* iPointer ) {} static size_t MyProviderGetBytesAtPosition( void* iInfo, void* oBuffer, off_t iPosition, size_t iCount ) { MyProviderStruct* mps = (MyProviderStruct*) iInfo; ::nMemoryUtils::Copy( oBuffer, (uint8*)(mps-mBlock-Pixels()) + iPosition, uint32(iCount) ); return iCount; } static void MyProviderReleaseInfo( void* iInfo ) {} Except for the leaked memory, it works as expected. Thanks -- Keep intel OUTSIDE my Mac ! Hiii !!! I can see Intel chips creeping around my G5 ! Eric M. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/david.duncan%40apple.com This email sent to david.dun...@apple.com -- David Duncan ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Thousands of leaked CGContext ?
On 20 Apr 2015, at 09:05, Eric Matecki eml...@wanadoo.fr wrote: CGDataProviderRef provider = CGDataProviderCreateDirect( mps, sizeof(mps), callbacks ); NSWindow* window = (NSWindow*)Window(); What does this line do? It's just a global function which returns the (only) window. For crossplatform compatibility reasons (our app runs on MacOSX, Linux, Windows and Android) it returns a void*, that's why the cast is needed. Not sure if you know this, but there are many tricks to let you avoid casts like this. For one, you can typedef the type, so the cross-platform code can assume a return type named CrossPlatformWindowPtr and platform-specific code sees a platform-specific type anyway: #if __OBJC__ #import Cocoa/Cocoa.h typedef NSWindow *CrossPlatformWindow; #else typedef struct NSWindow *CrossPlatformWindow; #endif This will produce the same name-mangling in C++ on Mac and iOS, and since both are pointers they're the identical size, but the second compiles in C and C++-only files. It also means that all ObjC source code can just use it as the NSWindow it is, taking advantage of what little type checking Objective-C offers, at least. And no accidental hidden bugs by casting a CrossPlatformButton to a CrossPlatformWindow by accident. And the Windows versions could just have a simple typedef HWND CrossPlatformWindow; or whatever would be appropriate there. If you're curious about more safe and practical C++ tricks, I spent almost an hour talking about a lot of C++ on Andrew Pontious' Edge Cases podcast once: http://edgecasesshow.com/017-then-youre-just-writing-cplusplus.html http://edgecasesshow.com/017-then-youre-just-writing-cplusplus.html -- Uli http://stacksmith http://stacksmith/.org/ ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Thousands of leaked CGContext ?
On Apr 17, 2015, at 2:38 AM, Eric Matecki eml...@wanadoo.fr wrote: Hi, (I know this is not 100% Cocoa, but it isn't 100% CoreGraphics either...) I'm drawing to an NSWindow with CoreGraphics, and each time there is a leaked CGContext, CGContextDelegate, CGColorTransform, NSBitmapGraphicsContext, and NSFocusStack (one of each). Here is how I do it : CGDataProviderDirectCallbacks callbacks = { 0, MyProviderGetBytePointer, MyProviderReleaseBytePointer, MyProviderGetBytesAtPosition, MyProviderReleaseInfo }; MyProviderStruct mps = { mBlock, mDirtyRect.X(), mDirtyRect.Y() }; CGDataProviderRef provider = CGDataProviderCreateDirect( mps, sizeof(mps), callbacks ); NSWindow* window = (NSWindow*)Window(); What does this line do? CGImageRef image = CGImageCreate( size_t(mDirtyRect.W()), size_t(mDirtyRect.H()), 8, 32, size_t(mBlock-Width()*4), [[window colorSpace] CGColorSpace], kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst, provider, NULL, false, kCGRenderingIntentRelativeColorimetric ); CGContextRef myContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; CGContextDrawImage( myContext, CGRectMake( mDirtyRect.X(), geom.H() - mDirtyRect.Y() - mDirtyRect.H(), mDirtyRect.W(), mDirtyRect.H() ), image ); CGContextFlush( myContext ); CGImageRelease( image ); CGDataProviderRelease( provider ); I don't release the CGContextRef because I don't 'create' it. If I release it, the app doesn't crash but doesn't draw anything anymore after the first one. My data provider just copy bytes from a legacy data structure. What am I doing wrong ? Or maybe there is a better way of doing this ? Thanks for any help ! -- Keep intel OUTSIDE my Mac ! Hiii !!! I can see Intel chips creeping around my G5 ! Eric M. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/david.duncan%40apple.com This email sent to david.dun...@apple.com -- David Duncan ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com