Can I increment SDL_Surface refcount myself - sdl

I'm using SDL2. I'd like to keep track of my codes references of the SDL_Surface that I'll be passing around.
My question is if it's safe to use ++surface->refcount on my own.
More broadly, will that be safe for all SDL structs which have a ref count?

Documentation says you can increment it. To decrement refcount, use SDL_FreeSurface.
The same goes for every other refcount SDL exposes - increment it yourself, but use corresponding Free function to decrement.

Related

Am I completely negating the benefit of Microsoft::WRL::ComPtr by passing it around as a reference (&)?

I've been tossing around ComPtrs in my code because I need them here and there but I've been doing it like so:
HRESULT Material::Initialize(aiMaterial* pMaterial,
Microsoft::WRL::ComPtr<ID3D11Device1> & d3dDevice,
Microsoft::WRL::ComPtr<ID3D11DeviceContext1> & d3dContext)
Is this completely negating the ref counting benefit of a ComPtr? Should I just do a pass by value (no &) instead?
Thanks you for reading
It's perfectly okay and preferred to pass it around as const&.
Pass by value is acceptable from semantics standpoint, not that much from performance, as passing so causes bumping the refcount up and down, and both are "interlocked" operations with serious consequences. And we gain nothing in return.
The benefit of ComPtr is that it allows proper matching of Release calls, that is all too easy to mess up, and even if it was easy the mess of the code it takes is unpleasant.
No, you're doing the right thing. The callee doesn't have to modify the reference count unless it needs to hold onto the interface for access after the call. Incrementing and decrementing the reference count is not free - it's a virtual call plus an interlocked increment or decrement - so you get better performance anyway. You should use a const reference though - or even just pass down a raw pointer.
Yep in my DirectX code, I arrange my engine to make it clear which object have the authority to manage the lifetime of a DirectX COM object. Then I pass it as raw pointer to methods that need them (I avoid to keep member variables track DX objects as much as possible).

D3D11 increased ref count from nowhere?

I have been working with d3d11 for quite a while now, and after discovering the directx debugger, i've recently discovered that my program is leaking memory everywhere from all the com objects that aren't releasing properly. After a bit of snooping around and hours of staring at the code, i've developed some methods to isolate where i'm getting these unexpected increases to the ref counts.
first off, all of the objects are wrapped in std::shared_ptrs with custom deleters that call their respective release function. I did this so i would never have to call addref, and the first call to release, the one in the deleter, would only be called when the object went out of scope. It would look something like this:
// in D3D11Renderer.h
...
// declaration
std::shared_ptr<ID3D11Device *> m_Device;
...
// after call to ID3D11CreateDeviceAndSwapChain
m_Device.reset(device, [](ID3D11Device * ptr){ptr->Release();})
Problem is certain random functions in the api calls will just randomly increase the ref count, expecting me to have to deal with it later.
something i found useful in diagnosis was a function that looked like this:
template <typename T>
int getRefCount(T object)
{
object->AddRef();
return object->Release();
}
which, just increments and decrements that count to obtain the current count of refs on that object. Using this, i found that, just before the release in the custom deleter is called, there are 10 outstanding references to the 1 ID3D11Device i created. Curious, i backtracked slowly, calling this function all the way back through the program, right up to where i originally created it. Funny thing, just after i first create the object, (even before the shared_ptr takes ownership), the number of outstanding refs is already 3! This occurs immediately after this here.
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, NULL, &deviceContext);
if(FAILED(result))
{
return false;
}
this is the first time i call any such function that creates the device, and when i check to see how many refs there are right after, and it says 3! So clearly, I'm misunderstanding something about the way these com objects are supposed to be handled. Is there any such way that i can just manually delete them, rather then use there behind-the-scenes ref counting nonsense?
Every time you create a buffer or a shader or anything that depends on the device, that object will likely contain a reference to the device so will bump up it's reference count to ensure it's not deleted while it is still using it.
It sounds like your approach might well work overall, as you'll essentially keep one single reference to the device in your code to stop it being deleted, and when all your internal references are gone release it. However d3d will still be doing it's own reference counting and so the reference count will only drop to zero when you release every reference to every other related object. Even just creating the swap chain and device will make back buffers and so on that likely need to maintain a reference to the device.
I tried this same idea for a while... And in the end found it much easier to just
#include <atlbase>
Then use
CComPtr<ID311Device> m_Device
as that's pretty much exactly what that class is designed for and it's more lightweight than std::shader_ptr as the objects already have a reference counter in them so there is no need to keep a separate one.
Using shared_ptr is not correct for Direct3D (COM) objects, even if you use custom deleters.
First, COM objects use intrusive reference counting, which means the reference count is stored in the object itself. shared_ptr on the other hand uses non-intrusive reference counting, which means the reference count is stored in the smart poiter object. Therefore, using shared_ptr for COM objects means that you have two separate, independent reference counts: the COM object's, and the shared_ptr's.
Second, using a custom deleter solves the problem of properly releasing the object, but it doesn't solve the problem of properly acquiring a reference to the object. Assigning a COM object to a shared_ptr will increment the reference count of the shared_ptr, but not the object's.
That explains why you're leaking objects: D3D methods increment objects' reference counts, but you are using shared_ptrs that decrement the object's reference count only once for the entire lifetime of the object (when all shared_ptrs pointing to the object are destroyed).
So, you need to use a COM smart pointer, such as ATL's CComPtr.

How exactly does memory handling (i.e, the function Release) work with Direct3D?

I came across a leak in a Direct3D application of mine, and I ended up correcting it, but I think the cause of the leak was due to my misunderstanding of how Direct3D handles its memory and interfaces.
I haven't been able to find a definitive article/tutorial on it (please provide one if you have one), but from what I've gathered, it works as such:
Every time you call a Get method, the number of references for the object returned is incremented. So if I call GetRenderTarget, the surface being rendered to has its reference count incremented.
Calling Release on the interface decrements its reference count. These first two points combined essentially mean: every time you get an interface, release it after you're done with it.
When the reference count reaches 0, the instance is deleted.
I'm not entirely sure if this is correct, but it seems to work in practice. If someone could clarify/confirm how it works, that'd be great.
P.S, are there any safeguards implemented in releasing interfaces? Calling Release any number of times on the back buffer doesn't seem to do any damage (which is a good thing, but I'm not sure why it doesn't).
Direct3D is based on COM, which is a technology that's at least 15 years old. Seems many people claim COM is dead and for that reason many overlook it, but reality is that there are many things in windows including Direct3D and MS's new Media Foundation that are all based on COM.
I strongly suggest you take a look at general COM programming. There are plenty of books and resources, but many of them are rather old but that's ok because the root of the technology hasn't changed for a very long time.
Basically what you've observed is interface reference counting. COM is based purely on accessing objects via interfaces, which all derive from the base interface, IUnknown. IUnknown implements methods AddRef() and Release() and it is the responsibility of your application to call AddRef() whenever you store a local copy of a pointer and to call Release() whenever that local copy is no longer needed.
When you have methods with interface out parameters (i.e. IFoo** ppObj ), that means the callee is giving you back an interface and now that you have it, it is still your responsibility to call Release() whenever you are done with it.
Once you get the hang of it, I'd suggest you start using CComPtr smart class for storing local and member variables (still pass raw interface values between function calls, no need for smart pointer parameter types). It will take care of all your reference counting. Also don't make it a practice of calling release "any number" of times. It might work today because the object is implemented as a singleton, or maybe something else is holding on to it, but that might change with next patch or next release. Always follow the rules. If you have an interface, when you don't need it call Release() exactly once. If you made a copy of interface pointer, make sure to call AddRef() exactly once.
The application of addref/release semantics is much wider than COM technology. There is simple rule one CreateObject() (or CreateTexture, or GetRenderTarget, or GetBackBuffer, etc...) have to be confronted with one Release(), one AddRef() have to be confronted with one Release().
In COM IUnknown::Release() returns number of references to object. It may delude you and you can think:
"Hm... I just call Release() until it return 0 and I will have no leaks. ???? PROFIT!!!!!111" <-- That is wrong! AddRef might be called by Direct3D itself or by 3rd_party library you pass this object to, or something else outside your app. One Release for one AddRef. You should call Release when you don't need object anymore, don't waste system resources.
You said:
Calling Release any number of times on the back buffer doesn't seem to do any damage
That means nothing. May be The Universe like you so much or you just too lucky to not get exceptions from D3D.
Smart pointers (such as CComPtr) could make your life much easier if you will use them. In this case you don't need to call Release explicitly, it is called in CComPtr dtor if it is assigned to some object.
void get_surface(IDirect3DDevice9 *pDevice)
{
IDirect3DSurface9 *surf0;
IDirect3DSurface9 *surf1;
CComPtr<IDirect3DSurface9> surf2;
CComPtr<IDirect3DSurface9> surf3;
CComPtr<IDirect3DSurface9> surf4;
pDevice->GetRenderTarget( 0, surf0 ); // surface reference counter incremented, you should call Release() for this
surf1 = surf0; // surface reference count is not incremented, you shouldn't call Release() for this
pDevice->GetRenderTarget( 0, surf2 ); // surface reference counter incremented
CComPtr<IDirect3DSurface9> surf3 = surf0; // surface reference counter incremented
surf0->Release(); // release for pDevice->GetRenderTarget( 0, surf0 );
surf2.Release(); // .Release() used not ->Release() - it is important
surf4.Release(); // nothing happens because surf4 == 0
} // surf3.Release() is called in surf3 destructor
Also you may #define D3D_DEBUG_INFObefore including direct 3d headers and switch to debug d3d runtime. It is helpful in finding leaks in d3d app.
May the CComPtr Force be with you.
D3D objects are COM objects, and they use a basic reference counting system to manage the lifetime of the object. (See wikipedia for more info about the Component Object Model, or the MSDN article Managing Object Lifetimes)
The reference count is modified purely through the AddRef/Release methods, and certain other functions call those methods.
Creating the object as well as calling certain Get methods that return an object derived from the IUnknown class will call AddRef internally to increment the reference count, so you will need to call Release for each call when you are finished with the object.
If you pass the object to another function or class that stores a copy of the point (even temporarily) that class/function should call AddRef to ensure that the object is not freed while it is using it (and Release to signal it is done).
When the reference counter reaches 0 from a call to Release the object is signalled that it may be a good time to delete the held resources, but it may not happen immediately. There is also no protection for calling Release multiple times. The reference counter will not become negative, but it will not perform any other sanity checking (because it can't really) so you can cause application instability by trying to release references you don't hold.
Yes, you are correct. This is called reference counting and it ensures that objects are alive as long as they are being used, and no longer. You can use a variety of smart pointers to enforce this rule- both shared_ptr and (C++11) unique_ptr allow for custom deleters to call Release(). This makes it easy to control the lifetime of Direct3D objects just like you would for any other object in your application. You don't need to start including ATL libraries and CComPtr to use smart pointers with COM interfaces.

Boost shared_ptr use_count function

My application problem is the following -
I have a large structure foo. Because these are large and for memory management reasons, we do not wish to delete them when processing on the data is complete.
We are storing them in std::vector<boost::shared_ptr<foo>>.
My question is related to knowing when all processing is complete. First decision is that we do not want any of the other application code to mark a complete flag in the structure because there are multiple execution paths in the program and we cannot predict which one is the last.
So in our implementation, once processing is complete, we delete all copies of boost::shared_ptr<foo>> except for the one in the vector. This will drop the reference counter in the shared_ptr to 1. Is it practical to use shared_ptr.use_count() to see if it is equal to 1 to know when all other parts of my app are done with the data.
One additional reason I'm asking the question is that the boost documentation on the shared pointer shared_ptr recommends not using "use_count" for production code.
Edit -
What I did not say is that when we need a new foo, we will scan the vector of foo pointers looking for a foo that is not currently in use and use that foo for the next round of processing. This is why I was thinking that having the reference counter of 1 would be a safe way to ensure that this particular foo object is no longer in use.
My immediate reaction (and I'll admit, it's no more than that) is that it sounds like you're trying to get the effect of a pool allocator of some sort. You might be better off overloading operator new and operator delete to get the effect you want a bit more directly. With something like that, you can probably just use a shared_ptr like normal, and the other work you want delayed, will be handled in operator delete for that class.
That leaves a more basic question: what are you really trying to accomplish with this? From a memory management viewpoint, one common wish is to allocate memory for a large number of objects at once, and after the entire block is empty, release the whole block at once. If you're trying to do something on that order, it's almost certainly easier to accomplish by overloading new and delete than by playing games with shared_ptr's use_count.
Edit: based on your comment, overloading new and delete for class sounds like the right thing to do. If anything, integration into your existing code will probably be easier; in fact, you can often do it completely transparently.
The general idea for the allocator is pretty much the same as you've outlined in your edited question: have a structure (bitmaps and linked lists are both common) to keep track of your free objects. When new needs to allocate an object, it can scan the bit vector or look at the head of the linked list of free objects, and return its address.
This is one case that linked lists can work out quite well -- you (usually) don't have to worry about memory usage, because you store your links right in the free object, and you (virtually) never have to walk the list, because when you need to allocate an object, you just grab the first item on the list.
This sort of thing is particularly common with small objects, so you might want to look at the Modern C++ Design chapter on its small object allocator (and an article or two since then by Andrei Alexandrescu about his newer ideas of how to do that sort of thing). There's also the Boost::pool allocator, which is generally at least somewhat similar.
If you want to know whether or not the use count is 1, use the unique() member function.
I would say your application should have some method that eliminates all references to the Foo from other parts of the app, and that method should be used instead of checking use_count(). Besides, if use_count() is greater than 1, what would your program do? You shouldn't be relying on shared_ptr's features to eliminate all references, your application architecture should be able to eliminate references. As a final check before removing it from the vector, you could assert(unique()) to verify it really is being released.
I think you can use shared_ptr's custom deleter functionality to call a particular function when the last copy has been released. That way, you're not using use_count at all.
You would need to hold something other than a copy of the shared_ptr in your vector so that the shared_ptr is only tracking the outstanding processing.
Boost has several examples of custom deleters in the shared_ptr docs.
I would suggest that instead of trying to use the shared_ptr's use_count to keep track, it might be better to implement your own usage counter. this way you will have full control over this rather than using the shared_ptr's one which, as you rightly suggest, is not recommended. You can also pre-set your own counter to allow for the number of threads you know will need to act on the data, rather than relying on them all being initialised at the beginning to get their copies of the structure.

Qt4.5: Implicitly shared QImage: are methods like .bits() always copying (documentation unclarity)

I am writing a Qt application that has to handle big QImage s.
QImage uses implicit sharing, which means it reference counts an internal data pointer. Whenever the refcount is > 1 the object counts as "shared" and any even only potentially data modifying call issues a deep copy of the image data.
In short: I don't want deep copies to happen.
I make a number of calls like setPixel(), bits() etc. that can trigger a copy. The documentation sometimes reads as if certain calls would always trigger a deep copy (detach call) even if I try my hardest to keep the refcount at 1.
Like here:
QImage::setPixel()
So I want to know:
Is the doc only formulated a bit clumsily and these calls are reliably copying only shared objects (as in refcount > 1)?
Can I ask an object what it's current refcount is, for debugging reasons and the like?
Can I force Qt not to implicitly share specific objects/instances (<- well here my educated guess is "no")
Operations that could modify the shared instance will detach. setPixel detaches.
Try QImage::isDetached() which does a return d && d->ref == 1;. By using a debugger, you can get to the actual refcount.
Other than passing by reference/shared pointer no.