summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/Source/system/Qt3DSMemoryHeap.cpp')
-rw-r--r--src/Runtime/Source/system/Qt3DSMemoryHeap.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp b/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp
new file mode 100644
index 00000000..4ab36178
--- /dev/null
+++ b/src/Runtime/Source/system/Qt3DSMemoryHeap.cpp
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 1993-2009 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "SystemPrefix.h"
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "Qt3DSMemory.h"
+#include "Qt3DSMemoryHeap.h"
+#include "Qt3DSMemoryStatistics.h"
+#include "Qt3DSIStream.h"
+#include "foundation/Qt3DSLogging.h"
+
+//==============================================================================
+// Namespace
+//==============================================================================
+namespace Q3DStudio {
+
+//==============================================================================
+// Static Initialzation
+//==============================================================================
+CMemoryProbe CMemoryHeap::s_Probe;
+
+#if Q3DStudio_MEMORY_HEAPTRACKING
+CMemoryHeap::TMemoryReport CMemoryHeap::s_MemoryReport;
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+
+//==============================================================================
+/**
+ * Allocate a chunk of memory and potentially track it.
+ * @param inSize size of requested memory block, in bytes
+ * @param inDescription allocation description such as class name or pool name
+ * @param inFile file name
+ * @param inFunction method name
+ * @param inLine line number
+ * @return void* a pointer to a memory block large enough to hold inSize bytes
+ */
+void *CMemoryHeap::Allocate(const INT32 inSize, const CHAR *inDescription, const CHAR *inFile,
+ const INT32 inLine)
+{
+ // Always track stats and trigger snapshot if this is a new record
+ s_Probe.Allocate(inSize);
+
+ // Check if we are exceeding the max memory limit
+ if (Q3DStudio_MEMORY_LIMIT > 0
+ && s_Probe.GetBytes(Q3DStudio::MEMSCOPE_GLOBAL, Q3DStudio::MEMVALUE_CURRENT)
+ > Q3DStudio_MEMORY_LIMIT) {
+ qCCritical (qt3ds::OUT_OF_MEMORY)
+ << "Q3DStudio_MEMORY_UNIT exceeded " << Q3DStudio_MEMORY_LIMIT;
+ Q3DStudio_ASSERT(false);
+ }
+
+#if Q3DStudio_MEMORY_HEAPTRACKING
+ void *theAllocatedPtr = CMemory::Malloc()(static_cast<const size_t>(inSize));
+ if (s_MemoryReport.GetCount() < s_MemoryReport.GetCapacity()) {
+ SReportEntry theEntry = { theAllocatedPtr, inSize, inDescription, inFile, inLine };
+ s_MemoryReport.Push(theEntry);
+ } else {
+ static BOOL s_FullWarning = false;
+ if (!s_FullWarning) {
+ qCWarning (qt3ds::TRACE_INFO) << "HeapTracker full. "
+ << "Please increase Q3DStudio_MEMORY_HEAPTRACKINGSIZE("
+ << Q3DStudio_MEMORY_HEAPTRACKINGSIZE << ") "
+ << "to track all allocation and tune your pools to avoid "
+ << "hitting the heap.";
+ s_FullWarning = true;
+ }
+ }
+ return theAllocatedPtr;
+#else
+ Q3DStudio_UNREFERENCED_PARAMETER(inLine);
+ Q3DStudio_UNREFERENCED_PARAMETER(inFile);
+ Q3DStudio_UNREFERENCED_PARAMETER(inDescription);
+
+ return CMemory::Malloc()(static_cast<const size_t>(inSize));
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+}
+
+//==============================================================================
+/**
+ * Free a block of memory allocated using CMemoryHeap::Allocate
+ * @param inPointer pointer given in a previous allocation
+ * @param inSize size of given memory block, in bytes
+ */
+void CMemoryHeap::Free(void *inPointer, INT32 inSize)
+{
+ // No-Op on NULL
+ if (!inPointer)
+ return;
+
+#if Q3DStudio_MEMORY_HEAPTRACKING
+ RemoveReport(inPointer);
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+
+ s_Probe.Free(inSize);
+ return CMemory::Free()(inPointer);
+}
+
+//==============================================================================
+/**
+ * Re-allocate an existing chunk of memory and potentially track it.
+ * @param inPointer pointer given in a previous allocation
+ * @param inOldSize size of current memory block, in bytes
+ * @param inNewSize size of requested memory block, in bytes
+ * @param inNewDescription allocation description such as class name or pool name
+ * @param inFile file name
+ * @param inFunction method name
+ * @param inLine line number
+ * @return void* a pointer to a memory block large enough to hold inSize bytes
+ */
+void *CMemoryHeap::Reallocate(void *inPointer, const INT32 inOldSize, const INT32 inNewSize,
+ const CHAR *inNewDescription, const CHAR *inFile, const INT32 inLine)
+{
+ // Make sure this isn't a new malloc
+ if (!inPointer)
+ return Allocate(inNewSize, inNewDescription, inFile, inLine);
+
+ // Always track stats and record new high if it's a record
+ s_Probe.Allocate(inNewSize);
+ s_Probe.Free(inOldSize);
+
+ // Check if we are exceeding the max memory limit
+ Q3DStudio_ASSERT(Q3DStudio_MEMORY_LIMIT == 0
+ ? true
+ : s_Probe.GetBytes(Q3DStudio::MEMSCOPE_GLOBAL, Q3DStudio::MEMVALUE_CURRENT)
+ < Q3DStudio_MEMORY_LIMIT);
+
+#if Q3DStudio_MEMORY_HEAPTRACKING
+ RemoveReport(inPointer);
+
+ void *theReallocatedPtr = CMemory::Realloc()(inPointer, static_cast<const size_t>(inNewSize));
+
+ SReportEntry theEntry = { theReallocatedPtr, inNewSize, inNewDescription, inFile, inLine };
+ s_MemoryReport.Push(theEntry);
+
+ return theReallocatedPtr;
+#else
+ return CMemory::Realloc()(inPointer, static_cast<const size_t>(inNewSize));
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+}
+
+//==============================================================================
+/**
+ * Retrieves memory info about a particular allocation
+ * @param inPointer allocated memory
+ * @return SMemoryHeapReportEntry* memory report
+ */
+CMemoryHeap::SReportEntry *CMemoryHeap::FindReport(void *inPointer)
+{
+ Q3DStudio_UNREFERENCED_PARAMETER(inPointer);
+
+#if Q3DStudio_MEMORY_HEAPTRACKING
+ INT32 theEnd = s_MemoryReport.GetCount();
+ for (INT32 theIndex = 0; theIndex < theEnd; ++theIndex)
+ if (s_MemoryReport[theIndex].m_AllocatedPointer == inPointer)
+ return &s_MemoryReport[theIndex];
+
+ Q3DStudio_ASSERT(false);
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+
+ return NULL;
+}
+
+//==============================================================================
+/**
+ * Removes memory info due to a deallocation.
+ * @param inPointer allocated memory
+ */
+void CMemoryHeap::RemoveReport(void *inPointer)
+{
+ Q3DStudio_UNREFERENCED_PARAMETER(inPointer);
+
+#if Q3DStudio_MEMORY_HEAPTRACKING
+ INT32 theEnd = s_MemoryReport.GetCount();
+ for (INT32 theIndex = 0; theIndex < theEnd; ++theIndex) {
+ if (s_MemoryReport[theIndex].m_AllocatedPointer == inPointer) {
+ s_MemoryReport.Remove(theIndex);
+ return;
+ }
+ }
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+}
+
+//==============================================================================
+/**
+ * The memory probe records basic heap activity
+ * @return reference to probe
+ */
+CMemoryProbe &CMemoryHeap::GetProbe()
+{
+ return s_Probe;
+}
+
+//==============================================================================
+/**
+ * The report records all heap activity
+ * @return pointer to report if tracking is on, or NULL
+ */
+CMemoryHeap::TMemoryReport *CMemoryHeap::GetReport()
+{
+#if Q3DStudio_MEMORY_HEAPTRACKING
+ return &s_MemoryReport;
+#else
+ return NULL;
+#endif // Q3DStudio_MEMORY_HEAPTRACKING
+}
+
+} // namespace Q3DStudio