aboutsummaryrefslogtreecommitdiff
path: root/shared/filebuf/include/PsMemoryBuffer.h
diff options
context:
space:
mode:
authorbgaldrikian <[email protected]>2020-11-10 20:53:31 -0800
committerbgaldrikian <[email protected]>2020-11-10 20:53:31 -0800
commitd61c455a4775f966b44cc47804b9e0f160d3d332 (patch)
tree7eff987598048409fe4ec9a1f733a87356f3aa21 /shared/filebuf/include/PsMemoryBuffer.h
parent* Updated license file (diff)
downloadblast-1.1.7_rc1.tar.xz
blast-1.1.7_rc1.zip
Merge request #17 PhysX4 compatibilityv1.1.7_rc1
Other changes for linux and UE4CrossCompileLinux, and all packaging to work
Diffstat (limited to 'shared/filebuf/include/PsMemoryBuffer.h')
-rw-r--r--shared/filebuf/include/PsMemoryBuffer.h449
1 files changed, 449 insertions, 0 deletions
diff --git a/shared/filebuf/include/PsMemoryBuffer.h b/shared/filebuf/include/PsMemoryBuffer.h
new file mode 100644
index 0000000..f708819
--- /dev/null
+++ b/shared/filebuf/include/PsMemoryBuffer.h
@@ -0,0 +1,449 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+#ifndef PSFILEBUFFER_PSMEMORYBUFFER_H
+#define PSFILEBUFFER_PSMEMORYBUFFER_H
+
+#include "Ps.h"
+#include "PsUserAllocated.h"
+#include "PsAlignedMalloc.h"
+#include "filebuf/PxFileBuf.h"
+#include "foundation/PxAssert.h"
+
+namespace physx
+{
+namespace general_PxIOStream2
+{
+ using namespace shdfnd;
+
+ const uint32_t BUFFER_SIZE_DEFAULT = 4096;
+
+//Use this class if you want to use your own allocator
+template<class Allocator>
+class PxMemoryBufferBase : public PxFileBuf, public Allocator
+{
+ PX_NOCOPY(PxMemoryBufferBase)
+ void init(const void *readMem, uint32_t readLen)
+ {
+ mAllocator = this;
+
+ mReadBuffer = mReadLoc = static_cast<const uint8_t *>(readMem);
+ mReadStop = &mReadLoc[readLen];
+
+ mWriteBuffer = mWriteLoc = mWriteStop = NULL;
+ mWriteBufferSize = 0;
+ mDefaultWriteBufferSize = BUFFER_SIZE_DEFAULT;
+
+ mOpenMode = OPEN_READ_ONLY;
+ mSeekType = SEEKABLE_READ;
+ }
+
+ void init(uint32_t defaultWriteBufferSize)
+ {
+ mAllocator = this;
+
+ mReadBuffer = mReadLoc = mReadStop = NULL;
+
+ mWriteBuffer = mWriteLoc = mWriteStop = NULL;
+ mWriteBufferSize = 0;
+ mDefaultWriteBufferSize = defaultWriteBufferSize;
+
+ mOpenMode = OPEN_READ_WRITE_NEW;
+ mSeekType = SEEKABLE_READWRITE;
+ }
+
+public:
+ PxMemoryBufferBase(const void *readMem,uint32_t readLen)
+ {
+ init(readMem, readLen);
+ }
+
+ PxMemoryBufferBase(const void *readMem,uint32_t readLen, const Allocator &alloc): Allocator(alloc)
+ {
+ init(readMem, readLen);
+ }
+
+ PxMemoryBufferBase(uint32_t defaultWriteBufferSize = BUFFER_SIZE_DEFAULT)
+ {
+ init(defaultWriteBufferSize);
+ }
+
+ PxMemoryBufferBase(uint32_t defaultWriteBufferSize, const Allocator &alloc): Allocator(alloc)
+ {
+ init(defaultWriteBufferSize);
+ }
+
+ virtual ~PxMemoryBufferBase(void)
+ {
+ reset();
+ }
+
+ void setAllocator(Allocator *allocator)
+ {
+ mAllocator = allocator;
+ }
+
+ void initWriteBuffer(uint32_t size)
+ {
+ if ( mWriteBuffer == NULL )
+ {
+ if ( size < mDefaultWriteBufferSize ) size = mDefaultWriteBufferSize;
+ mWriteBuffer = static_cast<uint8_t *>(mAllocator->allocate(size));
+ PX_ASSERT( mWriteBuffer );
+ mWriteLoc = mWriteBuffer;
+ mWriteStop = &mWriteBuffer[size];
+ mWriteBufferSize = size;
+ mReadBuffer = mWriteBuffer;
+ mReadStop = &mWriteBuffer[size];
+ mReadLoc = mWriteBuffer;
+ }
+ }
+
+ void reset(void)
+ {
+ mAllocator->deallocate(mWriteBuffer);
+ mWriteBuffer = NULL;
+ mWriteBufferSize = 0;
+ mWriteLoc = NULL;
+ mWriteStop = NULL;
+ mReadBuffer = NULL;
+ mReadStop = NULL;
+ mReadLoc = NULL;
+ }
+
+ virtual OpenMode getOpenMode(void) const
+ {
+ return mOpenMode;
+ }
+
+
+ SeekType isSeekable(void) const
+ {
+ return mSeekType;
+ }
+
+ virtual uint32_t read(void* buffer, uint32_t size)
+ {
+ if ( (mReadLoc+size) > mReadStop )
+ {
+ size = uint32_t(mReadStop - mReadLoc);
+ }
+ if ( size != 0 )
+ {
+ memmove(buffer,mReadLoc,size);
+ mReadLoc+=size;
+ }
+ return size;
+ }
+
+ virtual uint32_t peek(void* buffer, uint32_t size)
+ {
+ if ( (mReadLoc+size) > mReadStop )
+ {
+ size = uint32_t(mReadStop - mReadLoc);
+ }
+ if ( size != 0 )
+ {
+ memmove(buffer,mReadLoc,size);
+ }
+ return size;
+ }
+
+ virtual uint32_t write(const void* buffer, uint32_t size)
+ {
+ PX_ASSERT( mOpenMode == OPEN_READ_WRITE_NEW );
+ if ( mOpenMode == OPEN_READ_WRITE_NEW )
+ {
+ if ( (mWriteLoc+size) > mWriteStop )
+ growWriteBuffer(size);
+ memmove(mWriteLoc,buffer,size);
+ mWriteLoc+=size;
+ mReadStop = mWriteLoc;
+ }
+ else
+ {
+ size = 0;
+ }
+ return size;
+ }
+
+ PX_INLINE const uint8_t * getReadLoc(void) const { return mReadLoc; }
+ PX_INLINE void advanceReadLoc(uint32_t len)
+ {
+ PX_ASSERT(mReadBuffer);
+ if ( mReadBuffer )
+ {
+ mReadLoc+=len;
+ if ( mReadLoc >= mReadStop )
+ {
+ mReadLoc = mReadStop;
+ }
+ }
+ }
+
+ virtual uint32_t tellRead(void) const
+ {
+ uint32_t ret=0;
+
+ if ( mReadBuffer )
+ {
+ ret = uint32_t(mReadLoc-mReadBuffer);
+ }
+ return ret;
+ }
+
+ virtual uint32_t tellWrite(void) const
+ {
+ return uint32_t(mWriteLoc-mWriteBuffer);
+ }
+
+ virtual uint32_t seekRead(uint32_t loc)
+ {
+ uint32_t ret = 0;
+ PX_ASSERT(mReadBuffer);
+ if ( mReadBuffer )
+ {
+ mReadLoc = &mReadBuffer[loc];
+ if ( mReadLoc >= mReadStop )
+ {
+ mReadLoc = mReadStop;
+ }
+ ret = uint32_t(mReadLoc-mReadBuffer);
+ }
+ return ret;
+ }
+
+ virtual uint32_t seekWrite(uint32_t loc)
+ {
+ uint32_t ret = 0;
+ PX_ASSERT( mOpenMode == OPEN_READ_WRITE_NEW );
+ if ( mWriteBuffer )
+ {
+ if ( loc > mWriteBufferSize )
+ {
+ mWriteLoc = mWriteStop;
+ growWriteBuffer(loc - mWriteBufferSize);
+ }
+ mWriteLoc = &mWriteBuffer[loc];
+ ret = uint32_t(mWriteLoc-mWriteBuffer);
+ }
+ return ret;
+ }
+
+ virtual void flush(void)
+ {
+
+ }
+
+ virtual uint32_t getFileLength(void) const
+ {
+ uint32_t ret = 0;
+ if ( mReadBuffer )
+ {
+ ret = uint32_t(mReadStop-mReadBuffer);
+ }
+ else if ( mWriteBuffer )
+ {
+ ret = uint32_t(mWriteLoc-mWriteBuffer);
+ }
+ return ret;
+ }
+
+ uint32_t getWriteBufferSize(void) const
+ {
+ return uint32_t(mWriteLoc-mWriteBuffer);
+ }
+
+ void setWriteLoc(uint8_t *writeLoc)
+ {
+ PX_ASSERT(writeLoc >= mWriteBuffer && writeLoc < mWriteStop );
+ mWriteLoc = writeLoc;
+ mReadStop = mWriteLoc;
+ }
+
+ const uint8_t * getWriteBuffer(void) const
+ {
+ return mWriteBuffer;
+ }
+
+ /**
+ * Attention: if you use aligned allocator you cannot free memory with PX_FREE macros instead use deallocate method from base
+ */
+ uint8_t * getWriteBufferOwnership(uint32_t &dataLen) // return the write buffer, and zero it out, the caller is taking ownership of the memory
+ {
+ uint8_t *ret = mWriteBuffer;
+ dataLen = uint32_t(mWriteLoc-mWriteBuffer);
+ mWriteBuffer = NULL;
+ mWriteLoc = NULL;
+ mWriteStop = NULL;
+ mWriteBufferSize = 0;
+ return ret;
+ }
+
+
+ void alignRead(uint32_t a)
+ {
+ uint32_t loc = tellRead();
+ uint32_t aloc = ((loc+(a-1))/a)*a;
+ if ( aloc != loc )
+ {
+ seekRead(aloc);
+ }
+ }
+
+ void alignWrite(uint32_t a)
+ {
+ uint32_t loc = tellWrite();
+ uint32_t aloc = ((loc+(a-1))/a)*a;
+ if ( aloc != loc )
+ {
+ seekWrite(aloc);
+ }
+ }
+
+private:
+
+
+ // double the size of the write buffer or at least as large as the 'size' value passed in.
+ void growWriteBuffer(uint32_t size)
+ {
+ if ( mWriteBuffer == NULL )
+ {
+ if ( size < mDefaultWriteBufferSize ) size = mDefaultWriteBufferSize;
+ initWriteBuffer(size);
+ }
+ else
+ {
+ uint32_t oldWriteIndex = uint32_t(mWriteLoc - mWriteBuffer);
+ uint32_t newSize = mWriteBufferSize*2;
+ uint32_t avail = newSize-oldWriteIndex;
+ if ( size >= avail ) newSize = newSize+size;
+ uint8_t *writeBuffer = static_cast<uint8_t *>(mAllocator->allocate(newSize));
+ PX_ASSERT( writeBuffer );
+ memmove(writeBuffer,mWriteBuffer,mWriteBufferSize);
+ mAllocator->deallocate(mWriteBuffer);
+ mWriteBuffer = writeBuffer;
+ mWriteBufferSize = newSize;
+ mWriteLoc = &mWriteBuffer[oldWriteIndex];
+ mWriteStop = &mWriteBuffer[mWriteBufferSize];
+ uint32_t oldReadLoc = uint32_t(mReadLoc-mReadBuffer);
+ mReadBuffer = mWriteBuffer;
+ mReadStop = mWriteLoc;
+ mReadLoc = &mReadBuffer[oldReadLoc];
+ }
+ }
+
+ const uint8_t *mReadBuffer;
+ const uint8_t *mReadLoc;
+ const uint8_t *mReadStop;
+
+ uint8_t *mWriteBuffer;
+ uint8_t *mWriteLoc;
+ uint8_t *mWriteStop;
+
+ uint32_t mWriteBufferSize;
+ uint32_t mDefaultWriteBufferSize;
+ Allocator *mAllocator;
+ OpenMode mOpenMode;
+ SeekType mSeekType;
+
+};
+
+class PxMemoryBufferAllocator
+{
+public:
+ PxMemoryBufferAllocator(uint32_t a = 0) : alignment(a) {}
+
+ virtual void * allocate(uint32_t size)
+ {
+ switch(alignment)
+ {
+ case 0:
+ return PX_ALLOC(size, PX_DEBUG_EXP("PxMemoryBufferAllocator"));
+ case 16 :
+ return physx::AlignedAllocator<16>().allocate(size, __FILE__, __LINE__);
+ case 32 :
+ return physx::AlignedAllocator<32>().allocate(size, __FILE__, __LINE__);
+ case 64 :
+ return physx::AlignedAllocator<64>().allocate(size, __FILE__, __LINE__);
+ case 128 :
+ return physx::AlignedAllocator<128>().allocate(size, __FILE__, __LINE__);
+ default :
+ PX_ASSERT(0);
+ }
+ return NULL;
+ }
+ virtual void deallocate(void *mem)
+ {
+ switch(alignment)
+ {
+ case 0:
+ PX_FREE(mem);
+ break;
+ case 16 :
+ physx::AlignedAllocator<16>().deallocate(mem);
+ break;
+ case 32 :
+ physx::AlignedAllocator<32>().deallocate(mem);
+ break;
+ case 64 :
+ physx::AlignedAllocator<64>().deallocate(mem);
+ break;
+ case 128 :
+ physx::AlignedAllocator<128>().deallocate(mem);
+ break;
+ default :
+ PX_ASSERT(0);
+ }
+ }
+ virtual ~PxMemoryBufferAllocator(void) {}
+private:
+ PxMemoryBufferAllocator& operator=(const PxMemoryBufferAllocator&);
+
+ const uint32_t alignment;
+};
+
+//Use this class if you want to use PhysX memory allocator
+class PsMemoryBuffer: public PxMemoryBufferBase<PxMemoryBufferAllocator>, public UserAllocated
+{
+ PX_NOCOPY(PsMemoryBuffer)
+ typedef PxMemoryBufferBase<PxMemoryBufferAllocator> BaseClass;
+
+public:
+ PsMemoryBuffer(const void *readMem,uint32_t readLen): BaseClass(readMem, readLen) {}
+ PsMemoryBuffer(const void *readMem,uint32_t readLen, uint32_t alignment): BaseClass(readMem, readLen, PxMemoryBufferAllocator(alignment)) {}
+
+ PsMemoryBuffer(uint32_t defaultWriteBufferSize=BUFFER_SIZE_DEFAULT): BaseClass(defaultWriteBufferSize) {}
+ PsMemoryBuffer(uint32_t defaultWriteBufferSize,uint32_t alignment): BaseClass(defaultWriteBufferSize, PxMemoryBufferAllocator(alignment)) {}
+};
+
+}
+using namespace general_PxIOStream2;
+}
+
+#endif // PSFILEBUFFER_PSMEMORYBUFFER_H
+