/* ZRendererResource.hpp Author: James Russell Created: 7/8/2012 Purpose: A renderer resource is anything that is created by the renderer and is used as part of the rendering process. Generally, renderer resources are objects that act as an interface to graphics device state, such as buffers, textures, etc. It should be noted that resources are not safe to be used across multiple threads, even though the renderer is multi thread capable. A resource should only be used within the context of a single thread, and draw calls using that resource should also remain within the same thread (this is done to avoid costly concurrent operations). Different resources are free to be used across different threads. Usage: A renderer resource can be 'available', 'locked', or 'contended'. When a resource is available, all calls to methods that modify the underlying data (or make the underlying data available for modification) succeed and this will be indicated by the return value. If the resource is locked or contended, the return value of the method will indicate failure to modify the resource. If a resource is 'locked', then the resource is currently in the midst of modification. This means that some modification methods will be unavailable. As an example, 'MapBuffer' cannot be called while the buffer is already mapped, and 'FillBuffer' will fail if a buffer has been mapped. A locked resource can be unlocked and returned to 'available' state before rendering. If a resource is contended, this means that the renderer is relying on the data that is currently present in graphics memory, as a draw call has been placed using the data at the time of contention. This means that any calls that would allow the user to modify the underlying data will fail. A contended buffer becomes available when the renderer has finished reading the data needed from the resource, which will occur at frame end. Note that this means that the following set of actions (using an example of ZDataBuffer): buffer = dataBuffer->MapBuffer(true); ... //Update Buffer dataBuffer->UnmapBuffer(); renderer->SubmitDrawData(...); //Draw using this buffer buffer = dataBuffer->MapBuffer(true); ... //Update Buffer dataBuffer->UnmapBuffer(); renderer->SubmitDrawData(...); //Draw using the updated buffer renderer->RenderFrame(...); //Render this frame Will not work. The second call to 'MapBuffer' will fail because the buffer became contended as soon as the buffer was used as an argument to 'SubmitDrawData'. The renderer's 'WaitFameEnd' method will enable you to wait until the resource is no longer contended. License: TODO */ #pragma once #ifndef _ZRENDERERRESOURCE_HPP #define _ZRENDERERRESOURCE_HPP #include class ZRendererResource { private: DISABLE_COPY_AND_ASSIGN(ZRendererResource); protected: //Counter of 'owners' claiming contention int ContentionCount; //Flag indicating that this resource has been 'locked' bool bIsLocked; public: //Default Constructor ZRendererResource(); //Virtual Destructor virtual ~ZRendererResource() { } /* public ZRendererResource::Available Returns whether or not this resource is currently available (able to be modified). If a resource is locked or contended, then it is not available for modification. @return (bool) - true if available, false otherwise @context (all) */ bool IsAvailable(); /* public ZRendererResource::Lock Locks this resource, making it unavailable for modification. @return (void) @context (all) */ void Lock(); /* public ZRendererResource::MarkContended Marks this resource as contended. Resources should, from this point out, understand that modification of the underlying resource should not happen until after the frame is drawn that would release this resource from contention. From this point out, the caller 'owns' the resource. Resources can be marked as contended by multiple sources, and the resource will not be available until all owners who have marked contended have released their claim. Generally, this should only be called by the renderer. @return (void) @context (renderer) */ void MarkContended(); /* public ZRendererResource::ReleaseContended Removes a previous claim of contention. If all previous owners have released their contention, then the resource is available. @return (void) @context (all) */ void ReleaseContention(); /* public ZRendererResource::Unlock Unlocks a resource, making it available for modification. @return (void) @context (all) */ void Unlock(); }; #endif