Writing a releaseView Function#

releaseView will be called once when the window surface is going to be lost, but before it happens. The window surface is lost when the application loses focus or the window is going to be torn down. If the application is about to lose the window/API/surface or restarts, releaseView will be called before initView is called again.

OpenGL ES#

For OpenGL ES, follow normal OpenGL ES rules for deleting objects.

Vulkan (PVRVk)#

For PVRVk, make use of RAII (Resource Acquisition Is Initialisation) - release any API objects specifically created, by releasing any references that are held. Release can be achieved by calling reset() on the smart pointer itself, or if objects are held in containers, by emptying those containers.

Never attempt to release the underlying object. If an API to do so exists, it will mean something different and not behave as expected. Access the reset() function with the dot '.' (not arrow '->') operator on a PVRVk object. Do not explicitly delete an API object. All objects are deleted when no references to them are held.

When cleaning up, use device->waitIdle() before deleting objects that might still be executing. As this takes place during teardown, objects are being released, and there are no performance concerns.

Note that RAII deletion of PVRVk and other Framework objects is deterministic, not garbage-collected. Objects are always deleted exactly when the last reference to them is released. Also, note that objects may hold references to other objects that they require, and these object chains are also deleted when the last reference is released. For example, command buffers hold references to their corresponding pools, descriptor sets hold references to any objects they contain. This is one of the most important features of PVRVk.

There is no particular required deletion order imposed. Keep any objects needed to reference and release them when no longer required.

It is recommended that C++ destructors are used.

This is how the Framework examples handle destruction:

A struct/class is defined that contains all the PVRVk objects. It is allocated in initView and deleted in releaseView. Ideally, a std::unique_ptr is used. Then, as objects are deleted (unless a circular dependency was created) the dependency graph unfolds itself, and destructors are called in the correct order.

Important

There is a very important caveat to the automatic releasing of objects. While objects like command buffers and descriptor sets hold references to objects added to them and keep them alive, this is not true for command queues.

Command queues do not explicitly report when command buffers are executed, so it would have been very difficult to automatically report to a PVRVk command queue when the GPU has finished executing a command buffer, hence command queues do not hold references to command buffers. Therefore, it is necessary to explicitly track the execution status of command buffers and only release them after a command queue has finished executing them. This is one of the reasons waitIdle() is recommended before starting the teardown process.