Merge branch 'main' into ly-as-sdk/LYN-2948

# Conflicts:
#	CMakeLists.txt
This commit is contained in:
pappeste
2021-05-10 14:36:20 -07:00
421 changed files with 13429 additions and 27863 deletions
+1 -47
View File
@@ -711,31 +711,6 @@ static Win32SysInspect::DXFeatureLevel GetFeatureLevel(D3D_FEATURE_LEVEL feature
}
}
static int GetDXGIAdapterOverride()
{
#if defined(WIN32) || defined(WIN64)
ICVar* pCVar = gEnv->pConsole ? gEnv->pConsole->GetCVar("r_overrideDXGIAdapter") : 0;
return pCVar ? pCVar->GetIVal() : -1;
#else
return -1;
#endif
}
static void LogDeviceInfo(unsigned int adapterIdx, const DXGI_ADAPTER_DESC1& ad, Win32SysInspect::DXFeatureLevel fl, bool displaysConnected)
{
const bool suitableDevice = fl >= Win32SysInspect::DXFL_11_0 && displaysConnected;
CryLogAlways("- %s (vendor = 0x%.4x, device = 0x%.4x)", CryStringUtils::WStrToUTF8(ad.Description).c_str(), ad.VendorId, ad.DeviceId);
CryLogAlways(" - Adapter index: %d", adapterIdx);
CryLogAlways(" - Dedicated video memory: %d MB", ad.DedicatedVideoMemory >> 20);
CryLogAlways(" - Feature level: %s", GetFeatureLevelAsString(fl));
CryLogAlways(" - Displays connected: %s", displaysConnected ? "yes" : "no");
CryLogAlways(" - Suitable rendering device: %s", suitableDevice ? "yes" : "no");
}
static bool FindGPU(DXGI_ADAPTER_DESC1& adapterDesc, Win32SysInspect::DXFeatureLevel& featureLevel)
{
memset(&adapterDesc, 0, sizeof(adapterDesc));
@@ -757,15 +732,7 @@ static bool FindGPU(DXGI_ADAPTER_DESC1& adapterDesc, Win32SysInspect::DXFeatureL
if (pD3D11CD)
{
const int r_overrideDXGIAdapter = GetDXGIAdapterOverride();
const bool logDeviceInfo = !gEnv->pRenderer && r_overrideDXGIAdapter < 0;
if (logDeviceInfo)
{
CryLogAlways("Logging video adapters:");
}
unsigned int nAdapter = r_overrideDXGIAdapter >= 0 ? r_overrideDXGIAdapter : 0;
unsigned int nAdapter = 0;
IDXGIAdapter1* pAdapter = 0;
while (pFactory->EnumAdapters1(nAdapter, &pAdapter) != DXGI_ERROR_NOT_FOUND)
{
@@ -786,29 +753,16 @@ static bool FindGPU(DXGI_ADAPTER_DESC1& adapterDesc, Win32SysInspect::DXFeatureL
const Win32SysInspect::DXFeatureLevel fl = GetFeatureLevel(deviceFeatureLevel);
if (logDeviceInfo)
{
LogDeviceInfo(nAdapter, ad, fl, displaysConnected);
}
if (featureLevel < fl && displaysConnected)
{
adapterDesc = ad;
featureLevel = fl;
}
else if (r_overrideDXGIAdapter >= 0)
{
CryLogAlways("No display connected to DXGI adapter override %d. Adapter cannot be used for rendering.", r_overrideDXGIAdapter);
}
}
SAFE_RELEASE(pDevice);
SAFE_RELEASE(pAdapter);
}
if (r_overrideDXGIAdapter >= 0)
{
break;
}
++nAdapter;
}
}
-251
View File
@@ -1,251 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include <ITimer.h>
#include <CrySizer.h>
#include "CrySizerImpl.h"
CrySizerImpl::CrySizerImpl()
: m_pResourceCollector(0)
{
m_nFlags = 0;
m_nTotalSize = 0;
// to avoid reallocations during walk through the memory tree, reserve the space for the names
clear();
}
CrySizerImpl::~CrySizerImpl()
{
}
void CrySizerImpl::Push (const char* szComponentName)
{
m_stackNames.push_back (getNameIndex(getCurrentName(), szComponentName));
// if the depth is too deep, something is wrong, perhaps an infinite loop
assert (m_stackNames.size() < 128);
}
void CrySizerImpl::PushSubcomponent (const char* szSubcomponentName)
{
Push (szSubcomponentName);
}
void CrySizerImpl::Pop ()
{
if (!m_stackNames.empty())
{
m_stackNames.pop_back();
}
else
{
assert (0);
}
}
// returns the index of the current name on the top of the name stack
size_t CrySizerImpl::getCurrentName() const
{
assert(!m_stackNames.empty());
return m_stackNames.empty() ? 0 : m_stackNames.back();
}
// searches for the name in the name array; adds the name if it's not there and returns the index
size_t CrySizerImpl::getNameIndex(size_t nParent, const char* szComponentName)
{
NameArray::const_iterator it = m_arrNames.begin(), itEnd = it + m_arrNames.size();
for (; it != itEnd; ++it)
{
#if defined(LINUX)
if (!strcasecmp(it->strName.c_str(), szComponentName) && it->nParent == nParent)
#else
if (!strcmp(it->strName.c_str(), szComponentName) && it->nParent == nParent)
#endif
{
return (size_t)(it - m_arrNames.begin());//it-m_arrNames.begin();
}
}
size_t nNewName = m_arrNames.size();
m_arrNames.resize(nNewName + 1);
m_arrNames[nNewName].assign(szComponentName, nParent);
m_arrNames[nParent].arrChildren.push_back(nParent);
return nNewName;
}
static NullResCollector s_nullCollector;
IResourceCollector* CrySizerImpl::GetResourceCollector()
{
return m_pResourceCollector != 0 ? m_pResourceCollector : &s_nullCollector;
}
void CrySizerImpl::Reset()
{
clear();
m_nTotalSize = 0;
//m_arrNames.resize(0);
//m_arrNames.push_back("TOTAL"); // the default name, with index 0
//m_LastObject.clear();
////m_nFlags;
//m_nTotalSize=0;
//if (m_pResourceCollector)
//{
// m_pResourceCollector->Reset();
//}
//m_setObjects->clear();
//m_stackNames.resize(0);
//m_stackNames.push_back(0);
}
// adds an object identified by the unique pointer (it needs not be
// the actual object position in the memory, though it would be nice,
// but it must be unique throughout the system and unchanging for this object)
// RETURNS: true if the object has actually been added (for the first time)
// and calculated
bool CrySizerImpl::AddObject (const void* pIdentifier, size_t sizeBytes, int nCount)
{
if (!pIdentifier || !sizeBytes)
{
return false; // we don't add the NULL objects
}
Object NewObject(pIdentifier, sizeBytes, getCurrentName());
// check if the last object was the same
if (NewObject == m_LastObject)
{
assert (m_LastObject.nSize == sizeBytes);
return false;
}
ObjectSet& rSet = m_setObjects[getHash(pIdentifier)];
ObjectSet::iterator it = rSet.find (NewObject);
if (it == rSet.end())
{
// there's no such object in the map, add it
rSet.insert (NewObject);
ComponentName& CompName = m_arrNames[getCurrentName()];
CompName.numObjects += nCount;
CompName.sizeObjects += sizeBytes;
m_nTotalSize += sizeBytes;
return true;
}
else
{
Object* pObj = const_cast<Object*>(&(*it));
// if we do an heap check, don't accept the same object twice
if (sizeBytes != pObj->nSize)
{
// if the following assert fails:
// assert (0);
// .. it means we have one object that's added two times with different sizes; that's screws up the whole idea
// we assume there are two different objects that are for some reason assigned the same id
pObj->nSize += sizeBytes; // anyway it's an invalid situation
ComponentName& CompName = m_arrNames[getCurrentName()];
CompName.sizeObjects += sizeBytes;
return true; // yes we added the object, though there were an error condition
}
return false;
}
}
size_t CrySizerImpl::GetObjectCount()
{
size_t count = m_stackNames.size();
for (int i = 0; i < g_nHashSize; i++)
{
count += m_setObjects[i].size();
}
return count;
}
// finalizes data collection, should be called after all objects have been added
void CrySizerImpl::End()
{
// clean up the totals of each name
int i;
for (i = 0; i < m_arrNames.size(); ++i)
{
assert (i == 0 || ((int)m_arrNames[i].nParent < i && m_arrNames[i].nParent >= 0));
m_arrNames[i].sizeObjectsTotal = m_arrNames[i].sizeObjects;
}
// add the component's size to the total size of the parent.
// for every component, all their children are put after them in the name array
// we don't include the root because it doesn't belong to any other parent (nowhere further to add)
for (i = m_arrNames.size() - 1; i > 0; --i)
{
// the parent's total size is increased by the _total_ size (already calculated) of this object
m_arrNames[m_arrNames[i].nParent].sizeObjectsTotal += m_arrNames[i].sizeObjectsTotal;
}
}
void CrySizerImpl::clear()
{
for (unsigned i = 0; i < g_nHashSize; ++i)
{
m_setObjects[i].clear();
}
m_arrNames.clear();
m_arrNames.push_back("TOTAL"); // the default name, with index 0
m_stackNames.clear();
m_stackNames.push_back(0);
m_LastObject.pId = NULL;
if (m_pResourceCollector)
{
m_pResourceCollector->Reset();
}
}
// hash function for an address; returns value 0..1<<g_nHashSize
unsigned CrySizerImpl::getHash (const void* pId)
{
//return (((unsigned)pId) >> 4) & (g_nHashSize-1);
// pseudorandomizing transform
ldiv_t Qrem = (ldiv_t)ldiv(((uint32)(UINT_PTR)pId >> 2), 127773);
Qrem.rem = 16807 * Qrem.rem - 2836 * Qrem.quot;
if (Qrem.rem < 0)
{
Qrem.rem += 2147483647; // 0x7FFFFFFF
}
return ((unsigned)Qrem.rem) & (g_nHashSize - 1);
}
unsigned CrySizerImpl::GetDepthLevel(unsigned nCurrent)
{
uint32 nDepth = 0;
nCurrent = m_arrNames[nCurrent].nParent;
while (nCurrent != 0)
{
nDepth++;
nCurrent = m_arrNames[nCurrent].nParent;
}
return nDepth;
}
-184
View File
@@ -1,184 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Implementation of the ICrySizer interface, which is used to
// calculate the memory usage by the subsystems and components, to help
// the artists keep the memory budged low.
#ifndef CRYINCLUDE_CRYSYSTEM_CRYSIZERIMPL_H
#define CRYINCLUDE_CRYSYSTEM_CRYSIZERIMPL_H
#pragma once
// prerequisities
//////////////////////////////////////////////////////////////////////////
// implementation of interface ICrySizer
// ICrySizer is passed to all subsystems and has a lot of helper functions that
// are compiled in the appropriate subsystems. CrySizerImpl is created in CrySystem
// and is passed to all the other subsystems
class CrySizerImpl
: public ICrySizer
{
public:
CrySizerImpl();
~CrySizerImpl();
virtual void Release() { delete this; }
virtual size_t GetTotalSize() { return m_nTotalSize; };
virtual size_t GetObjectCount();
void Reset();
// adds an object identified by the unique pointer (it needs not be
// the actual object position in the memory, though it would be nice,
// but it must be unique throughout the system and unchanging for this object)
// RETURNS: true if the object has actually been added (for the first time)
// and calculated
virtual bool AddObject (const void* pIdentifier, size_t nSizeBytes, int nCount = 1);
virtual IResourceCollector* GetResourceCollector();
// finalizes data collection, should be called after all objects have been added
void End();
void clear();
// Arguments:
// pColl - can be 0
void SetResourceCollector(IResourceCollector* pColl) { m_pResourceCollector = pColl; }
protected:
IResourceCollector* m_pResourceCollector; //
// these functions must operate on the component name stack
// they are to be only accessible from within class CrySizerComponentNameHelper
// which should be used through macro SIZER_COMPONENT_NAME
virtual void Push (const char* szComponentName);
virtual void PushSubcomponent (const char* szSubcomponentName);
virtual void Pop ();
// searches for the name in the name array; adds the name if it's not there and returns the index
size_t getNameIndex (size_t nParent, const char* szComponentName);
// returns the index of the current name on the top of the name stack
size_t getCurrentName() const;
protected:
friend class CrySizerStatsBuilder;
// the stack of subsystem names; the indices in the name array are kept, not the names themselves
typedef DynArray<size_t> NameStack;
NameStack m_stackNames;
// the array of names; each name ever pushed on the stack is present here
struct ComponentName
{
ComponentName (){}
ComponentName (const char* szName, size_t parent = 0)
: strName (szName)
, nParent (parent)
, numObjects(0)
, sizeObjects (0)
, sizeObjectsTotal (0)
{
}
void assign (const char* szName, size_t parent = 0)
{
strName = szName;
nParent = parent;
numObjects = 0;
sizeObjects = 0;
sizeObjectsTotal = 0;
arrChildren.clear();
}
// the component name, not including the parents' names
string strName;
// the index of the parent, 0 being the root
size_t nParent;
// the number of objects within this component
size_t numObjects;
// the size of the objects belonging to this component, in bytes
size_t sizeObjects;
// the total size of all objects; gets filled by the end() method of the CrySizerImpl
size_t sizeObjectsTotal;
// the children components
DynArray<size_t> arrChildren;
};
typedef DynArray<ComponentName> NameArray;
NameArray m_arrNames;
// the set of objects and their sizes: the key is the object address/id,
// the value is the size of the object and its name (the index of the name actually)
struct Object
{
const void* pId; // unique pointer identifying the object in memory
size_t nSize; // the size of the object in bytes
size_t nName; // the index of the name in the name array
Object ()
{clear(); }
Object (const void* id, size_t size = 0, size_t name = 0)
: pId(id)
, nSize(size)
, nName(name) {}
// the objects are sorted by their Id
bool operator < (const Object& right) const {return (UINT_PTR)pId < (UINT_PTR)right.pId; }
bool operator < (const void* right) const {return (UINT_PTR)pId < (UINT_PTR)right; }
//friend bool operator < (const void* left, const Object& right);
bool operator == (const Object& right) const {return pId == right.pId; }
void clear()
{
pId = NULL;
nSize = 0;
nName = 0;
}
};
typedef std::set <Object> ObjectSet;
// 2^g_nHashPower == the number of subsets comprising the hash
enum
{
g_nHashPower = 12
};
// hash size (number of subsets)
enum
{
g_nHashSize = 1 << g_nHashPower
};
// hash function for an address; returns value 0..1<<g_nHashSize
unsigned getHash (const void* pId);
unsigned GetDepthLevel(unsigned nCurrent);
ObjectSet m_setObjects[g_nHashSize];
// the last object inserted; this is a small optimization for our template implementaiton
// that often can add two times the same object
Object m_LastObject;
size_t m_nTotalSize;
};
#endif // CRYINCLUDE_CRYSYSTEM_CRYSIZERIMPL_H
-484
View File
@@ -1,484 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "ILog.h"
#include "ITimer.h"
#include "ISystem.h"
#include "IConsole.h"
#include "IRenderer.h"
#include "CrySizerImpl.h"
#include "CrySizerStats.h"
#include "ITextModeConsole.h"
CrySizerStatsBuilder::CrySizerStatsBuilder (CrySizerImpl* pSizer, int nMinSubcomponentBytes)
: m_pSizer (pSizer)
, m_nMinSubcomponentBytes (nMinSubcomponentBytes < 0 || nMinSubcomponentBytes > 0x10000000 ? 0 : nMinSubcomponentBytes)
{
}
// creates the map of names from old (in the sizer Impl) to new (in the Stats)
void CrySizerStatsBuilder::processNames()
{
size_t numCompNames = m_pSizer->m_arrNames.size();
m_pStats->m_arrComponents.reserve (numCompNames);
m_pStats->m_arrComponents.clear();
m_mapNames.resize (numCompNames, (size_t)-1);
// add all root objects
addNameSubtree(0, 0);
}
//////////////////////////////////////////////////////////////////////////
// given the name in the old system, adds the subtree of names to the
// name map and components. In case all the subtree is empty, returns false and
// adds nothing
size_t CrySizerStatsBuilder::addNameSubtree (unsigned nDepth, size_t nName)
{
assert ((int)nName < m_pSizer->m_arrNames.size());
CrySizerImpl::ComponentName& rCompName = m_pSizer->m_arrNames[nName];
size_t sizeObjectsTotal = rCompName.sizeObjectsTotal;
if (sizeObjectsTotal <= m_nMinSubcomponentBytes)
{
return sizeObjectsTotal; // the subtree didn't pass
}
// the index of the component in the stats object (sorted by the depth-first traverse order)
size_t nNewName = m_pStats->m_arrComponents.size();
m_pStats->m_arrComponents.resize (nNewName + 1);
Component& rNewComp = m_pStats->m_arrComponents[nNewName];
rNewComp.strName = rCompName.strName;
rNewComp.nDepth = nDepth;
rNewComp.numObjects = rCompName.numObjects;
rNewComp.sizeBytes = rCompName.sizeObjects;
rNewComp.sizeBytesTotal = sizeObjectsTotal;
m_mapNames[nName] = nNewName;
// find the immediate children and sort them by their total size
typedef std::map<size_t, size_t> UintUintMap;
UintUintMap mapSizeName; // total size -> child index (name in old indexation)
for (int i = nName + 1; i < m_pSizer->m_arrNames.size(); ++i)
{
CrySizerImpl::ComponentName& rChild = m_pSizer->m_arrNames[i];
if (rChild.nParent == nName && rChild.sizeObjectsTotal > m_nMinSubcomponentBytes)
{
mapSizeName.insert (UintUintMap::value_type(rChild.sizeObjectsTotal, i));
}
}
// add the sorted components
/*
for (unsigned i = nName + 1; i < m_pSizer->m_arrNames.size(); ++i)
if (m_pSizer->m_arrNames[i].nParent == nName)
addNameSubtree(nDepth+1,i);
*/
for (UintUintMap::reverse_iterator it = mapSizeName.rbegin(); it != mapSizeName.rend(); ++it)
{
addNameSubtree(nDepth + 1, it->second);
}
return sizeObjectsTotal;
}
//////////////////////////////////////////////////////////////////////////
// creates the statistics out of the given CrySizerImpl into the given CrySizerStats
// Maps the old to new names according to the depth-walk tree rule
void CrySizerStatsBuilder::build (CrySizerStats* pStats)
{
m_pStats = pStats;
m_mapNames.clear();
processNames();
m_pSizer->clear();
pStats->refresh();
pStats->m_nAgeFrames = 0;
}
//////////////////////////////////////////////////////////////////////////
// constructs the statistics based on the given cry sizer
CrySizerStats::CrySizerStats (CrySizerImpl* pCrySizer)
{
CrySizerStatsBuilder builder (pCrySizer);
builder.build(this);
}
CrySizerStats::CrySizerStats ()
: m_nStartRow(0)
{
}
void CrySizerStats::updateKeys()
{
const unsigned int statSize = size();
//assume 10 pixels for font
unsigned int height = gEnv->pRenderer->GetHeight() / 12;
if (CryGetAsyncKeyState(VK_UP))
{
if (m_nStartRow > 0)
{
--m_nStartRow;
}
}
if (CryGetAsyncKeyState(VK_DOWN))
{
if (statSize > height + m_nStartRow)
{
++m_nStartRow;
}
}
if (CryGetAsyncKeyState(VK_RIGHT) & 1)
{
//assume 10 pixels for font
if (statSize > height)
{
m_nStartRow = statSize - height;
}
}
if (CryGetAsyncKeyState(VK_LEFT) & 1)
{
m_nStartRow = 0;
}
}
// if there is already such name in the map, then just returns the index
// of the compoentn in the component array; otherwise adds an entry to themap
// and to the component array nad returns its index
CrySizerStatsBuilder::Component& CrySizerStatsBuilder::mapName (unsigned nName)
{
assert (m_mapNames[nName] != -1);
return m_pStats->m_arrComponents[m_mapNames[nName]];
/*
IdToIdMap::iterator it = m_mapNames.find (nName);
if (it == m_mapNames.end())
{
unsigned nNewName = m_arrComponents.size();
m_mapNames.insert (IdToIdMap::value_type(nName, nNewName));
m_arrComponents.resize(nNewName + 1);
m_arrComponents[nNewName].strName.swap(m_pSizer->m_arrNames[nName]);
return m_arrComponents.back();
}
else
{
assert (it->second < m_arrComponents.size());
return m_arrComponents[it->second];
}
*/
}
// refreshes the statistics built after the component array is built
void CrySizerStats::refresh()
{
m_nMaxNameLength = 0;
for (size_t i = 0; i < m_arrComponents.size(); ++i)
{
size_t nLength = m_arrComponents[i].strName.length() + m_arrComponents[i].nDepth;
if (nLength > m_nMaxNameLength)
{
m_nMaxNameLength = nLength;
}
}
}
bool CrySizerStats::Component::GenericOrder::operator () (const Component& left, const Component& right) const
{
return left.strName < right.strName;
}
CrySizerStatsRenderer::CrySizerStatsRenderer (ISystem* pSystem, CrySizerStats* pStats, unsigned nMaxSubcomponentDepth, int nMinSubcomponentBytes)
: m_pStats(pStats)
, m_pRenderer(pSystem->GetIRenderer())
, m_pLog (pSystem->GetILog())
, m_pTextModeConsole(pSystem->GetITextModeConsole())
, m_nMinSubcomponentBytes (nMinSubcomponentBytes < 0 || nMinSubcomponentBytes > 0x10000000 ? 0x8000 : nMinSubcomponentBytes)
, m_nMaxSubcomponentDepth (nMaxSubcomponentDepth)
{
}
static void DrawStatsText(float x, float y, float fScale, float color[4], const char* format, ...)
{
va_list args;
va_start(args, format);
SDrawTextInfo ti;
ti.xscale = fScale;
ti.yscale = fScale;
ti.color[0] = color[0];
ti.color[1] = color[1];
ti.color[2] = color[2];
ti.color[3] = color[3];
ti.flags = eDrawText_2D | eDrawText_FixedSize | eDrawText_Monospace;
gEnv->pRenderer->DrawTextQueued(Vec3(x, y, 0.5f), ti, format, args);
va_end(args);
}
void CrySizerStatsRenderer::render(bool bRefreshMark)
{
if (!m_pStats->size())
{
return;
}
int x, y, dx, dy;
m_pRenderer->GetViewport(&x, &y, &dx, &dy);
// left coordinate of the text
unsigned nNameWidth = (unsigned)(m_pStats->getMaxNameLength() + 1);
if (nNameWidth < 25)
{
nNameWidth = 25;
}
float fCharScaleX = 1.2f;
float fLeft = 0;
float fTop = 8;
float fVStep = 9;
#ifdef _DEBUG
const char* szCountStr1 = "count";
const char* szCountStr2 = "_____";
#else // _DEBUG
const char* szCountStr1 = "", * szCountStr2 = "";
#endif // _DEBUG
float fTextColor[4] = {0.9f, 0.85f, 1, 0.85f};
DrawStatsText(fLeft, fTop, fCharScaleX, fTextColor,
"%-*s total partial %s", nNameWidth, bRefreshMark ? "Memory usage (refresh*)" : "Memory usage (refresh )", szCountStr1);
DrawStatsText(fLeft, fTop + fVStep * 0.25f, fCharScaleX, fTextColor,
"%*s _____ _______ %s", nNameWidth, "", szCountStr2);
unsigned nSubgroupDepth = 1;
// different colors used to paint the statistics subgroups
// a new statistic subgroup starts with a new subtree of depth <= specified
float fGray = 0;//0.45f;
float fLightGray = 0.5f;//0.8f;
float fColors[] =
{
fLightGray, fLightGray, fGray, 1,
1, 1, 1, 1,
fGray, 1, 1, 1,
1, fGray, 1, 1,
1, 1, fGray, 1,
fGray, fLightGray, 1, 1,
fGray, 1, fGray, 1,
1, fGray, fGray, 1
};
float* pColor = fColors;
unsigned statSize = m_pStats->size();
unsigned startRow = m_pStats->row();
unsigned i = 0;
for (; i < startRow; ++i)
{
const Component& rComp = (*m_pStats)[i];
if (rComp.nDepth <= nSubgroupDepth)
{
//switch the color
pColor += 4;
if (pColor >= fColors + sizeof(fColors) / sizeof(fColors[0]))
{
pColor = fColors;
}
fTop += fVStep * (0.333333f + (nSubgroupDepth - rComp.nDepth) * 0.15f);
}
}
for (unsigned r = startRow; i < statSize; ++i)
{
const Component& rComp = (*m_pStats)[i];
if (rComp.nDepth <= nSubgroupDepth)
{
//switch the color
pColor += 4;
if (pColor >= fColors + sizeof(fColors) / sizeof(fColors[0]))
{
pColor = fColors;
}
fTop += fVStep * (0.333333f + (nSubgroupDepth - rComp.nDepth) * 0.15f);
}
if (rComp.sizeBytesTotal <= m_nMinSubcomponentBytes || rComp.nDepth > m_nMaxSubcomponentDepth)
{
continue;
}
fTop += fVStep;
char szDepth[32] = " ..............................";
if (rComp.nDepth < sizeof(szDepth))
{
szDepth[rComp.nDepth] = '\0';
}
char szSize[32];
if (rComp.sizeBytes > 0)
{
if (rComp.sizeBytesTotal > rComp.sizeBytes)
{
azsprintf(szSize, "%7.3f %7.3f", rComp.getTotalSizeMBytes(), rComp.getSizeMBytes());
}
else
{
azsprintf(szSize, " %7.3f", rComp.getSizeMBytes());
}
}
else
{
assert (rComp.sizeBytesTotal > 0);
azsprintf(szSize, "%7.3f ", rComp.getTotalSizeMBytes());
}
char szCount[16];
#ifdef _DEBUG
if (rComp.numObjects)
{
azsprintf(szCount, "%zd" PRIu64 "", rComp.numObjects);
}
else
#endif
szCount[0] = '\0';
DrawStatsText(fLeft, fTop, fCharScaleX, pColor,
"%s%-*s:%s%s", szDepth, nNameWidth - rComp.nDepth, rComp.strName.c_str(), szSize, szCount);
if (m_pTextModeConsole)
{
string text;
text.Format("%s%-*s:%s%s", szDepth, nNameWidth - rComp.nDepth, rComp.strName.c_str(), szSize, szCount);
m_pTextModeConsole->PutText(0, r++, text.c_str());
}
}
float fLTGrayColor[4] = {fLightGray, fLightGray, fLightGray, 1.0f};
fTop += 0.25f * fVStep;
DrawStatsText(fLeft, fTop, fCharScaleX, fLTGrayColor,
"%-*s %s", nNameWidth, "___________________________", "________________");
fTop += fVStep;
const char* szOverheadNames[CrySizerStats::g_numTimers] =
{
".Collection",
".Transformation",
".Cleanup"
};
bool bOverheadsHeaderPrinted = false;
for (i = 0; i < CrySizerStats::g_numTimers; ++i)
{
float fTime = m_pStats->getTime(i);
if (fTime < 20)
{
continue;
}
// print the header
if (!bOverheadsHeaderPrinted)
{
DrawStatsText(fLeft, fTop, fCharScaleX, fTextColor,
"%-*s", nNameWidth, "Overheads");
fTop += fVStep;
bOverheadsHeaderPrinted = true;
}
DrawStatsText(fLeft, fTop, fCharScaleX, fTextColor,
"%-*s:%7.1f ms", nNameWidth, szOverheadNames[i], fTime);
fTop += fVStep;
}
}
void CrySizerStatsRenderer::dump(bool bUseKB)
{
if (!m_pStats->size())
{
return;
}
unsigned nNameWidth = (unsigned)(m_pStats->getMaxNameLength() + 1);
// left coordinate of the text
m_pLog->LogToFile ("Memory Statistics: %s", bUseKB ? "KB" : "MB");
m_pLog->LogToFile("%-*s TOTAL partial count", nNameWidth, "");
// different colors used to paint the statistics subgroups
// a new statistic subgroup starts with a new subtree of depth <= specified
for (unsigned i = 0; i < m_pStats->size(); ++i)
{
const Component& rComp = (*m_pStats)[i];
if (rComp.sizeBytesTotal <= m_nMinSubcomponentBytes || rComp.nDepth > m_nMaxSubcomponentDepth)
{
continue;
}
char szDepth[32] = " ..............................";
if (rComp.nDepth < sizeof(szDepth))
{
szDepth[rComp.nDepth] = '\0';
}
char szSize[32];
if (rComp.sizeBytes > 0)
{
if (rComp.sizeBytesTotal > rComp.sizeBytes)
{
azsprintf(szSize, bUseKB ? "%7.2f %7.2f" : "%7.3f %7.3f", bUseKB ? rComp.getTotalSizeKBytes() : rComp.getTotalSizeMBytes(), bUseKB ? rComp.getSizeKBytes() : rComp.getSizeMBytes());
}
else
{
azsprintf(szSize, bUseKB ? " %7.2f" : " %7.3f", bUseKB ? rComp.getSizeKBytes() : rComp.getSizeMBytes());
}
}
else
{
assert (rComp.sizeBytesTotal > 0);
azsprintf(szSize, bUseKB ? "%7.2f " : "%7.3f ", bUseKB ? rComp.getTotalSizeKBytes() : rComp.getTotalSizeMBytes());
}
char szCount[16];
if (rComp.numObjects)
{
azsprintf(szCount, "%8u", (unsigned int)rComp.numObjects);
}
else
{
szCount[0] = '\0';
}
m_pLog->LogToFile ("%s%-*s:%s%s", szDepth, nNameWidth - rComp.nDepth, rComp.strName.c_str(), szSize, szCount);
}
}
void CrySizerStats::startTimer(unsigned nTimer, ITimer* pTimer)
{
assert (nTimer < g_numTimers);
m_fTime[nTimer] = pTimer->GetAsyncCurTime();
}
void CrySizerStats::stopTimer(unsigned nTimer, ITimer* pTimer)
{
assert (nTimer < g_numTimers);
m_fTime[nTimer] = 1000 * (pTimer->GetAsyncCurTime() - m_fTime[nTimer]);
}
-207
View File
@@ -1,207 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Declaration of the CrySizerStats class, which is used to
// calculate the memory usage by the subsystems and components, to help
// the artists keep the memory budged low.
#ifndef CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H
#define CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H
#pragma once
class CrySizerImpl;
//////////////////////////////////////////////////////////////////////////
// This class holds only the necessary statistics data, which can be carried
// over a few frames without significant impact on memory usage
// CrySizerImpl is an implementation of ICrySizer, which is used to collect
// those data; it must be destructed immediately after constructing the Stats
// object to avoid excessive memory usage.
class CrySizerStats
{
public:
// constructs the statistics based on the given cry sizer
CrySizerStats (CrySizerImpl* pCrySizer);
CrySizerStats ();
// this structure describes one component of the memory size statistics
struct Component
{
Component() {clear(); }
Component (const string& name, unsigned size = 0, unsigned num = 0)
: strName(name)
, sizeBytes(size)
, numObjects(num)
, nDepth(0) {}
void clear()
{
strName = "";
sizeBytes = 0;
numObjects = 0;
nDepth = 0;
}
// the name of the component, as it appeared in the push() call
string strName;
// the total size, in bytes, of objects in the component
size_t sizeBytes;
// the total size including the subcomponents
size_t sizeBytesTotal;
// the number of objects allocated
size_t numObjects;
unsigned nDepth;
float getSizeKBytes() const {return sizeBytes / float(1 << 10); }
float getTotalSizeKBytes () const {return sizeBytesTotal / float(1 << 10); }
float getSizeMBytes() const {return sizeBytes / float(1 << 20); }
float getTotalSizeMBytes () const {return sizeBytesTotal / float(1 << 20); }
struct NameOrder
{
bool operator () (const Component& left, const Component& right) const {return left.strName < right.strName; }
};
struct SizeOrder
{
bool operator () (const Component& left, const Component& right) const {return left.sizeBytes < right.sizeBytes; }
};
struct GenericOrder
{
bool operator () (const Component& left, const Component& right) const;
};
};
// returns the number of different subsystems/components used
unsigned numComponents() const {return (unsigned)m_arrComponents.size(); }
// returns the name of the i-th component
const Component& getComponent(unsigned nComponent) const {return m_arrComponents[nComponent]; }
unsigned size() const {return numComponents(); }
const Component& operator [] (unsigned i) const {return getComponent(i); }
const Component& operator [] (signed i) const {return getComponent(i); }
unsigned row() const {return m_nStartRow; }
void updateKeys();
size_t getMaxNameLength() const {return m_nMaxNameLength; }
enum
{
g_numTimers = 3
};
void startTimer(unsigned nTimer, ITimer* pTimer);
void stopTimer(unsigned nTimer, ITimer* pTimer);
float getTime(unsigned nTimer) const {assert (nTimer < g_numTimers); return m_fTime[nTimer]; }
int getAgeFrames() const {return m_nAgeFrames; }
void incAgeFrames() {++m_nAgeFrames; }
protected:
// refreshes the statistics built after the component array is built
void refresh();
protected:
// the names of the components
typedef std::vector<Component> ComponentArray;
ComponentArray m_arrComponents;
// the maximum length of the component name, in characters
size_t m_nMaxNameLength;
// the timer that counts the time spent on statistics gathering
float m_fTime[g_numTimers];
// the age of the statistics, in frames
int m_nAgeFrames;
//current row offset inc/dec by cursor keys
unsigned m_nStartRow;
friend class CrySizerStatsBuilder;
};
//////////////////////////////////////////////////////////////////////////
// this is the constructor for the CrySizerStats
class CrySizerStatsBuilder
{
public:
CrySizerStatsBuilder (CrySizerImpl* pSizer, int nMinSubcomponentBytes = 0);
void build (CrySizerStats* pStats);
protected:
typedef CrySizerStats::Component Component;
// if there is already such name in the map, then just returns the index
// of the compoentn in the component array; otherwise adds an entry to themap
// and to the component array nad returns its index
Component& mapName (unsigned nName);
// creates the map of names from old to new, and initializes the components themselves
void processNames();
// given the name in the old system, adds the subtree of names to the
// name map and components. In case all the subtree is empty, returns 0 and
// adds nothing. Otherwise, returns the total size of objects belonging to the
// subtree
size_t addNameSubtree (unsigned nDepth, size_t nName);
protected:
CrySizerStats* m_pStats;
CrySizerImpl* m_pSizer;
// this is the mapping from the old names into the new componentn indices
typedef std::vector<size_t> IdToIdMap;
// from old to new
IdToIdMap m_mapNames;
// this is the threshold: if the total number of bytes in the subcomponent
// is less than this, the subcomponent isn't shown
unsigned m_nMinSubcomponentBytes;
};
//////////////////////////////////////////////////////////////////////////
// Renders the given usage stats; gets created upon every rendering
class CrySizerStatsRenderer
{
public:
// constructor
CrySizerStatsRenderer (ISystem* pSystem, CrySizerStats* pStats, unsigned nMaxDepth = 2, int nMinSubcomponentBytes = -1);
void render(bool bRefreshMark = false);
// dumps it to log. uses MB as default
void dump (bool bUseKB = false);
protected: // -------------------------------------------------
typedef CrySizerStats::Component Component;
IRenderer* m_pRenderer; //
ILog* m_pLog; //
CrySizerStats* m_pStats; //
ITextModeConsole* m_pTextModeConsole;
// this is the threshold: if the total number of bytes in the subcomponent
// is less than this, the subcomponent isn't shown
unsigned m_nMinSubcomponentBytes;
// the max depth of the branch to output
unsigned m_nMaxSubcomponentDepth;
};
#endif // CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H
@@ -287,18 +287,6 @@ int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer)
gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0';
WriteLineToLog("Debug Status: %s", gEnv->szDebugStatus);
}
if (gEnv->pRenderer)
{
ID3DDebugMessage* pMsg = 0;
gEnv->pRenderer->EF_Query(EFQ_GetLastD3DDebugMessage, pMsg);
if (pMsg)
{
const char* pStr = pMsg->GetMessage();
WriteLineToLog("Last D3D debug message: %s", pStr ? pStr : "#unknown#");
SAFE_RELEASE(pMsg);
}
}
}
firstTime = false;
@@ -832,17 +820,6 @@ int DebugCallStack::SubmitBug(EXCEPTION_POINTERS* exception_pointer)
assert(!hwndException);
// If in full screen minimize render window
{
ICVar* pFullscreen = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("r_Fullscreen") : 0;
if (pFullscreen && pFullscreen->GetIVal() != 0 && gEnv->pRenderer && gEnv->pRenderer->GetHWND())
{
::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE);
}
}
//hwndException = CreateDialog( gDLLHandle,MAKEINTRESOURCE(IDD_EXCEPTION),NULL,NULL );
RemoveOldFiles();
AZ::Debug::Trace::PrintCallstack("", 2);
File diff suppressed because it is too large Load Diff
-712
View File
@@ -1,712 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_DEFRAGALLOCATOR_H
#define CRYINCLUDE_CRYSYSTEM_DEFRAGALLOCATOR_H
#pragma once
#include "IDefragAllocator.h"
#include "System.h"
#ifndef _RELEASE
#define CDBA_DEBUG
#endif
//#define CDBA_MORE_DEBUG
#ifdef CDBA_DEBUG
#define CDBA_ASSERT(x) do { assert(x); if (!(x)) {__debugbreak(); } \
} while (0)
#else
#define CDBA_ASSERT(x) assert(x)
#endif
union SDefragAllocChunkAttr
{
enum
{
SizeWidth = 27,
SizeMask = (1 << SizeWidth) - 1,
BusyMask = 1 << 27,
MovingMask = 1 << 28,
MaxPinCount = 7,
PinnedCountShift = 29,
PinnedIncMask = 1 << PinnedCountShift,
PinnedCountMask = MaxPinCount << PinnedCountShift,
};
uint32 ui;
ILINE unsigned int GetSize() const { return ui & SizeMask; }
ILINE void SetSize(unsigned int size) { ui = (ui & ~SizeMask) | size; }
ILINE void AddSize(int size) { ui += size; }
ILINE bool IsBusy() const { return (ui & BusyMask) != 0; }
ILINE void SetBusy(bool b) { ui = b ? (ui | BusyMask) : (ui & ~BusyMask); }
ILINE bool IsMoving() const { return (ui & MovingMask) != 0; }
ILINE void SetMoving(bool m) { ui = m ? (ui | MovingMask) : (ui & ~MovingMask); }
ILINE void IncPinCount() { ui += PinnedIncMask; }
ILINE void DecPinCount() { ui -= PinnedIncMask; }
ILINE bool IsPinned() const { return (ui & PinnedCountMask) != 0; }
ILINE unsigned int GetPinCount() const { return (ui & PinnedCountMask) >> PinnedCountShift; }
ILINE void SetPinCount(unsigned int p) { ui = (ui & ~PinnedCountMask) | (p << PinnedCountShift); }
};
struct SDefragAllocChunk
{
enum
{
AlignBitCount = 4,
};
typedef IDefragAllocator::Hdl Index;
Index addrPrevIdx;
Index addrNextIdx;
union
{
struct
{
UINT_PTR ptr : sizeof(UINT_PTR) * 8 - AlignBitCount;
UINT_PTR logAlign: AlignBitCount;
};
UINT_PTR packedPtr;
};
SDefragAllocChunkAttr attr;
union
{
void* pContext;
struct
{
Index freePrevIdx;
Index freeNextIdx;
};
};
#ifndef _RELEASE
const char* source;
#endif
void SwapEndian()
{
::SwapEndian(addrPrevIdx, true);
::SwapEndian(addrNextIdx, true);
::SwapEndian(packedPtr, true);
::SwapEndian(attr.ui, true);
if (attr.IsBusy())
{
::SwapEndian(pContext, true);
}
else
{
::SwapEndian(freePrevIdx, true);
::SwapEndian(freeNextIdx, true);
}
#ifndef _RELEASE
::SwapEndian(source, true);
#endif
}
};
struct SDefragAllocSegment
{
uint32 address;
uint32 capacity;
SDefragAllocChunk::Index headSentinalChunkIdx;
void SwapEndian()
{
::SwapEndian(address, true);
::SwapEndian(capacity, true);
::SwapEndian(headSentinalChunkIdx, true);
}
};
class CDefragAllocator;
class CDefragAllocatorWalker
{
public:
explicit CDefragAllocatorWalker(CDefragAllocator& alloc);
~CDefragAllocatorWalker();
const SDefragAllocChunk* Next();
private:
CDefragAllocatorWalker(const CDefragAllocatorWalker&);
CDefragAllocatorWalker& operator = (const CDefragAllocatorWalker&);
private:
CDefragAllocator* m_pAlloc;
SDefragAllocChunk::Index m_nChunkIdx;
};
class CDefragAllocator
: public IDefragAllocator
{
friend class CDefragAllocatorWalker;
typedef SDefragAllocChunk::Index Index;
public:
CDefragAllocator();
void Release(bool bDiscard);
void Init(UINT_PTR capacity, UINT_PTR minAlignment, const Policy& policy);
#ifndef _RELEASE
void DumpState(const char* filename);
void RestoreState(const char* filename);
#endif
// allocatorDisplayOffset will offset the statistics for the allocator depending on the index.
// 0 means no offset and default location, 1 means bar will be rendered above the 0th bar and stats to the right of the 0th stats
void DisplayMemoryUsage(const char* title, unsigned int allocatorDisplayOffset = 0);
bool AppendSegment(UINT_PTR capacity);
void UnAppendSegment();
Hdl Allocate(size_t sz, const char* source, void* pContext = NULL);
Hdl AllocateAligned(size_t sz, size_t alignment, const char* source, void* pContext = NULL);
AllocatePinnedResult AllocatePinned(size_t sz, const char* source, void* pContext = NULL);
bool Free(Hdl hdl);
void ChangeContext(Hdl hdl, void* pNewContext);
size_t GetAllocated() const { return (size_t)(m_capacity - m_available) << m_logMinAlignment; }
IDefragAllocatorStats GetStats();
size_t DefragmentTick(size_t maxMoves, size_t maxAmount, bool bForce);
ILINE UINT_PTR UsableSize(Hdl hdl)
{
Index chunkIdx = ChunkIdxFromHdl(hdl);
CDBA_ASSERT(chunkIdx < m_chunks.size());
SDefragAllocChunk& chunk = m_chunks[chunkIdx];
SDefragAllocChunkAttr attr = chunk.attr;
CDBA_ASSERT(attr.IsBusy());
return (UINT_PTR)attr.GetSize() << m_logMinAlignment;
}
// Pin the chunk until the next defrag tick, when it will be automatically unpinned
ILINE UINT_PTR WeakPin(Hdl hdl)
{
Index chunkIdx = ChunkIdxFromHdl(hdl);
CDBA_ASSERT(chunkIdx < m_chunks.size());
SDefragAllocChunk& chunk = m_chunks[chunkIdx];
SDefragAllocChunkAttr attr = chunk.attr;
CDBA_ASSERT(attr.IsBusy());
if (attr.IsMoving())
{
CancelMove(chunkIdx, true);
}
return chunk.ptr << m_logMinAlignment;
}
// Pin the chunk until Unpin is called
ILINE UINT_PTR Pin(Hdl hdl)
{
Index chunkIdx = ChunkIdxFromHdl(hdl);
SDefragAllocChunk& chunk = m_chunks[chunkIdx];
SDefragAllocChunkAttr attr;
SDefragAllocChunkAttr newAttr;
do
{
attr.ui = const_cast<volatile uint32&>(chunk.attr.ui);
newAttr.ui = attr.ui;
CDBA_ASSERT(attr.GetPinCount() < SDefragAllocChunkAttr::MaxPinCount);
CDBA_ASSERT(attr.IsBusy());
newAttr.IncPinCount();
}
while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&chunk.attr.ui), newAttr.ui, attr.ui) != attr.ui);
// Potentially a Relocate could be in progress here. Either the Relocate is mid-way, in which case 'IsMoving()' will
// still be set, and CancelMove will sync and all is well.
// If 'IsMoving()' is not set, the Relocate should have just completed, in which case ptr should validly point
// to the new location.
if (attr.IsMoving())
{
CancelMove(chunkIdx, true);
}
return chunk.ptr << m_logMinAlignment;
}
ILINE void Unpin(Hdl hdl)
{
SDefragAllocChunk& chunk = m_chunks[ChunkIdxFromHdl(hdl)];
SDefragAllocChunkAttr attr;
SDefragAllocChunkAttr newAttr;
do
{
attr.ui = const_cast<volatile uint32&>(chunk.attr.ui);
newAttr.ui = attr.ui;
CDBA_ASSERT(attr.IsPinned());
CDBA_ASSERT(attr.IsBusy());
newAttr.DecPinCount();
}
while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&chunk.attr.ui), newAttr.ui, attr.ui) != attr.ui);
}
ILINE const char* GetSourceOf([[maybe_unused]] Hdl hdl)
{
#ifndef _RELEASE
return m_chunks[ChunkIdxFromHdl(hdl)].source;
#else
return "";
#endif
}
private:
enum
{
NumBuckets = 31, // 2GB
MaxPendingMoves = 64,
AddrStartSentinal = 0,
AddrEndSentinal = 1,
};
struct SplitResult
{
bool bSuccessful;
Index nLeftSplitChunkIdx;
Index nRightSplitChunkIdx;
};
struct PendingMove
{
PendingMove()
: srcChunkIdx(InvalidChunkIdx)
, dstChunkIdx(InvalidChunkIdx)
, userMoveId(0)
, relocated(false)
, cancelled(false)
{
}
Index srcChunkIdx;
Index dstChunkIdx;
uint32 userMoveId;
IDefragAllocatorCopyNotification notify;
bool relocated;
bool cancelled;
void SwapEndian()
{
::SwapEndian(srcChunkIdx, true);
::SwapEndian(dstChunkIdx, true);
::SwapEndian(userMoveId, true);
}
};
struct PendingMoveSrcChunkPredicate
{
PendingMoveSrcChunkPredicate(Index ci)
: m_ci(ci) {}
bool operator () (const PendingMove& pm) const { return pm.srcChunkIdx == m_ci; }
Index m_ci;
};
typedef DynArray<PendingMove> PendingMoveVec;
typedef std::vector<SDefragAllocSegment> SegmentVec;
static const Index InvalidChunkIdx = (Index) - 1;
private:
static ILINE Index ChunkIdxFromHdl(Hdl id) { return id - 1; }
static ILINE Hdl ChunkHdlFromIdx(Index idx) { return idx + 1; }
private:
~CDefragAllocator();
Index AllocateChunk();
void ReleaseChunk(Index idx);
ILINE void MarkAsInUse(SDefragAllocChunk& chunk)
{
CDBA_ASSERT(!chunk.attr.IsBusy());
chunk.attr.SetBusy(true);
m_available -= chunk.attr.GetSize();
++m_numAllocs;
// m_available is unsigned, so check for underflow
CDBA_ASSERT(m_available <= m_capacity);
}
ILINE void MarkAsFree(SDefragAllocChunk& chunk)
{
CDBA_ASSERT(chunk.attr.IsBusy());
chunk.attr.SetPinCount(0);
chunk.attr.SetMoving(false);
chunk.attr.SetBusy(0);
m_available += chunk.attr.GetSize();
--m_numAllocs;
// m_available is unsigned, so check for underflow
CDBA_ASSERT(m_available <= m_capacity);
}
void LinkFreeChunk(Index idx);
void UnlinkFreeChunk(Index idx)
{
SDefragAllocChunk& chunk = m_chunks[idx];
m_chunks[chunk.freePrevIdx].freeNextIdx = chunk.freeNextIdx;
m_chunks[chunk.freeNextIdx].freePrevIdx = chunk.freePrevIdx;
}
void LinkAddrChunk(Index idx, Index afterIdx)
{
SDefragAllocChunk& chunk = m_chunks[idx];
SDefragAllocChunk& afterChunk = m_chunks[afterIdx];
chunk.addrNextIdx = afterChunk.addrNextIdx;
chunk.addrPrevIdx = afterIdx;
m_chunks[chunk.addrNextIdx].addrPrevIdx = idx;
afterChunk.addrNextIdx = idx;
}
void UnlinkAddrChunk(Index id)
{
SDefragAllocChunk& chunk = m_chunks[id];
m_chunks[chunk.addrPrevIdx].addrNextIdx = chunk.addrNextIdx;
m_chunks[chunk.addrNextIdx].addrPrevIdx = chunk.addrPrevIdx;
}
void PrepareMergePopNext(Index* pLists)
{
for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx)
{
Index hdrChunkId = m_freeBuckets[bucketIdx];
Index nextId = m_chunks[hdrChunkId].freeNextIdx;
if (nextId != hdrChunkId)
{
pLists[bucketIdx] = nextId;
}
else
{
pLists[bucketIdx] = InvalidChunkIdx;
}
}
}
size_t MergePeekNextChunk(Index* pLists)
{
size_t farList = (size_t)-1;
UINT_PTR farPtr = (UINT_PTR)-1;
for (size_t listIdx = 0; listIdx < NumBuckets; ++listIdx)
{
Index chunkIdx = pLists[listIdx];
if (chunkIdx != InvalidChunkIdx)
{
SDefragAllocChunk& chunk = m_chunks[chunkIdx];
if (chunk.ptr < farPtr)
{
farPtr = chunk.ptr;
farList = listIdx;
}
}
}
return farList;
}
void MergePopNextChunk(Index* pLists, size_t list)
{
using std::swap;
Index fni = m_chunks[pLists[list]].freeNextIdx;
pLists[list] = fni;
if (m_chunks[fni].attr.IsBusy())
{
// End of the list
pLists[list] = InvalidChunkIdx;
}
}
void MergePatchNextRemove(Index* pLists, Index removeIdx)
{
for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx)
{
if (pLists[bucketIdx] == removeIdx)
{
Index nextIdx = m_chunks[removeIdx].freeNextIdx;
if (!m_chunks[nextIdx].attr.IsBusy())
{
pLists[bucketIdx] = nextIdx;
}
else
{
pLists[bucketIdx] = InvalidChunkIdx;
}
}
}
}
void MergePatchNextInsert(Index* pLists, Index insertIdx)
{
SDefragAllocChunk& insertChunk = m_chunks[insertIdx];
int bucket = BucketForSize(insertChunk.attr.GetSize());
if (pLists[bucket] != InvalidChunkIdx)
{
SDefragAllocChunk& listChunk = m_chunks[pLists[bucket]];
if (listChunk.ptr > insertChunk.ptr)
{
pLists[bucket] = insertIdx;
}
}
}
void PrepareMergePopPrev(Index* pLists)
{
for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx)
{
Index hdrChunkId = m_freeBuckets[bucketIdx];
Index prevIdx = m_chunks[hdrChunkId].freePrevIdx;
if (prevIdx != hdrChunkId)
{
pLists[bucketIdx] = prevIdx;
}
else
{
pLists[bucketIdx] = InvalidChunkIdx;
}
}
}
size_t MergePeekPrevChunk(Index* pLists)
{
size_t farList = (size_t)-1;
UINT_PTR farPtr = 0;
for (size_t listIdx = 0; listIdx < NumBuckets; ++listIdx)
{
Index chunkIdx = pLists[listIdx];
if (chunkIdx != InvalidChunkIdx)
{
SDefragAllocChunk& chunk = m_chunks[chunkIdx];
if (chunk.ptr >= farPtr)
{
farPtr = chunk.ptr;
farList = listIdx;
}
}
}
return farList;
}
void MergePopPrevChunk(Index* pLists, size_t list)
{
using std::swap;
Index fpi = m_chunks[pLists[list]].freePrevIdx;
pLists[list] = fpi;
if (m_chunks[fpi].attr.IsBusy())
{
// End of the list
pLists[list] = InvalidChunkIdx;
}
}
void MergePatchPrevInsert(Index* pLists, Index insertIdx)
{
SDefragAllocChunk& insertChunk = m_chunks[insertIdx];
int bucket = BucketForSize(insertChunk.attr.GetSize());
if (pLists[bucket] != InvalidChunkIdx)
{
SDefragAllocChunk& listChunk = m_chunks[pLists[bucket]];
if (listChunk.ptr < insertChunk.ptr)
{
pLists[bucket] = insertIdx;
}
}
}
void MergePatchPrevRemove(Index* pLists, Index removeIdx)
{
for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx)
{
if (pLists[bucketIdx] == removeIdx)
{
Index nextIdx = m_chunks[removeIdx].freePrevIdx;
if (!m_chunks[nextIdx].attr.IsBusy())
{
pLists[bucketIdx] = nextIdx;
}
else
{
pLists[bucketIdx] = InvalidChunkIdx;
}
}
}
}
void MarkAsMoving(SDefragAllocChunk& src)
{
SDefragAllocChunkAttr srcAttr, srcNewAttr;
do
{
srcAttr.ui = const_cast<volatile uint32&>(src.attr.ui);
srcNewAttr.ui = srcAttr.ui;
srcNewAttr.SetMoving(true);
}
while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&src.attr.ui), srcNewAttr.ui, srcAttr.ui) != srcAttr.ui);
}
void MarkAsNotMoving(SDefragAllocChunk& src)
{
SDefragAllocChunkAttr srcAttr, srcNewAttr;
do
{
srcAttr.ui = const_cast<volatile uint32&>(src.attr.ui);
srcNewAttr.ui = srcAttr.ui;
srcNewAttr.SetMoving(false);
}
while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&src.attr.ui), srcNewAttr.ui, srcAttr.ui) != srcAttr.ui);
}
ILINE bool IsMoveableCandidate(const SDefragAllocChunkAttr& a, uint32 sizeUpperBound)
{
return a.IsBusy() && !a.IsPinned() && !a.IsMoving() && (0 < a.GetSize()) && (a.GetSize() <= sizeUpperBound);
}
bool TryMarkAsMoving(SDefragAllocChunk& src, uint32 sizeUpperBound)
{
SDefragAllocChunkAttr srcAttr, srcNewAttr;
do
{
srcAttr.ui = const_cast<volatile uint32&>(src.attr.ui);
srcNewAttr.ui = srcAttr.ui;
if (!IsMoveableCandidate(srcAttr, sizeUpperBound))
{
return false;
}
srcNewAttr.SetMoving(true);
}
while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&src.attr.ui), srcNewAttr.ui, srcAttr.ui) != srcAttr.ui);
return true;
}
bool TryScheduleCopy(SDefragAllocChunk& srcChunk, SDefragAllocChunk& dstChunk, PendingMove* pPM, bool bLowHalf)
{
UINT_PTR dstChunkBase = dstChunk.ptr;
UINT_PTR dstChunkEnd = dstChunkBase + dstChunk.attr.GetSize();
#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64
UINT_PTR allocAlign = BIT64(srcChunk.logAlign);
#else
UINT_PTR allocAlign = BIT(srcChunk.logAlign);
#endif
UINT_PTR allocSize = srcChunk.attr.GetSize();
UINT_PTR dstAllocBase = bLowHalf
? Align(dstChunkBase, allocAlign)
: ((dstChunkEnd - allocSize) & ~(allocAlign - 1));
uint32 userId = m_policy.pDefragPolicy->BeginCopy(
srcChunk.pContext,
dstAllocBase << m_logMinAlignment,
srcChunk.ptr << m_logMinAlignment,
allocSize << m_logMinAlignment,
&pPM->notify);
pPM->userMoveId = userId;
return userId != 0;
}
Hdl Allocate_Locked(size_t sz, size_t alignment, const char* source, void* pContext);
SplitResult SplitFreeBlock(Index fbId, size_t sz, size_t alignment, bool allocateInLowHalf);
Index MergeFreeBlock(Index fbId);
#ifdef CDBA_MORE_DEBUG
void Defrag_ValidateFreeBlockIteration();
#endif
Index BestFit_FindFreeBlockForSegment(size_t sz, size_t alignment, uint32 nSegment);
Index BestFit_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressMin, UINT_PTR addressMax, bool allocateInLowHalf);
Index FirstFit_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressMin, UINT_PTR addressMax, bool allocateInLowHalf);
size_t Defrag_FindMovesBwd(PendingMove** pMoves, size_t maxMoves, size_t& curAmount, size_t maxAmount);
size_t Defrag_FindMovesFwd(PendingMove** pMoves, size_t maxMoves, size_t& curAmount, size_t maxAmount);
bool Defrag_CompletePendingMoves();
Index Defrag_Bwd_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressLimit);
Index Defrag_Fwd_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressLimit);
PendingMove* AllocPendingMove();
void FreePendingMove(PendingMove* pMove);
void CancelMove(Index srcChunkIdx, bool bIsContentNeeded);
void CancelMove_Locked(Index srcChunkIdx, bool bIsContentNeeded);
void Relocate(uint32 userMoveId, Index srcChunkIdx, Index dstChunkIdx);
void SyncMoveSegment(uint32 seg);
void RebuildFreeLists();
void ValidateAddressChain();
void ValidateFreeLists();
int BucketForSize(size_t sz) const
{
return sz > 0
? static_cast<int>(IntegerLog2(sz))
: 0;
}
private:
bool m_isThreadSafe;
bool m_chunksAreFixed;
CryCriticalSection m_lock;
uint32 m_capacity;
uint32 m_available;
Index m_numAllocs;
uint16 m_minAlignment;
uint16 m_logMinAlignment;
Index m_freeBuckets[NumBuckets];
std::vector<SDefragAllocChunk> m_chunks;
std::vector<Index> m_unusedChunks;
PendingMoveVec m_pendingMoves;
SegmentVec m_segments;
uint32 m_nCancelledMoves;
Policy m_policy;
};
#endif // CRYINCLUDE_CRYSYSTEM_DEFRAGALLOCATOR_H
-102
View File
@@ -1,102 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "HMDCVars.h"
#include <HMDBus.h>
#include <sstream>
namespace AZ
{
namespace VR
{
void HMDCVars::OnHMDRecenter([[maybe_unused]] IConsoleCmdArgs* args)
{
EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, RecenterPose);
}
void HMDCVars::OnHMDTrackingLevelChange(IConsoleCmdArgs* args)
{
if (args->GetArgCount() != 2)
{
// First arg should be the command itself, second arg should be the requested tracking level.
return;
}
// Read the new tracking level.
int argVal = 0;
std::stringstream stream(args->GetArg(1));
stream >> argVal;
AZ::VR::HMDTrackingLevel level = static_cast<AZ::VR::HMDTrackingLevel>(argVal);
EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, SetTrackingLevel, level);
}
void HMDCVars::OnOutputToHMDChanged(ICVar* var)
{
// Set the necessary cvars for turning on/off output to an HMD.
ICVar* mode = gEnv->pConsole->GetCVar("r_StereoMode");
ICVar* output = gEnv->pConsole->GetCVar("r_StereoOutput");
ICVar* height = gEnv->pConsole->GetCVar("r_height");
ICVar* width = gEnv->pConsole->GetCVar("r_width");
if (!mode || !output || !height || !width)
{
return;
}
bool enable = (var->GetIVal() == 1);
if (enable)
{
// Auto-set the resolution.
{
const AZ::VR::HMDDeviceInfo* deviceInfo = nullptr;
EBUS_EVENT_RESULT(deviceInfo, AZ::VR::HMDDeviceRequestBus, GetDeviceInfo);
// If the device info exists then there is a VR device connected and working.
if (deviceInfo)
{
mode->Set(EStereoMode::STEREO_MODE_DUAL_RENDERING);
output->Set(EStereoOutput::STEREO_OUTPUT_HMD);
width->Set(static_cast<int>(deviceInfo->renderWidth));
height->Set(static_cast<int>(deviceInfo->renderHeight));
}
}
}
else
{
mode->Set(EStereoMode::STEREO_MODE_NO_STEREO);
output->Set(EStereoOutput::STEREO_OUTPUT_STANDARD);
}
}
void HMDCVars::OnHMDDebugInfo(ICVar* var)
{
bool enable = (var->GetIVal() == 1);
EBUS_EVENT(AZ::VR::HMDDebuggerRequestBus, EnableInfo, enable);
}
void HMDCVars::OnHMDDebugCamera(ICVar* var)
{
bool enable = (var->GetIVal() == 1);
EBUS_EVENT(AZ::VR::HMDDebuggerRequestBus, EnableCamera, enable);
}
int HMDCVars::hmd_social_screen = static_cast<int>(HMDSocialScreen::UndistortedLeftEye);
int HMDCVars::hmd_debug_info = 0;
int HMDCVars::hmd_debug_camera = 0;
} // namespace VR
} // namespace AZ
-71
View File
@@ -1,71 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#include <IConsole.h>
#include <ISystem.h>
namespace AZ
{
namespace VR
{
class HMDCVars
{
public:
static int hmd_social_screen;
static int hmd_debug_info;
static int hmd_debug_camera;
static void Register()
{
REGISTER_CVAR2("hmd_social_screen", &hmd_social_screen, hmd_social_screen,
VF_NULL, "Selects the social screen mode: \n"
"-1- Off\n"
"0 - Undistorted left eye\n"
"1 - Undistorted right eye\n"
);
REGISTER_INT_CB("hmd_debug_info", 0, VF_ALWAYSONCHANGE,
"Enable/disable HMD and VR controller debug info/rendering",
OnHMDDebugInfo);
REGISTER_INT_CB("hmd_debug_camera", 0, VF_ALWAYSONCHANGE,
"Enable/disable HMD debug camera",
OnHMDDebugCamera);
REGISTER_COMMAND("hmd_tracking_level", &OnHMDTrackingLevelChange,
VF_NULL, "Set the HMD center reference point.\n"
"0 - Camera (Actor's head)\n"
"1 - Actor's feet (floor)\n");
REGISTER_COMMAND("hmd_recenter_pose", &OnHMDRecenter,
VF_NULL, "Re-centers sensor orientation of the HMD.");
REGISTER_INT_CB("output_to_hmd", 0, VF_ALWAYSONCHANGE,
"Enable/disable output to any connected HMD (for VR)",
OnOutputToHMDChanged);
}
private:
static void OnHMDRecenter(IConsoleCmdArgs* args);
static void OnHMDTrackingLevelChange(IConsoleCmdArgs* args);
static void OnOutputToHMDChanged(ICVar* var);
static void OnHMDDebugInfo(ICVar* var);
static void OnHMDDebugCamera(ICVar* var);
};
} // namespace VR
} // namespace AZ
@@ -258,28 +258,6 @@ void IDebugCallStack::WriteLineToLog(const char* format, ...)
}
}
void IDebugCallStack::Screenshot(const char* szFileName)
{
WriteLineToLog("Attempting to create error screenshot \"%s\"", szFileName);
static int g_numScreenshots = 0;
if (gEnv->pRenderer && !g_numScreenshots++)
{
if (gEnv->pRenderer->ScreenShot(szFileName))
{
WriteLineToLog("Successfully created screenshot.");
}
else
{
WriteLineToLog("Error creating screenshot.");
}
}
else
{
WriteLineToLog("Ignoring multiple calls to Screenshot");
}
}
//////////////////////////////////////////////////////////////////////////
void IDebugCallStack::StartMemLog()
{
@@ -77,8 +77,6 @@ protected:
static const char* TranslateExceptionCode(DWORD dwExcept);
static void PutVersion(char* str, size_t length);
static void Screenshot(const char* szFileName);
bool m_bIsFatalError;
static const char* const s_szFatalErrorCode;
@@ -20,7 +20,6 @@
#include "IMaterialEffects.h"
#include <IResourceManager.h>
#include <ILocalizationManager.h>
#include "IDeferredCollisionEvent.h"
#include "CryPath.h"
#include <Pak/CryPakUtils.h>
@@ -846,11 +845,6 @@ void CLevelSystem::OnLoadingError(const char* levelName, const char* error)
return;
}
if (gEnv->pRenderer)
{
gEnv->pRenderer->SetTexturePrecaching(false);
}
for (AZStd::vector<ILevelSystemListener*>::const_iterator it = m_listeners.begin(); it != m_listeners.end(); ++it)
{
(*it)->OnLoadingError(levelName, error);
@@ -968,33 +962,6 @@ void CLevelSystem::UnloadLevel()
CTimeValue tBegin = gEnv->pTimer->GetAsyncTime();
//AM: Flush render thread (Flush is not exposed - using EndFrame())
//We are about to delete resources that could be in use
if (gEnv->pRenderer)
{
gEnv->pRenderer->EndFrame();
bool isLoadScreenPlaying = false;
#if AZ_LOADSCREENCOMPONENT_ENABLED
LoadScreenBus::BroadcastResult(isLoadScreenPlaying, &LoadScreenBus::Events::IsPlaying);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
// force a black screen as last render command.
//if load screen is playing do not call this draw as it may lead to a crash due to UI loading code getting
//pumped while loading the shaders for this draw.
if (!isLoadScreenPlaying)
{
gEnv->pRenderer->BeginFrame();
gEnv->pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
gEnv->pRenderer->Draw2dImage(0, 0, 800, 600, -1, 0.0f, 0.0f, 1.0f, 1.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0, 0.f);
gEnv->pRenderer->EndFrame();
}
//flush any outstanding texture requests
gEnv->pRenderer->FlushPendingTextureTasks();
}
// Clear level entities and prefab instances.
EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext);
@@ -1045,27 +1012,6 @@ void CLevelSystem::UnloadLevel()
// Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event).
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
// Force to clean render resources left after deleting all objects and materials.
IRenderer* pRenderer = gEnv->pRenderer;
if (pRenderer)
{
pRenderer->FlushRTCommands(true, true, true);
CryComment("Deleting Render meshes, render resources and flush texture streaming");
// This may also release some of the materials.
int flags = FRR_DELETED_MESHES | FRR_FLUSH_TEXTURESTREAMING | FRR_OBJECTS | FRR_RENDERELEMENTS | FRR_RP_BUFFERS | FRR_POST_EFFECTS;
// Always keep the system resources around in the editor.
// If a level load fails for any reason, then do not unload the system resources, otherwise we will not have any system resources to continue rendering the console and debug output text.
if (!gEnv->IsEditor() && !GetLevelLoadFailed())
{
flags |= FRR_SYSTEM_RESOURCES;
}
pRenderer->FreeResources(flags);
CryComment("done");
}
// Perform level unload procedures for the LyShine UI system
if (gEnv && gEnv->pLyShine)
{
@@ -15,7 +15,6 @@
#include <IAudioSystem.h>
#include "IMovieSystem.h"
#include <IResourceManager.h>
#include "IDeferredCollisionEvent.h"
#include <LoadScreenBus.h>
@@ -423,11 +422,6 @@ namespace LegacyLevelSystem
{
AZ_Error("LevelSystem", false, "Error loading level '%s': %s\n", levelName, error);
if (gEnv->pRenderer)
{
gEnv->pRenderer->SetTexturePrecaching(false);
}
for (auto& listener : m_listeners)
{
listener->OnLoadingError(levelName, error);
@@ -541,32 +535,6 @@ namespace LegacyLevelSystem
CTimeValue tBegin = gEnv->pTimer->GetAsyncTime();
// AM: Flush render thread (Flush is not exposed - using EndFrame())
// We are about to delete resources that could be in use
if (gEnv->pRenderer)
{
gEnv->pRenderer->EndFrame();
bool isLoadScreenPlaying = false;
#if AZ_LOADSCREENCOMPONENT_ENABLED
LoadScreenBus::BroadcastResult(isLoadScreenPlaying, &LoadScreenBus::Events::IsPlaying);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
// force a black screen as last render command.
// if load screen is playing do not call this draw as it may lead to a crash due to UI loading code getting
// pumped while loading the shaders for this draw.
if (!isLoadScreenPlaying)
{
gEnv->pRenderer->BeginFrame();
gEnv->pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
gEnv->pRenderer->Draw2dImage(0, 0, 800, 600, -1, 0.0f, 0.0f, 1.0f, 1.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0, 0.f);
gEnv->pRenderer->EndFrame();
}
// flush any outstanding texture requests
gEnv->pRenderer->FlushPendingTextureTasks();
}
// Clear level entities and prefab instances.
EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext);
@@ -608,28 +576,6 @@ namespace LegacyLevelSystem
// Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event).
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
// Force to clean render resources left after deleting all objects and materials.
IRenderer* pRenderer = gEnv->pRenderer;
if (pRenderer)
{
pRenderer->FlushRTCommands(true, true, true);
CryComment("Deleting Render meshes, render resources and flush texture streaming");
// This may also release some of the materials.
int flags = FRR_DELETED_MESHES | FRR_FLUSH_TEXTURESTREAMING | FRR_OBJECTS | FRR_RENDERELEMENTS | FRR_RP_BUFFERS | FRR_POST_EFFECTS;
// Always keep the system resources around in the editor.
// If a level load fails for any reason, then do not unload the system resources, otherwise we will not have any system resources to
// continue rendering the console and debug output text.
if (!gEnv->IsEditor() && !GetLevelLoadFailed())
{
flags |= FRR_SYSTEM_RESOURCES;
}
pRenderer->FreeResources(flags);
CryComment("done");
}
// Perform level unload procedures for the LyShine UI system
if (gEnv && gEnv->pLyShine)
{
@@ -32,9 +32,6 @@
#include <AzCore/std/string/conversions.h>
#include <AzFramework/StringFunc/StringFunc.h>
#if !defined(_RELEASE)
#include "CrySizerImpl.h"
#endif //#if !defined(_RELEASE)
#define MAX_CELL_COUNT 32
@@ -165,52 +162,6 @@ static void TestFormatMessage ([[maybe_unused]] IConsoleCmdArgs* pArgs)
}
#endif //#if !defined(_RELEASE)
//////////////////////////////////////////////////////////////////////////
#if !defined(_RELEASE)
void CLocalizedStringsManager::LocalizationDumpLoadedInfo([[maybe_unused]] IConsoleCmdArgs* pArgs)
{
CLocalizedStringsManager* pLoca = (CLocalizedStringsManager*) gEnv->pSystem->GetLocalizationManager();
for (TTagFileNames::iterator tagit = pLoca->m_tagFileNames.begin(); tagit != pLoca->m_tagFileNames.end(); ++tagit)
{
CryLogAlways("Tag %s (%d)", tagit->first.c_str(), tagit->second.id);
int entries = 0;
CrySizerImpl* pSizer = new CrySizerImpl();
for (tmapFilenames::iterator it = pLoca->m_loadedTables.begin(); it != pLoca->m_loadedTables.end(); it++)
{
if (tagit->second.id == it->second.nTagID)
{
CryLogAlways("\t%s", it->first.c_str());
}
if (pLoca->m_pLanguage)
{
const uint32 numEntries = pLoca->m_pLanguage->m_vLocalizedStrings.size();
for (int32 i = numEntries - 1; i >= 0; i--)
{
SLocalizedStringEntry* entry = pLoca->m_pLanguage->m_vLocalizedStrings[i];
if (tagit->second.id == entry->nTagID)
{
entries++;
entry->GetMemoryUsage((ICrySizer*) pSizer);
}
}
}
}
// This line messes up Uncrustify so turn it off: *INDENT-OFF*
CryLogAlways("\t\tEntries %d, Approx Size %" PRISIZE_T "Kb", entries, pSizer->GetTotalSize() / 1024);
// turn it back on again: *INDENT-ON*
SAFE_RELEASE(pSizer);
}
}
#endif //#if !defined(_RELEASE)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -249,9 +200,6 @@ CLocalizedStringsManager::CLocalizedStringsManager(ISystem* pSystem)
"0: No encoding, store as wide strings\n"
"1: Huffman encode translated text, saves approx 30% with a small runtime performance cost\n"
"Default is 1.");
REGISTER_COMMAND("LocalizationDumpLoadedInfo", LocalizationDumpLoadedInfo, VF_NULL, "Dump out into about the loaded localization files");
#endif //#if !defined(_RELEASE)
REGISTER_CVAR2(c_sys_localization_format, &m_cvarLocalizationFormat, 1, VF_NULL,
@@ -96,10 +96,6 @@ public:
void GetLoadedTags(TLocalizationTagVec& tagVec);
void FreeLocalizationData();
#if !defined(_RELEASE)
static void LocalizationDumpLoadedInfo(IConsoleCmdArgs* pArgs);
#endif //#if !defined(_RELEASE)
private:
void SetAvailableLocalizationsBitfield(const ILocalizationManager::TLocalizationBitfield availableLocalizations);
@@ -1,325 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_MEMORYFRAGMENTATIONPROFILER_H
#define CRYINCLUDE_CRYSYSTEM_MEMORYFRAGMENTATIONPROFILER_H
#pragma once
// useful class to investigate memory fragmentation
// every time you call this from the console:
//
// #System.DumpMemoryCoverage()
//
// it adds a line to "MemoryCoverage.bmp" (generated the first time, there is a max line count)
// blue stripes mark some special positions (DLL positions)
// Dependencies: only CryLog()
#include <vector> // STL vector<>
#if defined(WIN32) || defined(WIN64)
class CMemoryFragmentationProfiler
{
public:
// constructor - clean file
CMemoryFragmentationProfiler()
: m_dwLine(0xffffffff) // 0xffffffff means not initialized yet
{
}
// call this if you want to add one line (on first call the file is generated)
void DumpMemoryCoverage()
{
if (m_dwLine == 0xffffffff)
{
Init();
}
const size_t nMinMemoryPerUnit = 4 * 1024; // down to a few KB
const size_t nUnitsPerLine = 1024 * 8; // amount of bits, should only occupy a few KB memory
const size_t nMaxMemoryPerUnit = 0x100000000 / nUnitsPerLine; // 4GB in total
static std::vector<bool> vCoverage;
vCoverage.clear();
vCoverage.resize(nUnitsPerLine, 0); // should occupy nUnitsPerLine/8 bytes (vector<bool> is specialized)
size_t nAvailableMem = 0, nUsedMem = 0;
const size_t nMallocOverhead = 24; // depends on used runtime (debug:32, release:24)
size_t nCurrentUnitSize = 256 * 1024 * 1024; // start with 256 MB blocks
void** pMemoryBlocks = 0; // linked list of memory blocks (to free them)
size_t nUnits = 0;
uint32 dwAllocCnt = 0, dwFreeCnt = 0;
while (nCurrentUnitSize >= nMinMemoryPerUnit)
{
size_t nLocalUnits = 0;
for (;; )
{
void** pMem = (void**)::malloc(nCurrentUnitSize - nMallocOverhead);
if (!pMem)
{
break;
}
++dwAllocCnt;
// update coverage (conservative)
{
size_t nStartUnit = ((size_t)pMem + nMaxMemoryPerUnit - 1) / (nMaxMemoryPerUnit);
size_t nEndUnit = ((size_t)pMem + nCurrentUnitSize) / (nMaxMemoryPerUnit);
if (nStartUnit > nUnitsPerLine)
{
nStartUnit = nUnitsPerLine;
}
if (nEndUnit > nUnitsPerLine)
{
nEndUnit = nUnitsPerLine;
}
for (size_t i = nStartUnit; i < nEndUnit; ++i)
{
vCoverage[i] = 1;
}
}
++nLocalUnits;
// insert in linked list
*pMem = pMemoryBlocks;
pMemoryBlocks = pMem;
}
nUnits += nLocalUnits;
nAvailableMem += nLocalUnits * nCurrentUnitSize;
nCurrentUnitSize /= 2;
nUnits *= 2;
}
// free all memory blocks allocated
while (pMemoryBlocks)
{
void* pNext = *pMemoryBlocks;
::free(pMemoryBlocks);
++dwFreeCnt;
pMemoryBlocks = (void**)pNext;
}
// _heapmin();
CryLog("CMemoryFragmentationProfiler Y=%d, available memory=%d MB, used memory=%d MB",
m_dwLine, (nAvailableMem + 1024 * 1024 - 1) / (1024 * 1024), (nUsedMem + 1024 * 1024 - 1) / (1024 * 1024));
LogCoverage(vCoverage);
DumpToRAWCoverage(vCoverage);
}
private: // ------------------------------------------------------------------
void Init()
{
FILE* out = nullptr;
azfopen(&out, "MemoryCoverage.bmp", "wb");
if (out)
{
BITMAPFILEHEADER pHeader;
BITMAPINFOHEADER pInfoHeader;
memset(&pHeader, 0, sizeof(BITMAPFILEHEADER));
memset(&pInfoHeader, 0, sizeof(BITMAPINFOHEADER));
pHeader.bfType = 0x4D42;
pHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_nPixelsPerLine * m_nLineCount * 3;
pHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
pInfoHeader.biWidth = m_nPixelsPerLine;
pInfoHeader.biHeight = m_nLineCount;
pInfoHeader.biPlanes = 1;
pInfoHeader.biBitCount = 24;
pInfoHeader.biCompression = 0;
pInfoHeader.biSizeImage = m_nPixelsPerLine * m_nLineCount;
fwrite(&pHeader, 1, sizeof(BITMAPFILEHEADER), out);
fwrite(&pInfoHeader, 1, sizeof(BITMAPINFOHEADER), out);
for (int y = 0; y < m_nLineCount; y++) // amount of lines
{
for (int x = 0; x < m_nPixelsPerLine; x++)
{
size_t nAddress = x * (0x100000000 / m_nPixelsPerLine);
if (nAddress == 0x30000000
|| nAddress == 0x30500000
|| nAddress == 0x31000000
|| nAddress == 0x31500000
|| nAddress == 0x32000000
|| nAddress == 0x32500000
|| nAddress == 0x33500000
|| nAddress == 0x34000000
|| nAddress == 0x35000000
|| nAddress == 0x35500000
|| nAddress == 0x36000000
|| nAddress == 0x36500000
|| nAddress == 0x38000000
|| nAddress == 0x39000000)
{
putc((unsigned char)100, out); // blue DLL start
}
else
{
putc((unsigned char)0, out); // black
}
putc((unsigned char)0, out);
putc((unsigned char)0, out);
}
}
fclose(out);
m_dwLine = 0;
}
}
void LogCoverage(std::vector<bool>& vCov)
{
const size_t nCharPerLine = 128; // readable amount
char szResult[nCharPerLine + 1], * pCursor = szResult;
szResult[nCharPerLine] = 0; // zero termination
size_t nSize = vCov.size();
size_t nUnitsPerChar = nSize / nCharPerLine;
for (size_t i = 0; i < nSize; )
{
unsigned int nLocalCov = 0;
for (size_t e = 0; e < nUnitsPerChar; ++e, ++i)
{
if (vCov[i])
{
++nLocalCov;
}
}
if (nLocalCov == 0)
{
*pCursor++ = '#'; // occupied
}
else if (nLocalCov == nUnitsPerChar)
{
*pCursor++ = '.'; // free
}
else
{
*pCursor++ = '+'; // partly
}
}
CryLog(" Coverage=%s", szResult);
}
void DumpToRAWCoverage(std::vector<bool>& vCov)
{
FILE* out = nullptr;
azfopen(&out, "MemoryCoverage.bmp", "rb+");
if (!out)
{
return;
}
if (fseek(out, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * (m_nLineCount - 1 - m_dwLine) * m_nPixelsPerLine, SEEK_SET) != 0)
{
fclose(out);
return;
}
size_t nSize = vCov.size();
size_t nUnitsPerChar = nSize / m_nPixelsPerLine;
for (size_t i = 0; i < nSize; )
{
unsigned int nLocalCov = 0;
for (size_t e = 0; e < nUnitsPerChar; ++e, ++i)
{
if (vCov[i])
{
++nLocalCov;
}
}
size_t Val = 256 - (256 * nLocalCov) / nUnitsPerChar;
if (Val > 0)
{
Val = 127 + Val / 2;
}
putc((unsigned char)Val, out);
putc((unsigned char)Val, out);
putc((unsigned char)Val, out); // grey
}
fclose(out);
++m_dwLine;
}
unsigned int m_dwLine; // [0..m_nLineCount-1], m_nLineCount means bitmap is full, 0xffffffff means not initialized yet
static const size_t m_nPixelsPerLine = 1024; // bitmap width
static const size_t m_nLineCount = 128; //
};
#else // defined(WIN32) || defined(WIN64)
class CMemoryFragmentationProfiler
{
public:
void DumpMemoryCoverage() {}
};
#endif // defined(WIN32) || defined(WIN64)
#endif // CRYINCLUDE_CRYSYSTEM_MEMORYFRAGMENTATIONPROFILER_H
@@ -17,7 +17,6 @@
#include "CustomMemoryHeap.h"
#include "GeneralMemoryHeap.h"
#include "PageMappingHeap.h"
#include "DefragAllocator.h"
#if defined(AZ_RESTRICTED_PLATFORM)
@@ -217,11 +216,6 @@ IPageMappingHeap* CCryMemoryManager::CreatePageMappingHeap(size_t addressSpace,
return new CPageMappingHeap(addressSpace, sName);
}
IDefragAllocator* CCryMemoryManager::CreateDefragAllocator()
{
return new CDefragAllocator();
}
extern "C"
{
CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager)
-2
View File
@@ -44,8 +44,6 @@ public:
virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName);
virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName);
virtual IDefragAllocator* CreateDefragAllocator();
};
#else
typedef IMemoryManager CCryMemoryManager;
@@ -1,160 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "DrawContext.h"
#include <ISystem.h>
#include <IRenderer.h>
#include <IRenderAuxGeom.h>
MINIGUI_BEGIN
//////////////////////////////////////////////////////////////////////////
CDrawContext::CDrawContext(SMetrics* pMetrics)
{
m_currentStackLevel = 0;
m_x = 0;
m_y = 0;
m_pMetrics = pMetrics;
m_color = ColorB(0, 0, 0, 0);
m_defaultZ = 0.0f;
m_pAuxRender = gEnv->pRenderer->GetIRenderAuxGeom();
m_frameWidth = (float)gEnv->pRenderer->GetWidth();
m_frameHeight = (float)gEnv->pRenderer->GetHeight();
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::SetColor(ColorB color)
{
m_color = color;
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::DrawLine(float x0, float y0, float x1, float y1, float thickness /*= 1.0f */)
{
m_pAuxRender->DrawLine(Vec3(m_x + x0, m_y + y0, m_defaultZ), m_color, Vec3(m_x + x1, m_y + y1, m_defaultZ), m_color, thickness);
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::DrawTriangle(float x0, float y0, float x1, float y1, float x2, float y2)
{
m_pAuxRender->DrawTriangle(Vec3(m_x + x0, m_y + y0, m_defaultZ), m_color, Vec3(m_x + x1, m_y + y1, m_defaultZ), m_color, Vec3(m_x + x2, m_y + y2, m_defaultZ), m_color);
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::DrawRect(const Rect& rc)
{
m_pAuxRender->DrawTriangle(Vec3(m_x + rc.left, m_y + rc.top, m_defaultZ), m_color, Vec3(m_x + rc.left, m_y + rc.bottom, m_defaultZ), m_color, Vec3(m_x + rc.right, m_y + rc.top, m_defaultZ), m_color);
m_pAuxRender->DrawTriangle(Vec3(m_x + rc.left, m_y + rc.bottom, m_defaultZ), m_color, Vec3(m_x + rc.right, m_y + rc.bottom, m_defaultZ), m_color, Vec3(m_x + rc.right, m_y + rc.top, m_defaultZ), m_color);
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::DrawFrame(const Rect& rc, ColorB lineColor, ColorB solidColor, float thickness)
{
ColorB prevColor = m_color;
SetColor(solidColor);
DrawRect(rc);
SetColor(lineColor);
uint32 curFlags = m_pAuxRender->GetRenderFlags().m_renderFlags;
m_pAuxRender->SetRenderFlags(curFlags | e_DrawInFrontOn);
DrawLine(rc.left, rc.top, rc.right, rc.top, thickness);
DrawLine(rc.right, rc.top, rc.right, rc.bottom, thickness);
DrawLine(rc.left, rc.top, rc.left, rc.bottom, thickness);
DrawLine(rc.left, rc.bottom, rc.right, rc.bottom, thickness);
m_pAuxRender->SetRenderFlags(curFlags);
m_color = prevColor;
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::StartDrawing()
{
uint32 width = gEnv->pRenderer->GetWidth();
uint32 height = gEnv->pRenderer->GetHeight();
gEnv->pRenderer->Set2DMode(width, height, m_backupSceneMatrices);
m_prevRenderFlags = m_pAuxRender->GetRenderFlags().m_renderFlags;
m_pAuxRender->SetRenderFlags(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOff | e_DepthTestOff);
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::StopDrawing()
{
// Restore old flags that where set before our draw context.
m_pAuxRender->SetRenderFlags(m_prevRenderFlags);
gEnv->pRenderer->Unset2DMode(m_backupSceneMatrices);
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::DrawString(float x, float y, float font_size, ETextAlign align, const char* format, ...)
{
//text will be off screen
if (y > m_frameHeight || x > m_frameWidth)
{
return;
}
va_list args;
va_start(args, format);
SDrawTextInfo ti;
ti.xscale = ti.yscale = font_size / 12.0f; // font size in pixels to text scale.
ti.flags = eDrawText_Monospace | eDrawText_2D | eDrawText_FixedSize | eDrawText_IgnoreOverscan;
if (align == eTextAlign_Left)
{
}
else if (align == eTextAlign_Right)
{
ti.flags |= eDrawText_Right;
}
else if (align == eTextAlign_Center)
{
ti.flags |= eDrawText_Center;
}
ti.color[0] = (float)m_color.r / 255.0f;
ti.color[1] = (float)m_color.g / 255.0f;
ti.color[2] = (float)m_color.b / 255.0f;
ti.color[3] = (float)m_color.a / 255.0f;
gEnv->pRenderer->DrawTextQueued(Vec3(m_x + x, m_y + y, m_defaultZ), ti, format, args);
va_end(args);
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::PushClientRect(const Rect& rc)
{
m_currentStackLevel++;
assert(m_currentStackLevel < MAX_ORIGIN_STACK);
m_clientRectStack[m_currentStackLevel] = rc;
m_x += rc.left;
m_y += rc.top;
}
//////////////////////////////////////////////////////////////////////////
void CDrawContext::PopClientRect()
{
if (m_currentStackLevel > 0)
{
Rect& rc = m_clientRectStack[m_currentStackLevel];
m_x -= rc.left;
m_y -= rc.top;
m_currentStackLevel--;
}
}
MINIGUI_END
@@ -1,89 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : DrawContext helper class for MiniGUI
#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_DRAWCONTEXT_H
#define CRYINCLUDE_CRYSYSTEM_MINIGUI_DRAWCONTEXT_H
#pragma once
#include "ICryMiniGUI.h"
#include <Cry_Color.h>
struct IRenderAuxGeom;
MINIGUI_BEGIN
enum ETextAlign
{
eTextAlign_Left,
eTextAlign_Right,
eTextAlign_Center
};
//////////////////////////////////////////////////////////////////////////
// Context of MiniGUI drawing.
//////////////////////////////////////////////////////////////////////////
class CDrawContext
{
public:
CDrawContext(SMetrics* pMetrics);
// Must be called before any drawing happens
void StartDrawing();
// Must be called after all drawing have been complete.
void StopDrawing();
void PushClientRect(const Rect& rc);
void PopClientRect();
SMetrics& Metrics() { return *m_pMetrics; }
void SetColor(ColorB color);
void DrawLine(float x0, float y0, float x1, float y1, float thickness = 1.0f);
void DrawTriangle(float x0, float y0, float x1, float y1, float x2, float y2);
void DrawRect(const Rect& rc);
void DrawFrame(const Rect& rc, ColorB lineColor, ColorB solidColor, float thickness = 1.0f);
void DrawString(float x, float y, float font_size, ETextAlign align, const char* format, ...);
protected:
SMetrics* m_pMetrics;
ColorB m_color;
float m_defaultZ;
IRenderAuxGeom* m_pAuxRender;
uint32 m_prevRenderFlags;
enum
{
MAX_ORIGIN_STACK = 16
};
int m_currentStackLevel;
float m_x, m_y; // Reference X,Y positions
Rect m_clientRectStack[MAX_ORIGIN_STACK];
float m_frameWidth;
float m_frameHeight;
private:
TransformationMatrices m_backupSceneMatrices;
};
MINIGUI_END
#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_DRAWCONTEXT_H
@@ -1,316 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#include "CrySystem_precompiled.h"
#include "MiniButton.h"
#include "DrawContext.h"
#include <ISystem.h>
#include <IConsole.h>
MINIGUI_BEGIN
CMiniButton::CMiniButton()
{
m_pCVar = NULL;
m_fCVarValue[0] = 0;
m_fCVarValue[1] = 1;
m_saveStateOn = false;
m_clickCallback = NULL;
m_pCallbackData = NULL;
m_pConnectedCtrl = NULL;
}
//////////////////////////////////////////////////////////////////////////
void CMiniButton::Reset()
{
/*if (m_pCVar)
{
pCVar->Set( m_fCVarValue[0] );
}*/
/*if(m_pConnectedCtrl)
{
m_pConnectedCtrl->SetVisible(false);
}*/
clear_flag(eCtrl_Checked);
}
//////////////////////////////////////////////////////////////////////////
void CMiniButton::SaveState()
{
if (is_flag(eCtrl_Checked))
{
if (m_pConnectedCtrl && m_pConnectedCtrl->CheckFlag(eCtrl_Hidden))
{
m_saveStateOn = false;
}
else
{
m_saveStateOn = true;
}
}
else
{
m_saveStateOn = false;
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniButton::RestoreState()
{
if (m_pCVar)
{
if (m_pCVar->GetFVal() == m_fCVarValue[1])
{
set_flag(eCtrl_Checked);
//Restoring CVars has caused a few issues, especially when the user is changing
//CVars through the console while perfHud is active, removing for now
//pCVar->Set( m_saveStateOn ? m_fCVarValue[1] : m_fCVarValue[0] );
}
else
{
clear_flag(eCtrl_Checked);
}
}
else
{
//connected controls (tables / info boxes etc) now look after themselves
/*if(m_pConnectedCtrl)
{
m_pConnectedCtrl->SetVisible(m_saveStateOn);
}*/
if (CheckFlag(eCtrl_CheckButton))
{
if (m_saveStateOn)
{
set_flag(eCtrl_Checked);
}
else
{
clear_flag(eCtrl_Checked);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniButton::OnPaint(CDrawContext& dc)
{
ColorB bkgColor = dc.Metrics().clrBackground;
if (is_flag(eCtrl_Highlight))
{
bkgColor = dc.Metrics().clrBackgroundHighlight;
}
else if (is_flag(eCtrl_Checked))
{
//if connected control has been hidden, this button should not be checked
if (m_pConnectedCtrl && m_pConnectedCtrl->CheckFlag(eCtrl_Hidden))
{
clear_flag(eCtrl_Checked);
}
else
{
bkgColor = dc.Metrics().clrBackgroundSelected;
}
}
float borderThickness = 1.0f;
if (is_flag(eCtrl_Focus))
{
borderThickness = 3.0f;
}
ColorB borderCol = dc.Metrics().clrFrameBorder;
if (!m_pGUI->InFocus())
{
borderCol = dc.Metrics().clrFrameBorderOutOfFocus;
bkgColor.a = dc.Metrics().outOfFocusAlpha;
}
dc.DrawFrame(m_rect, borderCol, bkgColor, borderThickness);
ColorB textColor = dc.Metrics().clrText;
if (is_flag(eCtrl_Checked | eCtrl_Highlight))
{
textColor = dc.Metrics().clrTextSelected;
}
dc.SetColor(textColor);
ETextAlign align;
float startX;
if (is_flag(eCtrl_TextAlignCentre))
{
startX = (m_rect.left + m_rect.right) / 2.f;
align = eTextAlign_Center;
}
else
{
startX = m_rect.left + 5.f;
align = eTextAlign_Left;
}
dc.DrawString(startX, m_rect.top, dc.Metrics().fTitleSize, align, GetTitle());
//Check not very obvious
#if 0
if (is_flag(eCtrl_Checked))
{
// Draw checked mark.
float checkX = m_rect.left + 4;
float checkY = (m_rect.bottom + m_rect.top) * 0.5f;
dc.SetColor(dc.Metrics().clrChecked);
dc.DrawLine(checkX, checkY, checkX + 3, checkY + 3);
dc.DrawLine(checkX + 3, checkY + 3, checkX + 7, checkY - 6);
}
#endif
}
//////////////////////////////////////////////////////////////////////////
void CMiniButton::SetRect(const Rect& rc)
{
Rect newrc = rc;
newrc.bottom = newrc.top + m_pGUI->Metrics().fTitleSize + 2;
CMiniCtrl::SetRect(newrc);
}
//////////////////////////////////////////////////////////////////////////
void CMiniButton::OnEvent(float x, float y, EMiniCtrlEvent event)
{
switch (event)
{
case eCtrlEvent_LButtonDown:
{
SCommand cmd;
if (CheckFlag(eCtrl_CheckButton))
{
if (!CheckFlag(eCtrl_Checked))
{
cmd.command = eCommand_ButtonChecked;
}
else
{
cmd.command = eCommand_ButtonUnchecked;
}
}
else
{
cmd.command = eCommand_ButtonPress;
}
cmd.nCtrlID = GetId();
cmd.pCtrl = this;
GetGUI()->OnCommand(cmd);
if (CheckFlag(eCtrl_CheckButton))
{
bool bOn = false;
if (CheckFlag(eCtrl_Checked))
{
bOn = false;
ClearFlag(eCtrl_Checked);
}
else
{
bOn = true;
SetFlag(eCtrl_Checked);
}
if (m_pCVar)
{
m_pCVar->Set(m_fCVarValue[bOn ? 1 : 0]);
}
if (m_pConnectedCtrl)
{
m_pConnectedCtrl->SetVisible(bOn);
}
}
else
{
//cross button behavior
if (m_pConnectedCtrl)
{
m_pConnectedCtrl->SetVisible(false);
}
}
if (m_clickCallback)
{
m_clickCallback(m_pCallbackData, true);
}
}
break;
case eCtrlEvent_MouseOff:
{
if (m_pParent)
{
m_pParent->OnEvent(x, y, eCtrlEvent_MouseOff);
}
}
break;
}
}
//////////////////////////////////////////////////////////////////////////
bool CMiniButton::SetControlCVar(const char* sCVarName, float fOffValue, float fOnValue)
{
m_pCVar = GetISystem()->GetIConsole()->GetCVar(sCVarName);
if (!m_pCVar)
{
CryLogAlways("failed to find CVar: %s\n", sCVarName);
}
m_fCVarValue[0] = fOffValue;
m_fCVarValue[1] = fOnValue;
if (m_pCVar && m_pCVar->GetFVal() == fOnValue)
{
set_flag(eCtrl_Checked);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CMiniButton::SetClickCallback(ClickCallback callback, void* pCallbackData)
{
m_clickCallback = callback;
m_pCallbackData = pCallbackData;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CMiniButton::SetConnectedCtrl(IMiniCtrl* pConnectedCtrl)
{
m_pConnectedCtrl = pConnectedCtrl;
return true;
}
MINIGUI_END
@@ -1,60 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIBUTTON_H
#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIBUTTON_H
#pragma once
#include "MiniGUI.h"
MINIGUI_BEGIN
//////////////////////////////////////////////////////////////////////////
// Root window all other controls derive from
class CMiniButton
: public CMiniCtrl
{
public:
CMiniButton();
//////////////////////////////////////////////////////////////////////////
// CMiniCtrl interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual EMiniCtrlType GetType() const { return eCtrlType_Button; }
virtual void SetRect(const Rect& rc);
virtual void OnPaint(CDrawContext& dc);
virtual void OnEvent(float x, float y, EMiniCtrlEvent event);
virtual void Reset();
virtual void SaveState();
virtual void RestoreState();
//////////////////////////////////////////////////////////////////////////
virtual bool SetControlCVar(const char* sCVarName, float fOffValue, float fOnValue);
virtual bool SetClickCallback(ClickCallback callback, void* pCallbackData);
virtual bool SetConnectedCtrl(IMiniCtrl* pConnectedCtrl);
protected:
ICVar* m_pCVar;
float m_fCVarValue[2];
ClickCallback m_clickCallback;
void* m_pCallbackData;
IMiniCtrl* m_pConnectedCtrl;
};
MINIGUI_END
#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIBUTTON_H
@@ -1,862 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Implementation of the MiniGUI class
#include "CrySystem_precompiled.h"
#include "MiniGUI.h"
#include "DrawContext.h"
#include "MiniButton.h"
#include "MiniMenu.h"
#include "MiniInfoBox.h"
#include "MiniTable.h"
#include <ISystem.h>
#include <IRenderer.h>
#include <LyShine/Bus/UiCursorBus.h>
#include <AzFramework/Input/Devices/Gamepad/InputDeviceGamepad.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
namespace minigui
{
CRYREGISTER_SINGLETON_CLASS(CMiniGUI)
}
MINIGUI_BEGIN
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::InitMetrics()
{
m_metrics.clrText = ColorB(255, 255, 255, 255);
m_metrics.clrTextSelected = ColorB(0, 255, 0, 255);
m_metrics.fTextSize = 12.0f;
m_metrics.clrTitle = ColorB(255, 255, 255, 255);
m_metrics.fTitleSize = 14.0f;
const int backgroundAlpha = 255;
m_metrics.clrBackground = ColorB(20, 20, 20, backgroundAlpha);
m_metrics.clrBackgroundHighlight = ColorB(10, 10, 150, backgroundAlpha);
m_metrics.clrBackgroundSelected = ColorB(10, 120, 10, backgroundAlpha);
m_metrics.clrFrameBorder = ColorB(255, 0, 0, 255);
m_metrics.clrFrameBorderHighlight = ColorB(255, 255, 0, 255);
m_metrics.clrFrameBorderOutOfFocus = ColorB(0, 0, 0, 255);
m_metrics.clrChecked = ColorB(0, 0, 0, 255);
m_metrics.outOfFocusAlpha = 32;
}
class CMiniCtrlRoot
: public CMiniCtrl
{
public:
CMiniCtrlRoot() {};
virtual EMiniCtrlType GetType() const { return eCtrlType_Unknown; };
virtual void OnPaint([[maybe_unused]] class CDrawContext& dc) {};
};
//////////////////////////////////////////////////////////////////////////
CMiniGUI::CMiniGUI()
: m_enabled(false)
, m_inFocus(true)
, m_pDPadMenu(NULL)
, m_pMovingCtrl(NULL)
{
}
//////////////////////////////////////////////////////////////////////////
CMiniGUI::~CMiniGUI()
{
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::Init()
{
m_pEventListener = NULL;
InitMetrics();
AzFramework::InputChannelEventListener::Connect();
m_pRootCtrl = new CMiniCtrlRoot;
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::Reset()
{
m_pRootCtrl->Reset();
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::SaveState()
{
m_pRootCtrl->SaveState();
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::RestoreState()
{
m_pRootCtrl->RestoreState();
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::SetEnabled(bool status)
{
m_enabled = status;
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::SetInFocus(bool status)
{
if (status)
{
m_inFocus = true;
}
else
{
CloseDPadMenu();
m_inFocus = false;
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::Done()
{
AzFramework::InputChannelEventListener::Disconnect();
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::Draw()
{
FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_SYSTEM, g_bProfilerEnabled);
// When console opened hide MiniGui
bool bConsoleOpened = gEnv->pConsole->IsOpened();
if (m_enabled && !bConsoleOpened)
{
ProcessInput();
CDrawContext dc(&m_metrics);
dc.StartDrawing();
{
// Draw all controls.
m_pRootCtrl->DrawCtrl(dc);
}
dc.StopDrawing();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::ProcessInput()
{
//check we are not in digital selection mode
if (!m_pDPadMenu)
{
float mx(0), my(0);
AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero();
AzFramework::InputSystemCursorRequestBus::EventResult(systemCursorPositionNormalized,
AzFramework::InputDeviceMouse::Id,
&AzFramework::InputSystemCursorRequests::GetSystemCursorPositionNormalized);
mx = systemCursorPositionNormalized.GetX() * gEnv->pRenderer->GetWidth();
my = systemCursorPositionNormalized.GetY() * gEnv->pRenderer->GetHeight();
//update moving control
if (m_pMovingCtrl)
{
m_pMovingCtrl->Move(mx, my);
}
IMiniCtrl* pCtrl = GetCtrlFromPoint(mx, my);
if (pCtrl)
{
SetHighlight(pCtrl, true, mx, my);
}
else
{
SetHighlight(m_highlightedCtrl, false, mx, my);
}
}
}
//////////////////////////////////////////////////////////////////////////
IMiniCtrl* CMiniGUI::GetCtrlFromPoint(float x, float y) const
{
// Draw all controls.
return m_pRootCtrl->GetCtrlFromPoint(x, y);
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::SetHighlight(IMiniCtrl* pCtrl, bool bEnable, float x, float y)
{
if (pCtrl)
{
if (m_highlightedCtrl && m_highlightedCtrl != pCtrl)
{
m_highlightedCtrl->OnEvent(x, y, eCtrlEvent_MouseOff);
m_highlightedCtrl->ClearFlag(eCtrl_Highlight);
}
if (bEnable)
{
pCtrl->OnEvent(x, y, eCtrlEvent_MouseOver);
pCtrl->SetFlag(eCtrl_Highlight);
m_highlightedCtrl = pCtrl;
}
else
{
pCtrl->OnEvent(x, y, eCtrlEvent_MouseOff);
pCtrl->ClearFlag(eCtrl_Highlight);
m_highlightedCtrl = NULL;
}
}
else
{
assert(bEnable == false);
if (m_highlightedCtrl)
{
m_highlightedCtrl->OnEvent(x, y, eCtrlEvent_MouseOff);
m_highlightedCtrl->ClearFlag(eCtrl_Highlight);
m_highlightedCtrl = NULL;
}
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::SetFocus(IMiniCtrl* pCtrl, bool bEnable)
{
if (m_focusCtrl)
{
m_focusCtrl->ClearFlag(eCtrl_Focus);
}
m_focusCtrl = pCtrl;
if (m_focusCtrl)
{
if (bEnable)
{
m_focusCtrl->SetFlag(eCtrl_Focus);
}
else
{
m_focusCtrl->ClearFlag(eCtrl_Focus);
}
}
}
//////////////////////////////////////////////////////////////////////////
SMetrics& CMiniGUI::Metrics()
{
return m_metrics;
}
//////////////////////////////////////////////////////////////////////////
IMiniCtrl* CMiniGUI::CreateCtrl(IMiniCtrl* pParentCtrl, int nCtrlID, EMiniCtrlType type, int nCtrlFlags, const Rect& rc, const char* title)
{
CMiniCtrl* pCtrl = 0;
// Test code.
switch (type)
{
case eCtrlType_Button:
pCtrl = new CMiniButton;
break;
case eCtrlType_Menu:
pCtrl = new CMiniMenu;
break;
case eCtrlType_InfoBox:
pCtrl = new CMiniInfoBox;
break;
case eCtrlType_Table:
pCtrl = new CMiniTable;
break;
default:
assert(0 && "Unknown MiniGUI control type");
break;
}
;
if (pCtrl)
{
pCtrl->SetGUI(this);
pCtrl->SetFlag(nCtrlFlags);
pCtrl->SetTitle(title);
pCtrl->SetRect(rc);
pCtrl->SetId(nCtrlID);
if (pCtrl->CheckFlag(eCtrl_AutoResize))
{
pCtrl->AutoResize();
}
if (pCtrl->CheckFlag(eCtrl_CloseButton))
{
pCtrl->CreateCloseButton();
}
if (pParentCtrl)
{
pParentCtrl->AddSubCtrl(pCtrl);
}
else
{
m_pRootCtrl->AddSubCtrl(pCtrl);
}
if (type == eCtrlType_Menu && pParentCtrl == NULL)
{
m_rootMenus.push_back(pCtrl);
}
}
return pCtrl;
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::OnCommand(SCommand& cmd)
{
if (m_pEventListener)
{
m_pEventListener->OnCommand(cmd);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::OnMouseInputEvent(const AzFramework::InputChannel& inputChannel)
{
if (!m_inFocus || !m_enabled)
{
return;
}
const AzFramework::InputChannel::PositionData2D* positionData2D = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
if (!positionData2D)
{
return;
}
const float mx = positionData2D->m_normalizedPosition.GetX() * gEnv->pRenderer->GetWidth();
const float my = positionData2D->m_normalizedPosition.GetY() * gEnv->pRenderer->GetHeight();
IMiniCtrl* pCtrl = GetCtrlFromPoint(mx, my);
if (pCtrl)
{
const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId();
if (channelId == AzFramework::InputDeviceMouse::Button::Left)
{
if (inputChannel.IsStateBegan())
{
pCtrl->OnEvent(mx, my, eCtrlEvent_LButtonDown);
}
else if (inputChannel.IsStateEnded())
{
pCtrl->OnEvent(mx, my, eCtrlEvent_LButtonUp);
}
}
}
}
void CMiniGUI::SetDPadMenu(IMiniCtrl* pMenu)
{
m_pDPadMenu = (CMiniMenu*)pMenu;
UiCursorBus::Broadcast(&UiCursorInterface::DecrementVisibleCounter);
}
void CMiniGUI::CloseDPadMenu()
{
if (m_pDPadMenu)
{
CMiniMenu* closeMenu = m_pDPadMenu;
//close menu and all parent menus
do
{
closeMenu->Close();
closeMenu = (CMiniMenu*)closeMenu->GetParent();
} while (closeMenu->GetType() == eCtrlType_Menu);
m_pDPadMenu->ClearFlag(eCtrl_Highlight);
m_pDPadMenu = NULL;
UiCursorBus::Broadcast(&UiCursorInterface::IncrementVisibleCounter);
}
}
void CMiniGUI::UpdateDPadMenu(const AzFramework::InputChannel& inputChannel)
{
const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId();
const bool isPressed = inputChannel.IsStateBegan();
if (m_pDPadMenu)
{
if (channelId == AzFramework::InputDeviceGamepad::Button::B)
{
CloseDPadMenu();
return;
}
if (isPressed)
{
if (channelId == AzFramework::InputDeviceGamepad::Button::DD ||
channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LD)
{
m_pDPadMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadDown);
}
else if (channelId == AzFramework::InputDeviceGamepad::Button::DU ||
channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LU)
{
m_pDPadMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadUp);
}
else if (channelId == AzFramework::InputDeviceGamepad::Button::DL ||
channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LL)
{
CMiniMenu* pNewMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadLeft);
//get previous root menu
if (pNewMenu == NULL)
{
int i = 0, nRootMenus = m_rootMenus.size();
for (i = 0; i < nRootMenus; i++)
{
if (m_rootMenus[i] == m_pDPadMenu)
{
break;
}
}
if (i > 0)
{
m_pDPadMenu->Close();
m_pDPadMenu->ClearFlag(eCtrl_Highlight);
m_pDPadMenu = (CMiniMenu*)m_rootMenus[i - 1];
m_pDPadMenu->Open();
m_pDPadMenu->SetFlag(eCtrl_Highlight);
}
//else selected menu remains the same
}
else
{
m_pDPadMenu = pNewMenu;
}
}
else if (channelId == AzFramework::InputDeviceGamepad::Button::DR ||
channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LR)
{
CMiniMenu* pNewMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadRight);
//get next root menu
if (pNewMenu == NULL)
{
int i = 0, nRootMenus = m_rootMenus.size();
for (i = 0; i < nRootMenus; i++)
{
if (m_rootMenus[i] == m_pDPadMenu)
{
break;
}
}
if (i < nRootMenus - 1)
{
m_pDPadMenu->Close();
m_pDPadMenu->ClearFlag(eCtrl_Highlight);
m_pDPadMenu = (CMiniMenu*)m_rootMenus[i + 1];
m_pDPadMenu->Open();
m_pDPadMenu->SetFlag(eCtrl_Highlight);
}
//else selected menu remains the same
}
else
{
m_pDPadMenu = pNewMenu;
}
}
else if (channelId == AzFramework::InputDeviceGamepad::Button::A)
{
m_pDPadMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_LButtonDown);
}
}
}
}
bool CMiniGUI::OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel)
{
const AzFramework::InputDeviceId& deviceId = inputChannel.GetInputDevice().GetInputDeviceId();
if (AzFramework::InputDeviceMouse::IsMouseDevice(deviceId))
{
OnMouseInputEvent(inputChannel);
return false;
}
if (!m_inFocus)
{
return false;
}
if (!AzFramework::InputDeviceGamepad::IsGamepadDevice(deviceId))
{
return false;
}
if (m_pDPadMenu)
{
UpdateDPadMenu(inputChannel);
}
else
{
float posX = 0.0f;
float posY = 0.0f;
const AzFramework::InputChannel::PositionData2D* positionData2D = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
if (positionData2D)
{
posX = positionData2D->m_normalizedPosition.GetX() * gEnv->pRenderer->GetWidth();
posY = positionData2D->m_normalizedPosition.GetY() * gEnv->pRenderer->GetHeight();
}
IMiniCtrl* pCtrl = GetCtrlFromPoint(posX, posY);
if (pCtrl)
{
const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId();
if (channelId == AzFramework::InputDeviceGamepad::Button::A)
{
switch (inputChannel.GetState())
{
case AzFramework::InputChannel::State::Began:
pCtrl->OnEvent(posX, posY, eCtrlEvent_LButtonDown);
break;
case AzFramework::InputChannel::State::Ended:
pCtrl->OnEvent(posX, posY, eCtrlEvent_LButtonUp);
break;
case AzFramework::InputChannel::State::Updated:
pCtrl->OnEvent(posX, posY, eCtrlEvent_LButtonPressed);
//if we've clicked on a menu, enter menu selection mode, disable mouse
if (pCtrl->GetType() == eCtrlType_Menu)
{
SetDPadMenu(pCtrl);
}
break;
}
}
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::SetEventListener(IMiniGUIEventListener* pListener)
{
m_pEventListener = pListener;
}
//////////////////////////////////////////////////////////////////////////
void CMiniGUI::RemoveAllCtrl()
{
m_highlightedCtrl = NULL;
//reset all console variables to default state
Reset();
m_pRootCtrl->RemoveAllSubCtrl();
}
//////////////////////////////////////////////////////////////////////////
//CMiniCtrl
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::Reset()
{
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->Reset();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::SaveState()
{
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->SaveState();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::RestoreState()
{
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->RestoreState();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::AddSubCtrl(IMiniCtrl* pCtrl)
{
assert(pCtrl);
_smart_ptr<IMiniCtrl> pTempCtrl(pCtrl);
IMiniCtrl* pParent = pCtrl->GetParent();
if (pParent)
{
pParent->RemoveSubCtrl(pCtrl);
}
static_cast<CMiniCtrl*>(pCtrl)->m_pParent = this;
m_subCtrls.push_back(pCtrl);
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::RemoveSubCtrl(IMiniCtrl* pCtrl)
{
assert(pCtrl);
_smart_ptr<IMiniCtrl> pTempCtrl(pCtrl);
IMiniCtrl* pParent = pCtrl->GetParent();
if (pParent == this)
{
static_cast<CMiniCtrl*>(pCtrl)->m_pParent = 0;
for (int i = 0, num = (int)m_subCtrls.size(); i < num; i++)
{
if (m_subCtrls[i] == pCtrl)
{
m_subCtrls.erase(m_subCtrls.begin() + i);
break;
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::RemoveAllSubCtrl()
{
int nSubCtrls = m_subCtrls.size();
if (nSubCtrls)
{
for (int i = 0; i < nSubCtrls; i++)
{
IMiniCtrl* pSubCtrl = m_subCtrls[i].get();
pSubCtrl->RemoveAllSubCtrl();
}
m_subCtrls.clear();
}
}
//////////////////////////////////////////////////////////////////////////
IMiniCtrl* CMiniCtrl::GetCtrlFromPoint(float x, float y)
{
if (is_flag(eCtrl_Hidden))
{
return 0;
}
for (int i = 0, num = (int)m_subCtrls.size(); i < num; i++)
{
float lx = x - m_rect.left;
float ly = y - m_rect.top;
IMiniCtrl* pHit = m_subCtrls[i]->GetCtrlFromPoint(lx, ly);
if (pHit)
{
return pHit;
}
}
if (m_rect.IsPointInside(x, y))
{
return this;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::DrawCtrl(CDrawContext& dc)
{
OnPaint(dc);
dc.PushClientRect(m_rect);
for (int i = 0, num = (int)m_subCtrls.size(); i < num; i++)
{
CMiniCtrl* pCtrl = static_cast<CMiniCtrl*>((IMiniCtrl*)m_subCtrls[i]);
if (!pCtrl->is_flag(eCtrl_Hidden))
{
pCtrl->DrawCtrl(dc);
}
}
dc.PopClientRect();
}
//////////////////////////////////////////////////////////////////////////
int CMiniCtrl::GetSubCtrlCount() const
{
return (int)m_subCtrls.size();
}
//////////////////////////////////////////////////////////////////////////
IMiniCtrl* CMiniCtrl::GetSubCtrl(int nIndex) const
{
assert(nIndex >= 0 && nIndex < (int)m_subCtrls.size());
return m_subCtrls[nIndex];
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::SetRect(const Rect& rc)
{
m_rect = rc;
if (m_pCloseButton)
{
float width = rc.Width();
//relative position of cross box
Rect closeRect(width - 20.f, 0.f, width, 20.f);
m_pCloseButton->SetRect(closeRect);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::SetVisible(bool state)
{
if (state)
{
clear_flag(eCtrl_Hidden);
}
else
{
set_flag(eCtrl_Hidden);
}
if (m_pCloseButton)
{
m_pCloseButton->SetVisible(state);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::AutoResize()
{
uint32 stringLen = m_title.length();
if (stringLen)
{
//just an approximation for now - should take into account font size / kerning
m_rect.right = m_rect.left + (8.5f * stringLen);
}
m_requiresResize = false;
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::StartMoving(float x, float y)
{
if (!m_moving)
{
m_prevX = x;
m_prevY = y;
m_moving = true;
m_pGUI->SetMovingCtrl(this);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::StopMoving()
{
if (m_moving)
{
m_moving = false;
m_pGUI->SetMovingCtrl(NULL);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::Move(float x, float y)
{
if (m_moving)
{
float moveX = x - m_prevX;
float moveY = y - m_prevY;
m_rect.top += moveY;
m_rect.bottom += moveY;
m_rect.left += moveX;
m_rect.right += moveX;
m_prevX = x;
m_prevY = y;
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::OnEvent(float x, float y, EMiniCtrlEvent event)
{
switch (event)
{
case eCtrlEvent_LButtonDown:
{
if (is_flag(eCtrl_Highlight | eCtrl_Moveable))
{
StartMoving(x, y);
}
}
break;
case eCtrlEvent_LButtonUp:
if (m_moving)
{
StopMoving();
}
break;
case eCtrlEvent_MouseOver:
break;
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniCtrl::CreateCloseButton()
{
if (m_pGUI)
{
m_pCloseButton = m_pGUI->CreateCtrl(this, 100, eCtrlType_Button, 0, Rect(0, 0, 100, 20), "X");
if (m_pCloseButton)
{
m_pCloseButton->SetConnectedCtrl(this);
float width = m_rect.Width();
//relative position of cross box
Rect closeRect(width - 20.f, 0.f, width, 20.f);
m_pCloseButton->SetRect(closeRect);
}
}
}
MINIGUI_END
-219
View File
@@ -1,219 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Interface to the Mini GUI subsystem
#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIGUI_H
#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIGUI_H
#pragma once
#include "ICryMiniGUI.h"
#include <Cry_Color.h>
#include <AzFramework/Input/Events/InputChannelEventListener.h>
#include <CryExtension/Impl/ClassWeaver.h>
MINIGUI_BEGIN
class CMiniMenu;
//////////////////////////////////////////////////////////////////////////
// Root window all other controls derive from
class CMiniCtrl
: public IMiniCtrl
{
public:
CMiniCtrl()
: m_nFlags(0)
, m_id(0)
, m_renderCallback(NULL)
, m_fTextSize(12.f)
, m_prevX(0.f)
, m_prevY(0.f)
, m_moving(false)
, m_requiresResize(false)
, m_pCloseButton(NULL)
, m_saveStateOn(false)
{};
//////////////////////////////////////////////////////////////////////////
// IMiniCtrl interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual void Reset();
virtual void SaveState();
virtual void RestoreState();
virtual void SetGUI(IMiniGUI* pGUI) { m_pGUI = pGUI; };
virtual IMiniGUI* GetGUI() const { return m_pGUI; };
virtual int GetId() const { return m_id; };
virtual void SetId(int id) { m_id = id; };
virtual const char* GetTitle() const { return m_title; };
virtual void SetTitle(const char* title) { m_title = title; };
virtual Rect GetRect() const { return m_rect; }
virtual void SetRect(const Rect& rc);
virtual void SetFlag(uint32 flag) { set_flag(flag); }
virtual void ClearFlag(uint32 flag) { clear_flag(flag); };
virtual bool CheckFlag(uint32 flag) const { return is_flag(flag); }
virtual void AddSubCtrl(IMiniCtrl* pCtrl);
virtual void RemoveSubCtrl(IMiniCtrl* pCtrl);
virtual void RemoveAllSubCtrl();
virtual int GetSubCtrlCount() const;
virtual IMiniCtrl* GetSubCtrl(int nIndex) const;
virtual IMiniCtrl* GetParent() const { return m_pParent; };
virtual IMiniCtrl* GetCtrlFromPoint(float x, float y);
virtual void SetVisible(bool state);
virtual void OnEvent(float x, float y, EMiniCtrlEvent);
virtual bool SetRenderCallback(RenderCallback callback) { m_renderCallback = callback; return true; };
// Not implemented in base control
virtual bool SetControlCVar([[maybe_unused]] const char* sCVarName, [[maybe_unused]] float fOffValue, [[maybe_unused]] float fOnValue) { assert(0); return false; };
virtual bool SetClickCallback([[maybe_unused]] ClickCallback callback, [[maybe_unused]] void* pCallbackData) { assert(0); return false; };
virtual bool SetConnectedCtrl([[maybe_unused]] IMiniCtrl* pConnectedCtrl) { assert(0); return false; };
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
virtual void AutoResize();
//////////////////////////////////////////////////////////////////////////
virtual void CreateCloseButton();
void DrawCtrl(CDrawContext& dc);
virtual void Move(float x, float y);
protected:
void set_flag(uint32 flag) { m_nFlags |= flag; }
void clear_flag(uint32 flag) { m_nFlags &= ~flag; };
bool is_flag(uint32 flag) const { return (m_nFlags & flag) == flag; }
//dynamic movement
void StartMoving(float x, float y);
void StopMoving();
protected:
int m_id;
IMiniGUI* m_pGUI;
uint32 m_nFlags;
CryFixedStringT<32> m_title;
Rect m_rect;
_smart_ptr<IMiniCtrl> m_pParent;
std::vector<IMiniCtrlPtr> m_subCtrls;
RenderCallback m_renderCallback;
float m_fTextSize;
//optional close 'X' button on controls, ref counted by m_subCtrls
IMiniCtrl* m_pCloseButton;
//dynamic movement
float m_prevX;
float m_prevY;
bool m_moving;
bool m_requiresResize;
bool m_saveStateOn;
};
//////////////////////////////////////////////////////////////////////////
class CMiniGUI
: public IMiniGUI
, public AzFramework::InputChannelEventListener
{
public:
CRYINTERFACE_BEGIN()
CRYINTERFACE_ADD(IMiniGUI)
CRYINTERFACE_END()
CRYGENERATE_SINGLETONCLASS(CMiniGUI, "MiniGUI", 0x1a049b879a4e4b58, 0xac14026e17e6255e)
public:
void InitMetrics();
void ProcessInput();
//////////////////////////////////////////////////////////////////////////
// IMiniGUI interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual void Init();
virtual void Done();
virtual void Draw();
virtual void Reset();
virtual void SaveState();
virtual void RestoreState();
virtual void SetEnabled(bool status);
virtual void SetInFocus(bool status);
virtual bool InFocus() {return m_inFocus; }
virtual void SetEventListener(IMiniGUIEventListener* pListener);
virtual SMetrics& Metrics();
virtual void OnCommand(SCommand& cmd);
virtual void RemoveAllCtrl();
virtual IMiniCtrl* CreateCtrl(IMiniCtrl* pParentCtrl, int nCtrlID, EMiniCtrlType type, int nCtrlFlags, const Rect& rc, const char* title);
virtual IMiniCtrl* GetCtrlFromPoint(float x, float y) const;
void SetHighlight(IMiniCtrl* pCtrl, bool bEnable, float x, float y);
void SetFocus(IMiniCtrl* pCtrl, bool bEnable);
// AzFramework::InputChannelEventListener
bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override;
AZ::s32 GetPriority() const override { return AzFramework::InputChannelEventListener::GetPriorityUI(); }
virtual void SetMovingCtrl(IMiniCtrl* pCtrl)
{
m_pMovingCtrl = pCtrl;
}
protected:
void OnMouseInputEvent(const AzFramework::InputChannel& inputChannel);
//DPad menu navigation
void UpdateDPadMenu(const AzFramework::InputChannel& inputChannel);
void SetDPadMenu(IMiniCtrl* pMenu);
void CloseDPadMenu();
protected:
bool m_enabled;
bool m_inFocus;
SMetrics m_metrics;
_smart_ptr<CMiniCtrl> m_pRootCtrl;
_smart_ptr<IMiniCtrl> m_highlightedCtrl;
_smart_ptr<IMiniCtrl> m_focusCtrl;
IMiniGUIEventListener* m_pEventListener;
CMiniMenu* m_pDPadMenu;
IMiniCtrl* m_pMovingCtrl;
std::vector<minigui::IMiniCtrl*> m_rootMenus;
};
MINIGUI_END
#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIGUI_H
@@ -1,174 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#include "CrySystem_precompiled.h"
#include "MiniInfoBox.h"
#include "DrawContext.h"
#include <ISystem.h>
MINIGUI_BEGIN
CMiniInfoBox::CMiniInfoBox()
: m_fTextIndent(4)
{
}
//////////////////////////////////////////////////////////////////////////
void CMiniInfoBox::SaveState()
{
if (CheckFlag(eCtrl_Hidden))
{
m_saveStateOn = false;
}
else
{
m_saveStateOn = true;
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniInfoBox::Reset()
{
SetFlag(eCtrl_Hidden);
}
//////////////////////////////////////////////////////////////////////////
void CMiniInfoBox::RestoreState()
{
if (m_saveStateOn)
{
ClearFlag(eCtrl_Hidden);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniInfoBox::OnPaint(CDrawContext& dc)
{
if (m_requiresResize)
{
AutoResize();
}
ColorB borderCol = dc.Metrics().clrFrameBorder;
ColorB backgroundCol = dc.Metrics().clrBackground;
if (!m_pGUI->InFocus())
{
borderCol = dc.Metrics().clrFrameBorderOutOfFocus;
backgroundCol.a = dc.Metrics().outOfFocusAlpha;
}
else if (m_moving)
{
borderCol = dc.Metrics().clrFrameBorderHighlight;
}
dc.DrawFrame(m_rect, borderCol, backgroundCol);
dc.SetColor(dc.Metrics().clrTitle);
dc.DrawString(m_rect.left + 4, m_rect.top, dc.Metrics().fTitleSize, eTextAlign_Left, GetTitle());
float fTextSize = m_fTextSize;
if (fTextSize == 0)
{
fTextSize = dc.Metrics().fTextSize;
}
float x = m_fTextIndent + m_rect.left + 8;
float y = m_rect.top + fTextSize + fTextSize;
// Draw entries.
for (int i = 0, num = (int)m_entries.size(); i < num; i++)
{
SInfoEntry& info = m_entries[i];
dc.SetColor(info.color);
dc.DrawString(x, y, info.textSize, eTextAlign_Left, info.text);
y += info.textSize * 0.8f;
if (y + info.textSize > m_rect.bottom)
{
break;
}
}
if (m_renderCallback)
{
m_renderCallback(m_rect.left, m_rect.top);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniInfoBox::OnEvent(float x, float y, EMiniCtrlEvent event)
{
CMiniCtrl::OnEvent(x, y, event);
}
void CMiniInfoBox::AddEntry(const char* str, ColorB col, float textSize)
{
SInfoEntry info;
info.color = col;
info.textSize = textSize;
cry_strcpy(info.text, str);
m_entries.push_back(info);
if (CheckFlag(eCtrl_AutoResize))
{
//set dirty flag instead of resizing for every elem
m_requiresResize = true; //AutoResize();
}
}
void CMiniInfoBox::ClearEntries()
{
m_entries.clear();
m_requiresResize = true;
}
//////////////////////////////////////////////////////////////////////////
void CMiniInfoBox::AutoResize()
{
float width = 0.f;
float height = 32.f;
//must be at least the size of title and cross box
width = m_fTextIndent + ((float)m_title.size() * 14.f) + 30.f;
for (int i = 0, num = (int)m_entries.size(); i < num; i++)
{
SInfoEntry& info = m_entries[i];
uint32 strLength = strlen(info.text);
float strSize = info.textSize * strLength;
width = max(strSize, width);
height += info.textSize * 0.8f;
}
//scale width, could do with kerning info
width *= 0.6f;
Rect newRect = m_rect;
newRect.right = newRect.left + width;
newRect.bottom = newRect.top + height;
SetRect(newRect);
m_requiresResize = false;
}
MINIGUI_END
@@ -1,79 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIINFOBOX_H
#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIINFOBOX_H
#pragma once
#include "MiniGUI.h"
MINIGUI_BEGIN
//////////////////////////////////////////////////////////////////////////
// Root window all other controls derive from
class CMiniInfoBox
: public CMiniCtrl
, public IMiniInfoBox
{
public:
CMiniInfoBox();
//////////////////////////////////////////////////////////////////////////
// CMiniCtrl interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual EMiniCtrlType GetType() const { return eCtrlType_InfoBox; }
virtual void OnPaint(CDrawContext& dc);
virtual void OnEvent(float x, float y, EMiniCtrlEvent event);
virtual void Reset();
virtual void SaveState();
virtual void RestoreState();
virtual void AutoResize();
//////////////////////////////////////////////////////////////////////////
virtual void SetTextIndent(float x) { m_fTextIndent = x; }
virtual void SetTextSize(float sz) { m_fTextSize = sz; }
virtual void ClearEntries();
virtual void AddEntry(const char* str, ColorB col, float textSize);
//////////////////////////////////////////////////////////////////////////
// IMiniTable interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual bool IsHidden() { return CheckFlag(eCtrl_Hidden); }
virtual void Hide(bool stat) { SetVisible(!stat); }
public:
//////////////////////////////////////////////////////////////////////////
static const int MAX_TEXT_LENGTH = 64;
struct SInfoEntry
{
char text[MAX_TEXT_LENGTH];
ColorB color;
float textSize;
};
//////////////////////////////////////////////////////////////////////////
protected:
std::vector<SInfoEntry> m_entries;
float m_fTextIndent;
};
MINIGUI_END
#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIINFOBOX_H
@@ -1,364 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#include "CrySystem_precompiled.h"
#include "MiniMenu.h"
#include "DrawContext.h"
MINIGUI_BEGIN
CMiniMenu::CMiniMenu()
{
m_bVisible = false;
m_bSubMenu = false;
m_menuWidth = 0.f;
m_selectionIndex = -1;
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::OnPaint(CDrawContext& dc)
{
CMiniButton::OnPaint(dc);
if (m_bSubMenu)
{
// Draw checked mark.
float x1 = m_rect.right - 12;
float y1 = m_rect.top + 3;
float x2 = m_rect.right - 3;
float y2 = (m_rect.bottom + m_rect.top) / 2;
float x3 = m_rect.right - 12;
float y3 = m_rect.bottom - 3;
dc.SetColor(ColorB(0, 0, 0, 255));
dc.DrawLine(x1, y1, x2, y2, 2.f);
dc.DrawLine(x2, y2, x3, y3, 2.f);
x1 -= 1;
x2 -= 1;
x3 -= 1;
y1 -= 1;
y2 -= 1;
y3 -= 1;
dc.SetColor(ColorB(255, 255, 255, 255));
dc.DrawLine(x1, y1, x2, y2, 2.f);
dc.DrawLine(x2, y2, x3, y3, 2.f);
}
//dc.DrawFrame( m_rect,dc.Metrics().clrFrameBorder,dc.Metrics().clrBackground );
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::SetRect(const Rect& rc)
{
Rect newrc = rc;
newrc.bottom = newrc.top + m_pGUI->Metrics().fTitleSize + 2;
CMiniCtrl::SetRect(newrc);
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::OnEvent(float x, float y, EMiniCtrlEvent event)
{
switch (event)
{
case eCtrlEvent_LButtonDown:
{
if (m_bVisible)
{
Close();
}
else
{
Open();
}
}
break;
case eCtrlEvent_MouseOff:
{
bool closeMenu = true;
IMiniCtrl* pCtrl = m_pGUI->GetCtrlFromPoint(x, y);
//check if the cursor is still in one of the menu's children
if (pCtrl)
{
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
if (pCtrl == GetSubCtrl(i))
{
closeMenu = false;
break;
}
}
}
if (closeMenu)
{
Close();
if (m_pParent)
{
m_pParent->OnEvent(x, y, eCtrlEvent_MouseOff);
}
}
}
break;
}
}
CMiniMenu* CMiniMenu::UpdateSelection(EMiniCtrlEvent event)
{
CMiniMenu* pNewMenu = this;
IMiniCtrl* pCurrentSelection = NULL;
if (m_selectionIndex != -1)
{
pCurrentSelection = m_subCtrls[m_selectionIndex];
}
switch (event)
{
case eCtrlEvent_DPadLeft: //move to parent
if (!pCurrentSelection)
{
//move to previous root menu
pNewMenu = NULL;
}
else if (m_bSubMenu)
{
Close();
pNewMenu = (CMiniMenu*)m_pParent.get();
//pNewMenu->SetFlag(eCtrl_Highlight);
}
break;
case eCtrlEvent_DPadRight: //move to child
if (!pCurrentSelection)
{
//move to next root menu
pNewMenu = NULL;
}
else if (pCurrentSelection->GetType() == eCtrlType_Menu)
{
pNewMenu = (CMiniMenu*)pCurrentSelection;
pNewMenu->Open();
pNewMenu->ClearFlag(eCtrl_Highlight);
}
break;
case eCtrlEvent_DPadUp: //move up list
if (m_bSubMenu)
{
if (m_selectionIndex > 0)
{
m_selectionIndex--;
}
}
else
{
if (m_selectionIndex >= 0)
{
m_selectionIndex--;
if (m_selectionIndex == -1)
{
SetFlag(eCtrl_Highlight);
}
}
}
break;
case eCtrlEvent_DPadDown: //move down the list
if (m_selectionIndex < (int)(m_subCtrls.size() - 1))
{
if (m_selectionIndex == -1)
{
ClearFlag(eCtrl_Highlight);
}
m_selectionIndex++;
}
break;
case eCtrlEvent_LButtonDown: //pass on button press
{
if (pCurrentSelection)
{
if (pCurrentSelection->GetType() == eCtrlType_Menu)
{
pNewMenu = (CMiniMenu*)pCurrentSelection;
}
pCurrentSelection->OnEvent(0, 0, eCtrlEvent_LButtonDown);
}
else
{
OnEvent(0, 0, eCtrlEvent_LButtonDown);
}
}
break;
}
if (pCurrentSelection)
{
pCurrentSelection->ClearFlag(eCtrl_Highlight);
}
if (m_selectionIndex >= 0)
{
m_subCtrls[m_selectionIndex]->SetFlag(eCtrl_Highlight);
}
return pNewMenu;
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::Open()
{
m_bVisible = true;
Rect rc(0, 0, m_menuWidth, 1);
//render sub menu to the right
if (m_bSubMenu)
{
CMiniMenu* pParent = static_cast<CMiniMenu*>(m_pParent.get());
rc.left = pParent->m_menuWidth; //rcParent.right;
rc.right = rc.left + m_menuWidth;
}
else
{
Rect rcThis = GetRect();
rc.top = rcThis.Height();
}
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->ClearFlag(eCtrl_Hidden);
float h = pSubCtrl->GetRect().Height();
Rect rcCtrl = rc;
rcCtrl.top = rc.top;
rcCtrl.bottom = rcCtrl.top + h;
pSubCtrl->SetRect(rcCtrl);
rc.top += h;
}
//highlight first item when opened
if (m_bSubMenu)
{
m_selectionIndex = 0;
m_subCtrls[m_selectionIndex]->SetFlag(eCtrl_Highlight);
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::Close()
{
m_bVisible = false;
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->SetFlag(eCtrl_Hidden);
}
if (m_selectionIndex != -1)
{
m_subCtrls[m_selectionIndex]->ClearFlag(eCtrl_Highlight);
}
m_selectionIndex = -1;
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::Reset()
{
m_bVisible = false;
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->Reset();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::SaveState()
{
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->SaveState();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::RestoreState()
{
for (int i = 0, num = GetSubCtrlCount(); i < num; i++)
{
IMiniCtrl* pSubCtrl = GetSubCtrl(i);
pSubCtrl->RestoreState();
}
}
//////////////////////////////////////////////////////////////////////////
void CMiniMenu::AddSubCtrl(IMiniCtrl* pCtrl)
{
assert(pCtrl);
pCtrl->SetFlag(eCtrl_Hidden);
pCtrl->SetFlag(eCtrl_NoBorder);
bool bSubMenu = false;
if (pCtrl->GetType() == eCtrlType_Menu)
{
CMiniMenu* pSubMenu = static_cast<CMiniMenu*>(pCtrl);
pSubMenu->m_bSubMenu = true;
bSubMenu = true;
}
if (!m_bSubMenu)
{
//menu is at least the size of title bar
m_menuWidth = max(m_menuWidth, strlen(GetTitle()) * 8.5f);
}
const char* title = pCtrl->GetTitle();
if (title)
{
uint32 titleLen = strlen(title);
float width = (float)titleLen * 8.5f;
if (bSubMenu)
{
//increase width for submenu arrow
width += 10.f;
}
m_menuWidth = max(m_menuWidth, width);
}
// Call parent
CMiniButton::AddSubCtrl(pCtrl);
}
MINIGUI_END
@@ -1,66 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIMENU_H
#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIMENU_H
#pragma once
#include "MiniGUI.h"
#include "MiniButton.h"
MINIGUI_BEGIN
//////////////////////////////////////////////////////////////////////////
// Root window all other controls derive from
class CMiniMenu
: public CMiniButton
{
public:
CMiniMenu();
//////////////////////////////////////////////////////////////////////////
// CMiniCtrl interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual EMiniCtrlType GetType() const { return eCtrlType_Menu; }
virtual void SetRect(const Rect& rc);
virtual void OnPaint(CDrawContext& dc);
virtual void OnEvent(float x, float y, EMiniCtrlEvent event);
virtual void AddSubCtrl(IMiniCtrl* pCtrl);
virtual void Reset();
virtual void SaveState();
virtual void RestoreState();
//////////////////////////////////////////////////////////////////////////
//digital selection funcs
CMiniMenu* UpdateSelection(EMiniCtrlEvent event);
void Open();
void Close();
protected:
protected:
bool m_bVisible;
bool m_bSubMenu;
float m_menuWidth;
int m_selectionIndex;
};
MINIGUI_END
#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIMENU_H
@@ -1,336 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Table implementation in the MiniGUI
#include "CrySystem_precompiled.h"
#include "MiniTable.h"
#include "DrawContext.h"
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
MINIGUI_BEGIN
CMiniTable::CMiniTable()
{
m_fTextSize = 15.f;
m_pageNum = 0;
m_pageSize = 35;
}
void CMiniTable::OnPaint(CDrawContext& dc)
{
if (m_requiresResize)
{
AutoResize();
}
ColorB borderCol;
ColorB backgroundCol = dc.Metrics().clrBackground;
if (m_pGUI->InFocus())
{
if (m_moving)
{
borderCol = dc.Metrics().clrFrameBorderHighlight;
}
else
{
borderCol = dc.Metrics().clrFrameBorder;
}
}
else
{
borderCol = dc.Metrics().clrFrameBorderOutOfFocus;
backgroundCol.a = dc.Metrics().outOfFocusAlpha;
}
dc.DrawFrame(m_rect, borderCol, backgroundCol);
float fTextSize = m_fTextSize;
if (fTextSize == 0)
{
fTextSize = dc.Metrics().fTextSize;
}
float indent = 4.f;
float x = m_rect.left + indent;
float y = m_rect.top + indent;
const int nColumns = m_columns.size();
int numEntries = nColumns > 0 ? m_columns[0].cells.size() : 0;
int startIdx = 0;
int endIdx = numEntries;
//Page number
if (nColumns)
{
int numPages = numEntries / m_pageSize;
if (numPages)
{
startIdx = m_pageNum * m_pageSize;
endIdx = min(startIdx + m_pageSize, numEntries);
dc.SetColor(ColorB(255, 255, 255, 255));
//print page details (adjust for zero indexed)
dc.DrawString(x, y, fTextSize, eTextAlign_Left, "Page %d of %d (Page Up / Page Down)", m_pageNum + 1, numPages + 1);
y += fTextSize;
}
}
float topOfTable = y;
for (int i = 0; i < nColumns; i++)
{
SColumn& column = m_columns[i];
y = topOfTable;
dc.SetColor(ColorB(32, 32, 255, 255));
dc.DrawString(x, y, fTextSize, eTextAlign_Left, column.name);
y += fTextSize + indent;
ColorB currentCol(255, 255, 255, 255);
dc.SetColor(currentCol);
const int nCells = column.cells.size();
for (int j = startIdx; j < endIdx && j < nCells; j++)
{
if (column.cells[j].col != currentCol)
{
dc.SetColor(column.cells[j].col);
currentCol = column.cells[j].col;
}
dc.DrawString(x, y, fTextSize, eTextAlign_Left, column.cells[j].text);
y += fTextSize;
}
x += column.width;
}
}
void CMiniTable::OnEvent(float x, float y, EMiniCtrlEvent event)
{
//movement
CMiniCtrl::OnEvent(x, y, event);
}
void CMiniTable::AutoResize()
{
//must be at least the size of cross box
float tableWidth = 30.f;
float tableHeight = 0.f;
const float widthScale = 0.6f;
const int nColumns = m_columns.size();
int startIdx = 0;
int endIdx = 0;
bool bPageHeader = false;
//Update Page index
if (nColumns)
{
int numEntries = m_columns[0].cells.size();
//page index is now invalid, cap at max
if ((m_pageNum * m_pageSize) > numEntries)
{
m_pageNum = (numEntries / m_pageSize);
}
startIdx = m_pageNum * m_pageSize;
endIdx = min(startIdx + m_pageSize, numEntries);
if (numEntries > m_pageSize)
{
bPageHeader = true;
}
}
for (int i = 0; i < nColumns; i++)
{
SColumn& column = m_columns[i];
float width = strlen(column.name) * m_fTextSize;
int nCells = column.cells.size();
for (int j = startIdx; j < endIdx && j < nCells; j++)
{
width = max(width, strlen(column.cells[j].text) * m_fTextSize);
}
width *= widthScale;
column.width = width;
tableWidth += width;
tableHeight = max(tableHeight, min(endIdx - startIdx, m_pageSize) * m_fTextSize);
}
tableHeight += m_fTextSize * 2.f;
//Page index
if (bPageHeader)
{
tableHeight += m_fTextSize;
}
Rect newRect = m_rect;
newRect.right = newRect.left + tableWidth;
newRect.bottom = newRect.top + tableHeight;
SetRect(newRect);
m_requiresResize = false;
}
void CMiniTable::Reset()
{
SetFlag(eCtrl_Hidden);
m_pageNum = 0;
}
void CMiniTable::SaveState()
{
if (CheckFlag(eCtrl_Hidden))
{
m_saveStateOn = false;
}
else
{
m_saveStateOn = true;
}
}
void CMiniTable::RestoreState()
{
if (m_saveStateOn)
{
ClearFlag(eCtrl_Hidden);
}
}
int CMiniTable::AddColumn(const char* name)
{
assert(name);
SColumn col;
cry_strcpy(col.name, name);
col.width = strlen(col.name) * 8.f;
m_columns.push_back(col);
m_requiresResize = true;
return m_columns.size() - 1;
}
void CMiniTable::RemoveColumns()
{
m_columns.clear();
}
int CMiniTable::AddData(int columnIndex, ColorB col, const char* format, ...)
{
assert(columnIndex < (int)m_columns.size());
SCell cell;
va_list args;
va_start(args, format);
int written = vsnprintf_s(cell.text, MAX_TEXT_LENGTH, MAX_TEXT_LENGTH - 1, format, args);
va_end(args);
if (written == -1)
{
cell.text[MAX_TEXT_LENGTH - 1] = '\0';
}
cell.col = col;
m_columns[columnIndex].cells.push_back(cell);
m_requiresResize = true;
return m_columns[columnIndex].cells.size() - 1;
}
void CMiniTable::ClearTable()
{
const int nColumns = m_columns.size();
for (int i = 0; i < nColumns; i++)
{
m_columns[i].cells.clear();
}
}
void CMiniTable::SetVisible(bool state)
{
if (state)
{
clear_flag(eCtrl_Hidden);
AzFramework::InputChannelEventListener::Connect();
}
else
{
set_flag(eCtrl_Hidden);
AzFramework::InputChannelEventListener::Disconnect();
}
if (m_pCloseButton)
{
m_pCloseButton->SetVisible(state);
}
}
void CMiniTable::Hide(bool stat)
{
SetVisible(!stat);
}
bool CMiniTable::OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel)
{
if (!IsHidden() && inputChannel.IsStateBegan())
{
const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId();
if (channelId == AzFramework::InputDeviceKeyboard::Key::NavigationPageUp)
{
m_pageNum++;
m_requiresResize = true;
}
else if (channelId == AzFramework::InputDeviceKeyboard::Key::NavigationPageDown)
{
if (m_pageNum > 0)
{
m_pageNum--;
m_requiresResize = true;
}
}
}
return false;
}
MINIGUI_END
@@ -1,96 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Table implementation in the MiniGUI
#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINITABLE_H
#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINITABLE_H
#pragma once
#include "MiniGUI.h"
MINIGUI_BEGIN
class CMiniTable
: public CMiniCtrl
, public IMiniTable
, public AzFramework::InputChannelEventListener
{
public:
CMiniTable();
//////////////////////////////////////////////////////////////////////////
// CMiniCtrl interface implementation.
//////////////////////////////////////////////////////////////////////////
virtual EMiniCtrlType GetType() const { return eCtrlType_Table; }
virtual void OnPaint(CDrawContext& dc);
virtual void OnEvent(float x, float y, EMiniCtrlEvent event);
virtual void Reset();
virtual void SaveState();
virtual void RestoreState();
virtual void AutoResize();
virtual void SetVisible(bool state);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// IMiniTable interface implementation.
//////////////////////////////////////////////////////////////////////////
//Add a new column to the table, return column index
virtual int AddColumn(const char* name);
//Remove all columns an associated data
virtual void RemoveColumns();
//Add data to specified column (add onto the end), return row index
virtual int AddData(int columnIndex, ColorB col, const char* format, ...);
//Clear all data from table
virtual void ClearTable();
virtual bool IsHidden() { return CheckFlag(eCtrl_Hidden); }
virtual void Hide(bool stat);
// AzFramework::InputChannelEventListener
bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override;
AZ::s32 GetPriority() const override { return AzFramework::InputChannelEventListener::GetPriorityUI(); }
static const int MAX_TEXT_LENGTH = 64;
protected:
struct SCell
{
char text[MAX_TEXT_LENGTH];
ColorB col;
};
struct SColumn
{
char name[MAX_TEXT_LENGTH];
float width;
std::vector<SCell> cells;
};
std::vector<SColumn> m_columns;
int m_pageSize;
int m_pageNum;
};
MINIGUI_END
#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINITABLE_H
@@ -1,290 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Manages overload values (eg CPU,GPU etc)
// 1.0="everything is ok" 0.0="very bad frame rate"
// various systems can use this information and control what is currently in the scene
#include "CrySystem_precompiled.h"
#include "OverloadSceneManager.h"
//--------------------------------------------------------------------------------------------------
// Name: COverloadSceneManager
// Desc: Constructor
//--------------------------------------------------------------------------------------------------
COverloadSceneManager::COverloadSceneManager()
{
InitialiseCVars();
m_currentFrameStat = 0;
ResetDefaultValues();
}//-------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Desc: static console callback functions
//--------------------------------------------------------------------------------------------------
static void OnChange_osm_enabled(ICVar* pCVar)
{
if (pCVar->GetIVal() == 0)
{
gEnv->pOverloadSceneManager->Reset();
//gEnv->pRenderer->EnablePipelineProfiler(false); // would need push/pop since something else might have enabled it
}
else if (pCVar->GetIVal() == 1)
{
gEnv->pRenderer->EnablePipelineProfiler(true);
}
}
static void cmd_setFBScale(IConsoleCmdArgs* pParams)
{
int argCount = pParams->GetArgCount();
Vec2 newScale = Vec2(0.0f, 0.0f);
gEnv->pRenderer->EF_Query(EFQ_GetViewportDownscaleFactor, newScale);
if (argCount > 1)
{
newScale.x = clamp_tpl((float)atof(pParams->GetArg(1)), 0.0f, 1.0f);
if (argCount > 2)
{
newScale.y = clamp_tpl((float)atof(pParams->GetArg(2)), 0.0f, 1.0f);
}
else
{
newScale.y = newScale.x;
}
newScale = gEnv->pRenderer->SetViewportDownscale(newScale.x, newScale.y);
}
int nWidth = gEnv->pRenderer->GetWidth();
int nHeight = gEnv->pRenderer->GetHeight();
gEnv->pLog->LogWithType(ILog::eInputResponse, "Current Viewport Resolution: %dx%d",
int(nWidth * newScale.x), int(nHeight * newScale.y));
}
//--------------------------------------------------------------------------------------------------
// Name: InitialiseCVars
// Desc: Initialises CVars
//--------------------------------------------------------------------------------------------------
void COverloadSceneManager::InitialiseCVars()
{
// depending on final requirements, these could be made into const cvars
REGISTER_CVAR_CB(osm_enabled, 0, VF_NULL, "Enables/disables overload scene manager", &OnChange_osm_enabled);
REGISTER_CVAR(osm_historyLength, 5, VF_NULL, "Overload scene manager number of frames to record stats for");
REGISTER_CVAR(osm_targetFPS, 28.0f, VF_NULL, "Overload scene manager target frame rate");
REGISTER_CVAR(osm_targetFPSTolerance, 1.0f, VF_NULL, "The overload scene manager will make adjustments if fps is outside targetFPS +/- this value");
REGISTER_CVAR(osm_fbScaleDeltaDown, 5.0f, VF_NULL, "The speed multiplier for the overload scene manager frame buffer scaling down");
REGISTER_CVAR(osm_fbScaleDeltaUp, 1.0f, VF_NULL, "The speed multiplier for the overload scene manager frame buffer scaling up");
REGISTER_CVAR(osm_fbMinScale, 0.66f, VF_NULL, "The minimum scale factor the overload scene manager will drop to");
REGISTER_COMMAND("osm_setFBScale", cmd_setFBScale, VF_NULL, "Sets the framebuffer scale to either a single scale on both X and Y, or independent scales.\n"
"NOTE: Will be overridden immediately if Overload scene manager is still enabled - see osm_enabled");
}//-------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Name: Reset
// Desc: Resets overload scene manager outputs to sensible defaults
//--------------------------------------------------------------------------------------------------
void COverloadSceneManager::Reset()
{
ResetDefaultValues();
gEnv->pRenderer->SetViewportDownscale(m_fbScale, m_fbScale);
}
void COverloadSceneManager::ResetDefaultValues()
{
m_fbScale = 1.0f;
m_scaleState = FBSCALE_AUTO;
m_lerpOverride.m_start = m_lerpOverride.m_length = 1.0f;
m_lerpOverride.m_reversed = false;
m_lerpAuto.m_start = m_lerpAuto.m_length = 1.0f;
m_lerpAuto.m_reversed = true;
m_fbAutoScale = m_fbOverrideDestScale = m_fbOverrideCurScale = 1.0f;
// completely reset history
for (int i = 0; i < osm_historyLength; i++)
{
SScenePerformanceStats& stats = m_sceneStats[i];
stats.frameRate = stats.gpuFrameRate = osm_targetFPS;
}
m_smoothedSceneStats.frameRate = m_smoothedSceneStats.gpuFrameRate = osm_targetFPS;
}
//-------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Name: Update
// Desc: Updates overload scene manager
//--------------------------------------------------------------------------------------------------
void COverloadSceneManager::Update()
{
if (!osm_enabled)
{
return;
}
UpdateStats();
ResizeFB();
}//-------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Name: OverrideScale and ResetScale
// Desc: sets up appropriate members for lerping between automatic framebuffer scale and manual
// overrides.
//--------------------------------------------------------------------------------------------------
void COverloadSceneManager::OverrideScale(float frameScale, float dt)
{
dt = max(dt, 1.0f / 1000.0f);
float curTime = gEnv->pTimer->GetCurrTime();
frameScale = clamp_tpl(frameScale, osm_fbMinScale, 1.0f);
m_fbOverrideDestScale = frameScale;
if (m_scaleState == FBSCALE_AUTO)
{
// remove any override lerp - we want to lerp straight from auto to the given value.
m_lerpOverride.m_start = m_lerpOverride.m_length = 1.0f;
m_lerpOverride.m_reversed = false;
m_fbOverrideCurScale = frameScale;
m_lerpAuto.m_start = curTime;
m_lerpAuto.m_length = dt;
m_lerpAuto.m_reversed = false;
}
else if (m_scaleState == FBSCALE_OVERRIDE)
{
m_lerpOverride.m_start = curTime;
m_lerpOverride.m_length = dt;
m_lerpOverride.m_reversed = false;
m_fbOverrideCurScale = m_fbScale;
}
m_scaleState = FBSCALE_OVERRIDE;
}
void COverloadSceneManager::ResetScale(float dt)
{
dt = max(dt, 1.0f / 1000.0f);
float curTime = gEnv->pTimer->GetCurrTime();
// remove any override lerp - we want to lerp straight to auto
m_lerpOverride.m_start = m_lerpOverride.m_length = 1.0f;
m_lerpOverride.m_reversed = false;
m_fbOverrideCurScale = m_fbOverrideDestScale = m_fbScale;
m_lerpAuto.m_start = curTime;
m_lerpAuto.m_length = dt;
m_lerpAuto.m_reversed = true; // want to lerp back to auto mode
m_scaleState = FBSCALE_AUTO;
}//-------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Name: UpdateStats
// Desc: Updates overload stats
//--------------------------------------------------------------------------------------------------
void COverloadSceneManager::UpdateStats()
{
m_currentFrameStat++;
if (m_currentFrameStat >= osm_historyLength)
{
m_currentFrameStat = 0;
}
SScenePerformanceStats& currentStats = m_sceneStats[m_currentFrameStat];
const float frameLength = gEnv->pTimer->GetRealFrameTime() * 1000.0f;
const float gpuFrameLength = gEnv->pRenderer->GetGPUFrameTime() * 1000.0f;
currentStats.frameRate = frameLength > 0.0f ? 1000.0f / frameLength : 0.0f;
currentStats.gpuFrameRate = gpuFrameLength > 0.0f ? 1000.0f / gpuFrameLength : 0.0f;
CalculateSmoothedStats();
}//-------------------------------------------------------------------------------------------------
void COverloadSceneManager::CalculateSmoothedStats()
{
m_smoothedSceneStats.Reset();
for (int i = 0; i < osm_historyLength; i++)
{
SScenePerformanceStats& stats = m_sceneStats[i];
m_smoothedSceneStats.frameRate += stats.frameRate;
m_smoothedSceneStats.gpuFrameRate += stats.gpuFrameRate;
}
m_smoothedSceneStats.frameRate /= osm_historyLength;
m_smoothedSceneStats.gpuFrameRate /= osm_historyLength;
}
float COverloadSceneManager::CalcFBScale()
{
float curTime = gEnv->pTimer->GetCurrTime();
// first calculate delta of the override lerp
float delta = clamp_tpl((curTime - m_lerpOverride.m_start) / m_lerpOverride.m_length, 0.0f, 1.0f);
if (m_lerpOverride.m_reversed)
{
delta = 1.0f - delta;
}
// get the current target override
float curOverrideScale = LERP(m_fbOverrideCurScale, m_fbOverrideDestScale, delta);
// calculate the delta from (or two) automatic scaling
delta = clamp_tpl((curTime - m_lerpAuto.m_start) / m_lerpAuto.m_length, 0.0f, 1.0f);
if (m_lerpAuto.m_reversed)
{
delta = 1.0f - delta;
}
// final lerp from automatic to current override
return LERP(m_fbAutoScale, curOverrideScale, delta);
}
void COverloadSceneManager::ResizeFB()
{
// don't do anything for invalid framerates
if (m_smoothedSceneStats.gpuFrameRate < 5.0f || m_smoothedSceneStats.gpuFrameRate > 100.0f)
{
return;
}
float fpsDiff = fabsf(m_smoothedSceneStats.gpuFrameRate - osm_targetFPS);
if (m_smoothedSceneStats.gpuFrameRate < osm_targetFPS - osm_targetFPSTolerance)
{
m_fbAutoScale -= osm_fbScaleDeltaDown / 1000.0f * fpsDiff;
}
else if (m_smoothedSceneStats.gpuFrameRate > osm_targetFPS + osm_targetFPSTolerance)
{
m_fbAutoScale += osm_fbScaleDeltaUp / 1000.0f * fpsDiff;
}
m_fbAutoScale = clamp_tpl(m_fbAutoScale, osm_fbMinScale, 1.0f);
m_fbScale = clamp_tpl(CalcFBScale(), osm_fbMinScale, 1.0f);
gEnv->pRenderer->SetViewportDownscale(m_fbScale, m_fbScale);
}
@@ -1,127 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_OVERLOADSCENEMANAGER_OVERLOADSCENEMANAGER_H
#define CRYINCLUDE_CRYSYSTEM_OVERLOADSCENEMANAGER_OVERLOADSCENEMANAGER_H
#pragma once
// Includes
#include "IOverloadSceneManager.h"
#define SCENE_PERFORMANCE_FRAME_HISTORY 64
//==================================================================================================
// Name: SOverloadSceneStats
// Desc: Overload scene stats
// Author: James Chilvers
//==================================================================================================
struct SScenePerformanceStats
{
SScenePerformanceStats()
{
Reset();
}
void Reset()
{
frameRate = 0.0f;
gpuFrameRate = 0.0f;
}
float frameRate;
float gpuFrameRate;
};//------------------------------------------------------------------------------------------------
//==================================================================================================
// Name: COverloadSceneManager
// Desc: Manages overload values (eg CPU,GPU etc)
// 1.0="everything is ok" 0.0="very bad frame rate"
// various systems can use this information and control what is currently in the scene
// Author: James Chilvers
//==================================================================================================
class COverloadSceneManager
: public IOverloadSceneManager
{
friend class COverloadDG;
public:
COverloadSceneManager();
~COverloadSceneManager() override = default;
virtual void Reset();
virtual void Update();
virtual void OverrideScale(float frameScale, float dt);
virtual void ResetScale(float dt);
private:
void ResetDefaultValues();
void InitialiseCVars();
void UpdateStats();
void CalculateSmoothedStats();
void ResizeFB();
float CalcFBScale(); // performs all lerping and returns final framebuffer scale
// cvars
int osm_enabled;
int osm_historyLength;
float osm_targetFPS;
float osm_targetFPSTolerance;
float osm_fbScaleDeltaUp, osm_fbScaleDeltaDown;
float osm_fbMinScale;
SScenePerformanceStats m_smoothedSceneStats;
SScenePerformanceStats m_sceneStats[SCENE_PERFORMANCE_FRAME_HISTORY];
int m_currentFrameStat;
// current output scale, set to the renderer
float m_fbScale;
// Lerping behaviour is to lerp from autoscale to (lerp between cur/dest override)
//
// m_fbOverrideCurScale
// |
// |
// m_fbAutoScale ---- m_lerpAuto ---> m_lerpOverride
// |
// v
// m_fbOverrideDestScale
// framebuffer scales to support lerping & overriding of calculated scale
float m_fbAutoScale, m_fbOverrideCurScale, m_fbOverrideDestScale;
struct ScaleLerp
{
bool m_reversed; // Normally lerp is 0 -> 1. If reversed it's 1 -> 0
float m_start; // time in seconds
float m_length; // time in seconds
};
// lerpAuto is the lerp between auto scale and whatever override is.
// lerpOverride is the lerp between m_fbOverrideCurScale and m_fbOverrideDestScale
ScaleLerp m_lerpAuto, m_lerpOverride;
// State is the current destination of any lerps.
enum ScaleState
{
FBSCALE_AUTO,
FBSCALE_OVERRIDE,
} m_scaleState;
};//------------------------------------------------------------------------------------------------
#endif // CRYINCLUDE_CRYSYSTEM_OVERLOADSCENEMANAGER_OVERLOADSCENEMANAGER_H
File diff suppressed because it is too large Load Diff
-478
View File
@@ -1,478 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Button implementation in the MiniGUI
#ifndef CRYINCLUDE_CRYSYSTEM_PERFHUD_H
#define CRYINCLUDE_CRYSYSTEM_PERFHUD_H
#pragma once
#include <IPerfHud.h>
#ifdef USE_PERFHUD
#include <AzFramework/Input/Events/InputChannelEventListener.h>
#include "MiniGUI/MiniInfoBox.h"
#include "MiniGUI/MiniTable.h"
//Macros for console based widget control
#define SET_WIDGET_DECL(WIDGET_NAME) \
static int s_cvar_##WIDGET_NAME; \
static void Set_##WIDGET_NAME##_Widget(ICVar * pCvar);
#define SET_WIDGET_DEF(WIDGET_NAME, WIDGET_ID) \
int CPerfHUD::s_cvar_##WIDGET_NAME = 0; \
void CPerfHUD::Set_##WIDGET_NAME##_Widget(ICVar * pCvar) \
{ \
ICryPerfHUD* pPerfHud = gEnv->pSystem->GetPerfHUD(); \
if (pPerfHud) \
{ \
int val = pCvar->GetIVal(); \
if (val) \
{ \
pPerfHud->SetState(eHudOutOfFocus); \
pPerfHud->EnableWidget(ICryPerfHUDWidget::WIDGET_ID, val); \
} \
else \
{ \
pPerfHud->DisableWidget(ICryPerfHUDWidget::WIDGET_ID); \
} \
} \
}
#define SET_WIDGET_COMMAND(COMMAND_NAME, WIDGET_NAME) \
REGISTER_CVAR2_CB(COMMAND_NAME, &s_cvar_##WIDGET_NAME, 0, VF_ALWAYSONCHANGE, "", Set_##WIDGET_NAME##_Widget);
//////////////////////////////////////////////////////////////////////////
// Root window all other controls derive from
class CPerfHUD
: public ICryPerfHUD
, public minigui::IMiniGUIEventListener
, public AzFramework::InputChannelEventListener
{
public:
CRYINTERFACE_BEGIN()
CRYINTERFACE_ADD(ICryPerfHUD)
CRYINTERFACE_END()
CRYGENERATE_SINGLETONCLASS(CPerfHUD, "PerfHUD", 0x006945f9985e4ce2, 0x872120bfdec09ca5)
public:
//////////////////////////////////////////////////////////////////////////
// ICryPerfHUD implementation
//////////////////////////////////////////////////////////////////////////
virtual void Init();
virtual void Done();
virtual void Draw();
virtual void LoadBudgets();
virtual void SaveStats(const char* filename);
virtual void ResetWidgets();
virtual void Reset();
virtual void Destroy();
//Set state through code (rather than using joypad input)
virtual void SetState(EHudState state);
virtual void Show(bool bRestoreState);
virtual void AddWidget(ICryPerfHUDWidget* pWidget);
virtual void RemoveWidget(ICryPerfHUDWidget* pWidget);
//////////////////////////////////////////////////////////////////////////
// Gui Creation helper funcs
//////////////////////////////////////////////////////////////////////////
virtual minigui::IMiniCtrl* CreateMenu(const char* name, minigui::IMiniCtrl* pParent = NULL);
virtual bool CreateCVarMenuItem(minigui::IMiniCtrl* pMenu, const char* name, const char* controlVar, float controlVarOn, float controlVarOff);
virtual bool CreateCallbackMenuItem(minigui::IMiniCtrl* pMenu, const char* name, minigui::ClickCallback callback, void* pCallbackData);
virtual minigui::IMiniInfoBox* CreateInfoMenuItem(minigui::IMiniCtrl* pMenu, const char* name, minigui::RenderCallback renderCallback, const minigui::Rect& rect, bool onAtStart = false);
virtual minigui::IMiniTable* CreateTableMenuItem(minigui::IMiniCtrl* pMenu, const char* name);
virtual minigui::IMiniCtrl* GetMenu(const char* name);
virtual void EnableWidget(ICryPerfHUDWidget::EWidgetID id, int mode);
virtual void DisableWidget(ICryPerfHUDWidget::EWidgetID id);
//////////////////////////////////////////////////////////////////////////
// WARNINGS - Widget Specific Interface
//////////////////////////////////////////////////////////////////////////
virtual void AddWarning(float duration, const char* fmt, va_list argList);
virtual bool WarningsWindowEnabled() const;
//////////////////////////////////////////////////////////////////////////
// FPS - Widget Specific Interface
//////////////////////////////////////////////////////////////////////////
virtual const std::vector<PerfBucket>* GetFpsBuckets(float& totalTime) const;
//////////////////////////////////////////////////////////////////////////
// IMiniGUIEventListener implementation
//////////////////////////////////////////////////////////////////////////
virtual void OnCommand(minigui::SCommand& cmd);
//////////////////////////////////////////////////////////////////////////
// AzFramework::InputChannelEventListener
bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override;
AZ::s32 GetPriority() const override { return AzFramework::InputChannelEventListener::GetPriorityUI(); }
//////////////////////////////////////////////////////////////////////////
// CLICK CALLBACKS
//////////////////////////////////////////////////////////////////////////
static void ResetCallback(void* data, bool status);
static void ReloadBudgetsCallback(void* data, bool status);
static void SaveStatsCallback(void* data, bool status);
//////////////////////////////////////////////////////////////////////////
// RENDER CALLBACKS
//////////////////////////////////////////////////////////////////////////
static void DisplayRenderInfoCallback(const minigui::Rect& rect);
//////////////////////////////////////////////////////////////////////////
// CVAR CALLBACK
//////////////////////////////////////////////////////////////////////////
static void CVarChangeCallback(ICVar* pCvar);
SET_WIDGET_DECL(Warnings);
SET_WIDGET_DECL(RenderSummary);
SET_WIDGET_DECL(RenderBatchStats);
SET_WIDGET_DECL(FpsBuckets);
SET_WIDGET_DECL(Particles);
SET_WIDGET_DECL(PakFile);
//////////////////////////////////////////////////////////////////////////
// Static Data
//////////////////////////////////////////////////////////////////////////
static const float OVERSCAN_X;
static const float OVERSCAN_Y;
static const ColorB COL_NORM;
static const ColorB COL_WARN;
static const ColorB COL_ERROR;
static const float TEXT_SIZE_NORM;
static const float TEXT_SIZE_WARN;
static const float TEXT_SIZE_ERROR;
static const float ACTIVATE_TIME_FROM_GAME;
static const float ACTIVATE_TIME_FROM_HUD;
protected:
void InitUI(minigui::IMiniGUI* pGUI);
void SetNextState();
protected:
static int m_sys_perfhud;
static int m_sys_perfhud_pause;
int m_sys_perfhud_prev;
//record last menu position
float m_menuStartX;
float m_menuStartY;
bool m_hudCreated;
bool m_L1Pressed;
bool m_L2Pressed;
bool m_R1Pressed;
bool m_R2Pressed;
bool m_changingState;
bool m_hwMouseEnabled;
float m_triggersDownStartTime;
EHudState m_hudState;
EHudState m_hudLastState;
typedef std::vector< _smart_ptr<ICryPerfHUDWidget>, stl::STLGlobalAllocator<_smart_ptr<ICryPerfHUDWidget> > >::iterator TWidgetIterator;
std::vector< _smart_ptr<ICryPerfHUDWidget>, stl::STLGlobalAllocator<_smart_ptr<ICryPerfHUDWidget> > > m_widgets;
std::vector<minigui::IMiniCtrl*, stl::STLGlobalAllocator<minigui::IMiniCtrl*> > m_rootMenus;
};
class CFpsWidget
: public ICryPerfHUDWidget
{
public:
CFpsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud);
virtual void Reset();
virtual void Update();
virtual bool ShouldUpdate();
virtual void LoadBudgets(XmlNodeRef perfXML);
virtual void SaveStats(XmlNodeRef statsXML);
virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); }
virtual void Disable() { m_pInfoBox->Hide(true); }
void Init();
const std::vector<ICryPerfHUD::PerfBucket>* GetFpsBuckets(float& totalTime) const;
static void ResetCallback(void* data, bool status);
protected:
static const uint32 NUM_FPS_BUCKETS_DEFAULT = 6;
struct PerfBucketsStat
{
std::vector<ICryPerfHUD::PerfBucket> buckets;
float totalTime;
};
template <bool LESS_THAN>
void UpdateBuckets(PerfBucketsStat& buckets, float frameTime, const char* name, float stat);
// Data
static int m_cvarPerfHudFpsExclusive;
enum EPerfBucketType
{
BUCKET_FPS = 0,
BUCKET_GPU,
BUCKET_DP,
BUCKET_TYPE_NUM
};
PerfBucketsStat m_perfBuckets[BUCKET_TYPE_NUM];
float m_fpsBucketSize;
float m_fpsBudget;
float m_dpBudget;
float m_dpBucketSize;
minigui::IMiniInfoBox* m_pInfoBox;
};
class CRenderStatsWidget
: public ICryPerfHUDWidget
{
public:
CRenderStatsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud);
virtual void Reset() {}
virtual void Update();
virtual bool ShouldUpdate();
virtual void LoadBudgets(XmlNodeRef perfXML);
virtual void SaveStats(XmlNodeRef statsXML);
virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); }
virtual void Disable() { m_pInfoBox->Hide(true); }
protected:
//budgets
float m_fpsBudget;
uint32 m_dpBudget;
uint32 m_polyBudget;
uint32 m_postEffectBudget;
uint32 m_shadowCastBudget;
uint32 m_particlesBudget;
//runtime data
struct SRuntimeData
{
Vec3 cameraPos;
Ang3 cameraRot;
float fps;
uint32 nDrawPrims;
uint32 nPolys;
uint32 nPostEffects;
uint32 nFwdLights;
uint32 nFwdShadowLights;
uint32 nDefLights;
uint32 nDefShadowLights;
uint32 nDefCubeMaps;
int nParticles;
bool hdrEnabled;
bool renderThreadEnabled;
};
SRuntimeData m_runtimeData;
minigui::IMiniInfoBox* m_pInfoBox;
ICryPerfHUD* m_pPerfHUD;
uint32 m_buildNum;
};
class CStreamingStatsWidget
: public ICryPerfHUDWidget
{
public:
CStreamingStatsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud);
virtual void Reset() {}
virtual void Update();
virtual bool ShouldUpdate();
virtual void LoadBudgets(XmlNodeRef perfXML);
virtual void SaveStats(XmlNodeRef statsXML) {};
virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); }
virtual void Disable() { m_pInfoBox->Hide(true); }
protected:
//float m_maxMeshSizeArroundMB;
//float m_maxTextureSizeArroundMB;
minigui::IMiniInfoBox* m_pInfoBox;
ICryPerfHUD* m_pPerfHUD;
};
class CWarningsWidget
: public ICryPerfHUDWidget
{
public:
CWarningsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud);
virtual void Reset();
virtual void Update();
virtual bool ShouldUpdate();
virtual void LoadBudgets(XmlNodeRef perfXML) {};
virtual void SaveStats(XmlNodeRef statsXML);
virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); }
virtual void Disable() { m_pInfoBox->Hide(true); }
void AddWarningV(float duration, const char* fmt, va_list argList);
void AddWarning(float duration, const char* warning);
protected:
static const uint32 WARNING_LENGTH = 64;
struct SWarning
{
char text[WARNING_LENGTH];
float remainingDuration;
};
minigui::IMiniInfoBox* m_pInfoBox;
typedef std::vector< SWarning > TSWarnings;
TSWarnings m_warnings;
CryMT::queue<SWarning> m_threadWarnings;
threadID m_nMainThreadId;
};
class CRenderBatchWidget
: public ICryPerfHUDWidget
{
public:
CRenderBatchWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud);
virtual void Reset();
virtual void Update();
virtual bool ShouldUpdate();
virtual void LoadBudgets(XmlNodeRef perfXML) {};
virtual void SaveStats(XmlNodeRef statsXML);
virtual void Enable(int mode);
virtual void Disable();
void Update_ModeGpuTimes();
void Update_ModeBatchStats();
protected:
struct BatchInfoGpuTimes
{
const char* name;
uint32 nBatches;
float gpuTime;
int numVerts;
int numIndices;
};
struct BatchInfoSortGpuTimes
{
inline bool operator() (const BatchInfoGpuTimes& lhs, const BatchInfoGpuTimes& rhs) const
{
return lhs.gpuTime > rhs.gpuTime;
}
};
struct BatchInfoPerPass
{
const char* name;
uint16 nBatches;
uint16 nInstances;
uint16 nZpass;
uint16 nShadows;
uint16 nGeneral;
uint16 nTransparent;
uint16 nMisc;
ColorB col;
BatchInfoPerPass()
{
Reset();
}
void Reset()
{
name = NULL;
nBatches = 0;
nInstances = 0;
nZpass = 0;
nShadows = 0;
nGeneral = 0;
nTransparent = 0;
nMisc = 0;
col.set(255, 255, 255, 255);
}
void operator += (const BatchInfoPerPass& rhs)
{
nBatches += rhs.nBatches;
nInstances += rhs.nInstances;
nZpass += rhs.nZpass;
nShadows += rhs.nShadows;
nGeneral += rhs.nGeneral;
nTransparent += rhs.nTransparent;
nMisc += rhs.nMisc;
}
};
struct BatchInfoSortPerPass
{
inline bool operator() (const BatchInfoPerPass* lhs, const BatchInfoPerPass* rhs) const
{
return lhs->nBatches > rhs->nBatches;
}
};
enum EDisplayMode
{
DISPLAY_MODE_NONE = 0,
DISPLAY_MODE_BATCH_STATS,
DISPLAY_MODE_GPU_TIMES,
DISPLAY_MODE_NUM,
};
minigui::IMiniTable* m_pTable;
ICVar* m_pRStatsCVar;
EDisplayMode m_displayMode;
};
#endif //USE_PERFHUD
#endif // CRYINCLUDE_CRYSYSTEM_PERFHUD_H
@@ -320,7 +320,6 @@ bool CResourceManager::LoadFastLoadPaks(bool bToMemory)
}
const char* const assetsDir = "@assets@";
const char* shaderPakPath = "ShaderCacheStartup.pak";
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_2
@@ -328,7 +327,6 @@ bool CResourceManager::LoadFastLoadPaks(bool bToMemory)
#endif
gEnv->pCryPak->OpenPacks(assetsDir, AZ::IO::PathString(FAST_LOADING_PAKS_SRC_FOLDER) + "*.pak", nPakPreloadFlags, &m_fastLoadPakPaths);
gEnv->pCryPak->OpenPack(assetsDir, shaderPakPath, AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK);
gEnv->pCryPak->OpenPack(assetsDir, "Engine.pak", AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY);
return !m_fastLoadPakPaths.empty();
}
@@ -343,11 +341,6 @@ void CResourceManager::UnloadFastLoadPaks()
gEnv->pCryPak->ClosePack(m_fastLoadPakPaths[i].c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL);
}
m_fastLoadPakPaths.clear();
if (gEnv && gEnv->pRenderer)
{
gEnv->pRenderer->UnloadShaderStartupCache();
}
}
//////////////////////////////////////////////////////////////////////////
@@ -712,23 +705,11 @@ void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_P
}
}
//Load and precache frontend shader cache
if (g_cvars.archiveVars.nLoadFrontendShaderCache)
{
gEnv->pRenderer->LoadShaderLevelCache();
gEnv->pRenderer->EF_Query(EFQ_SetShaderCombinations);
}
break;
}
case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE:
{
if (g_cvars.archiveVars.nLoadFrontendShaderCache)
{
gEnv->pRenderer->UnloadShaderLevelCache();
}
if (!gEnv->bMultiplayer)
{
UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp");
@@ -1211,20 +1211,9 @@ void CStreamEngine::TempFree(void* p, size_t nSize)
namespace
{
#ifdef STREAMENGINE_ENABLE_STATS
void DrawText(const float x, const float y, ColorF c, const char* format, ...)
void DrawText(const float, const float, ColorF, const char*, ...)
{
va_list args;
va_start(args, format);
SDrawTextInfo ti;
ti.flags = eDrawText_FixedSize | eDrawText_2D | eDrawText_Monospace;
ti.xscale = ti.yscale = 1.2f;
ti.color[0] = c.r;
ti.color[1] = c.g;
ti.color[2] = c.b;
ti.color[3] = c.a;
gEnv->pRenderer->DrawTextQueued(Vec3(x, y, 1.0f), ti, format, args);
va_end(args);
// ToDo: Remove whole file with SPEC-343, or update to draw with Atom? Likely the former as I think this whole system is dead.
}
#endif
+1 -129
View File
@@ -127,7 +127,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include <IProcess.h>
#include <INotificationNetwork.h>
#include <ISoftCodeMgr.h>
#include "VisRegTest.h"
#include <LyShine/ILyShine.h>
#include <LoadScreenBus.h>
@@ -135,8 +134,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include <AzFramework/Archive/Archive.h>
#include "XConsole.h"
#include "Log.h"
#include "CrySizerStats.h"
#include "CrySizerImpl.h"
#include "NotificationNetwork.h"
#include "ProfileLog.h"
@@ -153,7 +150,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include "ServerThrottle.h"
#include "ResourceManager.h"
#include "HMDBus.h"
#include "OverloadSceneManager/OverloadSceneManager.h"
#include <IThreadManager.h>
#include "IZLibCompressor.h"
@@ -318,11 +314,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_pSystemEventDispatcher->RegisterListener(this);
}
#ifdef WIN32
m_hInst = NULL;
m_hWnd = NULL;
#endif
//////////////////////////////////////////////////////////////////////////
// Clear environment.
//////////////////////////////////////////////////////////////////////////
@@ -357,7 +348,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_pIFont = NULL;
m_pIFontUi = NULL;
m_pVisRegTest = NULL;
m_rWidth = NULL;
m_rHeight = NULL;
m_rWidthAndHeightAsFractionOfScreenSize = NULL;
@@ -368,7 +358,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_cvSSInfo = NULL;
m_rStencilBits = NULL;
m_rFullscreen = NULL;
m_rDriver = NULL;
m_sysNoUpdate = NULL;
m_pMemoryManager = NULL;
m_pProcess = NULL;
@@ -413,7 +402,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_pCpu = NULL;
m_bInitializedSuccessfully = false;
m_bShaderCacheGenMode = false;
m_bRelaunch = false;
m_iLoadingMode = 0;
m_bTestMode = false;
@@ -430,9 +418,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_expectingMapCommand = false;
#endif
// no mem stats at the moment
m_pMemStats = NULL;
m_pSizer = NULL;
m_pCVarQuit = NULL;
m_bForceNonDevMode = false;
@@ -468,9 +453,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
InitThreadSystem();
m_pMiniGUI = NULL;
m_pPerfHUD = NULL;
g_pPakHeap = new CMTSafeHeap;
if (!AZ::AllocatorInstance<AZ::OSAllocator>::IsReady())
@@ -516,7 +498,6 @@ CSystem::~CSystem()
CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere");
SAFE_DELETE(m_pVisRegTest);
SAFE_DELETE(m_pXMLUtils);
SAFE_DELETE(m_pArchiveHost);
SAFE_DELETE(m_pThreadTaskManager);
@@ -704,13 +685,6 @@ void CSystem::ShutDown()
SAFE_RELEASE(m_pViewSystem);
SAFE_RELEASE(m_pLevelSystem);
//Can't kill renderer before we delete CryFont, 3DEngine, etc
if (GetIRenderer())
{
GetIRenderer()->ShutDown();
SAFE_RELEASE(m_env.pRenderer);
}
if (m_env.pLog)
{
m_env.pLog->UnregisterConsoleVariables();
@@ -731,7 +705,6 @@ void CSystem::ShutDown()
SAFE_RELEASE(m_cvSSInfo);
SAFE_RELEASE(m_rStencilBits);
SAFE_RELEASE(m_rFullscreen);
SAFE_RELEASE(m_rDriver);
SAFE_RELEASE(m_sysWarnings);
SAFE_RELEASE(m_sysKeyboard);
@@ -751,13 +724,9 @@ void CSystem::ShutDown()
SAFE_RELEASE(m_pNotificationNetwork);
SAFE_DELETE(m_env.pSoftCodeMgr);
SAFE_DELETE(m_pMemStats);
SAFE_DELETE(m_pSizer);
SAFE_DELETE(m_pDefaultValidator);
m_pValidator = nullptr;
SAFE_DELETE(m_env.pOverloadSceneManager);
SAFE_DELETE(m_pLocalizationManager);
//DebugStats(false, false);//true);
@@ -816,11 +785,6 @@ void CSystem::Quit()
m_pUserCallback->OnQuit();
}
if (GetIRenderer())
{
GetIRenderer()->RestoreGamma();
}
gEnv->pLog->FlushAndClose();
// Latest possible place to flush any pending messages to disk before the forceful termination.
@@ -1229,8 +1193,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
}
#endif //EXCLUDE_UPDATE_ON_CONSOLE
gEnv->pOverloadSceneManager->Update();
#ifdef WIN32
// enable/disable SSE fp exceptions (#nan and /0)
// need to do it each frame since sometimes they are being reset
@@ -1242,12 +1204,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
m_nUpdateCounter++;
#ifndef EXCLUDE_UPDATE_ON_CONSOLE
if (!m_sDelayedScreeenshot.empty())
{
gEnv->pRenderer->ScreenShot(m_sDelayedScreeenshot.c_str());
m_sDelayedScreeenshot.clear();
}
// Check if game needs to be sleeping when not active.
SleepIfInactive();
@@ -1278,27 +1234,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
#ifdef USE_REMOTE_CONSOLE
GetIRemoteConsole()->Update();
#endif
if (!gEnv->IsEditor() && gEnv->pRenderer)
{
// If the dimensions of the render target change,
// or are different from the camera defaults,
// we need to update the camera frustum.
CCamera& viewCamera = GetViewCamera();
const int renderTargetWidth = m_rWidth->GetIVal();
const int renderTargetHeight = m_rHeight->GetIVal();
if (renderTargetWidth != viewCamera.GetViewSurfaceX() ||
renderTargetHeight != viewCamera.GetViewSurfaceZ())
{
viewCamera.SetFrustum(renderTargetWidth,
renderTargetHeight,
viewCamera.GetFov(),
viewCamera.GetNearPlane(),
viewCamera.GetFarPlane(),
gEnv->pRenderer->GetPixelAspectRatio());
}
}
if (nPauseMode != 0)
{
m_bPaused = true;
@@ -1346,53 +1281,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
m_pStreamEngine->Update();
}
if (g_cvars.az_streaming_stats)
{
SDrawTextInfo ti;
ti.flags = eDrawText_FixedSize | eDrawText_2D | eDrawText_Monospace;
ti.xscale = ti.yscale = 1.2f;
const int viewportHeight = GetViewCamera().GetViewSurfaceZ();
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_8
#include AZ_RESTRICTED_FILE(System_cpp)
#else
float y = static_cast<float>(viewportHeight) - 85.0f;
#endif
AZStd::vector<AZ::IO::Statistic> stats;
AZ::Interface<AZ::IO::IStreamer>::Get()->CollectStatistics(stats);
for (AZ::IO::Statistic& stat : stats)
{
switch (stat.GetType())
{
case AZ::IO::Statistic::Type::FloatingPoint:
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti,
AZStd::string::format("%s/%s: %.3f", stat.GetOwner().data(), stat.GetName().data(), stat.GetFloatValue()).c_str());
break;
case AZ::IO::Statistic::Type::Integer:
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti,
AZStd::string::format("%s/%s: %lli", stat.GetOwner().data(), stat.GetName().data(), stat.GetIntegerValue()).c_str());
break;
case AZ::IO::Statistic::Type::Percentage:
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti,
AZStd::string::format("%s/%s: %.2f (percent)", stat.GetOwner().data(), stat.GetName().data(), stat.GetPercentage()).c_str());
break;
default:
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti, AZStd::string::format("Unsupported stat type: %i", static_cast<int>(stat.GetType())).c_str());
break;
}
y -= 12.0f;
if (y < 0.0f)
{
//Exit the loop because there's no purpose on rendering text outside of the visible area.
break;
}
}
}
#ifndef EXCLUDE_UPDATE_ON_CONSOLE
if (m_bIgnoreUpdates)
{
@@ -1476,12 +1364,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
m_pServerThrottle->Update();
}
//////////////////////////////////////////////////////////////////////////
if (m_env.pRenderer && m_env.pRenderer->GetIStereoRenderer()->IsRenderingToHMD())
{
EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, UpdateInternalState);
}
//////////////////////////////////////////////////////////////////////
//update console system
if (m_env.pConsole)
@@ -1527,6 +1409,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
//////////////////////////////////////////////////////////////////////////
// Update Threads Task Manager.
//////////////////////////////////////////////////////////////////////////
if (m_pThreadTaskManager)
{
FRAME_PROFILER("SysUpdate:ThreadTaskManager", this, PROFILE_SYSTEM);
m_pThreadTaskManager->OnUpdate();
@@ -2000,12 +1883,6 @@ void CSystem::Relaunch(bool bRelaunch)
SaveConfiguration();
}
//////////////////////////////////////////////////////////////////////////
ICrySizer* CSystem::CreateSizer()
{
return new CrySizerImpl;
}
//////////////////////////////////////////////////////////////////////////
uint32 CSystem::GetUsedMemory()
{
@@ -2113,11 +1990,6 @@ void CSystem::ExecuteCommandLine(bool deferred)
//gEnv->pConsole->ExecuteString("sys_RestoreSpec test*"); // to get useful debugging information about current spec settings to the log file
}
void CSystem::DumpMemoryCoverage()
{
m_MemoryFragmentationProfiler.DumpMemoryCoverage();
}
ITextModeConsole* CSystem::GetITextModeConsole()
{
if (m_bDedicatedServer)
-73
View File
@@ -26,7 +26,6 @@
#include "MTSafeAllocator.h"
#include "CPUDetect.h"
#include <AzFramework/Archive/ArchiveVars.h>
#include "MemoryFragmentationProfiler.h" // CMemoryFragmentationProfiler
#include "ThreadTask.h"
#include "RenderBus.h"
@@ -48,12 +47,6 @@ struct IZLibCompressor;
class CWatchdogThread;
class CThreadManager;
struct ICryPerfHUD;
namespace minigui
{
struct IMiniGUI;
}
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
#define SYSTEM_H_SECTION_1 1
@@ -214,7 +207,6 @@ namespace Audio
} // namespace Audio
struct SDefaultValidator;
struct IDataProbe;
class CVisRegTest;
#define PHSYICS_OBJECT_ENTITY 0
@@ -227,7 +219,6 @@ extern VTuneFunction VTPause;
struct SSystemCVars
{
int az_streaming_stats;
int sys_streaming_requests_grouping_time_period;
int sys_streaming_sleep;
int sys_streaming_memory_budget;
@@ -270,15 +261,6 @@ struct SSystemCVars
int sys_error_debugbreak;
int sys_FilesystemCaseSensitivity;
int sys_rendersplashscreen;
const char* sys_splashscreen;
enum SplashScreenScaleMode
{
SplashScreenScaleMode_Fit = 0,
SplashScreenScaleMode_Fill
};
int sys_splashScreenScaleMode;
int sys_deferAudioUpdateOptim;
#if USE_STEAM
@@ -424,10 +406,6 @@ public:
uint32 GetUsedMemory();
virtual void DumpMemoryUsageStatistics(bool bUseKB);
virtual void DumpMemoryCoverage();
void CollectMemInfo(SCryEngineStatsGlobalMemInfo&);
#ifndef _RELEASE
virtual void GetCheckpointData(ICheckpointData& data);
virtual void IncreaseCheckpointLoadCount();
@@ -444,7 +422,6 @@ public:
void Quit();
bool IsQuitting() const;
void ShutdownFileSystem(); // used to cleanup any file resources, such as cache handle.
bool IsShaderCacheGenMode() const { return m_bShaderCacheGenMode; }
void SetAffinity();
virtual const char* GetUserName();
virtual int GetApplicationInstance();
@@ -452,7 +429,6 @@ public:
virtual sUpdateTimes& GetCurrentUpdateTimeStats();
virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&);
IRenderer* GetIRenderer(){ return m_env.pRenderer; }
ITimer* GetITimer(){ return m_env.pTimer; }
AZ::IO::IArchive* GetIPak() { return m_env.pCryPak; };
IConsole* GetIConsole() { return m_env.pConsole; };
@@ -472,16 +448,13 @@ public:
IThreadTaskManager* GetIThreadTaskManager();
IResourceManager* GetIResourceManager();
ITextModeConsole* GetITextModeConsole();
IFileChangeMonitor* GetIFileChangeMonitor() { return m_env.pFileChangeMonitor; }
IVisualLog* GetIVisualLog() { return m_env.pVisualLog; }
INotificationNetwork* GetINotificationNetwork() { return m_pNotificationNetwork; }
IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; }
ICryPerfHUD* GetPerfHUD() { return m_pPerfHUD; }
IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; }
IZLibDecompressor* GetIZLibDecompressor() { return m_pIZLibDecompressor; }
ILZ4Decompressor* GetLZ4Decompressor() { return m_pILZ4Decompressor; }
IZStdDecompressor* GetZStdDecompressor() { return m_pIZStdDecompressor; }
WIN_HWND GetHWND(){ return m_hWnd; }
//////////////////////////////////////////////////////////////////////////
// retrieves the perlin noise singleton instance
CPNoise3* GetNoiseGen();
@@ -499,7 +472,6 @@ public:
void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) { m_env.pMaterialEffects = pMaterialEffects; }
void SetIOpticsManager(IOpticsManager* pOpticsManager) { m_env.pOpticsManager = pOpticsManager; }
void SetIFileChangeMonitor(IFileChangeMonitor* pFileChangeMonitor) { m_env.pFileChangeMonitor = pFileChangeMonitor; }
void SetIVisualLog(IVisualLog* pVisualLog) { m_env.pVisualLog = pVisualLog; }
void DetectGameFolderAccessRights();
@@ -603,7 +575,6 @@ public:
//////////////////////////////////////////////////////////////////////////
virtual int SetThreadState(ESubsystem subsys, bool bActive);
virtual ICrySizer* CreateSizer();
virtual bool IsPaused() const { return m_bPaused; };
virtual ILocalizationManager* GetLocalizationManager();
@@ -616,18 +587,6 @@ public:
virtual ICryFactoryRegistry* GetCryFactoryRegistry() const;
public:
// this enumeration describes the purpose for which the statistics is gathered.
// if it's gathered to be dumped, then some different rules may be applied
enum MemStatsPurposeEnum
{
nMSP_ForDisplay, nMSP_ForDump, nMSP_ForCrashLog, nMSP_ForBudget
};
// collects the whole memory statistics into the given sizer object
void CollectMemStats (class ICrySizer* pSizer, MemStatsPurposeEnum nPurpose = nMSP_ForDisplay, std::vector<SmallModuleInfo>* pStats = 0);
void GetExeSizes (ICrySizer* pSizer, MemStatsPurposeEnum nPurpose = nMSP_ForDisplay);
//! refreshes the m_pMemStats if necessary; creates it if it's not created
void TickMemStats(MemStatsPurposeEnum nPurpose = nMSP_ForDisplay, IResourceCollector* pResourceCollector = 0);
#if !defined(RELEASE)
void SetVersionInfo(const char* const szVersion);
#endif
@@ -680,7 +639,6 @@ private:
//////////////////////////////////////////////////////////////////////////
// Helper functions.
//////////////////////////////////////////////////////////////////////////
void CreateRendererVars(const SSystemInitParams& startupParams);
void CreateSystemVars();
void CreateAudioVars();
@@ -755,23 +713,9 @@ public:
CCpuFeatures* GetCPUFeatures() { return m_pCpu; };
string& GetDelayedScreeenshot() {return m_sDelayedScreeenshot; }
CVisRegTest*& GetVisRegTestPtrRef() {return m_pVisRegTest; }
const CTimeValue& GetLastTickTime(void) const { return m_lastTickTime; }
const ICVar* GetDedicatedMaxRate(void) const { return m_svDedicatedMaxRate; }
const char* GetRenderingDriverName(void) const
{
if(m_rDriver)
{
return m_rDriver->GetString();
}
return nullptr;
}
std::shared_ptr<AZ::IO::FileIOBase> CreateLocalFileIO();
// Gets the dimensions (in pixels) of the primary physical display.
@@ -787,7 +731,6 @@ private: // ------------------------------------------------------
CTimer m_Time; //!<
CCamera m_ViewCamera; //!<
bool m_bInitializedSuccessfully; //!< true if the system completed all initialization steps
bool m_bShaderCacheGenMode;//!< true if the application runs in shader cache generation mode
bool m_bRelaunch; //!< relaunching the app or not (true beforerelaunch)
int m_iLoadingMode; //!< Game is loading w/o changing context (0 not, 1 quickloading, 2 full loading)
bool m_bTestMode; //!< If running in testing mode.
@@ -804,7 +747,6 @@ private: // ------------------------------------------------------
bool m_bInDevMode; //!< Set to true if was in dev mode.
bool m_bGameFolderWritable;//!< True when verified that current game folder have write access.
SDefaultValidator* m_pDefaultValidator; //!<
string m_sDelayedScreeenshot;//!< to delay a screenshot call for a frame
CCpuFeatures* m_pCpu; //!< CPU features
int m_ttMemStatSS; //!< Time to memstat screenshot
string m_szCmdLine;
@@ -917,7 +859,6 @@ private: // ------------------------------------------------------
ICVar* m_rFullscreen;
ICVar* m_rFullscreenWindow;
ICVar* m_rFullscreenNativeRes;
ICVar* m_rDriver;
ICVar* m_rDisplayInfo;
ICVar* m_rOverscanBordersDrawDebugView;
ICVar* m_sysNoUpdate;
@@ -966,17 +907,6 @@ private: // ------------------------------------------------------
ILoadConfigurationEntrySink* m_pCVarsWhitelistConfigSink;
#endif // defined(CVARS_WHITELIST)
WIN_HWND m_hWnd;
WIN_HINSTANCE m_hInst;
// this is the memory statistics that is retained in memory between frames
// in which it's not gathered
class CrySizerStats* m_pMemStats;
class CrySizerImpl* m_pSizer;
ICryPerfHUD* m_pPerfHUD;
minigui::IMiniGUI* m_pMiniGUI;
//int m_nCurrentLogVerbosity;
SFileVersion m_fileVersion;
@@ -1085,7 +1015,6 @@ protected: // -------------------------------------------------------------
ILoadingProgressListener* m_pProgressListener;
CCmdLine* m_pCmdLine;
CVisRegTest* m_pVisRegTest;
CThreadManager* m_pThreadManager;
CThreadTaskManager* m_pThreadTaskManager;
class CResourceManager* m_pResourceManager;
@@ -1097,8 +1026,6 @@ protected: // -------------------------------------------------------------
std::vector< std::pair<CTimeValue, float> > m_updateTimes;
CMemoryFragmentationProfiler m_MemoryFragmentationProfiler;
struct SErrorMessage
{
string m_Message;
+3 -402
View File
@@ -95,7 +95,6 @@
#include <IProcess.h>
#include <LyShine/ILyShine.h>
#include <HMDBus.h>
#include "HMDCVars.h"
#include <AzFramework/Archive/Archive.h>
#include <Pak/CryPakUtils.h>
@@ -112,7 +111,6 @@
#include "SystemCFG.h"
#include "AutoDetectSpec.h"
#include "ResourceManager.h"
#include "VisRegTest.h"
#include "MTSafeAllocator.h"
#include "NotificationNetwork.h"
#include "ExtensionSystem/CryFactoryRegistryImpl.h"
@@ -123,7 +121,6 @@
#include "ZLibDecompressor.h"
#include "ZStdDecompressor.h"
#include "LZ4Decompressor.h"
#include "OverloadSceneManager/OverloadSceneManager.h"
#include "ServiceNetwork.h"
#include "RemoteCommand.h"
#include "LevelSystem/LevelSystem.h"
@@ -134,9 +131,6 @@
#include <AzCore/Jobs/JobManagerBus.h>
#include <AzFramework/Driller/DrillerConsoleAPI.h>
#include "PerfHUD.h"
#include "MiniGUI/MiniGUI.h"
#if USE_STEAM
#include "Steamworks/public/steam/steam_api.h"
#include "Steamworks/public/steam/isteamremotestorage.h"
@@ -740,28 +734,6 @@ static void LoadDetectedSpec(ICVar* pVar)
GetISystem()->LoadConfiguration("editor.cfg");
}
bool bMultiGPUEnabled = false;
if (gEnv->pRenderer)
{
gEnv->pRenderer->EF_Query(EFQ_MultiGPUEnabled, bMultiGPUEnabled);
#if defined(AZ_PLATFORM_ANDROID)
AZStd::string gpuConfigFile;
const AZStd::string& adapterDesc = gEnv->pRenderer->GetAdapterDescription();
const AZStd::string& apiver = gEnv->pRenderer->GetApiVersion();
if (!adapterDesc.empty())
{
MobileSysInspect::GetSpecForGPUAndAPI(adapterDesc, apiver, gpuConfigFile);
GetISystem()->LoadConfiguration(gpuConfigFile.c_str(), pSysSpecOverrideSinkConsole);
}
#endif
}
if (bMultiGPUEnabled)
{
GetISystem()->LoadConfiguration("mgpu.cfg");
}
// override cvars just loaded based on current API version/GPU
GetISystem()->SetConfigSpec(static_cast<ESystemConfigSpec>(spec), platform, false);
@@ -1279,7 +1251,7 @@ void CSystem::ShutdownFileSystem()
}
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams)
bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&)
{
LOADING_TIME_PROFILE_SECTION;
{
@@ -1320,10 +1292,6 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initPara
static const char* g_additionalConfig = gEnv->IsDedicated() ? "server_cfg" : "client_cfg";
LoadConfiguration(g_additionalConfig, nullptr, false);
if (initParams.bShaderCacheGen)
{
LoadConfiguration("shadercachegen.cfg");
}
// We do not use CVar groups on the consoles
AddCVarGroupDirectory("Config/CVarGroups");
@@ -1359,7 +1327,6 @@ bool CSystem::InitAudioSystem(const SSystemInitParams& initParams)
bool useRealAudioSystem = false;
if (!initParams.bPreview
&& !initParams.bShaderCacheGen
&& !initParams.bMinimal
&& !m_bDedicatedServer
&& m_sys_audio_disable->GetIVal() == 0)
@@ -1859,7 +1826,6 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
m_env.bTesting = startupParams.bTesting;
m_env.bNoAssertDialog = startupParams.bTesting;
m_env.bNoRandomSeed = startupParams.bNoRandom;
m_bShaderCacheGenMode = startupParams.bShaderCacheGen;
m_bNoCrashDialog = gEnv->IsDedicated();
@@ -1938,9 +1904,6 @@ AZ_POP_DISABLE_WARNING
QueryVersionInfo();
DetectGameFolderAccessRights();
m_hInst = (WIN_HINSTANCE)startupParams.hInstance;
m_hWnd = (WIN_HWND)startupParams.hWnd;
m_bEditor = startupParams.bEditor;
m_bPreviewMode = startupParams.bPreview;
m_bTestMode = startupParams.bTestMode;
@@ -2226,11 +2189,6 @@ AZ_POP_DISABLE_WARNING
InlineInitializationProcessing("CSystem::Init Create console");
if (!startupParams.bSkipRenderer)
{
CreateRendererVars(startupParams);
}
// Need to load the engine.pak that includes the config files needed during initialization
m_env.pCryPak->OpenPack("@assets@", "Engine.pak");
#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS)
@@ -2305,17 +2263,6 @@ AZ_POP_DISABLE_WARNING
// Optional user defined overrides
LoadConfiguration("user.cfg", pCVarsWhiteListConfigSink);
if (!startupParams.bSkipRenderer)
{
// Load the hmd.cfg if it exists. This will enable optional stereo rendering.
LoadConfiguration("hmd.cfg");
}
if (startupParams.bShaderCacheGen)
{
LoadConfiguration("shadercachegen.cfg", pCVarsWhiteListConfigSink);
}
#if defined(ENABLE_STATS_AGENT)
if (m_pCmdLine->FindArg(eCLAT_Pre, "useamblecfg"))
{
@@ -2365,30 +2312,6 @@ AZ_POP_DISABLE_WARNING
InlineInitializationProcessing("CSystem::Init LoadConfigurations");
m_env.pOverloadSceneManager = new COverloadSceneManager;
if (m_bDedicatedServer && m_rDriver)
{
m_sSavedRDriver = m_rDriver->GetString();
m_rDriver->Set("NULL");
}
#if defined(WIN32) || defined(WIN64)
if (!startupParams.bSkipRenderer)
{
if (azstricmp(m_rDriver->GetString(), "Auto") == 0)
{
m_rDriver->Set("DX11");
}
}
if (gEnv->IsEditor() && azstricmp(m_rDriver->GetString(), "DX12") == 0)
{
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, "DX12 mode is not supported in the editor. Reverting to DX11 mode.");
m_rDriver->Set("DX11");
}
#endif
#ifdef WIN32
if ((g_cvars.sys_WER) && (!startupParams.bMinimal))
{
@@ -2410,72 +2333,6 @@ AZ_POP_DISABLE_WARNING
m_thermalInfoHandler = AZStd::make_unique<ThermalInfoAndroidHandler>();
#endif
if (g_cvars.sys_rendersplashscreen && !startupParams.bEditor && !startupParams.bShaderCacheGen)
{
if (m_env.pRenderer)
{
LOADING_TIME_PROFILE_SECTION_NAMED("Rendering Splash Screen");
ITexture* pTex = m_env.pRenderer->EF_LoadTexture(g_cvars.sys_splashscreen, FT_DONT_STREAM | FT_NOMIPS | FT_USAGE_ALLOWREADSRGB);
//check the width and height as extra verification hack. This texture is loaded before the replace me, so there is
//no backup if it fails to load.
if (pTex && pTex->GetWidth() && pTex->GetHeight())
{
const int splashWidth = pTex->GetWidth();
const int splashHeight = pTex->GetHeight();
const int screenWidth = m_env.pRenderer->GetOverlayWidth();
const int screenHeight = m_env.pRenderer->GetOverlayHeight();
const float scaleX = (float)screenWidth / (float)splashWidth;
const float scaleY = (float)screenHeight / (float)splashHeight;
float scale = 1.0f;
switch (g_cvars.sys_splashScreenScaleMode)
{
case SSystemCVars::SplashScreenScaleMode_Fit:
{
scale = AZStd::GetMin(scaleX, scaleY);
}
break;
case SSystemCVars::SplashScreenScaleMode_Fill:
{
scale = AZStd::GetMax(scaleX, scaleY);
}
break;
}
const float w = splashWidth * scale;
const float h = splashHeight * scale;
const float x = (screenWidth - w) * 0.5f;
const float y = (screenHeight - h) * 0.5f;
const float vx = (800.0f / (float) screenWidth);
const float vy = (600.0f / (float) screenHeight);
m_env.pRenderer->SetViewport(0, 0, screenWidth, screenHeight);
#if defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_MAC)
// Pump system events in order to update the screen
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty);
#endif
pTex->Release();
}
#if defined(AZ_PLATFORM_ANDROID)
bool engineSplashEnabled = (g_cvars.sys_rendersplashscreen != 0);
if (engineSplashEnabled)
{
AZ::Android::Utils::DismissSplashScreen();
}
#endif
}
else
{
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, "Could not load startscreen image: %s.", g_cvars.sys_splashscreen);
}
}
//////////////////////////////////////////////////////////////////////////
// Open basic pak files after intro movie playback started
//////////////////////////////////////////////////////////////////////////
@@ -2507,21 +2364,6 @@ AZ_POP_DISABLE_WARNING
m_pUserCallback->OnInitProgress("First time asset processing - may take a minute...");
}
//////////////////////////////////////////////////////////////////////////
// POST RENDERER
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bSkipRenderer && m_env.pRenderer)
{
m_env.pRenderer->PostInit();
if (!startupParams.bShaderCacheGen)
{
// try to do a flush to keep the renderer busy during loading
m_env.pRenderer->TryFlush();
}
}
InlineInitializationProcessing("CSystem::Init Renderer::PostInit");
#ifdef SOFTCODE_SYSTEM_ENABLED
m_env.pSoftCodeMgr = new SoftCodeMgr();
#else
@@ -2537,10 +2379,8 @@ AZ_POP_DISABLE_WARNING
// - System cursor has to be enabled manually by the Game if needed; the custom UiCursor will typically be used instead
if (!gEnv->IsDedicated() &&
m_env.pRenderer &&
!gEnv->IsEditor() &&
!startupParams.bTesting &&
!m_pCmdLine->FindArg(eCLAT_Pre, "nomouse"))
!startupParams.bTesting)
{
AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id,
&AzFramework::InputSystemCursorRequests::SetSystemCursorState,
@@ -2561,7 +2401,7 @@ AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
// UI. Should be after input and hardware mouse
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bShaderCacheGen && !m_bDedicatedServer)
if (!m_bDedicatedServer)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "UI system initialization");
INDENT_LOG_DURING_SCOPE();
@@ -2573,21 +2413,6 @@ AZ_POP_DISABLE_WARNING
InlineInitializationProcessing("CSystem::Init InitShine");
//////////////////////////////////////////////////////////////////////////
// Create MiniGUI
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bMinimal)
{
minigui::IMiniGUIPtr pMiniGUI;
if (CryCreateClassInstanceForInterface(cryiidof<minigui::IMiniGUI>(), pMiniGUI))
{
m_pMiniGUI = pMiniGUI.get();
m_pMiniGUI->Init();
}
}
InlineInitializationProcessing("CSystem::Init InitMiniGUI");
//////////////////////////////////////////////////////////////////////////
// CONSOLE
//////////////////////////////////////////////////////////////////////////
@@ -2612,62 +2437,6 @@ AZ_POP_DISABLE_WARNING
m_env.pRemoteCommandManager = new CRemoteCommandManager();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// VR SYSTEM INITIALIZATION
//////////////////////////////////////////////////////////////////////////
if ((!startupParams.bSkipRenderer) && (!startupParams.bMinimal))
{
if (m_pUserCallback)
{
m_pUserCallback->OnInitProgress("Initializing VR Systems...");
}
AZStd::vector<AZ::VR::HMDInitBus*> devices;
AZ::VR::HMDInitRequestBus::EnumerateHandlers([&devices](AZ::VR::HMDInitBus* device)
{
devices.emplace_back(device);
return true;
});
// Order the devices so that devices that only support one type of HMD are ordered first as we want
// to use any device-specific drivers over more general ones.
std::sort(devices.begin(), devices.end(), [](AZ::VR::HMDInitBus* left, AZ::VR::HMDInitBus* right)
{
return left->GetInitPriority() > right->GetInitPriority();
});
//Start up a job to init the HMDs since they may take a while to start up
AZ::JobContext* jobContext = nullptr;
EBUS_EVENT_RESULT(jobContext, AZ::JobManagerBus, GetGlobalContext);
AZ::Job* hmdJob = AZ::CreateJobFunction([devices]()
{
// Loop through the attached devices and attempt to initialize them. We'll use the first
// one that succeeds since we currently only support a single HMD.
for (AZ::VR::HMDInitBus* device : devices)
{
if (device->AttemptInit())
{
// At this point if any device connected to the HMDDeviceRequestBus then we are good to go for VR.
EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, OutputHMDInfo);
EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, EnableDebugging, false);
// Since this was a job and we may have beaten the level's output_to_hmd cvar initialization
// We just want to retrigger the callback to this cvar
ICVar* outputToHMD = gEnv->pConsole->GetCVar("output_to_hmd");
if (outputToHMD != nullptr)
{
int outputToHMDVal = gEnv->pConsole->GetCVar("output_to_hmd")->GetIVal();
gEnv->pConsole->GetCVar("output_to_hmd")->Set(outputToHMDVal);
}
break;
}
}
}, true, jobContext);
hmdJob->Start();
}
if (m_pUserCallback)
{
m_pUserCallback->OnInitProgress("Initializing additional systems...");
@@ -2724,28 +2493,10 @@ AZ_POP_DISABLE_WARNING
m_pIZStdDecompressor = new CZStdDecompressor();
InlineInitializationProcessing("CSystem::Init ZStdDecompressor");
//////////////////////////////////////////////////////////////////////////
// Create PerfHUD
//////////////////////////////////////////////////////////////////////////
#if defined(USE_PERFHUD)
if (!gEnv->bTesting && !gEnv->IsInToolMode())
{
//Create late in Init so that associated CVars have already been created
ICryPerfHUDPtr pPerfHUD;
if (CryCreateClassInstanceForInterface(cryiidof<ICryPerfHUD>(), pPerfHUD))
{
m_pPerfHUD = pPerfHUD.get();
m_pPerfHUD->Init();
}
}
#endif
//////////////////////////////////////////////////////////////////////////
// Initialize task threads.
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bSkipRenderer)
{
m_pThreadTaskManager->InitThreads();
@@ -2775,12 +2526,6 @@ AZ_POP_DISABLE_WARNING
AZ::Interface<AZ::IConsole>::Get()->VisitRegisteredFunctors([](AZ::ConsoleFunctorBase* functor) { AzConsoleToCryConsoleBinder::Visit(functor); });
AzConsoleToCryConsoleBinder::s_commandRegisteredHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetConsoleCommandRegisteredEvent());
// final tryflush to be sure that all framework init request have been processed
if (!startupParams.bShaderCacheGen && m_env.pRenderer)
{
m_env.pRenderer->TryFlush();
}
if (g_cvars.sys_float_exceptions > 0)
{
if (g_cvars.sys_float_exceptions == 3 && gEnv->IsEditor()) // Turn off float exceptions in editor if sys_float_exceptions = 3
@@ -2874,99 +2619,6 @@ static string ConcatPath(const char* szPart1, const char* szPart2)
return ret;
}
static void ScreenshotCmd(IConsoleCmdArgs* pParams)
{
assert(pParams);
uint32 dwCnt = pParams->GetArgCount();
if (dwCnt <= 1)
{
if (!gEnv->IsEditing())
{
// open console one line only
//line should lie within title safe area, so calculate overscan border
Vec2 overscanBorders = Vec2(0.0f, 0.0f);
gEnv->pRenderer->EF_Query(EFQ_OverscanBorders, overscanBorders);
float yDelta = /*((float)gEnv->pRenderer->GetHeight())*/ 600.0f * overscanBorders.y;
//set console height depending on top/bottom overscan border
gEnv->pConsole->ShowConsole(true, (int)(16 + yDelta));
gEnv->pConsole->SetInputLine("Screenshot ");
}
else
{
gEnv->pLog->LogWithType(ILog::eInputResponse, "Screenshot <annotation> missing - no screenshot was done");
}
}
else
{
static int iScreenshotNumber = -1;
const char* szPrefix = "Screenshot";
uint32 dwPrefixSize = strlen(szPrefix);
char path[AZ::IO::IArchive::MaxPath];
path[sizeof(path) - 1] = 0;
gEnv->pCryPak->AdjustFileName("@user@/ScreenShots", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
if (iScreenshotNumber == -1) // first time - find max number to start
{
auto pCryPak = gEnv->pCryPak;
AZ::IO::ArchiveFileIterator handle = pCryPak->FindFirst((string(path) + "/*").c_str()); // mastercd folder
if (handle)
{
do
{
int iCurScreenshotNumber;
if (_strnicmp(handle.m_filename.data(), szPrefix, dwPrefixSize) == 0)
{
int iCnt = azsscanf(handle.m_filename.data() + dwPrefixSize, "%d", &iCurScreenshotNumber);
if (iCnt)
{
iScreenshotNumber = max(iCurScreenshotNumber, iScreenshotNumber);
}
}
handle = pCryPak->FindNext(handle);
} while (handle);
pCryPak->FindClose(handle);
}
}
++iScreenshotNumber;
char szNumber[16];
azsprintf(szNumber, "%.4d ", iScreenshotNumber);
string sScreenshotName = string(szPrefix) + szNumber;
for (uint32 dwI = 1; dwI < dwCnt; ++dwI)
{
if (dwI > 1)
{
sScreenshotName += "_";
}
sScreenshotName += pParams->GetArg(dwI);
}
sScreenshotName.replace("\\", "_");
sScreenshotName.replace("/", "_");
sScreenshotName.replace(":", "_");
sScreenshotName.replace(".", "_");
gEnv->pConsole->ShowConsole(false);
CSystem* pCSystem = (CSystem*)(gEnv->pSystem);
pCSystem->GetDelayedScreeenshot() = string(path) + "/" + sScreenshotName;// to delay a screenshot call for a frame
}
}
// Helper to maintain backwards compatibility with our CVar but not force our new code to
// pull in CryCommon by routing through an environment variable
void CmdSetAwsLogLevel(IConsoleCmdArgs* pArgs)
@@ -3182,18 +2834,6 @@ void ChangeLogAllocations(ICVar* pVal)
}
}
static void VisRegTest(IConsoleCmdArgs* pParams)
{
CSystem* pCSystem = (CSystem*)(gEnv->pSystem);
CVisRegTest*& visRegTest = pCSystem->GetVisRegTestPtrRef();
if (!visRegTest)
{
visRegTest = new CVisRegTest();
}
visRegTest->Init(pParams);
}
//////////////////////////////////////////////////////////////////////////
void CSystem::CreateSystemVars()
{
@@ -3278,28 +2918,10 @@ void CSystem::CreateSystemVars()
attachVariable("sys_PakLogAllFileAccess", &g_cvars.archiveVars.nLogAllFileAccess, "Log all file access allowing you to easily see whether a file has been loaded directly, or which pak file.");
#endif
attachVariable("sys_PakValidateFileHash", &g_cvars.archiveVars.nValidateFileHashes, "Validate file hashes in pak files for collisions");
attachVariable("sys_LoadFrontendShaderCache", &g_cvars.archiveVars.nLoadFrontendShaderCache, "Load frontend shader cache (on/off)");
attachVariable("sys_UncachedStreamReads", &g_cvars.archiveVars.nUncachedStreamReads, "Enable stream reads via an uncached file handle");
attachVariable("sys_PakDisableNonLevelRelatedPaks", &g_cvars.archiveVars.nDisableNonLevelRelatedPaks, "Disables all paks that are not required by specific level; This is used with per level splitted assets.");
attachVariable("sys_PakWarnOnPakAccessFailures", &g_cvars.archiveVars.nWarnOnPakAccessFails, "If 1, access failure for Paks is treated as a warning, if zero it is only a log message.");
{
int nDefaultRenderSplashScreen = 1;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_10
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
REGISTER_CVAR2("sys_rendersplashscreen", &g_cvars.sys_rendersplashscreen, nDefaultRenderSplashScreen, VF_NULL,
"Render the splash screen during game initialization");
REGISTER_CVAR2("sys_splashscreenscalemode", &g_cvars.sys_splashScreenScaleMode, static_cast<int>(SSystemCVars::SplashScreenScaleMode_Fill), VF_NULL,
"0 - scale to fit (letterbox)\n"
"1 - scale to fill (cropped)\n"
"Default is 1");
REGISTER_CVAR2("sys_splashscreen", &g_cvars.sys_splashscreen, "EngineAssets/Textures/startscreen.tif", VF_NULL,
"The splash screen to render during game initialization");
}
static const int fileSystemCaseSensitivityDefault = 0;
REGISTER_CVAR2("sys_FilesystemCaseSensitivity", &g_cvars.sys_FilesystemCaseSensitivity, fileSystemCaseSensitivityDefault, VF_NULL,
"0 - CryPak lowercases all input file names\n"
@@ -3452,10 +3074,6 @@ void CSystem::CreateSystemVars()
REGISTER_CVAR2("sys_streaming_max_finalize_per_frame", &g_cvars.sys_streaming_max_finalize_per_frame, 0, VF_NULL,
"Maximum stream finalizing calls per frame to reduce the CPU impact on main thread (0 to disable)");
REGISTER_CVAR2("sys_streaming_max_bandwidth", &g_cvars.sys_streaming_max_bandwidth, 0, VF_NULL, "Enables capping of max streaming bandwidth in MB/s");
REGISTER_CVAR2("az_streaming_stats", &g_cvars.az_streaming_stats, 0, VF_NULL, "Show stats from AZ::IO::Streamer\n"
"0=off\n"
"1=on\n"
);
REGISTER_CVAR2("sys_streaming_debug", &g_cvars.sys_streaming_debug, 0, VF_NULL, "Enable streaming debug information\n"
"0=off\n"
"1=Streaming Stats\n"
@@ -3580,12 +3198,6 @@ void CSystem::CreateSystemVars()
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F12", "Screenshot");
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F11", "RecordClip");
// screenshot functionality in system as console
REGISTER_COMMAND("Screenshot", &ScreenshotCmd, VF_BLOCKFRAME,
"Create a screenshot with annotation\n"
"e.g. Screenshot beach scene with shark\n"
"Usage: Screenshot <annotation text>");
/*
// experimental feature? - needs to be created very early
m_sys_filecache = REGISTER_INT("sys_FileCache",0,0,
@@ -3606,9 +3218,6 @@ void CSystem::CreateSystemVars()
"'test*' and 'info' log to the log file only\n"
"Usage: sys_RestoreSpec [test|test*|apply|info]");
REGISTER_COMMAND("VisRegTest", &VisRegTest, 0, "Run visual regression test.\n"
"Usage: VisRegTest [<name>=test] [<config>=visregtest.xml] [quit=false]");
#if defined(WIN32)
REGISTER_CVAR2("sys_display_threads", &g_cvars.sys_display_threads, 0, 0, "Displays Thread info");
#elif defined(AZ_RESTRICTED_PLATFORM)
@@ -3629,9 +3238,6 @@ void CSystem::CreateSystemVars()
REGISTER_CVAR2("sys_error_debugbreak", &g_cvars.sys_error_debugbreak, 0, VF_CHEAT, "__debugbreak() if a VALIDATOR_ERROR_DBGBREAK message is hit");
// [VR]
AZ::VR::HMDCVars::Register();
REGISTER_STRING("dlc_directory", "", 0, "Holds the path to the directory where DLC should be installed to and read from");
#if defined(MAP_LOADING_SLICING)
@@ -3694,11 +3300,6 @@ void CSystem::AddCVarGroupDirectory(const string& sPath)
string sCVarName = sFilePath;
PathUtil::RemoveExtension(sCVarName);
if (m_env.pConsole != 0)
{
((CXConsole*)m_env.pConsole)->RegisterCVarGroup(PathUtil::GetFile(sCVarName), sFilePath);
}
}
} while (handle = gEnv->pCryPak->FindNext(handle));
-140
View File
@@ -35,15 +35,10 @@
#include "PhysRenderer.h"
#include <IMovieSystem.h>
#include "CrySizerStats.h"
#include "CrySizerImpl.h"
#include "VisRegTest.h"
#include "ITextModeConsole.h"
#include <ILevelSystem.h>
#include <LyShine/ILyShine.h>
#include "MiniGUI/MiniGUI.h"
#include "PerfHUD.h"
#include "ThreadInfo.h"
#include <LoadScreenBus.h>
@@ -61,17 +56,6 @@ extern CMTSafeHeap* g_pPakHeap;
extern int CryMemoryGetAllocatedSize();
/////////////////////////////////////////////////////////////////////////////////
static void VerifySizeRenderVar(ICVar* pVar)
{
const int size = pVar->GetIVal();
if (size <= 0)
{
AZ_Error("Console Variable", false, "'%s' set to invalid value: %i. Setting to nearest safe value: 1.", pVar->GetName(), size);
pVar->Set(1);
}
}
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::GetPrimaryPhysicalDisplayDimensions([[maybe_unused]] int& o_widthPixels, [[maybe_unused]] int& o_heightPixels)
{
@@ -97,130 +81,6 @@ bool CSystem::IsTablet()
#endif
}
/////////////////////////////////////////////////////////////////////////////////
void CSystem::CreateRendererVars(const SSystemInitParams& startupParams)
{
int iFullScreenDefault = 1;
int iDisplayInfoDefault = 0;
int iWidthDefault = 1280;
int iHeightDefault = 720;
#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS)
GetPrimaryPhysicalDisplayDimensions(iWidthDefault, iHeightDefault);
#elif defined(WIN32) || defined(WIN64)
iFullScreenDefault = 0;
iWidthDefault = GetSystemMetrics(SM_CXFULLSCREEN) * 2 / 3;
iHeightDefault = GetSystemMetrics(SM_CYFULLSCREEN) * 2 / 3;
#endif
if (IsDevMode())
{
iFullScreenDefault = 0;
iDisplayInfoDefault = 1;
}
// load renderer settings from engine.ini
m_rWidth = REGISTER_INT_CB("r_Width", iWidthDefault, VF_DUMPTODISK,
"Sets the display width, in pixels. Default is 1280.\n"
"Usage: r_Width [800/1024/..]", VerifySizeRenderVar);
m_rHeight = REGISTER_INT_CB("r_Height", iHeightDefault, VF_DUMPTODISK,
"Sets the display height, in pixels. Default is 720.\n"
"Usage: r_Height [600/768/..]", VerifySizeRenderVar);
m_rWidthAndHeightAsFractionOfScreenSize = REGISTER_FLOAT("r_WidthAndHeightAsFractionOfScreenSize", 1.0f, VF_DUMPTODISK,
"(iOS/Android only) Sets the display width and height as a fraction of the physical screen size. Default is 1.0.\n"
"Usage: rWidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]");
m_rTabletWidthAndHeightAsFractionOfScreenSize = REGISTER_FLOAT("r_TabletWidthAndHeightAsFractionOfScreenSize", 1.0f, VF_DUMPTODISK,
"(iOS only) NOTE: TABLETS ONLY Sets the display width and height as a fraction of the physical screen size. Default is 1.0.\n"
"Usage: rTabletWidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]");
m_rMaxWidth = REGISTER_INT("r_MaxWidth", 0, VF_DUMPTODISK,
"(iOS/Android only) Sets the maximum display width while maintaining the device aspect ratio.\n"
"Usage: r_MaxWidth [1024/1920/..] (0 for no max), combined with r_WidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]");
m_rMaxHeight = REGISTER_INT("r_MaxHeight", 0, VF_DUMPTODISK,
"(iOS/Android only) Sets the maximum display height while maintaining the device aspect ratio.\n"
"Usage: r_MaxHeight [768/1080/..] (0 for no max), combined with r_WidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]");
m_rColorBits = REGISTER_INT("r_ColorBits", 32, VF_DUMPTODISK,
"Sets the color resolution, in bits per pixel. Default is 32.\n"
"Usage: r_ColorBits [32/24/16/8]");
m_rDepthBits = REGISTER_INT("r_DepthBits", 24, VF_DUMPTODISK | VF_REQUIRE_APP_RESTART,
"Sets the depth precision, in bits per pixel. Default is 24.\n"
"Usage: r_DepthBits [32/24]");
m_rStencilBits = REGISTER_INT("r_StencilBits", 8, VF_DUMPTODISK,
"Sets the stencil precision, in bits per pixel. Default is 8.\n");
// Needs to be initialized as soon as possible due to swap chain creation modifications..
m_rHDRDolby = REGISTER_INT_CB("r_HDRDolby", 0, VF_DUMPTODISK,
"HDR dolby output mode\n"
"Usage: r_HDRDolby [Value]\n"
"0: Off (default)\n"
"1: Dolby maui output\n"
"2: Dolby vision output\n",
[] (ICVar* cvar)
{
eDolbyVisionMode mode = static_cast<eDolbyVisionMode>(cvar->GetIVal());
if (mode == eDVM_Vision && gEnv->IsEditor())
{
cvar->Set(static_cast<int>(eDVM_Disabled));
}
});
// Restrict the limits of this cvar to the eDolbyVisionMode values
m_rHDRDolby->SetLimits(static_cast<float>(eDVM_Disabled), static_cast<float>(eDVM_Vision));
#if defined(WIN32) || defined(WIN64)
REGISTER_INT("r_overrideDXGIAdapter", -1, VF_REQUIRE_APP_RESTART,
"Specifies index of the preferred video adapter to be used for rendering (-1=off, loops until first suitable adapter is found).\n"
"Use this to resolve which video card to use if more than one DX11 capable GPU is available in the system.");
#endif
#if defined(WIN32) || defined(WIN64)
const char* p_r_DriverDef = "Auto";
#elif defined(APPLE)
const char* p_r_DriverDef = "METAL";
#elif defined(ANDROID)
const char* p_r_DriverDef = "GL";
#elif defined(LINUX)
const char* p_r_DriverDef = "GL";
if (gEnv->IsDedicated())
{
p_r_DriverDef = "NULL";
}
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMRENDERER_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(SystemRender_cpp)
#else
const char* p_r_DriverDef = "DX9"; // required to be deactivated for final release
#endif
if (startupParams.pCvarsDefault)
{ // hack to customize the default value of r_Driver
SCvarsDefault* pCvarsDefault = startupParams.pCvarsDefault;
if (pCvarsDefault->sz_r_DriverDef && pCvarsDefault->sz_r_DriverDef[0])
{
p_r_DriverDef = startupParams.pCvarsDefault->sz_r_DriverDef;
}
}
m_rDriver = REGISTER_STRING("r_Driver", p_r_DriverDef, VF_DUMPTODISK | VF_INVISIBLE,
"Sets the renderer driver ( DX11/AUTO/NULL ).\n"
"Specify in bootstrap.cfg like this: r_Driver = \"DX11\"");
m_rFullscreen = REGISTER_INT("r_Fullscreen", iFullScreenDefault, VF_DUMPTODISK,
"Toggles fullscreen mode. Default is 1 in normal game and 0 in DevMode.\n"
"Usage: r_Fullscreen [0=window/1=fullscreen]");
m_rFullscreenWindow = REGISTER_INT("r_FullscreenWindow", 0, VF_DUMPTODISK,
"Toggles fullscreen-as-window mode. Fills screen but allows seamless switching. Default is 0.\n"
"Usage: r_FullscreenWindow [0=locked fullscreen/1=fullscreen as window]");
m_rFullscreenNativeRes = REGISTER_INT("r_FullscreenNativeRes", 0, VF_DUMPTODISK, "");
m_rDisplayInfo = REGISTER_INT("r_DisplayInfo", iDisplayInfoDefault, VF_RESTRICTEDMODE | VF_DUMPTODISK,
"Toggles debugging information display.\n"
"Usage: r_DisplayInfo [0=off/1=show/2=enhanced/3=compact]");
m_rOverscanBordersDrawDebugView = REGISTER_INT("r_OverscanBordersDrawDebugView", 0, VF_RESTRICTEDMODE | VF_DUMPTODISK,
"Toggles drawing overscan borders.\n"
"Usage: r_OverscanBordersDrawDebugView [0=off/1=show]");
}
void CSystem::OnScene3DEnd()
{
//Render Console
-331
View File
@@ -53,8 +53,6 @@
#endif
#include "XConsole.h"
#include "CrySizerStats.h"
#include "CrySizerImpl.h"
#include "StreamEngine/StreamEngine.h"
#include "LocalizedStringManager.h"
#include "XML/XmlUtils.h"
@@ -69,51 +67,6 @@ __pragma(comment(lib, "Winmm.lib"))
#include <AzFramework/Utils/SystemUtilsApple.h>
#endif
static AZStd::vector<AZStd::string> GetModuleNames()
{
AZStd::vector<AZStd::string> moduleNames;
if (moduleNames.empty())
{
# ifdef MODULE_EXTENSION
# error MODULE_EXTENSION already defined!
# endif
# if defined(LINUX)
# define MODULE_EXTENSION ".so"
# elif defined(APPLE)
# define MODULE_EXTENSION ".dylib"
# else
# define MODULE_EXTENSION ".dll"
# endif
moduleNames.push_back("Cry3DEngine" MODULE_EXTENSION);
moduleNames.push_back("CryFont" MODULE_EXTENSION);
moduleNames.push_back("CrySystem" MODULE_EXTENSION);
#undef MODULE_EXTENSION
# if defined(LINUX)
moduleNames.push_back("CryRenderNULL.so");
# elif defined(APPLE)
moduleNames.push_back("CryRenderNULL.dylib");
# else
moduleNames.push_back("Editor.exe");
moduleNames.push_back("CryRenderD3D9.dll");
moduleNames.push_back("CryRenderD3D10.dll");
moduleNames.push_back("CryRenderNULL.dll");
//TODO: launcher?
# endif
}
return moduleNames;
}
static bool QueryModuleMemoryInfo([[maybe_unused]] SCryEngineStatsModuleInfo& moduleInfo, [[maybe_unused]] int index)
{
return false;
}
// this is the list of modules that can be loaded into the game process
// Each array element contains 2 strings: the name of the module (case-insensitive)
// and the name of the group the module belongs to
@@ -158,30 +111,6 @@ void CSystem::SetAffinity()
#endif
}
//! dumps the memory usage statistics to the log
//////////////////////////////////////////////////////////////////////////
void CSystem::DumpMemoryUsageStatistics(bool bUseKB)
{
// CResourceCollector ResourceCollector;
// TickMemStats(nMSP_ForDump,&ResourceCollector);
TickMemStats(nMSP_ForDump);
CrySizerStatsRenderer StatsRenderer (this, m_pMemStats, 10, 0);
StatsRenderer.dump(bUseKB);
// since we've recalculated this mem stats for dumping, we'll want to calculate it anew the next time it's rendered
SAFE_DELETE(m_pMemStats);
}
// collects the whole memory statistics into the given sizer object
//////////////////////////////////////////////////////////////////////////
#if defined(WIN32)
#pragma pack(push,1)
struct PEHeader_DLL
@@ -207,162 +136,6 @@ const SmallModuleInfo* FindModuleInfo(std::vector<SmallModuleInfo>& vec, const c
return 0;
}
//////////////////////////////////////////////////////////////////////////
void CSystem::CollectMemInfo(SCryEngineStatsGlobalMemInfo& m_stats)
{
m_stats.totalUsedInModules = 0;
m_stats.totalCodeAndStatic = 0;
m_stats.countedMemoryModules = 0;
m_stats.totalAllocatedInModules = 0;
m_stats.totalNumAllocsInModules = 0;
AZStd::vector<AZStd::string> szModules = GetModuleNames();
const int numModules = szModules.size();
//////////////////////////////////////////////////////////////////////////
// Hardcoded value for the OS memory allocation.
//////////////////////////////////////////////////////////////////////////
for (int i = 0; i < numModules; i++)
{
const char* szModule = szModules[i].c_str();
SCryEngineStatsModuleInfo moduleInfo;
ZeroStruct(moduleInfo.memInfo);
moduleInfo.moduleStaticSize = moduleInfo.SizeOfCode = moduleInfo.SizeOfInitializedData = moduleInfo.SizeOfUninitializedData = moduleInfo.usedInModule = 0;
moduleInfo.name = szModule;
if (!QueryModuleMemoryInfo(moduleInfo, i))
{
continue;
}
m_stats.totalNumAllocsInModules += moduleInfo.memInfo.num_allocations;
m_stats.totalAllocatedInModules += moduleInfo.memInfo.allocated;
m_stats.totalUsedInModules += moduleInfo.usedInModule;
m_stats.countedMemoryModules++;
m_stats.totalCodeAndStatic += moduleInfo.moduleStaticSize;
m_stats.modules.push_back(moduleInfo);
}
}
void CSystem::CollectMemStats (ICrySizer* pSizer, MemStatsPurposeEnum nPurpose, std::vector<SmallModuleInfo>* pStats)
{
std::vector<SmallModuleInfo> stats;
if (pStats)
{
pStats->assign(stats.begin(), stats.end());
}
if (nMSP_ForCrashLog == nPurpose || nMSP_ForBudget == nPurpose)
{
return;
}
{
SIZER_COMPONENT_NAME(pSizer, "CrySystem");
{
pSizer->AddObject(this, sizeof(*this));
{
//SIZER_COMPONENT_NAME (pSizer, "$Allocations waste");
//const SmallModuleInfo* info = FindModuleInfo(stats, "CrySystem.dll");
//if (info)
//pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested );
}
{
SIZER_COMPONENT_NAME(pSizer, "VFS");
if (m_pStreamEngine)
{
SIZER_COMPONENT_NAME(pSizer, "Stream Engine");
m_pStreamEngine->GetMemoryStatistics(pSizer);
}
}
{
SIZER_COMPONENT_NAME(pSizer, "Localization Data");
m_pLocalizationManager->GetMemoryUsage(pSizer);
}
{
SIZER_COMPONENT_NAME(pSizer, "XML");
m_pXMLUtils->GetMemoryUsage(pSizer);
}
if (m_env.pConsole)
{
SIZER_COMPONENT_NAME (pSizer, "Console");
m_env.pConsole->GetMemoryUsage (pSizer);
}
if (m_env.pLog)
{
SIZER_COMPONENT_NAME (pSizer, "Log");
m_env.pLog->GetMemoryUsage(pSizer);
}
}
}
if (m_env.pRenderer)
{
SIZER_COMPONENT_NAME(pSizer, "CryRenderer");
{
{
SIZER_COMPONENT_NAME (pSizer, "$Allocations waste D3D9");
const SmallModuleInfo* info = FindModuleInfo(stats, "CryRenderD3D9.dll");
if (info)
{
pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested);
}
}
{
SIZER_COMPONENT_NAME (pSizer, "$Allocations waste D3D10");
const SmallModuleInfo* info = FindModuleInfo(stats, "CryRenderD3D10.dll");
if (info)
{
pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested);
}
}
m_env.pRenderer->GetMemoryUsage(pSizer);
}
}
if (m_env.pCryFont)
{
SIZER_COMPONENT_NAME(pSizer, "CryFont");
{
{
SIZER_COMPONENT_NAME (pSizer, "$Allocations waste");
const SmallModuleInfo* info = FindModuleInfo(stats, "CryFont.dll");
if (info)
{
pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested);
}
}
m_env.pCryFont->GetMemoryUsage(pSizer);
// m_pIFont and m_pIFontUi are both counted in pCryFont sizing if they exist.
// no need to manually add them here.
}
}
{
SIZER_COMPONENT_NAME(pSizer, "UserData");
if (m_pUserCallback)
{
m_pUserCallback->GetMemoryUsage(pSizer);
}
}
#ifdef WIN32
{
SIZER_COMPONENT_NAME(pSizer, "Code");
GetExeSizes (pSizer, nPurpose);
}
#endif
pSizer->End();
}
//////////////////////////////////////////////////////////////////////////
const char* CSystem::GetUserName()
{
@@ -460,52 +233,6 @@ int CSystem::GetApplicationLogInstance([[maybe_unused]] const char* logFilePath)
#endif
}
// refreshes the m_pMemStats if necessary; creates it if it's not created
//////////////////////////////////////////////////////////////////////////
void CSystem::TickMemStats(MemStatsPurposeEnum nPurpose, IResourceCollector* pResourceCollector)
{
// gather the statistics, if required
// if there's no object, or if it's time to recalculate, or if it's for dump, then recalculate it
if (!m_pMemStats || (m_env.pRenderer->GetFrameID(false) % m_cvMemStats->GetIVal()) == 0 || nPurpose == nMSP_ForDump)
{
if (!m_pMemStats)
{
if (m_cvMemStats->GetIVal() < 4 && m_cvMemStats->GetIVal())
{
GetILog()->LogToConsole("memstats is too small (%d). Performance impact can be significant. Please set to a greater value.", m_cvMemStats->GetIVal());
}
m_pMemStats = new CrySizerStats();
}
if (!m_pSizer)
{
m_pSizer = new CrySizerImpl();
}
m_pSizer->SetResourceCollector(pResourceCollector);
m_pMemStats->startTimer(0, GetITimer());
CollectMemStats (m_pSizer, nPurpose);
m_pMemStats->stopTimer(0, GetITimer());
m_pMemStats->startTimer(1, GetITimer());
CrySizerStatsBuilder builder (m_pSizer);
builder.build (m_pMemStats);
m_pMemStats->stopTimer(1, GetITimer());
m_pMemStats->startTimer(2, GetITimer());
m_pSizer->clear();
m_pMemStats->stopTimer(2, GetITimer());
}
else
{
m_pMemStats->incAgeFrames();
}
}
//#define __HASXP
// these 2 functions are duplicated in System.cpp in editor
//////////////////////////////////////////////////////////////////////////
#if !defined(LINUX)
@@ -839,51 +566,6 @@ const char* GetModuleGroup (const char* szString)
return "Other";
}
//////////////////////////////////////////////////////////////////////////
void CSystem::GetExeSizes (ICrySizer* pSizer, MemStatsPurposeEnum nPurpose)
{
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
{
CryLogAlways ("Cannot get the module snapshot, error code %d", GetLastError());
return;
}
DWORD dwProcessID = GetCurrentProcessId();
MODULEENTRY32 me;
memset (&me, 0, sizeof(me));
me.dwSize = sizeof(me);
if (Module32First (hSnapshot, &me))
{
// the sizes of each module group
StringToSizeMap mapGroupSize;
do
{
dwProcessID = me.th32ProcessID;
const char* szGroup = GetModuleGroup (me.szModule);
SIZER_COMPONENT_NAME(pSizer, szGroup);
if (nPurpose == nMSP_ForDump)
{
SIZER_COMPONENT_NAME(pSizer, me.szModule);
pSizer->AddObject(me.modBaseAddr, me.modBaseSize);
}
else
{
pSizer->AddObject(me.modBaseAddr, me.modBaseSize);
}
} while (Module32Next(hSnapshot, &me));
}
else
{
CryLogAlways ("No modules to dump");
}
CloseHandle (hSnapshot);
}
#endif
//////////////////////////////////////////////////////////////////////////
@@ -1061,18 +743,11 @@ void CSystem::FatalError(const char* format, ...)
LogSystemInfo();
CollectMemStats(0, nMSP_ForCrashLog);
OutputDebugString(szBuffer);
#ifdef WIN32
OnFatalError(szBuffer);
if (!g_cvars.sys_no_crash_dialog)
{
ICVar* pFullscreen = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("r_Fullscreen") : 0;
if (pFullscreen && pFullscreen->GetIVal() != 0 && gEnv->pRenderer && gEnv->pRenderer->GetHWND())
{
::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE);
}
::MessageBox(NULL, szBuffer, "Open 3D Engine Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
}
@@ -1169,12 +844,6 @@ void CSystem::debug_LogCallStack(int nMaxFuncs, [[maybe_unused]] int nFlags)
// Print call stack for each find.
const char* funcs[32];
int nCount = nMaxFuncs;
int nCurFrame = 0;
if (m_env.pRenderer)
{
nCurFrame = (int)m_env.pRenderer->GetFrameID(false);
}
CryLogAlways(" ----- CallStack (Frame: %d) -----", nCurFrame);
GetISystem()->debug_GetCallStack(funcs, nCount);
for (int i = 1; i < nCount; i++) // start from 1 to skip this function.
{
@@ -1,102 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "CrySystem_precompiled.h"
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/UnitTest/UnitTest.h>
#include <AzTest/AzTest.h>
#include <AzCore/Memory/OSAllocator.h>
#include "CrySizerImpl.h"
namespace UnitTest
{
class CrySizerTest
: public AllocatorsFixture
{
public:
void SetUp() override
{
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
AZ::AllocatorInstance<CryStringAllocator>::Create();
m_sizer = new CrySizerImpl();
}
void TearDown() override
{
delete m_sizer;
AZ::AllocatorInstance<CryStringAllocator>::Destroy();
AZ::AllocatorInstance<AZ::LegacyAllocator>::Destroy();
}
protected:
CrySizerImpl* m_sizer;
}; //class StatisticsTest
/**
* The key data structures fed to ICrySizer in CTerrain::GetMemoryUsage(class ICrySizer* pSizer):
* 1. structs and classes.
* 2. PodArray< of structs / classes>
* 3. PodArray< of pointers>
*/
TEST_F(CrySizerTest, CrySizerTest_AddSomeObjectsUsedInCTerrain_GetExpectedSize)
{
struct TmpStruct
{
AZ::u32 a;
AZ::u32 b;
};
TmpStruct tmpStructObj;
//Tracking a simple struct.
m_sizer->AddObjectSize(&tmpStructObj);
//The AddObject method is only available when using the ICrySizer base class.
ICrySizer* sizer = static_cast<ICrySizer*>(m_sizer);
const int numItemsPerArray = 1024;
//PodArray of structs
PodArray<TmpStruct> podArrayOfTmpStruct;
podArrayOfTmpStruct.resize(numItemsPerArray);
sizer->AddObject(podArrayOfTmpStruct);
//PodArray of pointers
PodArray<TmpStruct*> podArrayOfTmpStructPointers;
podArrayOfTmpStructPointers.resize(numItemsPerArray);
sizer->AddObject(podArrayOfTmpStructPointers);
//PodArray of Array2d of pointers.
const int array2dAxisSize = 64;
PodArray<Array2d<TmpStruct*>> podArrayOfArray2d;
podArrayOfArray2d.resize(numItemsPerArray);
for (int i = 0; i < numItemsPerArray; ++i)
{
//Array2d will allocate array2dAxisSize * array2dAxisSize elements.
podArrayOfArray2d[i].Allocate(array2dAxisSize);
}
sizer->AddObject(podArrayOfArray2d);
//Calculate the total expected size
const size_t expectedSizeOfArray2d = sizeof(Array2d<TmpStruct*>)
+ (array2dAxisSize * array2dAxisSize) * sizeof(TmpStruct*);
const size_t expectedTotalSize = sizeof(TmpStruct)
+ numItemsPerArray * sizeof(TmpStruct)
+ numItemsPerArray * sizeof(TmpStruct*)
+ numItemsPerArray * expectedSizeOfArray2d;
EXPECT_EQ( m_sizer->GetTotalSize(), expectedTotalSize);
}
}//namespace UnitTest
+4 -7
View File
@@ -26,9 +26,6 @@
#include "Mmsystem.h"
#endif
//this should not be included here
#include <IRenderer.h> // needed for m_pSystem->GetIRenderer()->EF_Query(EFQ_RecurseLevel)
//#define PROFILING 1
#ifdef PROFILING
static int64 g_lCurrentTime = 0;
@@ -432,7 +429,7 @@ void CTimer::UpdateOnFrameStart()
if (m_TimeDebug > 1)
{
CryLogAlways("[CTimer]: Frame=%d Cur=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)currentTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
CryLogAlways("[CTimer]: Cur=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)currentTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
@@ -558,7 +555,7 @@ void CTimer::Serialize(TSerialize ser)
if (m_TimeDebug)
{
const int64 now = CryGetTicks();
CryLogAlways("[CTimer]: Serialize: Frame=%d Last=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)m_lLastTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
CryLogAlways("[CTimer]: Serialize: Last=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
}
@@ -584,7 +581,7 @@ bool CTimer::PauseTimer(ETimer which, bool bPause)
m_lGameTimerPausedTime = m_lLastTime + m_lOffsetTime;
if (m_TimeDebug)
{
CryLogAlways("[CTimer]: Pausing ON: Frame=%d Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
CryLogAlways("[CTimer]: Pausing ON: Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
else
@@ -593,7 +590,7 @@ bool CTimer::PauseTimer(ETimer which, bool bPause)
m_lGameTimerPausedTime = 0;
if (m_TimeDebug)
{
CryLogAlways("[CTimer]: Pausing OFF: Frame=%d Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
CryLogAlways("[CTimer]: Pausing OFF: Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
-5
View File
@@ -43,11 +43,6 @@ struct SDefaultValidator
}
#ifdef WIN32
ICVar* pFullscreen = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("r_Fullscreen") : 0;
if (pFullscreen && pFullscreen->GetIVal() != 0 && gEnv->pRenderer && gEnv->pRenderer->GetHWND())
{
::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE);
}
string strMessage = record.text;
strMessage += "\n---------------------------------------------\nAbort - terminate application\nRetry - continue running the application\nIgnore - don't show this message box any more";
switch (::MessageBox(NULL, strMessage.c_str(), "CryEngine Warning", MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 | MB_ICONWARNING | MB_SYSTEMMODAL))
@@ -137,15 +137,6 @@ void DebugCamera::PostUpdate()
CCamera& camera = gEnv->pSystem->GetViewCamera();
camera.SetMatrix(Matrix34(m_view, m_position));
const float FONT_COLOR[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
gEnv->pRenderer->Draw2dLabel(0.0f, 700.0f, 1.3f, FONT_COLOR, false,
"Debug Camera: pos [ %.3f, %.3f, %.3f ] p/y [ %.1f, %.1f ] dir [ %.3f, %.3f, %.3f ] scl %.2f inv %d",
m_position.x, m_position.y, m_position.z,
m_cameraPitch, m_cameraYaw,
m_view.GetColumn1().x, m_view.GetColumn1().y, m_view.GetColumn1().z,
m_moveScale,
m_isYInverted);
}
///////////////////////////////////////////////////////////////////////////////
@@ -101,25 +101,6 @@ void CView::Update(float frameTime, bool isActive)
const float farPlane = (m_viewParams.farplane > 0.f) ? m_viewParams.farplane : DEFAULT_FAR;
float fov = (m_viewParams.fov < 0.001f) ? DEFAULT_FOV : m_viewParams.fov;
// [VR] specific
// Modify FOV based on the HMD device configuration
bool isRenderingToHMD = gEnv->pRenderer ? gEnv->pRenderer->GetIStereoRenderer()->IsRenderingToHMD() : false;
if (isRenderingToHMD)
{
const AZ::VR::HMDDeviceInfo* deviceInfo = nullptr;
EBUS_EVENT_RESULT(deviceInfo, AZ::VR::HMDDeviceRequestBus, GetDeviceInfo);
if (deviceInfo)
{
//Add 12 degrees to the FOV here used for culling.
//It won't be used for rendering, just to make sure we don't cull
//anything out incorrectly.
//This value was decided based on experimentation with the HTC Vive
//and works perfectly fine for the Oculus Rift
const float fovCorrection = 12.0f;
fov = deviceInfo->fovV + DEG2RAD(fovCorrection);
}
}
m_camera.SetFrustum(pSysCam->GetViewSurfaceX(), pSysCam->GetViewSurfaceZ(), fov, nearPlane, farPlane, pSysCam->GetPixelAspectRatio());
//apply shake & set the view matrix
@@ -140,20 +121,6 @@ void CView::Update(float frameTime, bool isActive)
Vec3 pos = m_viewParams.position;
Vec3 p = Vec3(ZERO);
if (isRenderingToHMD)
{
//This HMD tracking state is used JUST for use in the visibility system.
//RT_SetStereoCamera in D3DRendPipeline will override this info before rendering with the absolute
//latest tracking info.
const AZ::VR::TrackingState* trackingState = nullptr;
EBUS_EVENT_RESULT(trackingState, AZ::VR::HMDDeviceRequestBus, GetTrackingState);
if (trackingState && trackingState->CheckStatusFlags(AZ::VR::HMDStatus_IsUsable))
{
p = q * AZVec3ToLYVec3(trackingState->pose.position);
q = q * AZQuaternionToLYQuaternion(trackingState->pose.orientation);
}
}
Matrix34 viewMtx(q);
viewMtx.SetTranslation(pos + p);
m_camera.SetMatrix(viewMtx);
@@ -640,30 +640,6 @@ void CViewSystem::ClearAllViews()
////////////////////////////////////////////////////////////////////
void CViewSystem::DebugDraw()
{
IRenderer* pRenderer = gEnv->pRenderer;
if (pRenderer)
{
float xpos = 20;
float ypos = 15;
float fColor[4] = {1.0f, 1.0f, 1.0f, 0.7f};
float fColorRed[4] = {1.0f, 0.0f, 0.0f, 0.7f};
float fColorGreen[4] = {0.0f, 1.0f, 0.0f, 0.7f};
pRenderer->Draw2dLabel(xpos, 5, 1.35f, fColor, false, "ViewSystem Stats: %" PRISIZE_T " Views ", m_views.size());
IView* pActiveView = GetActiveView();
for (TViewMap::iterator it = m_views.begin(); it != m_views.end(); ++it)
{
IView* pView = it->second;
const CCamera& cam = pView->GetCamera();
bool isActive = (pView == pActiveView);
Vec3 pos = cam.GetPosition();
Ang3 ang = cam.GetAngles();
pRenderer->Draw2dLabel(xpos, ypos, 1.35f, isActive ? fColorGreen : fColorRed, false, "View Camera: %p . View Id: %d, pos (%f, %f, %f), ang (%f, %f, %f)", &cam, it->first, pos.x, pos.y, pos.z, ang.x, ang.y, ang.z);
ypos += 11;
}
}
}
//////////////////////////////////////////////////////////////////////////
-384
View File
@@ -1,384 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Visual Regression Test
#include "CrySystem_precompiled.h"
#include "VisRegTest.h"
#include "ISystem.h"
#include "IRenderer.h"
#include "IConsole.h"
#include "ITimer.h"
#include "IStreamEngine.h"
#include <Pak/CryPakUtils.h>
#include <AzFramework/IO/FileOperations.h>
const float CVisRegTest::MaxStreamingWait = 30.0f;
CVisRegTest::CVisRegTest()
: m_nextCmd(0)
, m_waitFrames(0)
{
CryLog("Enabled visual regression tests");
}
void CVisRegTest::Init(IConsoleCmdArgs* pParams)
{
assert(pParams);
stack_string configFile("visregtest.xml");
// Reset
m_cmdBuf.clear();
m_dataSamples.clear();
m_nextCmd = 0;
m_cmdFreq = 0;
m_waitFrames = 0;
m_streamingTimeout = 0.0f;
m_testName = "test";
m_quitAfterTests = false;
// Parse arguments
if (pParams->GetArgCount() >= 2)
{
m_testName = pParams->GetArg(1);
}
if (pParams->GetArgCount() >= 3)
{
configFile = pParams->GetArg(2);
}
if (pParams->GetArgCount() >= 4)
{
if (_stricmp(pParams->GetArg(3), "quit") == 0)
{
m_quitAfterTests = true;
}
}
// Fill cmd buffer
if (!LoadConfig(configFile.c_str()))
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "VisRegTest: Failed to load config file '%s' from game folder", configFile.c_str());
return;
}
gEnv->pTimer->SetTimeScale(0);
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RANDOM_SEED, 0, 0);
srand(0);
gEnv->pRenderer->EnableGPUTimers2(true);
}
void CVisRegTest::AfterRender()
{
ExecCommands();
}
bool CVisRegTest::LoadConfig(const char* configFile)
{
XmlNodeRef rootNode = GetISystem()->LoadXmlFromFile(configFile);
if (!rootNode || !rootNode->isTag("VisRegTest"))
{
return false;
}
m_cmdBuf.push_back(SCmd(eCMDStart, ""));
for (int i = 0; i < rootNode->getChildCount(); ++i)
{
XmlNodeRef node = rootNode->getChild(i);
if (node->isTag("Config"))
{
SCmd cmd;
for (int j = 0; j < node->getChildCount(); ++j)
{
XmlNodeRef node2 = node->getChild(j);
if (node2->isTag("ConsoleCmd"))
{
m_cmdBuf.push_back(SCmd(eCMDConsoleCmd, node2->getAttr("cmd")));
}
}
}
else if (node->isTag("Map"))
{
const char* mapName = node->getAttr("name");
int imageIndex = 0;
m_cmdBuf.push_back(SCmd(eCMDLoadMap, mapName));
m_cmdBuf.push_back(SCmd(eCMDOnMapLoaded, ""));
for (int j = 0; j < node->getChildCount(); ++j)
{
XmlNodeRef node2 = node->getChild(j);
if (node2->isTag("ConsoleCmd"))
{
m_cmdBuf.push_back(SCmd(eCMDConsoleCmd, node2->getAttr("cmd")));
}
else if (node2->isTag("Sample"))
{
m_cmdBuf.push_back(SCmd(eCMDGoto, node2->getAttr("location")));
m_cmdBuf.push_back(SCmd(eCMDWaitStreaming, ""));
char strbuf[256];
#ifdef WIN32
sprintf_s(strbuf, "%s_%i.bmp", mapName, imageIndex++);
#else
sprintf_s(strbuf, "%s_%i.tga", mapName, imageIndex++);
#endif
m_cmdBuf.push_back(SCmd(eCMDCaptureSample, strbuf, SampleCount));
}
}
}
}
m_cmdBuf.push_back(SCmd(eCMDFinish, ""));
return true;
}
void CVisRegTest::ExecCommands()
{
if (m_nextCmd >= m_cmdBuf.size())
{
return;
}
float col[] = {0, 1, 0, 1};
gEnv->pRenderer->Draw2dLabel(10, 10, 2, col, false, "Visual Regression Test");
if (m_waitFrames > 0)
{
--m_waitFrames;
return;
}
else if (m_waitFrames < 0) // Wait for streaming
{
SStreamEngineOpenStats stats;
gEnv->pSystem->GetStreamEngine()->GetStreamingOpenStatistics(stats);
if (stats.nOpenRequestCount > 0 && m_streamingTimeout > 0)
{
gEnv->pConsole->ExecuteString("t_FixedStep 0");
m_streamingTimeout -= gEnv->pTimer->GetRealFrameTime();
m_waitFrames = -16;
}
else if (++m_waitFrames == 0)
{
gEnv->pConsole->ExecuteString("t_FixedStep 0.033333");
m_waitFrames = 64; // Wait some more frames for tone-mapper to adapt
}
return;
}
stack_string tmp;
while (m_nextCmd < m_cmdBuf.size())
{
SCmd& cmd = m_cmdBuf[m_nextCmd];
if (m_cmdFreq == 0)
{
m_cmdFreq = cmd.freq;
}
switch (cmd.cmd)
{
case eCMDStart:
break;
case eCMDFinish:
Finish();
break;
case eCMDOnMapLoaded:
gEnv->pTimer->SetTimer(ITimer::ETIMER_GAME, 0);
gEnv->pTimer->SetTimer(ITimer::ETIMER_UI, 0);
gEnv->pConsole->ExecuteString("t_FixedStep 0.033333");
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RANDOM_SEED, 0, 0);
srand(0);
break;
case eCMDConsoleCmd:
gEnv->pConsole->ExecuteString(cmd.args.c_str());
break;
case eCMDLoadMap:
LoadMap(cmd.args.c_str());
break;
case eCMDWaitStreaming:
m_waitFrames = -1;
m_streamingTimeout = MaxStreamingWait;
break;
case eCMDWaitFrames:
m_waitFrames = (uint32)atoi(cmd.args.c_str());
break;
case eCMDGoto:
tmp = "playerGoto ";
tmp.append(cmd.args.c_str());
gEnv->pConsole->ExecuteString(tmp.c_str());
m_waitFrames = 1;
break;
case eCMDCaptureSample:
CaptureSample(cmd);
break;
}
if (m_cmdFreq-- == 1)
{
++m_nextCmd;
}
if (m_waitFrames != 0)
{
break;
}
}
}
void CVisRegTest::LoadMap(const char* mapName)
{
string mapCmd("map ");
mapCmd.append(mapName);
gEnv->pConsole->ExecuteString(mapCmd.c_str());
gEnv->pTimer->SetTimer(ITimer::ETIMER_GAME, 0);
gEnv->pTimer->SetTimer(ITimer::ETIMER_UI, 0);
gEnv->pConsole->ExecuteString("t_FixedStep 0");
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RANDOM_SEED, 0, 0);
srand(0);
}
void CVisRegTest::CaptureSample(const SCmd& cmd)
{
if (m_cmdFreq == SampleCount) // First sample
{
m_dataSamples.push_back(SSample());
gEnv->pConsole->ExecuteString("t_FixedStep 0");
}
SSample& sample = m_dataSamples.back();
// Collect stats
sample.imageName = cmd.args.c_str();
sample.frameTime += gEnv->pTimer->GetRealFrameTime() * 1000.f;
sample.drawCalls += gEnv->pRenderer->GetCurrentNumberOfDrawCalls();
const RPProfilerStats* pRPPStats = gEnv->pRenderer->GetRPPStatsArray();
if (pRPPStats)
{
sample.gpuTimes[0] += pRPPStats[eRPPSTATS_OverallFrame].gpuTime;
sample.gpuTimes[1] += pRPPStats[eRPPSTATS_SceneOverall].gpuTime;
sample.gpuTimes[2] += pRPPStats[eRPPSTATS_ShadowsOverall].gpuTime;
sample.gpuTimes[3] += pRPPStats[eRPPSTATS_LightingOverall].gpuTime;
sample.gpuTimes[4] += pRPPStats[eRPPSTATS_VfxOverall].gpuTime;
}
if (m_cmdFreq == 1) // Final sample
{
// Screenshot
stack_string filename("@usercache@/TestResults/VisReg/"); // the default unaliased assets folder is read-only!
filename += m_testName + "/" + cmd.args.c_str();
gEnv->pRenderer->ScreenShot(filename);
// Average results
sample.frameTime /= (float)SampleCount;
sample.drawCalls /= SampleCount;
for (uint32 i = 0; i < MaxNumGPUTimes; ++i)
{
sample.gpuTimes[i] /= (float)SampleCount;
}
gEnv->pConsole->ExecuteString("t_FixedStep 0.033333");
}
}
void CVisRegTest::Finish()
{
WriteResults();
gEnv->pConsole->ExecuteString("t_FixedStep 0");
gEnv->pTimer->SetTimeScale(1);
gEnv->pRenderer->EnableGPUTimers2(false);
CryLog("VisRegTest: Finished tests");
if (m_quitAfterTests)
{
gEnv->pConsole->ExecuteString("quit");
return;
}
}
bool CVisRegTest::WriteResults()
{
stack_string filename("@usercache@/TestResults/VisReg/");
filename += m_testName + "/visreg_results.xml";
AZ::IO::HandleType fileHandle = fxopen(filename.c_str(), "wb");
if (fileHandle == AZ::IO::InvalidHandle)
{
return false;
}
AZ::IO::Print(fileHandle, "<testsuites>\n");
AZ::IO::Print(fileHandle, "\t<testsuite name=\"Visual Regression Test\" LevelName=\"\">\n");
for (int i = 0; i < (int)m_dataSamples.size(); ++i)
{
SSample sample = m_dataSamples[i];
AZ::IO::Print(fileHandle, "\t\t<phase name=\"%i\" duration=\"1\" image=\"%s\">\n", i, sample.imageName);
AZ::IO::Print(fileHandle, "\t\t\t<metrics name=\"general\">\n");
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"frameTime\" value=\"%f\" />\n", sample.frameTime);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"drawCalls\" value=\"%i\" />\n", sample.drawCalls);
AZ::IO::Print(fileHandle, "\t\t\t</metrics>\n");
AZ::IO::Print(fileHandle, "\t\t\t<metrics name=\"gpu_times\">\n");
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"scene\" value=\"%f\" />\n", sample.gpuTimes[0]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"shadows\" value=\"%f\" />\n", sample.gpuTimes[1]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"zpass\" value=\"%f\" />\n", sample.gpuTimes[2]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"deferred_decals\" value=\"%f\" />\n", sample.gpuTimes[3]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"deferred_lighting\" value=\"%f\" />\n", sample.gpuTimes[4]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"dl_ambient\" value=\"%f\" />\n", sample.gpuTimes[5]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"dl_cubemaps\" value=\"%f\" />\n", sample.gpuTimes[6]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"dl_lights\" value=\"%f\" />\n", sample.gpuTimes[7]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"gi_and_ssao\" value=\"%f\" />\n", sample.gpuTimes[8]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"opaque\" value=\"%f\" />\n", sample.gpuTimes[9]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"transparent\" value=\"%f\" />\n", sample.gpuTimes[10]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"hdr\" value=\"%f\" />\n", sample.gpuTimes[11]);
AZ::IO::Print(fileHandle, "\t\t\t\t<metric name=\"postfx\" value=\"%f\" />\n", sample.gpuTimes[12]);
AZ::IO::Print(fileHandle, "\t\t\t</metrics>\n");
AZ::IO::Print(fileHandle, "\t\t</phase>\n");
}
AZ::IO::Print(fileHandle, "\t</testsuite>\n");
AZ::IO::Print(fileHandle, "</testsuites>");
gEnv->pFileIO->Close(fileHandle);
return true;
}
-104
View File
@@ -1,104 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Visual Regression Test
#ifndef CRYINCLUDE_CRYSYSTEM_VISREGTEST_H
#define CRYINCLUDE_CRYSYSTEM_VISREGTEST_H
#pragma once
struct IConsoleCmdArgs;
class CVisRegTest
{
public:
static const uint32 SampleCount = 16;
static const uint32 MaxNumGPUTimes = 13;
static const float MaxStreamingWait;
protected:
enum ECmd
{
eCMDStart,
eCMDFinish,
eCMDOnMapLoaded,
eCMDConsoleCmd,
eCMDLoadMap,
eCMDWaitStreaming,
eCMDWaitFrames,
eCMDGoto,
eCMDCaptureSample
};
struct SCmd
{
ECmd cmd;
uint32 freq;
string args;
SCmd() {}
SCmd(ECmd _cmd, const string& _args, uint32 _freq = 1)
{ this->cmd = _cmd; this->args = _args; this->freq = _freq; }
};
struct SSample
{
const char* imageName;
float frameTime;
uint32 drawCalls;
float gpuTimes[MaxNumGPUTimes];
SSample()
: imageName(NULL)
, frameTime(0.f)
, drawCalls(0)
{
for (uint32 i = 0; i < MaxNumGPUTimes; ++i)
{
gpuTimes[i] = 0;
}
}
};
protected:
string m_testName;
std::vector< SCmd > m_cmdBuf;
std::vector< SSample > m_dataSamples;
uint32 m_nextCmd;
uint32 m_cmdFreq;
int m_waitFrames;
float m_streamingTimeout;
int m_curSample;
bool m_quitAfterTests;
public:
CVisRegTest();
void Init(IConsoleCmdArgs* pParams);
void AfterRender();
protected:
bool LoadConfig(const char* configFile);
void ExecCommands();
void LoadMap(const char* mapName);
void CaptureSample(const SCmd& cmd);
void Finish();
bool WriteResults();
};
#endif // CRYINCLUDE_CRYSYSTEM_VISREGTEST_H
+4 -352
View File
@@ -328,7 +328,6 @@ CXConsole::CXConsole()
m_fRepeatTimer = 0;
m_pSysDeactivateConsole = 0;
m_pFont = NULL;
m_pRenderer = NULL;
m_pImage = NULL;
m_nCursorPos = 0;
m_nScrollPos = 0;
@@ -397,18 +396,6 @@ CXConsole::~CXConsole()
//////////////////////////////////////////////////////////////////////////
void CXConsole::FreeRenderResources()
{
if (m_pRenderer)
{
if (m_nLoadingBackTexID)
{
m_pRenderer->RemoveTexture(m_nLoadingBackTexID);
m_nLoadingBackTexID = -1;
}
if (m_pImage)
{
m_pImage->Release();
}
}
}
//////////////////////////////////////////////////////////////////////////
@@ -485,7 +472,6 @@ void CXConsole::Init(ISystem* pSystem)
{
m_pFont = pSystem->GetICryFont()->GetFont("default");
}
m_pRenderer = pSystem->GetIRenderer();
m_pTimer = pSystem->GetITimer();
AzFramework::InputChannelEventListener::Connect();
@@ -534,10 +520,7 @@ void CXConsole::Init(ISystem* pSystem)
// ----------------------------------------------------------
if (!m_pRenderer || gEnv->IsInToolMode())
{
m_nLoadingBackTexID = -1;
}
m_nLoadingBackTexID = -1;
if (gEnv->IsDedicated())
{
@@ -1176,7 +1159,6 @@ void CXConsole::Clear()
//////////////////////////////////////////////////////////////////////////
void CXConsole::Update()
{
// Repeat GetIRenderer (For Editor).
if (!m_pSystem)
{
return;
@@ -1192,8 +1174,6 @@ void CXConsole::Update()
// Execute the deferred commands
ExecuteDeferredCommands();
m_pRenderer = m_pSystem->GetIRenderer();
if (!m_bConsoleActive)
{
m_nRepeatEventId = s_nullRepeatEventId;
@@ -1588,206 +1568,10 @@ const char* CXConsole::GetHistoryElement(const bool bUpOrDown)
//////////////////////////////////////////////////////////////////////////
void CXConsole::Draw()
{
//ShowConsole(true);
if (!m_pSystem || !m_nTempScrollMax)
{
return;
}
if (!m_pRenderer)
{
// For Editor.
m_pRenderer = m_pSystem->GetIRenderer();
}
if (!m_pRenderer)
{
return;
}
if (!m_pFont)
{
// For Editor.
ICryFont* pICryFont = m_pSystem->GetICryFont();
if (pICryFont)
{
m_pFont = m_pSystem->GetICryFont()->GetFont("default");
}
}
ScrollConsole();
if (!m_bConsoleActive && con_display_last_messages == 0)
{
return;
}
if (m_pRenderer->GetIRenderAuxGeom())
{
m_pRenderer->GetIRenderAuxGeom()->Flush();
}
m_pRenderer->EF_RenderTextMessages();
m_pRenderer->PushProfileMarker("DISPLAY_CONSOLE");
if (m_nScrollPos <= 0)
{
DrawBuffer(70, "console");
}
else
{
// cursor blinking
{
m_fCursorBlinkTimer += gEnv->pTimer->GetRealFrameTime(); // works even when time is manipulated
// m_fCursorBlinkTimer += gEnv->pTimer->GetFrameTime(ITimer::ETIMER_UI); // can be used once ETIMER_UI works even with t_FixedTime
const float fCursorBlinkDelay = 0.5f; // in sec (similar to Windows default but might differ from actual setting)
if (m_fCursorBlinkTimer > fCursorBlinkDelay)
{
m_bDrawCursor = !m_bDrawCursor;
m_fCursorBlinkTimer = 0.0f;
}
}
CScopedWireFrameMode scopedWireFrame(m_pRenderer, R_SOLID_MODE);
if (!m_nProgressRange)
{
int whiteTexId = gEnv->pRenderer ? gEnv->pRenderer->GetWhiteTextureId() : -1;
if (m_bStaticBackground)
{
m_pRenderer->SetState(GS_NODEPTHTEST);
m_pRenderer->Draw2dImage(0, 0, 800, 600, m_pImage ? m_pImage->GetTextureID() : whiteTexId, 0.0f, 1.0f, 1.0f, 0.0f);
}
else
{
TransformationMatrices backupSceneMatrices;
m_pRenderer->Set2DMode(m_pRenderer->GetWidth(), m_pRenderer->GetHeight(), backupSceneMatrices);
float fReferenceSize = 600.0f;
float fSizeX = (float)m_pRenderer->GetWidth();
float fSizeY = m_nTempScrollMax * m_pRenderer->GetHeight() / fReferenceSize;
m_pRenderer->SetState(GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA);
m_pRenderer->DrawImage(0, 0, fSizeX, fSizeY, whiteTexId, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.7f);
m_pRenderer->DrawImage(0, fSizeY, fSizeX, 2.0f * m_pRenderer->GetHeight() / fReferenceSize, whiteTexId, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 1.0f);
m_pRenderer->Unset2DMode(backupSceneMatrices);
}
}
// draw progress bar
if (m_nProgressRange)
{
m_pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
m_pRenderer->Draw2dImage(0.0, 0.0, 800.0f, 600.0f, m_nLoadingBackTexID, 0.0f, 1.0f, 1.0f, 0.0f);
}
DrawBuffer(m_nScrollPos, "console");
}
m_pRenderer->PopProfileMarker("DISPLAY_CONSOLE");
}
void CXConsole::DrawBuffer(int nScrollPos, const char* szEffect)
void CXConsole::DrawBuffer(int, const char*)
{
if (m_pFont && m_pRenderer)
{
// The scroll position is in pixels for a 800x600 screen so we scale it to the current resolution.
Vec2 referenceSize(800.0f, 600.0f);
const float fontSizeIn800x600 = 14;
const float maxYPos = nScrollPos * (m_pRenderer->GetHeight() / referenceSize.y);
// We also scale the font from the original 800x600 size
float fontSize = fontSizeIn800x600 * (m_pRenderer->GetWidth() / referenceSize.x);
const float fontAspectRatio = 0.75f;
float minFontSize = 10.f;
float maxFontSize = 50.f;
ICVar* minFontCVar = GetCVar("r_minConsoleFontSize");
if (minFontCVar)
{
minFontSize = minFontCVar->GetFVal();
}
ICVar* maxFontCVar = GetCVar("r_maxConsoleFontSize");
if (maxFontCVar)
{
maxFontSize = maxFontCVar->GetFVal();
}
// Limit max font size in case minFontSize > maxFontSize
maxFontSize = AZStd::max(minFontSize, maxFontSize);
fontSize = AZStd::min(AZStd::max(fontSize, minFontSize), maxFontSize);
STextDrawContext ctx;
//ctx.Reset();
ctx.SetEffect(m_pFont->GetEffectId(szEffect));
ctx.SetProportional(false);
ctx.SetCharWidthScale(0.5f);
ctx.SetSize(Vec2(fontSize, fontAspectRatio * fontSize));
ctx.SetColor(ColorF(1, 1, 1, 1));
ctx.SetFlags(eDrawText_CenterV | eDrawText_2D);
float csize = 0.8f * ctx.GetCharHeight();
ctx.SetSizeIn800x600(false);
float yPos = maxYPos - csize - 3.0f;
float xPos = LINE_BORDER;
float fCharWidth = (ctx.GetCharWidth() * ctx.GetCharWidthScale());
//int ypos=nScrollPos-csize-3;
//Draw the input line
if (m_bConsoleActive && !m_nProgressRange)
{
/*m_pRenderer->DrawString(xPos-nCharWidth, yPos, false, ">");
m_pRenderer->DrawString(xPos, yPos, false, m_sInputBuffer.c_str());
if(m_bDrawCursor)
m_pRenderer->DrawString(xPos+nCharWidth*m_nCursorPos, yPos, false, "_");*/
m_pFont->DrawString((float)(xPos - fCharWidth), (float)yPos, ">", false, ctx);
m_pFont->DrawString((float)xPos, (float)yPos, m_sInputBuffer.c_str(), false, ctx);
if (m_bDrawCursor)
{
string szCursorLeft(m_sInputBuffer.c_str(), m_sInputBuffer.c_str() + m_nCursorPos);
int n = m_pFont->GetTextLength(szCursorLeft.c_str(), false);
m_pFont->DrawString((float)(xPos + (fCharWidth * n)), (float)yPos, "_", false, ctx);
}
}
yPos -= csize;
ConsoleBufferRItor ritor;
ritor = m_dqConsoleBuffer.rbegin();
int nScroll = 0;
while (ritor != m_dqConsoleBuffer.rend() && yPos >= 0)
{
if (nScroll >= m_nScrollLine)
{
const char* buf = ritor->c_str();// GetBuf(k);
if (*buf > 0 && *buf < 32)
{
buf++; // to jump over verbosity level character
}
if (yPos + csize > 0)
{
m_pFont->DrawString((float)xPos, (float)yPos, buf, false, ctx);
}
yPos -= csize;
}
nScroll++;
++ritor;
} //k
}
}
@@ -1828,44 +1612,6 @@ int CXConsole::GetLineCount() const
//////////////////////////////////////////////////////////////////////////
void CXConsole::ScrollConsole()
{
if (!m_pRenderer)
{
return;
}
int nCurrHeight = m_pRenderer->GetHeight();
switch (m_sdScrollDir)
{
/////////////////////////////////
case sdDOWN: // The console is scrolling down
// Vlads note: console should go down immediately, otherwise it can look very bad on startup
//m_nScrollPos+=nCurrHeight/2;
m_nScrollPos = m_nTempScrollMax;
if (m_nScrollPos > m_nTempScrollMax)
{
m_nScrollPos = m_nTempScrollMax;
m_sdScrollDir = sdNONE;
}
break;
/////////////////////////////////
case sdUP: // The console is scrolling up
m_nScrollPos -= nCurrHeight;//2;
if (m_nScrollPos < 0)
{
m_nScrollPos = 0;
m_sdScrollDir = sdNONE;
}
break;
/////////////////////////////////
case sdNONE:
break;
/////////////////////////////////
}
}
@@ -2467,13 +2213,6 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso
if (!sTemp.empty() || (pCVar->GetType() == CVAR_STRING))
{
// renderer cvars will be updated in the render thread
if ((pCVar->GetFlags() & VF_RENDERER_CVAR) && m_pRenderer)
{
m_pRenderer->SetRendererCVar(pCVar, sTemp.c_str(), bSilentMode);
continue;
}
pCVar->Set(sTemp.c_str());
}
}
@@ -2500,36 +2239,8 @@ void CXConsole::ExecuteDeferredCommands()
{
TDeferredCommandList::iterator it;
// const float fontHeight = 10;
// ColorF col = Col_Yellow;
//
// float curX = 10;
// float curY = 10;
//IRenderer* pRenderer = gEnv->pRenderer;
// Print the deferred messages
// it = m_deferredCommands.begin();
// if (it != m_deferredCommands.end())
// {
// pRenderer->Draw2dLabel( curX, curY += fontHeight, 1.2f, &col.r, false
// , "Pending deferred commands = %d", m_deferredCommands.size() );
// }
//
// for (
// ; it != m_deferredCommands.end()
// ; ++it
// )
// {
// pRenderer->Draw2dLabel( curX + fontHeight * 2.0f, curY += fontHeight, 1.2f, &col.r, false
// , "Cmd: %s", it->command.c_str() );
// }
if (m_waitFrames)
{
// pRenderer->Draw2dLabel( curX, curY += fontHeight, 1.2f, &col.r, false
// , "Waiting frames = %d", m_waitFrames );
--m_waitFrames;
return;
}
@@ -2538,10 +2249,6 @@ void CXConsole::ExecuteDeferredCommands()
{
if (m_waitSeconds > gEnv->pTimer->GetFrameStartTime())
{
// pRenderer->Draw2dLabel( curX, curY += fontHeight, 1.2f, &col.r, false
// , "Waiting seconds = %f"
// , m_waitSeconds.GetSeconds() - gEnv->pTimer->GetFrameStartTime().GetSeconds() );
return;
}
@@ -2566,8 +2273,6 @@ void CXConsole::ExecuteDeferredCommands()
break;
}
}
//m_deferredExecution = false;
}
//////////////////////////////////////////////////////////////////////////
@@ -3143,71 +2848,18 @@ void CXConsole::PostLine(const char* lineOfText, size_t len)
}
//////////////////////////////////////////////////////////////////////////
void CXConsole::ResetProgressBar(int nProgressBarRange)
void CXConsole::ResetProgressBar(int)
{
m_nProgressRange = nProgressBarRange;
m_nProgress = 0;
if (nProgressBarRange < 0)
{
nProgressBarRange = 0;
}
if (!m_nProgressRange)
{
if (m_nLoadingBackTexID)
{
if (m_pRenderer)
{
m_pRenderer->RemoveTexture(m_nLoadingBackTexID);
}
m_nLoadingBackTexID = -1;
}
}
static ICVar* log_Verbosity = GetCVar("log_Verbosity");
if (log_Verbosity && (!log_Verbosity->GetIVal()))
{
Clear();
}
}
//////////////////////////////////////////////////////////////////////////
void CXConsole::TickProgressBar()
{
if (m_nProgressRange != 0 && m_nProgressRange > m_nProgress)
{
m_nProgress++;
m_pSystem->UpdateLoadingScreen();
}
if (m_pSystem->GetIRenderer())
{
m_pSystem->GetIRenderer()->FlushRTCommands(false, false, false); // Try to switch render thread contexts to make RT always busy during loading
}
}
//////////////////////////////////////////////////////////////////////////
void CXConsole::SetLoadingImage(const char* szFilename)
void CXConsole::SetLoadingImage(const char*)
{
ITexture* pTex = 0;
pTex = m_pSystem->GetIRenderer()->EF_LoadTexture(szFilename, FT_DONT_STREAM | FT_NOMIPS);
if (!pTex || (pTex->GetFlags() & FT_FAILED))
{
SAFE_RELEASE(pTex);
pTex = m_pSystem->GetIRenderer()->EF_LoadTexture("Textures/Console/loadscreen_default.dds", FT_DONT_STREAM | FT_NOMIPS);
}
if (pTex)
{
m_nLoadingBackTexID = pTex->GetTextureID();
}
else
{
m_nLoadingBackTexID = -1;
}
}
//////////////////////////////////////////////////////////////////////////
-1
View File
@@ -418,7 +418,6 @@ private: // ----------------------------------------------------------
CSystem* m_pSystem;
IFFont* m_pFont;
IRenderer* m_pRenderer;
ITimer* m_pTimer;
ICVar* m_pSysDeactivateConsole;
@@ -19,7 +19,6 @@ set(FILES
ConsoleBatchFile.cpp
ConsoleHelpGen.cpp
CryAsyncMemcpy.cpp
CrySizerStats.cpp
DebugCallStack.cpp
GeneralMemoryHeap.cpp
HandlerBase.cpp
@@ -57,7 +56,6 @@ set(FILES
UnixConsole.h
SystemInit.h
Serialization/MemoryReader.h
MemoryFragmentationProfiler.h
XML/ReadWriteXMLSink.h
Serialization/ArchiveHost.h
Serialization/MemoryWriter.h
@@ -70,7 +68,6 @@ set(FILES
CmdLineArg.h
ConsoleBatchFile.h
ConsoleHelpGen.h
CrySizerStats.h
CryWaterMark.h
DebugCallStack.h
GeneralMemoryHeap.h
@@ -92,13 +89,11 @@ set(FILES
crash_face.bmp
ImageHandler.h
ImageHandler.cpp
DefragAllocator.cpp
MemoryAddressRange.cpp
PageMappingHeap.cpp
CustomMemoryHeap.cpp
MemoryManager.cpp
MTSafeAllocator.cpp
DefragAllocator.h
MemoryAddressRange.h
PageMappingHeap.h
MemoryManager.h
@@ -118,10 +113,8 @@ set(FILES
XML/WriteXMLSource.cpp
ZipFile.h
ZipFileFormat_info.h
PerfHUD.cpp
ProfileLogSystem.cpp
Sampler.cpp
PerfHUD.h
ProfileLogSystem.h
Sampler.h
LocalizedStringManager.cpp
@@ -138,24 +131,10 @@ set(FILES
ExtensionSystem/CryFactoryRegistryImpl.h
ExtensionSystem/TestCases/TestExtensions.cpp
ExtensionSystem/TestCases/TestExtensions.h
MiniGUI/DrawContext.cpp
MiniGUI/MiniButton.cpp
MiniGUI/MiniGUI.cpp
MiniGUI/MiniInfoBox.cpp
MiniGUI/MiniMenu.cpp
MiniGUI/MiniTable.cpp
MiniGUI/DrawContext.h
MiniGUI/MiniButton.h
MiniGUI/MiniGUI.h
MiniGUI/MiniInfoBox.h
MiniGUI/MiniMenu.h
MiniGUI/MiniTable.h
ZLibCompressor.cpp
ZLibCompressor.h
SoftCode/SoftCodeMgr.cpp
SoftCode/SoftCodeMgr.h
OverloadSceneManager/OverloadSceneManager.cpp
OverloadSceneManager/OverloadSceneManager.h
Huffman.cpp
Huffman.h
RemoteConsole/RemoteConsole.cpp
@@ -197,8 +176,6 @@ set(FILES
Serialization/XmlIArchive.h
Serialization/XmlOArchive.cpp
Serialization/XmlOArchive.h
HMDCVars.h
HMDCVars.cpp
StreamEngine/StreamAsyncFileRequest.cpp
StreamEngine/StreamAsyncFileRequest_Jobs.cpp
StreamEngine/StreamEngine.cpp
@@ -210,13 +187,9 @@ set(FILES
StreamEngine/StreamIOThread.h
StreamEngine/StreamReadStream.h
StreamEngine/AZRequestReadStream.h
VisRegTest.cpp
VisRegTest.h
CrashHandler.rc
CrySystem_precompiled.cpp
CPUDetect.cpp
CPUDetect.h
CrySizerImpl.cpp
CrySizerImpl.h
WindowsErrorReporting.cpp
)
@@ -15,7 +15,6 @@ set(FILES
Tests/Test_CLog.cpp
Tests/Test_CommandRegistration.cpp
Tests/Test_CryPrimitives.cpp
Tests/Test_CrySizer.cpp
Tests/test_CrySystem.cpp
Tests/Test_Localization.cpp
Tests/test_Main.cpp