diff --git a/Code/CryEngine/CryCommon/AABBSV.h b/Code/CryEngine/CryCommon/AABBSV.h deleted file mode 100644 index 4c1c277e35..0000000000 --- a/Code/CryEngine/CryCommon/AABBSV.h +++ /dev/null @@ -1,525 +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 : shadow volume AABB functionality for overlap testings - - -#ifndef CRYINCLUDE_CRYCOMMON_AABBSV_H -#define CRYINCLUDE_CRYCOMMON_AABBSV_H -#pragma once - -#include "Cry_Geo.h" - -struct Shadowvolume -{ - uint32 sideamount; - uint32 nplanes; - - Plane oplanes[10]; -}; - -namespace NAABB_SV -{ - //*************************************************************************************** - //*************************************************************************************** - //*** Calculate a ShadowVolume using an AABB and a point-light *** - //*************************************************************************************** - //*** The planes of the AABB facing away from the point-light are the far-planes *** - //*** of the ShadowVolume. There can be 3-6 far-planes. *** - //*************************************************************************************** - void AABB_ReceiverShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv); - - //*************************************************************************************** - //*************************************************************************************** - //*** Calculate a ShadowVolume using an AABB and a point-light *** - //*************************************************************************************** - //*** The planes of the AABB facing the point-light are the near-planes of the *** - //*** the ShadowVolume. There can be 1-3 near-planes. *** - //*** The far-plane is defined by lightrange. *** - //*************************************************************************************** - void AABB_ShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv, f32 lightrange); - - //*************************************************************************************** - //*** this is the "fast" version to check if an AABB is overlapping a shadowvolume *** - //*************************************************************************************** - bool Is_AABB_In_ShadowVolume(const Shadowvolume& sv, const AABB& Receiver); - - //*************************************************************************************** - //*** this is the "hierarchical" check *** - //*************************************************************************************** - char Is_AABB_In_ShadowVolume_hierarchical(const Shadowvolume& sv, const AABB& Receiver); -} - - - - - -inline void NAABB_SV::AABB_ReceiverShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv) -{ - sv.sideamount = 0; - sv.nplanes = 0; - - //------------------------------------------------------------------------------ - //-- check if PointLight is in front of any occluder plane or inside occluder -- - //------------------------------------------------------------------------------ - uint32 front = 0; - if (PointLight.x < Occluder.min.x) - { - front |= 0x01; - } - if (PointLight.x > Occluder.max.x) - { - front |= 0x02; - } - if (PointLight.y < Occluder.min.y) - { - front |= 0x04; - } - if (PointLight.y > Occluder.max.y) - { - front |= 0x08; - } - if (PointLight.z < Occluder.min.z) - { - front |= 0x10; - } - if (PointLight.z > Occluder.max.z) - { - front |= 0x20; - } - - sv.sideamount = BoxSides[(front << 3) + 7]; - - uint32 back = front ^ 0x3f; - if (back & 0x01) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(-1, +0, +0), Occluder.min); - sv.nplanes++; - } - if (back & 0x02) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+1, +0, +0), Occluder.max); - sv.nplanes++; - } - if (back & 0x04) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, -1, +0), Occluder.min); - sv.nplanes++; - } - if (back & 0x08) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +1, +0), Occluder.max); - sv.nplanes++; - } - if (back & 0x10) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, -1), Occluder.min); - sv.nplanes++; - } - if (back & 0x20) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, +1), Occluder.max); - sv.nplanes++; - } - - if (front == 0) - { - return; //light is inside occluder - } - //all 8 vertices of a AABB - Vec3 o[8] = - { - Vec3(Occluder.min.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.max.z) - }; - - //--------------------------------------------------------------------- - //--- find the silhouette-vertices of the occluder-AABB --- - //--------------------------------------------------------------------- - uint32 p0 = BoxSides[(front << 3) + 0]; - uint32 p1 = BoxSides[(front << 3) + 1]; - uint32 p2 = BoxSides[(front << 3) + 2]; - uint32 p3 = BoxSides[(front << 3) + 3]; - uint32 p4 = BoxSides[(front << 3) + 4]; - uint32 p5 = BoxSides[(front << 3) + 5]; - - float a; - if (sv.sideamount == 4) - { - //sv.oplanes[sv.nplanes+0] = Plane::CreatePlane( o[p0],o[p1], PointLight ); - //sv.oplanes[sv.nplanes+1] = Plane::CreatePlane( o[p1],o[p2], PointLight ); - //sv.oplanes[sv.nplanes+2] = Plane::CreatePlane( o[p2],o[p3], PointLight ); - //sv.oplanes[sv.nplanes+3] = Plane::CreatePlane( o[p3],o[p0], PointLight ); - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p3]) | (o[p3] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p0], PointLight); - sv.sideamount++; - } - } - - if (sv.sideamount == 6) - { - //sv.oplanes[sv.nplanes+0] = Plane::CreatePlane( o[p0],o[p1], PointLight ); - //sv.oplanes[sv.nplanes+1] = Plane::CreatePlane( o[p1],o[p2], PointLight ); - //sv.oplanes[sv.nplanes+2] = Plane::CreatePlane( o[p2],o[p3], PointLight ); - //sv.oplanes[sv.nplanes+3] = Plane::CreatePlane( o[p3],o[p4], PointLight ); - //sv.oplanes[sv.nplanes+4] = Plane::CreatePlane( o[p4],o[p5], PointLight ); - //sv.oplanes[sv.nplanes+5] = Plane::CreatePlane( o[p5],o[p0], PointLight ); - - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p4] - o[p3]) | (o[p3] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p4], PointLight); - sv.sideamount++; - } - a = (o[p5] - o[p4]) | (o[p4] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p4], o[p5], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p5]) | (o[p5] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p5], o[p0], PointLight); - sv.sideamount++; - } - } -} - -inline void NAABB_SV::AABB_ShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv, f32 lightrange) -{ - sv.sideamount = 0; - sv.nplanes = 0; - - //------------------------------------------------------------------------------ - //-- check if PointLight is in front of any occluder plane or inside occluder -- - //------------------------------------------------------------------------------ - uint32 front = 0; - if (PointLight.x < Occluder.min.x) - { - front |= 0x01; - } - if (PointLight.x > Occluder.max.x) - { - front |= 0x02; - } - if (PointLight.y < Occluder.min.y) - { - front |= 0x04; - } - if (PointLight.y > Occluder.max.y) - { - front |= 0x08; - } - if (PointLight.z < Occluder.min.z) - { - front |= 0x10; - } - if (PointLight.z > Occluder.max.z) - { - front |= 0x20; - } - if (front == 0) - { - return; //light is inside occluder - } - sv.sideamount = BoxSides[(front << 3) + 7]; - - if (front & 0x01) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(-1, +0, +0), Occluder.min); - sv.nplanes++; - } - if (front & 0x02) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+1, +0, +0), Occluder.max); - sv.nplanes++; - } - if (front & 0x04) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, -1, +0), Occluder.min); - sv.nplanes++; - } - if (front & 0x08) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +1, +0), Occluder.max); - sv.nplanes++; - } - if (front & 0x10) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, -1), Occluder.min); - sv.nplanes++; - } - if (front & 0x20) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, +1), Occluder.max); - sv.nplanes++; - } - - //all 8 vertices of a AABB - Vec3 o[8] = - { - Vec3(Occluder.min.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.max.z) - }; - - //--------------------------------------------------------------------- - //--- find the silhouette-vertices of the occluder-AABB --- - //--------------------------------------------------------------------- - uint32 p0 = BoxSides[(front << 3) + 0]; - uint32 p1 = BoxSides[(front << 3) + 1]; - uint32 p2 = BoxSides[(front << 3) + 2]; - uint32 p3 = BoxSides[(front << 3) + 3]; - uint32 p4 = BoxSides[(front << 3) + 4]; - uint32 p5 = BoxSides[(front << 3) + 5]; - - //the new center-position in world-space - Vec3 MiddleOfOccluder = (Occluder.max + Occluder.min) * 0.5f; - sv.oplanes[sv.nplanes] = Plane::CreatePlane((MiddleOfOccluder - PointLight).GetNormalized(), (MiddleOfOccluder - PointLight).GetNormalized() * lightrange + PointLight); - sv.nplanes++; - - float a; - if (sv.sideamount == 4) - { - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p3]) | (o[p3] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p0], PointLight); - sv.sideamount++; - } - } - - if (sv.sideamount == 6) - { - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p4] - o[p3]) | (o[p3] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p4], PointLight); - sv.sideamount++; - } - a = (o[p5] - o[p4]) | (o[p4] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p4], o[p5], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p5]) | (o[p5] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p5], o[p0], PointLight); - sv.sideamount++; - } - } -} - -inline bool NAABB_SV::Is_AABB_In_ShadowVolume(const Shadowvolume& sv, const AABB& Receiver) -{ - uint32 pa = sv.sideamount + sv.nplanes; - - f32 d; - const Vec3* pAABB = &Receiver.min; - - union f32_u - { - float floatVal; - uint32 uintVal; - }; - - //------------------------------------------------------------------------------ - //---- check if receiver-AABB is in front of any of these planes ------ - //------------------------------------------------------------------------------ - for (uint32 x = 0; x < pa; x++) - { - d = sv.oplanes[x].d; - - //avoid breaking strict aliasing rules - f32_u ux; - ux.floatVal = sv.oplanes[x].n.x; - f32_u uy; - uy.floatVal = sv.oplanes[x].n.y; - f32_u uz; - uz.floatVal = sv.oplanes[x].n.z; - const uint32 bitX = ux.uintVal >> 31; - const uint32 bitY = uy.uintVal >> 31; - const uint32 bitZ = uz.uintVal >> 31; - - d += sv.oplanes[x].n.x * pAABB[bitX].x; - d += sv.oplanes[x].n.y * pAABB[bitY].y; - d += sv.oplanes[x].n.z * pAABB[bitZ].z; - if (d > 0) - { - return CULL_EXCLUSION; - } - } - return CULL_OVERLAP; -} - -inline char NAABB_SV::Is_AABB_In_ShadowVolume_hierarchical(const Shadowvolume& sv, const AABB& Receiver) -{ - uint32 pa = sv.sideamount + sv.nplanes; - const Vec3* pAABB = &Receiver.min; - - f32 dot1, dot2; - uint32 notOverlap = 0x80000000; // will be reset to 0 if there's at least one overlapping - - union f32_u - { - float floatVal; - uint32 uintVal; - }; - - //------------------------------------------------------------------------------ - //---- check if receiver-AABB is in front of any of these planes ------ - //------------------------------------------------------------------------------ - for (uint32 x = 0; x < pa; x++) - { - dot1 = dot2 = sv.oplanes[x].d; - - //avoid breaking strict aliasing rules - f32_u ux; - ux.floatVal = sv.oplanes[x].n.x; - f32_u uy; - uy.floatVal = sv.oplanes[x].n.y; - f32_u uz; - uz.floatVal = sv.oplanes[x].n.z; - const uint32 bitX = ux.uintVal >> 31; - const uint32 bitY = uy.uintVal >> 31; - const uint32 bitZ = uz.uintVal >> 31; - - dot1 += sv.oplanes[x].n.x * pAABB[0 + bitX].x; - dot2 += sv.oplanes[x].n.x * pAABB[1 - bitX].x; - dot1 += sv.oplanes[x].n.y * pAABB[0 + bitY].y; - dot2 += sv.oplanes[x].n.y * pAABB[1 - bitY].y; - dot1 += sv.oplanes[x].n.z * pAABB[0 + bitZ].z; - dot2 += sv.oplanes[x].n.z * pAABB[1 - bitZ].z; - PREFAST_SUPPRESS_WARNING(6001) f32_u d; - d.floatVal = dot1; - if (!(d.uintVal & 0x80000000)) - { - return CULL_EXCLUSION; - } - PREFAST_SUPPRESS_WARNING(6001) f32_u d2; - d2.floatVal = dot2; - notOverlap &= d2.uintVal; - } - if (notOverlap) - { - return CULL_INCLUSION; - } - return CULL_OVERLAP; -} - -#endif // CRYINCLUDE_CRYCOMMON_AABBSV_H - diff --git a/Code/CryEngine/CryCommon/Algorithm.h b/Code/CryEngine/CryCommon/Algorithm.h deleted file mode 100644 index 554fe7f507..0000000000 --- a/Code/CryEngine/CryCommon/Algorithm.h +++ /dev/null @@ -1,74 +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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_ALGORITHM_H -#define CRYINCLUDE_CRYCOMMON_ALGORITHM_H -#pragma once -//short hand for using stl algorithms. same syntax (from users perspective) of c++17 range library. Only the shorthand algorithms from range library(N4128) though. -//Not all algorithms are covered. Add any as you need them. It would be a fair amount of work to add them all, so I'm just adding them as needed. -//Note Android doesn't have non member cbegin and cend yet. - -#include -#include -#include - -namespace std17 -{ - template - void for_each(const Container& con, Callable callable) - { - std::for_each(begin(con), end(con), callable); - } - - template - bool any_of(const Container& con, UnaryPredicate pred) - { - return std::any_of(begin(con), end(con), pred); - } - - template - bool all_of(const Container& con, UnaryPredicate pred) - { - return std::all_of(begin(con), end(con), pred); - } - - template - bool none_of(const Container& con, UnaryPredicate pred) - { - return std::none_of(begin(con), end(con), pred); - } - - template - typename Container::iterator find_if(Container& con, UnaryPredicate pred) - { - return std::find_if(begin(con), end(con), pred); - } - - template - T accumulate(const Container& con, T init) - { - return std::accumulate(begin(con), end(con), init); - } - - template - T accumulate(const Container& con, T init, BinaryOperation binary_op) - { - return std::accumulate(begin(con), end(con), init, binary_op); - } - - template - auto count_if(const Container&con, UnaryPredicate pred)->decltype(std::count_if(begin(con), end(con), pred)) - { - return std::count_if(begin(con), end(con), pred); - } -} - -#endif // CRYINCLUDE_CRYCOMMON_ALGORITHM_H diff --git a/Code/CryEngine/CryCommon/Allocator.h b/Code/CryEngine/CryCommon/Allocator.h deleted file mode 100644 index 682de1e862..0000000000 --- a/Code/CryEngine/CryCommon/Allocator.h +++ /dev/null @@ -1,75 +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_CRYCOMMON_ALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_ALLOCATOR_H -#pragma once - -#include "CryMemoryAllocator.h" - -//////////////////////////////////////////////////////////////////////// -// Allocator default implementation - -struct StdAllocator -{ - // Class-specific alloc/free/size functions. Use aligned versions only when necessary. - template - static void* Allocate(T*& p) - { - return p = NeedAlign() ? - (T*)CryModuleMemalign(sizeof(T), alignof(T)) : - (T*)CryModuleMalloc(sizeof(T)); - } - - template - static void Deallocate(T* p) - { - if (NeedAlign()) - { - CryModuleMemalignFree(p); - } - else - { - CryModuleFree(p); - } - } - - template - static size_t GetMemSize(const T* p) - { - return NeedAlign() ? - sizeof(T) + alignof(T) : - sizeof(T); - } - - template - void GetMemoryUsage(ICrySizer* pSizer) const { /*nothing*/} -protected: - - template - static bool NeedAlign() - { PREFAST_SUPPRESS_WARNING(6326); return alignof(T) > _ALIGNMENT; } -}; - -// Handy delete template function, for any allocator. -template -void Delete(TAlloc& alloc, T* ptr) -{ - if (ptr) - { - ptr->~T(); - alloc.Deallocate(ptr); - } -} - -#endif // CRYINCLUDE_CRYCOMMON_ALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/CGFContent.h b/Code/CryEngine/CryCommon/CGFContent.h deleted file mode 100644 index 9c6ff391ef..0000000000 --- a/Code/CryEngine/CryCommon/CGFContent.h +++ /dev/null @@ -1,903 +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 : Describe contents on CGF file. - - -#ifndef CRYINCLUDE_CRYCOMMON_CGFCONTENT_H -#define CRYINCLUDE_CRYCOMMON_CGFCONTENT_H -#pragma once - -#include // <> required for Interfuscator -#include // <> required for Interfuscator -#include -#include -#include -#include -#include - -#include //Required for LOD support for touch bending vegetation -#include //Required for LOD support for touch bending vegetation - -const int CGF_NODE_NAME_LENGTH = 64; -//END: Add LOD support for touch bending vegetation - -struct CMaterialCGF; -struct IConvertContext; - -#define CGF_NODE_NAME_LOD_PREFIX "$lod" - -////////////////////////////////////////////////////////////////////////// -// This structure represents CGF node. -////////////////////////////////////////////////////////////////////////// -struct CNodeCGF - : public _cfg_reference_target -{ - enum ENodeType - { - NODE_MESH, - NODE_LIGHT, - NODE_HELPER, - }; - enum EPhysicalizeFlags - { - ePhysicsalizeFlag_MeshNotNeeded = BIT(2), // When set physics data doesn't need additional Mesh indices or vertices. - ePhysicsalizeFlag_NoBreaking = BIT(3), // node is unsuitable for procedural 3d breaking - }; - - ENodeType type; - //START: Add LOD support for touch bending vegetation - char name[CGF_NODE_NAME_LENGTH]; - //END: Add LOD support for touch bending vegetation - string properties; - Matrix34 localTM; // Local space transformation matrix. - Matrix34 worldTM; // World space transformation matrix. - CNodeCGF* pParent; // Pointer to parent node. - CNodeCGF* pSharedMesh; // Not NULL if this node is sharing mesh and physics from referenced Node. - CMesh* pMesh; // Pointer to mesh loaded for this node. (Only when type == NODE_MESH) - - HelperTypes helperType; // Only relevant if type==NODE_HELPER - Vec3 helperSize; // Only relevant if type==NODE_HELPER - - CMaterialCGF* pMaterial; // Material node. - - // Physical data of the node with mesh. - int nPhysicalizeFlags; // Saved into the nFlags2 chunk member. - AZStd::vector physicalGeomData[4]; - int nPhysTriCount; // Not saved! only used for statistics in RC - - ////////////////////////////////////////////////////////////////////////// - // Used internally. - int nChunkId; // Chunk id as loaded from CGF. - int nParentChunkId; // Chunk id of parent Node. - int nObjectChunkId; // Chunk id of the corresponding mesh. - int pos_cont_id; // position controller chunk id - int rot_cont_id; // rotation controller chunk id - int scl_cont_id; // scale controller chunk id - ////////////////////////////////////////////////////////////////////////// - - // True if worldTM is identity. - bool bIdentityMatrix; - // True when this node is invisible physics proxy. - bool bPhysicsProxy; - - // These values are not saved, but are only used for loading empty mesh chunks. - struct MeshInfo - { - int nVerts; - int nIndices; - int nSubsets; - Vec3 bboxMin; - Vec3 bboxMax; - float fGeometricMean; - }; - MeshInfo meshInfo; - - CrySkinVtx* pSkinInfo; // for skinning with skeleton meshes (deformable objects) - - ////////////////////////////////////////////////////////////////////////// - // Constructor. - ////////////////////////////////////////////////////////////////////////// - void Init() - { - type = NODE_MESH; - localTM.SetIdentity(); - worldTM.SetIdentity(); - pParent = 0; - pSharedMesh = 0; - pMesh = 0; - pMaterial = 0; - helperType = HP_POINT; - helperSize.Set(0, 0, 0); - nPhysicalizeFlags = 0; - nChunkId = 0; - nParentChunkId = 0; - nObjectChunkId = 0; - pos_cont_id = rot_cont_id = scl_cont_id = 0; - bIdentityMatrix = true; - bPhysicsProxy = false; - pSkinInfo = 0; - nPhysTriCount = 0; - - ZeroStruct(meshInfo); - } - - CNodeCGF() - { - Init(); - } - - explicit CNodeCGF(_cfg_reference_target::DeleteFncPtr pDeleteFnc) - : _cfg_reference_target(pDeleteFnc) - { - Init(); - } - - ~CNodeCGF() - { - if (!pSharedMesh) - { - delete pMesh; - } - if (pSkinInfo) - { - delete[] pSkinInfo; - } - } -}; - - -////////////////////////////////////////////////////////////////////////// -// structures for skinning -////////////////////////////////////////////////////////////////////////// - -struct TFace -{ - uint16 i0, i1, i2; - TFace() {} - TFace(uint16 v0, uint16 v1, uint16 v2) { i0 = v0; i1 = v1; i2 = v2; } - TFace(const CryFace& face) { i0 = aznumeric_caster(face[0]); i1 = aznumeric_caster(face[1]); i2 = aznumeric_caster(face[2]); } - void operator = (const TFace& f) { i0 = f.i0; i1 = f.i1; i2 = f.i2; } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - AUTO_STRUCT_INFO -}; - -struct PhysicalProxy -{ - uint32 ChunkID; - DynArray m_arrPoints; - DynArray m_arrIndices; - DynArray m_arrMaterials; -}; - -struct MorphTargets -{ - uint32 MeshID; - string m_strName; - DynArray m_arrIntMorph; - DynArray m_arrExtMorph; -}; - -typedef MorphTargets* MorphTargetsPtr; - -struct IntSkinVertex -{ - Vec3 __obsolete0; // thin/fat vertex position. must be removed in the next RC refactoring - Vec3 pos; // vertex-position of model.2 - Vec3 __obsolete2; // thin/fat vertex position. must be removed in the next RC refactoring - uint16 boneIDs[4]; - f32 weights[4]; - ColorB color; //index for blend-array - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - AUTO_STRUCT_INFO -}; - - - -////////////////////////////////////////////////////////////////////////// -// TCB Controller implementation. -////////////////////////////////////////////////////////////////////////// - - -// retrieves the position and orientation (in the logarithmic space, i.e. instead of quaternion, its logarithm is returned) -// may be optimal for motion interpolation -struct PQLog -{ - Vec3 vPos; - Vec3 vRotLog; // logarithm of the rotation - void blendPQ (const PQLog& pqFrom, const PQLog& pqTo, f32 fBlend); - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -struct CControllerType -{ - uint16 m_controllertype; - uint16 m_index; - CControllerType() - { - m_controllertype = 0xffff; - m_index = 0xffff; - } -}; - -struct TCBFlags -{ - uint8 f0, f1; - TCBFlags() { f0 = f1 = 0; } -}; - -struct CStoredSkinningInfo -{ - int32 m_nTicksPerFrame; - f32 m_secsPerTick; - int32 m_nStart; - int32 m_nEnd; - f32 m_Speed; - f32 m_Distance; - f32 m_Slope; - int m_nAssetFlags; - f32 m_LHeelStart, m_LHeelEnd; - f32 m_LToe0Start, m_LToe0End; - f32 m_RHeelStart, m_RHeelEnd; - f32 m_RToe0Start, m_RToe0End; - Vec3 m_MoveDirection; // raw storage - - CStoredSkinningInfo() - : m_Speed(-1.0f) - , m_Distance(-1.0f) - , m_nAssetFlags(0) - , m_LHeelStart(-10000.0f) - , m_LHeelEnd(-10000.0f) - , m_LToe0Start(-10000.0f) - , m_LToe0End(-10000.0f) - , m_RHeelStart(-10000.0f) - , m_RHeelEnd(-10000.0f) - , m_RToe0Start(-10000.0f) - , m_RToe0End(-10000.0f) - , m_Slope(-1.0f) - { - } - AUTO_STRUCT_INFO -}; - - - -// structure for recreating controllers -struct CControllerInfo -{ - uint32 m_nControllerID; - uint32 m_nPosKeyTimeTrack; - uint32 m_nPosTrack; - uint32 m_nRotKeyTimeTrack; - uint32 m_nRotTrack; - - CControllerInfo() - : m_nControllerID(~0) - , m_nPosKeyTimeTrack(~0) - , m_nPosTrack(~0) - , m_nRotKeyTimeTrack(~0) - , m_nRotTrack(~0) {} - - AUTO_STRUCT_INFO -}; - -struct MeshCollisionInfo -{ - AABB m_aABB; - OBB m_OBB; - Vec3 m_Pos; - DynArray m_arrIndexes; - int32 m_iBoneId; - - MeshCollisionInfo() - { - // This didn't help much. - // The BBs are reset to opposite infinites, - // but never clamped/grown by any member points. - m_aABB.min.zero(); - m_aABB.max.zero(); - m_OBB.m33.SetIdentity(); - m_OBB.h.zero(); - m_OBB.c.zero(); - m_Pos.zero(); - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_arrIndexes); - } -}; - - - -struct SJointsAimIK_Rot -{ - const char* m_strJointName; - int16 m_nJointIdx; - int16 m_nPosIndex; - uint8 m_nPreEvaluate; - uint8 m_nAdditive; - int16 m_nRotJointParentIdx; - SJointsAimIK_Rot() - { - m_strJointName = 0; - m_nJointIdx = -1; - m_nPosIndex = -1; - m_nPreEvaluate = 0; - m_nAdditive = 0; - m_nRotJointParentIdx = -1; - }; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -struct SJointsAimIK_Pos -{ - const char* m_strJointName; - int16 m_nJointIdx; - uint8 m_nAdditive; - uint8 m_nEmpty; - SJointsAimIK_Pos() - { - m_strJointName = 0; - m_nJointIdx = -1; - m_nAdditive = 0; - m_nEmpty = 0; - }; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - - -struct DirectionalBlends -{ - string m_AnimToken; - uint32 m_AnimTokenCRC32; - const char* m_strParaJointName; - int16 m_nParaJointIdx; - int16 m_nRotParaJointIdx; - const char* m_strStartJointName; - int16 m_nStartJointIdx; - int16 m_nRotStartJointIdx; - const char* m_strReferenceJointName; - int32 m_nReferenceJointIdx; - DirectionalBlends() - { - m_AnimTokenCRC32 = 0; - m_strParaJointName = 0; - m_nParaJointIdx = -1; - m_nRotParaJointIdx = -1; - m_strStartJointName = 0; - m_nStartJointIdx = -1; - m_nRotStartJointIdx = -1; - m_strReferenceJointName = 0; - m_nReferenceJointIdx = 1; //by default we use the Pelvis - }; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - - -struct CSkinningInfo - : public _reference_target_t -{ - DynArray m_arrBonesDesc; //animation-bones - - DynArray m_LookIK_Rot; //rotational joints used for Look-IK - DynArray m_LookIK_Pos; //positional joints used for Look-IK - DynArray m_LookDirBlends; //positional joints used for Look-IK - - DynArray m_AimIK_Rot; //rotational joints used for Aim-IK - DynArray m_AimIK_Pos; //positional joints used for Aim-IK - DynArray m_AimDirBlends; //positional joints used for Aim-IK - - - DynArray m_arrPhyBoneMeshes; //collision proxi - DynArray m_arrMorphTargets; - DynArray m_arrIntFaces; - DynArray m_arrIntVertices; - DynArray m_arrExt2IntMap; - DynArray m_arrBoneEntities; //physical-bones - DynArray m_arrCollisions; - - uint32 m_numChunks{ 0 }; - bool m_bRotatedMorphTargets; - bool m_bProperBBoxes; - - CSkinningInfo() - : m_bRotatedMorphTargets(false) - , m_bProperBBoxes(false) {} - - ~CSkinningInfo() - { - for (DynArray::iterator it = m_arrMorphTargets.begin(), end = m_arrMorphTargets.end(); it != end; ++it) - { - delete *it; - } - } - - int32 GetJointIDByName(const char* strJointName) const - { - uint32 numJoints = m_arrBonesDesc.size(); - for (uint32 i = 0; i < numJoints; i++) - { - if (_stricmp(m_arrBonesDesc[i].m_arrBoneName, strJointName) == 0) - { - return i; - } - } - return -1; - } - - // Return name of bone from bone table, return zero id nId is out of range - const char* GetJointNameByID(int32 nJointID) const - { - int32 numJoints = m_arrBonesDesc.size(); - if (nJointID >= 0 && nJointID < numJoints) - { - return m_arrBonesDesc[nJointID].m_arrBoneName; - } - return ""; // invalid bone id - } -}; - -////////////////////////////////////////////////////////////////////////// -// This structure represents Material inside CGF. -////////////////////////////////////////////////////////////////////////// -struct CMaterialCGF - : public _cfg_reference_target -{ - char name[128]; // Material name; - int nFlags; // Material flags. - int nPhysicalizeType; - bool bOldMaterial; - float shOpacity; - - // Array of sub materials. - DynArray subMaterials; - - ////////////////////////////////////////////////////////////////////////// - // Used internally. - int nChunkId; - ////////////////////////////////////////////////////////////////////////// - - void Init() - { - nFlags = 0; - nChunkId = 0; - bOldMaterial = false; - nPhysicalizeType = PHYS_GEOM_TYPE_DEFAULT; - shOpacity = 1.f; - } - - CMaterialCGF() { Init(); } - - explicit CMaterialCGF(_cfg_reference_target::DeleteFncPtr pDeleteFnc) - : _cfg_reference_target(pDeleteFnc) - { Init(); } -}; - -////////////////////////////////////////////////////////////////////////// -// Info about physicalization of the CGF. -////////////////////////////////////////////////////////////////////////// -struct CPhysicalizeInfoCGF -{ - bool bWeldVertices; - float fWeldTolerance; // Min Distance between vertices when they collapse to single vertex if bWeldVertices enabled. - - // breakable physics - int nGranularity; - int nMode; - - Vec3* pRetVtx; - int nRetVtx; - int* pRetTets; - int nRetTets; - - CPhysicalizeInfoCGF() - : bWeldVertices(true) - , fWeldTolerance(0.01f) - , nMode(-1) - , nGranularity(-1) - , pRetVtx(0) - , nRetVtx(0) - , pRetTets(0) - , nRetTets(0){} - - ~CPhysicalizeInfoCGF() - { - if (pRetVtx) - { - delete []pRetVtx; - pRetVtx = 0; - } - if (pRetTets) - { - delete []pRetTets; - pRetTets = 0; - } - } -}; - - -////////////////////////////////////////////////////////////////////////// -// Serialized skinnable foliage data -////////////////////////////////////////////////////////////////////////// - -#define NODE_PROPERTY_STIFFNESS "stiffness" -#define NODE_PROPERTY_DAMPING "damping" -#define NODE_PROPERTY_THICKNESS "thickness" - -struct SSpineRC -{ - SSpineRC() - : pVtx(nullptr) - , pSegDim(nullptr) - , nVtx(0) - , len(0) - , pBoneIDs(nullptr) - , parentBoneID(-1) - , pStiffness(nullptr) - , pDamping(nullptr) - , pThickness(nullptr) {} - - ~SSpineRC() - { - if (pVtx) - { - delete[] pVtx; - } - if (pSegDim) - { - delete[] pSegDim; - } - if (pBoneIDs) - { - delete[] pBoneIDs; - } - if (pStiffness) - { - delete[] pStiffness; - } - if (pDamping) - { - delete[] pDamping; - } - if (pThickness) - { - delete[] pThickness; - } - } - - /// Add Skinned Geometry (.CGF) export type (for touch bending vegetation) - static float GetDefaultStiffness() { return 0.5f; } - static float GetDefaultDamping() { return 0.5f; } - static float GetDefaultThickness() { return 0.03f; } - - Vec3* pVtx; - Vec4* pSegDim; - int nVtx; - float len; - Vec3 navg; - - int parentBoneID; - int* pBoneIDs; - - //Per Bone parameters. - float* pStiffness; - float* pDamping; - float* pThickness; - - int iAttachSpine; - int iAttachSeg; -}; - -struct SFoliageInfoCGF -{ - SFoliageInfoCGF() { nSpines = 0; pSpines = 0; pBoneMapping = 0; } - ~SFoliageInfoCGF() - { - if (pSpines) - { - for (int i = 1; i < nSpines; i++) // spines 1..n-1 use the same buffer, so make sure they don't delete it - { - pSpines[i].pVtx = nullptr; - pSpines[i].pSegDim = nullptr; - pSpines[i].pBoneIDs = nullptr; - pSpines[i].pStiffness = nullptr; - pSpines[i].pDamping = nullptr; - pSpines[i].pThickness = nullptr; - } - delete[] pSpines; - } - - SAFE_DELETE_ARRAY(pBoneMapping); - - AZStd::unordered_map::iterator iter = boneMappings.begin(); - while (iter != boneMappings.end()) - { - if (iter->second != nullptr) - { - SAFE_DELETE_ARRAY(iter->second->pBoneMapping); - } - iter++; - } - - } - - SSpineRC* pSpines; - int nSpines; - - ///Bone mappings for each LOD level - AZStd::unordered_map boneMappings; - - ///Bone mapping for legacy format - struct SMeshBoneMapping_uint8* pBoneMapping; - int nSkinnedVtx; - - DynArray chunkBoneIds; -}; - - -////////////////////////////////////////////////////////////////////////// -struct CExportInfoCGF -{ - bool bMergeAllNodes; - bool bUseCustomNormals; - bool bCompiledCGF; - bool bHavePhysicsProxy; - bool bHaveAutoLods; - bool bNoMesh; - bool bWantF32Vertices; - bool b8WeightsPerVertex; - - /// Prevent reprocessing skinning data for skinned CGF - bool bSkinnedCGF; - - bool bFromColladaXSI; - bool bFromColladaMAX; - bool bFromColladaMAYA; - - unsigned int rc_version[4]; // Resource compiler version. - char rc_version_string[16]; // Version as a string. - - unsigned int authorToolVersion; -}; - -////////////////////////////////////////////////////////////////////////// -// This class contain all info loaded from the CGF file. -////////////////////////////////////////////////////////////////////////// -class CContentCGF -{ -public: - ////////////////////////////////////////////////////////////////////////// - CContentCGF(const char* filename) - { - azstrcpy(m_filename, AZ_ARRAY_SIZE(m_filename), filename); - memset(&m_exportInfo, 0, sizeof(m_exportInfo)); - m_exportInfo.bMergeAllNodes = true; - m_exportInfo.bUseCustomNormals = false; - m_exportInfo.bWantF32Vertices = false; - m_exportInfo.b8WeightsPerVertex = false; - m_exportInfo.bSkinnedCGF = false; - m_pCommonMaterial = 0; - m_bConsoleFormat = false; - m_pOwnChunkFile = 0; - } - - ////////////////////////////////////////////////////////////////////////// - virtual ~CContentCGF() - { - // Free nodes. - m_nodes.clear(); - if (m_pOwnChunkFile) - { - m_pOwnChunkFile->Release(); - } - } - - ////////////////////////////////////////////////////////////////////////// - const char* GetFilename() const - { - return m_filename; - } - - void SetFilename(const char* filename) - { - azstrcpy(m_filename, AZ_ARRAY_SIZE(m_filename), filename); - } - - ////////////////////////////////////////////////////////////////////////// - // Access to CGF nodes. - void AddNode(CNodeCGF* pNode) - { - m_nodes.push_back(pNode); - } - - int GetNodeCount() const - { - return m_nodes.size(); - } - - CNodeCGF* GetNode(int i) - { - return m_nodes[i]; - } - - const CNodeCGF* GetNode(int i) const - { - return m_nodes[i]; - } - - void ClearNodes() - { - m_nodes.clear(); - } - - void RemoveNode(CNodeCGF* pNode) - { - assert(pNode); - for (int i = 0; i < m_nodes.size(); ++i) - { - if (m_nodes[i] == pNode) - { - pNode->pParent = 0; - m_nodes.erase(i); - break; - } - } - } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Access to CGF materials. - void AddMaterial(CMaterialCGF* pNode) - { - m_materials.push_back(pNode); - } - - int GetMaterialCount() const - { - return m_materials.size(); - } - - CMaterialCGF* GetMaterial(int i) - { - return m_materials[i]; - } - - void ClearMaterials() - { - m_materials.clear(); - } - - CMaterialCGF* GetCommonMaterial() const - { - return m_pCommonMaterial; - } - - void SetCommonMaterial(CMaterialCGF* pMtl) - { - m_pCommonMaterial = pMtl; - } - - DynArray& GetUsedMaterialIDs() - { - return m_usedMaterialIds; - } - - const DynArray& GetUsedMaterialIDs() const - { - return m_usedMaterialIds; - } - - ////////////////////////////////////////////////////////////////////////// - - CPhysicalizeInfoCGF* GetPhysicalizeInfo() - { - return &m_physicsInfo; - } - - const CPhysicalizeInfoCGF* GetPhysicalizeInfo() const - { - return &m_physicsInfo; - } - - CExportInfoCGF* GetExportInfo() - { - return &m_exportInfo; - } - - const CExportInfoCGF* GetExportInfo() const - { - return &m_exportInfo; - } - - CSkinningInfo* GetSkinningInfo() - { - return &m_SkinningInfo; - } - - const CSkinningInfo* GetSkinningInfo() const - { - return &m_SkinningInfo; - } - - SFoliageInfoCGF* GetFoliageInfo() - { - return &m_foliageInfo; - } - - bool GetConsoleFormat() - { - return m_bConsoleFormat; - } - - bool ValidateMeshes(const char** const ppErrorDescription) const - { - for (int i = 0; i < m_nodes.size(); ++i) - { - const CNodeCGF* const pNode = m_nodes[i]; - if (pNode && pNode->pMesh && (!pNode->pMesh->Validate(ppErrorDescription))) - { - return false; - } - } - return true; - } - - // Set chunk file that this CGF owns. - void SetChunkFile(IChunkFile* pChunkFile) - { - m_pOwnChunkFile = pChunkFile; - } - -public: - bool m_bConsoleFormat; - -private: - char m_filename[260]; - CSkinningInfo m_SkinningInfo; - DynArray<_smart_ptr > m_nodes; - DynArray<_smart_ptr > m_materials; - DynArray m_usedMaterialIds; - _smart_ptr m_pCommonMaterial; - - CPhysicalizeInfoCGF m_physicsInfo; - CExportInfoCGF m_exportInfo; - SFoliageInfoCGF m_foliageInfo; - - IChunkFile* m_pOwnChunkFile; -}; - -namespace AZ -{ - namespace SceneAPI - { - namespace DataTypes - { - class IAnimationGroup; - } - } -} - -// Asset Writer interface for writing CContentCGF content to asset file -struct IAssetWriter -{ - virtual ~IAssetWriter() - { - } - - virtual bool WriteCGF(CContentCGF* content) = 0; - virtual bool WriteCHR(CContentCGF* content, IConvertContext* convertContext) = 0; - virtual bool WriteSKIN(CContentCGF* content, IConvertContext* convertContext, bool exportMorphTargets) = 0; -}; - - -#endif // CRYINCLUDE_CRYCOMMON_CGFCONTENT_H diff --git a/Code/CryEngine/CryCommon/CGFContent_info.cpp b/Code/CryEngine/CryCommon/CGFContent_info.cpp deleted file mode 100644 index 27d61c2f62..0000000000 --- a/Code/CryEngine/CryCommon/CGFContent_info.cpp +++ /dev/null @@ -1,68 +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 "TypeInfo_impl.h" -#include "CGFContent.h" - -STRUCT_INFO_BEGIN(TFace) -STRUCT_VAR_INFO(i0, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(i1, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(i2, TYPE_INFO(uint16)) -STRUCT_INFO_END(TFace) - -STRUCT_INFO_BEGIN(IntSkinVertex) -STRUCT_VAR_INFO(__obsolete0, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(pos, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(__obsolete2, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(boneIDs, TYPE_ARRAY(4, TYPE_INFO(uint16))) -STRUCT_VAR_INFO(weights, TYPE_ARRAY(4, TYPE_INFO(f32))) -STRUCT_VAR_INFO(color, TYPE_INFO(ColorB)) -STRUCT_INFO_END(IntSkinVertex) - -STRUCT_INFO_BEGIN(CStoredSkinningInfo) -STRUCT_VAR_INFO(m_nTicksPerFrame, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_secsPerTick, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_nStart, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_nEnd, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_Speed, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_Distance, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_Slope, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_nAssetFlags, TYPE_INFO(int)) -STRUCT_VAR_INFO(m_LHeelStart, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_LHeelEnd, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_LToe0Start, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_LToe0End, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RHeelStart, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RHeelEnd, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RToe0Start, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RToe0End, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_MoveDirection, TYPE_INFO(Vec3)) -STRUCT_INFO_END(CStoredSkinningInfo) - -STRUCT_INFO_BEGIN(CControllerInfo) -STRUCT_VAR_INFO(m_nControllerID, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nPosKeyTimeTrack, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nPosTrack, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nRotKeyTimeTrack, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nRotTrack, TYPE_INFO(uint32)) -STRUCT_INFO_END(CControllerInfo) - -STRUCT_INFO_BEGIN(UCol) -STRUCT_VAR_INFO(dcolor, TYPE_INFO(uint32)) -STRUCT_INFO_END(UCol) - -STRUCT_INFO_BEGIN(SVF_P3S_C4B_T2S) -STRUCT_VAR_INFO(xyz, TYPE_INFO(Vec3f16)) -STRUCT_VAR_INFO(color, TYPE_INFO(UCol)) -STRUCT_VAR_INFO(st, TYPE_INFO(Vec2f16)) -STRUCT_INFO_END(SVF_P3S_C4B_T2S) diff --git a/Code/CryEngine/CryCommon/Console_std.h b/Code/CryEngine/CryCommon/Console_std.h deleted file mode 100644 index 55944a2960..0000000000 --- a/Code/CryEngine/CryCommon/Console_std.h +++ /dev/null @@ -1,24 +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. -* -*/ - -#pragma once - -#include - -#include - -namespace std -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(Console_std_h) -#endif -} diff --git a/Code/CryEngine/CryCommon/CountedValue.h b/Code/CryEngine/CryCommon/CountedValue.h deleted file mode 100644 index 8ff3c5639c..0000000000 --- a/Code/CryEngine/CryCommon/CountedValue.h +++ /dev/null @@ -1,77 +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 : A wrapper that counts the number of times the wrapped object -// has been set This is useful for netserializing an object -// that might be given a new value that s the same as the old value - - -#ifndef CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H -#define CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H -#pragma once - - -template -struct CountedValue -{ -public: - CountedValue() - : m_lastProducedId(0) - , m_lastConsumedId(0) {} - - typedef uint32 TCountedID; - - void SetAndDirty(const T& value) - { - m_value = value; - ++m_lastProducedId; - CRY_ASSERT(m_lastProducedId > 0); - } - - const T* GetLatestValue() - { - bool bHasNewValue = IsDirty(); // check for dirtiness before updating ids - m_lastConsumedId = m_lastProducedId; - - return bHasNewValue ? &m_value : NULL; - } - - inline bool IsDirty() const - { - return m_lastProducedId != m_lastConsumedId; - } - - const T& Peek() const - { - return m_value; - } - - TCountedID GetLatestID() const - { - return m_lastProducedId; - } - - // This method should only be used to update the object during serialization! - void UpdateDuringSerializationOnly(const T& value, TCountedID lastProducedId) - { - m_value = value; - m_lastProducedId = lastProducedId; - } - -private: - TCountedID m_lastProducedId; - TCountedID m_lastConsumedId; - T m_value; -}; - -#endif // CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H diff --git a/Code/CryEngine/CryCommon/CrtDebugStats.h b/Code/CryEngine/CryCommon/CrtDebugStats.h deleted file mode 100644 index 6f03d33c18..0000000000 --- a/Code/CryEngine/CryCommon/CrtDebugStats.h +++ /dev/null @@ -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. - -// support for leak dumping and statistics gathering using vs Crt Debug -// should be included in every DLL below DllMain() -#ifndef CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H -#define CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H -#pragma once - -#ifdef WIN32 -#ifdef _DEBUG - - -#include -#include // CryLogAlways -#include - -// copied from DBGINT.H (not a public header!) - -#define nNoMansLandSize 4 - -typedef struct _CrtMemBlockHeader -{ - struct _CrtMemBlockHeader* pBlockHeaderNext; - struct _CrtMemBlockHeader* pBlockHeaderPrev; - char* szFileName; - int nLine; - size_t nDataSize; - int nBlockUse; - long lRequest; - unsigned char gap[nNoMansLandSize]; - /* followed by: - * unsigned char data[nDataSize]; - * unsigned char anotherGap[nNoMansLandSize]; - */ -} _CrtMemBlockHeader; - -struct SFileInfo -{ - int blocks; - INT_PTR bytes; //AMD Port - SFileInfo(INT_PTR b) { blocks = 1; bytes = b; }; //AMD Port -}; - -_CrtMemState lastcheckpoint; -bool checkpointset = false; - -extern "C" void __declspec(dllexport) CheckPoint() -{ - _CrtMemCheckpoint(&lastcheckpoint); - checkpointset = true; -}; - -bool pairgreater(const std::pair& elem1, const std::pair& elem2) -{ - return elem1.second.bytes > elem2.second.bytes; -} - -extern "C" void __declspec(dllexport) UsageSummary([[maybe_unused]] ILog * log, char* modulename, int* extras) -{ - _CrtMemState state; - - if (checkpointset) - { - _CrtMemState recent; - _CrtMemCheckpoint(&recent); - _CrtMemDifference(&state, &lastcheckpoint, &recent); - } - else - { - _CrtMemCheckpoint(&state); - }; - - INT_PTR numblocks = state.lCounts[_NORMAL_BLOCK]; //AMD Port - INT_PTR totalalloc = state.lSizes[_NORMAL_BLOCK]; //AMD Port - - check_convert(extras[0]) = totalalloc; - check_convert(extras[1]) = numblocks; - - CryLogAlways("$5---------------------------------------------------------------------------------------------------"); - - if (!numblocks) - { - CryLogAlways("$3Module %s has no memory in use", modulename); - return; - } - ; - - CryLogAlways("$5Usage summary for module %s", modulename); - CryLogAlways("%d kbytes (peak %d) in %d objects of %d average bytes\n", - totalalloc / 1024, state.lHighWaterCount / 1024, numblocks, numblocks ? totalalloc / numblocks : 0); - CryLogAlways("%d kbytes allocated over time\n", state.lTotalCount / 1024); - - typedef std::map FileMap; - FileMap fm; - - for (_CrtMemBlockHeader* h = state.pBlockHeader; h; h = h->pBlockHeaderNext) - { - if (_BLOCK_TYPE(h->nBlockUse) != _NORMAL_BLOCK) - { - continue; - } - string s = h->szFileName ? h->szFileName : "NO_SOURCE"; - if (h->nLine > 0) - { - char buf[16]; - sprintf_s(buf, "_%d", h->nLine); - s += buf; - } - FileMap::iterator it = fm.find(s); - if (it != fm.end()) - { - (*it).second.blocks++; - (*it).second.bytes += h->nDataSize; - } - else - { - fm.insert(FileMap::value_type(s, SFileInfo(h->nDataSize))); - }; - } - ; - - typedef std::vector< std::pair > FileVector; - FileVector fv; - for (FileMap::iterator it = fm.begin(); it != fm.end(); ++it) - { - fv.push_back((*it)); - } - std::sort(fv.begin(), fv.end(), pairgreater); - - for (FileVector::iterator it = fv.begin(); it != fv.end(); ++it) - { - CryLogAlways("%6d kbytes / %6d blocks allocated from %s\n", - (*it).second.bytes / 1024, (*it).second.blocks, (*it).first.c_str()); - } - ; -}; - -#endif // _DEBUG - -#if !defined(_RELEASE) && !defined(_DLL) && defined(HANDLE) -extern "C" HANDLE _crtheap; -extern "C" HANDLE __declspec(dllexport) GetDLLHeap() { - return _crtheap; -}; -#endif - -#endif // WIN32 - -#endif // CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H diff --git a/Code/CryEngine/CryCommon/CryArray.h b/Code/CryEngine/CryCommon/CryArray.h index 793201cf40..73a9a9ec38 100644 --- a/Code/CryEngine/CryCommon/CryArray.h +++ b/Code/CryEngine/CryCommon/CryArray.h @@ -15,7 +15,7 @@ #define CRYINCLUDE_CRYCOMMON_CRYARRAY_H #pragma once -#include // <> required for Interfuscator +#include "CryLegacyAllocator.h" //--------------------------------------------------------------------------- // Convenient iteration macros @@ -91,8 +91,6 @@ Public classes: Array StaticArray DynArray - FastDynArray - FixedDynArray StaticDynArray Support classes are placed in namespaces NArray and NAlloc to reduce global name usage. @@ -612,13 +610,6 @@ namespace NAlloc //--------------------------------------------------------------------------- // Allocators for DynArray. - // No reallocation, for use in FixedDynArray - struct NullAlloc - { - static void* alloc(void* pMem, [[maybe_unused]] size_t& nSize, [[maybe_unused]] size_t nAlign, [[maybe_unused]] bool bSlack = false) - { return pMem; } - }; - // Standard CryModule memory allocation, using aligned versions struct ModuleAlloc { @@ -655,128 +646,15 @@ namespace NAlloc // Standard allocator for DynArray stores a compatibility pointer in the memory typedef AllocCompatible StandardAlloc; - - // Allocator using specific heaps - struct GeneralHeapAlloc - : ModuleAlloc - { - IGeneralMemoryHeap* m_pHeap; - - GeneralHeapAlloc() - : m_pHeap(0) {} - - explicit GeneralHeapAlloc(IGeneralMemoryHeap* pHeap) - : m_pHeap(pHeap) {} - - void* alloc(void* pMem, size_t& nSize, size_t nAlign, bool bSlack = false) const - { - if (m_pHeap) - { - if (pMem) - { - if (!nSize) - { - // Dealloc - m_pHeap->Free(pMem); - return 0; - } - } - else if (nSize) - { - // Alloc - if (bSlack) - { - nSize = realloc_size(nSize); - } - return m_pHeap->Memalign(nAlign, nSize, ""); - } - } - - return ModuleAlloc::alloc(pMem, nSize, nAlign, bSlack); - } - }; }; //--------------------------------------------------------------------------- // Storage schemes for dynamic arrays namespace NArray { - /*--------------------------------------------------------------------------- - // STORAGE prototype for DynArray - // Extends ArrayStorage with resizing functionality. - - struct DynStorage - { - struct Store: ArrayStorage::Store - { - I capacity() const; - size_t get_alloc_size() const; - void resize_raw( I new_size, bool allow_slack ); - }; - }; - ---------------------------------------------------------------------------*/ - - //--------------------------------------------------------------------------- - // FastDynStorage: STORAGE scheme for DynArray. - // Simple extension to ArrayStorage: size & capacity fields are inline, 3 words storage, fast access. - - template - struct FastDynStorage - { - template - struct Store - : private A - , public ArrayStorage::Store - { - typedef ArrayStorage::Store super_type; - - using super_type::m_aElems; - using super_type::m_nCount; - - // Construction. - Store() - : m_nCapacity(0) - { - } - - Store(const A& a) - : A(a) - , m_nCapacity(0) - { - } - - I capacity() const - { return m_nCapacity; } - - size_t get_alloc_size() const - { return NAlloc::get_alloc_size(*this, m_aElems, capacity() * sizeof(T), alignof(T)); } - - void resize_raw(I new_size, bool allow_slack = false) - { - if (allow_slack ? new_size > capacity() : new_size != capacity()) - { - m_nCapacity = new_size; - m_aElems = NAlloc::reallocate(static_cast(*this), m_aElems, m_nCount, m_nCapacity, alignof(T), allow_slack); - } - set_size(new_size); - } - - protected: - - I m_nCapacity; - - void set_size(I new_size) - { - assert(new_size >= 0 && new_size <= capacity()); - m_nCount = new_size; - } - }; - }; - //--------------------------------------------------------------------------- // SmallDynStorage: STORAGE scheme for DynArray. // Array is just a single pointer, size and capacity information stored before the array data. - // Slightly slower than FastDynStorage, optimal for saving space, especially when array likely to be empty. template struct SmallDynStorage @@ -1459,35 +1337,6 @@ struct LegacyDynArray } }; - -//--------------------------------------------------------------------------- - -template -struct FastDynArray - : DynArray< T, I, NArray::FastDynStorage > -{ -}; - -template -struct FixedDynArray - : LegacyDynArray< T, I, NArray::FastDynStorage > -{ - typedef NArray::ArrayStorage::Store S; - - void set(void* elems, I mem_size) - { - this->m_aElems = (T*)elems; - this->m_nCapacity = mem_size / sizeof(T); - this->m_nCount = 0; - } - void set(Array array) - { - this->m_aElems = array.begin(); - this->m_nCapacity = array.size(); - this->m_nCount = 0; - } -}; - template struct StaticDynArray : LegacyDynArray< T, I, NArray::StaticDynStorage > diff --git a/Code/CryEngine/CryCommon/CryCustomTypes.h b/Code/CryEngine/CryCommon/CryCustomTypes.h index e8f83145eb..25578ce9cc 100644 --- a/Code/CryEngine/CryCommon/CryCustomTypes.h +++ b/Code/CryEngine/CryCommon/CryCustomTypes.h @@ -1207,23 +1207,4 @@ protected: uint nPrefixLength; }; - -// Define an irregular enum with TypeInfo - -#define DEFINE_ENUM_VALS(EType, TInt, ...) \ - struct EType \ - { \ - enum E { __VA_ARGS__ }; \ - DEFINE_ENUM_VALUE(EType, E, TInt) \ - ILINE static uint Count() { return TypeInfo().Count(); } \ - static const CEnumInfo& TypeInfo() { \ - static char enum_str[] = #__VA_ARGS__; \ - static LegacyDynArray Elems; \ - CEnumDef::SInit::Init(Elems); \ - CEnumDef::SInit __VA_ARGS__; \ - static CEnumInfo info( #EType, Elems, enum_str); \ - return info; \ - } \ - }; - #endif // CRYINCLUDE_CRYCOMMON_CRYCUSTOMTYPES_H diff --git a/Code/CryEngine/CryCommon/CryFixedArray.h b/Code/CryEngine/CryCommon/CryFixedArray.h deleted file mode 100644 index 58bdd2b14f..0000000000 --- a/Code/CryEngine/CryCommon/CryFixedArray.h +++ /dev/null @@ -1,309 +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. - -/* -CryFixedArray.h - - no longer support being created on the stack (since the alignment code was changed to support adding CryFixedArrays into stl::vectors) - - performs construction or destruction only on elements as they become live/dead or are moved around during the RemoveAt() reshuffle - - just a range checked equivelant of a standard array - - for now only allows push_back() population of array - - if using as a class member variable ensure to put the CryFixedArrays after all other member variables at the bottom of your class - to ensure all members stay on the same cacheline -*/ - -#ifndef CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H -#define CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H -#pragma once - -#define DEBUG_CRYFIXED_ARRAY _DEBUG - -template< - unsigned int align > -struct CryFixedArrayDatum -{ -}; - -template<> -struct CryFixedArrayDatum< 4 > -{ - typedef uint32 TDatum; -}; - -template<> -struct CryFixedArrayDatum< 8 > -{ - typedef uint64 TDatum; -}; - -template -class CryFixedArray -{ -protected: - enum - { - ALIGN = MAX(alignof(T), sizeof(unsigned int)) - }; // ALIGN at least sizeof(unsigned int) - - typedef typename CryFixedArrayDatum< ALIGN >::TDatum TDatum; - - uint32 m_curSize[ sizeof (TDatum) / sizeof (uint32) ]; // Padded for alignment - - TDatum m_data[(N * sizeof(T) + (sizeof(TDatum) - 1)) / sizeof(TDatum)]; // simple debugging - in VS: just add to a watch as "(T*)m_data, " to see the array. ie. "(int*)m_data, 5" - the size of the array has to be a literal int - -public: - typedef T* iterator; - typedef const T* const_iterator; - - CryFixedArray() - { -#if DEBUG_CRYFIXED_ARRAY - if (((uintptr_t)m_data & (ALIGN - 1)) != 0) - { - CryLogAlways("CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported."); - } -#endif - CRY_ASSERT_MESSAGE(((uintptr_t)m_data & (ALIGN - 1)) == 0, "CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported."); - m_curSize[0] = 0; - } - - CryFixedArray(const CryFixedArray& other) - { - // doesn't require clear() this is newly constructed - m_curSize[0] = other.m_curSize[0]; - - int size = m_curSize[0]; - for (int i = 0; i < size; i++) - { - T& ele = operator[](i); - const T& otherEle = other.operator[](i); - new (&ele)T(otherEle); // placement new - } - } - - CryFixedArray& operator=(const CryFixedArray& other) - { - if (this != &other) - { - clear(); // necessary to avoid potentially leaking within existing elements - - m_curSize[0] = other.m_curSize[0]; - - int size = m_curSize[0]; - for (int i = 0; i < size; i++) - { - T& ele = operator[](i); - const T& otherEle = other.operator[](i); - //ele = otherEle; // assignment instead of placement new to keep type of operation consistent - this cannot be done until this is rewritten to assign over existing elements and deconstruct any left overs, and placement new any new elements - new (&ele)T(otherEle); // placement new - } - } - - return *this; - } - - virtual ~CryFixedArray() - { - clear(); - } - - ILINE T& at(unsigned int i) - { -#if DEBUG_CRYFIXED_ARRAY - if (i < size()) - { - return alias_cast(m_data)[i]; - } - else - { - // Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!! - CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N)); - abort(); // better option than dereferncing a nullptr? - } -#else - return alias_cast(m_data)[i]; -#endif - } - - ILINE const T& at(unsigned int i) const - { -#if DEBUG_CRYFIXED_ARRAY - if (i < size()) - { - return alias_cast(m_data)[i]; - } - else - { - // Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!! - CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N)); - abort(); // better option than dereferncing a nullptr? - } -#else - return alias_cast(m_data)[i]; -#endif - } - - ILINE const T& operator[](unsigned int i) const - { - return at(i); - } - - ILINE T& operator[](unsigned int i) - { - return at(i); - } - - ILINE void clear() - { - for (uint32 i = 0; i < m_curSize[0]; i++) - { - T& ele = operator[](i); - ele.~T(); - } - m_curSize[0] = 0; -#if DEBUG_CRYFIXED_ARRAY - memset(m_data, 0, N * sizeof(T)); -#endif - } - - ILINE iterator begin() - { - return alias_cast(m_data); - } - ILINE const_iterator begin() const - { - return alias_cast(m_data); - } - ILINE iterator end() - { - return &(alias_cast(m_data))[m_curSize[0]]; - } - ILINE const_iterator end() const - { - return &(alias_cast(m_data))[m_curSize[0]]; - } - - ILINE unsigned int max_size() const { return N; } - ILINE unsigned int size() const { return m_curSize[0]; } - ILINE bool empty() const { return size() == 0; } - ILINE unsigned int isfull() const { return (size() == max_size()); } - - // allows you to push back default constructed elements - ILINE void push_back () - { - unsigned int curSize = size(); - if (curSize < N) - { - T* newT = &(alias_cast(m_data))[curSize]; - new (newT) T(); - - m_curSize[0]++; - } - else - { - CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N); - CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N)); - } - } - - ILINE void push_back (const T& ele) - { - unsigned int curSize = size(); - if (curSize < N) - { - T* newT = &(alias_cast(m_data))[curSize]; - new (newT) T(ele); // placement new copy constructor - setup vtable etc - - m_curSize[0]++; - } - else - { - CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N); - CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N)); - } - } - - ILINE void pop_back() - { - if (size() > 0) - { - back().~T(); // destruct back - m_curSize[0]--; - } - else - { - CryLogAlways("CryFixedArray::pop_back() failed as array is empty"); - CRY_ASSERT_MESSAGE(0, "CryFixedArray::pop_back() failed as array is empty"); - } - } - -protected: - ILINE const T& backEx() const - { -#if DEBUG_CRYFIXED_ARRAY - if (m_curSize[0] > 0) - { - return (alias_cast(m_data))[m_curSize[0] - 1]; - } - else - { - CryLogAlways("CryFixedArray::back() failed as array is empty"); - CRY_ASSERT_MESSAGE(0, "CryFixedArray::back() failed as array is empty"); - abort(); // better option than dereferncing a nullptr? - } -#else - return (alias_cast(m_data))[m_curSize[0] - 1]; -#endif - } - -public: - ILINE const T& back() const - { - return backEx(); - } - - ILINE T& back() - { - return (T&)(backEx()); - } - - // if returns true then an element has been swapped into the new element[i] and as such may need updating to reflect its new location in memory - ILINE bool removeAt(uint32 i) - { - bool swappedElement = false; - - if (i < m_curSize[0]) - { - if (i != m_curSize[0] - 1) - { - operator[](i).~T(); // destruct element being removed - - // copy back() into element i - T* newT = &(alias_cast(m_data))[i]; - new (newT) T(back()); // placement new copy constructor - setup vtable etc - - swappedElement = true; - } - pop_back(); // will destruct back() - } - else - { - CryLog("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0]); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0])); - } - return swappedElement; - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H diff --git a/Code/CryEngine/CryCommon/CryFixedString.h b/Code/CryEngine/CryCommon/CryFixedString.h index 9c522ad078..cabcc7d06f 100644 --- a/Code/CryEngine/CryCommon/CryFixedString.h +++ b/Code/CryEngine/CryCommon/CryFixedString.h @@ -2019,21 +2019,6 @@ inline CryStackStringT CryStackStringT::Tokenize(const_str charSet, return CryStackStringT(); } -////////////////////////////////////////////////////////////////////////// -// Specialization providing efficient move semantics for array classes. -template -bool raw_movable(const CryStackStringT& str) -{ - return false; -} - -template -void move_init(CryStackStringT& dest, CryStackStringT& source) -{ - dest.move(source); -} - - #if defined(_RELEASE) #define ASSERT_LEN (void)(0) #define ASSERT_WLEN (void)(0) diff --git a/Code/CryEngine/CryCommon/CryMemoryAllocator.h b/Code/CryEngine/CryCommon/CryMemoryAllocator.h deleted file mode 100644 index b9003fc6fa..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryAllocator.h +++ /dev/null @@ -1,274 +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. -/* - * Part of this code coming from STLPort alloc - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Copyright (c) 1997 - * Moscow Center for SPARC Technology - * - * Copyright (c) 1999 - * Boris Fomitchev - * - * - */ - -#ifndef CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H -#pragma once - -#include - -#define CRY_STL_ALLOC - -#if defined(LINUX64) || defined(APPLE) -#include -#endif - -#include // memset - -// DON't USE _MAX_BYTES as identifier for Max Bytes, STLPORT defines the same enum -// this leads to situation where the wrong enum is choosen in different compilation units -// which in case leads to errors(The stlport one is defined as 128) -#if defined (__OS400__) || defined (_WIN64) || defined(MAC) || defined(LINUX64) -enum {_ALIGNMENT = 16, _ALIGN_SHIFT = 4, __MAX_BYTES = 512, NFREELISTS=32, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 40}; -#else -enum {_ALIGNMENT = 8, _ALIGN_SHIFT = 3, __MAX_BYTES = 512, NFREELISTS = 64, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 20}; -#endif /* __OS400__ */ - -#define CRY_MEMORY_ALLOCATOR - -#define S_FREELIST_INDEX(__bytes) ((__bytes - size_t(1)) >> (int)_ALIGN_SHIFT) - -class _Node_alloc_obj { -public: - _Node_alloc_obj * _M_next; -}; - -#if defined (_WIN64) || defined(APPLE) || defined(LINUX64) -#define MASK_COUNT 0x000000FFFFFFFFFF -#define MASK_VALUE 0xFFFFFF -#define MASK_NEXT 0xFFFFFFFFFF000000 -#define MASK_SHIFT 24 -#else -#define MASK_COUNT 0x000FFFFF -#define MASK_VALUE 0xFFF -#define MASK_NEXT 0xFFFFF000 -#define MASK_SHIFT 12 -#endif - -#define NUM_OBJ 64 - -struct _Obj_Address { - // short int * _M_next; - // short int - size_t GetNext(size_t pBase) { - return pBase +(size_t)(_M_value >> MASK_SHIFT); - } - - //size_t GetNext() { - // return (size_t)(_M_value >> 20); - //} - - size_t GetCount() { - return _M_value & MASK_VALUE; - } - - void SetNext(/*void **/size_t pNext) { - _M_value &= MASK_COUNT; - _M_value |= (size_t)pNext << MASK_SHIFT; - } - - void SetCount(size_t count) { - _M_value &= MASK_NEXT; - _M_value |= count & MASK_VALUE; - } -private: - size_t _M_value; - // short int * _M_end; -}; - -//struct _Node_Allocations_Tree { -// enum { eListSize = _Size / (sizeof(void *) * _Num_obj); }; -// _Obj_Address * _M_allocations_list[eListSize]; -// int _M_Count; -// _Node_Allocations_Tree * _M_next; -//}; - -template -struct _Node_Allocations_Tree { - //Pointer to the end of the memory block - char *_M_end; - - enum { eListSize = _Size / (sizeof(void *) * NUM_OBJ) }; - // List of allocations - _Obj_Address _M_allocations_list[eListSize]; - int _M_allocations_count; - //Pointer to the next memory block - _Node_Allocations_Tree *_M_Block_next; -}; - - -struct _Node_alloc_Mem_block_Huge { - //Pointer to the end of the memory block - char *_M_end; - // number - int _M_count; - _Node_alloc_Mem_block_Huge *_M_next; -}; - -template -struct _Node_alloc_Mem_block { - //Pointer to the end of the memory block - char *_M_end; - //Pointer to the next memory block - _Node_alloc_Mem_block_Huge *_M_huge_block; - _Node_alloc_Mem_block *_M_next; -}; - - -// Allocators! -enum EAllocFreeType -{ - eCryDefaultMalloc, - eCryMallocCryFreeCRTCleanup, -}; - -template -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryModuleMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - CryModuleFree(ptr); - return 0; - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } -}; - -// partial -template <> -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - size_t n = CryCrtSize(ptr); - CryCrtFree(ptr); - return n; - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } - -}; - -// partial -template <> -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - return CryCrtFree(ptr); - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } - -}; - -#include "MultiThread.h" - -struct InternalCriticalSectionDummy { - char padding[128]; -} ; - -inline void CryInternalCreateCriticalSection(void * pCS) -{ - CryCreateCriticalSectionInplace(pCS); -} - -// A class that forward node allocator calls directly to CRT -struct cry_crt_node_allocator -{ - static const size_t MaxSize = ~0; - - static void *alloc(size_t __n) - { - return CryCrtMalloc(__n); - } - static size_t dealloc( void *p ) - { - return CryCrtFree(p); - } - static void *allocate(size_t __n) - { - return alloc(__n); - } - static void *allocate(size_t __n, [[maybe_unused]] size_t nAlignment) - { - return alloc(__n); - } - static size_t deallocate(void *__p) - { - return dealloc(__p); - } - void cleanup() {} -}; - - -//#endif // WIN32|DEBUG - -#endif // CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/CryMemoryManager.h b/Code/CryEngine/CryCommon/CryMemoryManager.h deleted file mode 100644 index b3f8ba7c8e..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryManager.h +++ /dev/null @@ -1,295 +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 : Defines functions for CryEngine custom memory manager. - -#pragma once - -// Section dictionary -#if defined(AZ_RESTRICTED_PLATFORM) -#define CRYMEMORYMANAGER_H_SECTION_TRAITS 1 -#define CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY 2 -#endif - -#include -// Traits -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_TRAITS - #include AZ_RESTRICTED_FILE(CryMemoryManager_h) -#else -#if !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H 1 -#endif -#if defined(LINUX) || defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H 1 -#endif -#if !defined(LINUX) && !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H 1 -#endif -#if !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY 1 -#endif -#endif - -#include "platform.h" - -#include -#include - -#if defined(APPLE) || defined(ANDROID) - #include // memalign -#endif // defined(APPLE) - -#ifndef STLALLOCATOR_CLEANUP -#define STLALLOCATOR_CLEANUP -#endif - -#define _CRY_DEFAULT_MALLOC_ALIGNMENT 4 - -#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H - #include -#endif - -#if defined(__cplusplus) -#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H - #include -#else - #include -#endif -#endif - - #ifdef CRYSYSTEM_EXPORTS - #define CRYMEMORYMANAGER_API DLL_EXPORT - #else - #define CRYMEMORYMANAGER_API DLL_IMPORT - #endif - -#ifdef __cplusplus - -#if defined(_DEBUG) && CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H - #include -#endif //_DEBUG - -#include "LegacyAllocator.h" - -namespace CryMemory -{ - // checks if the heap is valid in debug; in release, this function shouldn't be called - // returns non-0 if it's valid and 0 if not valid - ILINE int IsHeapValid() - { - #if (defined(_DEBUG) && !defined(RELEASE_RUNTIME) && CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY) || (defined(DEBUG_MEMORY_MANAGER)) - return _CrtCheckMemory(); - #else - return true; - #endif - } - - inline void* AllocPages(size_t size) - { - const size_t alignment = AZ_PAGE_SIZE; - void* ret = AZ::AllocatorInstance::Get().Allocate(size, alignment, 0, "AllocPages", __FILE__, __LINE__); - return ret; - } - - inline void FreePages(void* p, size_t size) - { - const size_t alignment = AZ_PAGE_SIZE; - AZ::AllocatorInstance::Get().DeAllocate(p, size, alignment); - } -} - -////////////////////////////////////////////////////////////////////////// - -#endif //__cplusplus - -struct ICustomMemoryHeap; -class IGeneralMemoryHeap; -class IPageMappingHeap; -class IMemoryAddressRange; - -// Description: -// Interfaces that allow access to the CryEngine memory manager. -struct IMemoryManager -{ - typedef unsigned char HeapHandle; - enum - { - BAD_HEAP_HANDLE = 0xFF - }; - - struct SProcessMemInfo - { - uint64 PageFaultCount; - uint64 PeakWorkingSetSize; - uint64 WorkingSetSize; - uint64 QuotaPeakPagedPoolUsage; - uint64 QuotaPagedPoolUsage; - uint64 QuotaPeakNonPagedPoolUsage; - uint64 QuotaNonPagedPoolUsage; - uint64 PagefileUsage; - uint64 PeakPagefileUsage; - - uint64 TotalPhysicalMemory; - int64 FreePhysicalMemory; - - uint64 TotalVideoMemory; - int64 FreeVideoMemory; - }; - - enum EAllocPolicy - { - eapDefaultAllocator, - eapPageMapped, - eapCustomAlignment, -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY - #include AZ_RESTRICTED_FILE(CryMemoryManager_h) -#endif - }; - - virtual ~IMemoryManager(){} - - virtual bool GetProcessMemInfo(SProcessMemInfo& minfo) = 0; - - ////////////////////////////////////////////////////////////////////////// - // Heap Tracing API - virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase) = 0; - virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0) = 0; - virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize) = 0; - virtual void TraceHeapSetColor(uint32 color) = 0; - virtual uint32 TraceHeapGetColor() = 0; - virtual void TraceHeapSetLabel(const char* sLabel) = 0; - ////////////////////////////////////////////////////////////////////////// - - // Create an instance of ICustomMemoryHeap - virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(EAllocPolicy const eAllocPolicy) = 0; - virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) = 0; - virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) = 0; - - virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName) = 0; - virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName) = 0; -}; - -// Global function implemented in CryMemoryManager_impl.h -IMemoryManager* CryGetIMemoryManager(); - -// Summary: -// Structure filled by call to CryModuleGetMemoryInfo(). -struct CryModuleMemoryInfo -{ - uint64 requested; - // Total Ammount of memory allocated. - uint64 allocated; - // Total Ammount of memory freed. - uint64 freed; - // Total number of memory allocations. - int num_allocations; - // Allocated in CryString. - uint64 CryString_allocated; - // Allocated in STL. - uint64 STL_allocated; - // Amount of memory wasted in pools in stl (not usefull allocations). - uint64 STL_wasted; -}; - -struct CryReplayInfo -{ - uint64 uncompressedLength; - uint64 writtenLength; - uint32 trackingSize; - const char* filename; -}; - -////////////////////////////////////////////////////////////////////////// -// Extern declarations of globals inside CrySystem. -////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -void* CryMalloc(size_t size, size_t& allocated, size_t alignment); -void* CryRealloc(void* memblock, size_t size, size_t& allocated, size_t& oldsize, size_t alignment); -size_t CryFree(void* p, size_t alignment); -size_t CryGetMemSize(void* p, size_t size); -int CryStats(char* buf); -void CryFlushAll(); -void CryCleanup(); -int CryGetUsedHeapSize(); -int CryGetWastedHeapSize(); -size_t CrySystemCrtGetUsedSpace(); -CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager); - -#ifdef __cplusplus -} -#endif //__cplusplus - -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -// Cry Memory Manager accessible in all build modes. -////////////////////////////////////////////////////////////////////////// -#if !defined(USING_CRY_MEMORY_MANAGER) -#define USING_CRY_MEMORY_MANAGER -#endif - -#include "CryLegacyAllocator.h" - - -template -inline T* CryAlignedNew(Args&& ... args) -{ - void* pAlignedMemory = CryModuleMemalign(sizeof(T), std::alignment_of::value); - return new(pAlignedMemory) T(std::forward(args) ...); -} - -// This utility function should be used for allocating arrays of objects with specific alignment requirements on the heap. -// Note: The caller must remember the number of items in the array, since CryAlignedDeleteArray needs this information. -template -inline T* CryAlignedNewArray(size_t count) -{ - T* const pAlignedMemory = reinterpret_cast(CryModuleMemalign(sizeof(T) * count, std::alignment_of::value)); - T* pCurrentItem = pAlignedMemory; - for (size_t i = 0; i < count; ++i, ++pCurrentItem) - { - new(static_cast(pCurrentItem))T(); - } - return pAlignedMemory; -} - -// Utility function that frees an object previously allocated with CryAlignedNew. -template -inline void CryAlignedDelete(T* pObject) -{ - if (pObject) - { - pObject->~T(); - CryModuleMemalignFree(pObject); - } -} - -// Utility function that frees an array of objects previously allocated with CryAlignedNewArray. -// The same count used to allocate the array must be passed to this function. -template -inline void CryAlignedDeleteArray(T* pObject, size_t count) -{ - if (pObject) - { - for (size_t i = 0; i < count; ++i) - { - (pObject + i)->~T(); - } - CryModuleMemalignFree(pObject); - } -} diff --git a/Code/CryEngine/CryCommon/CryMemoryManager_impl.h b/Code/CryEngine/CryCommon/CryMemoryManager_impl.h deleted file mode 100644 index fdb4f5665e..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryManager_impl.h +++ /dev/null @@ -1,41 +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 : Provides implementation for CryMemoryManager globally defined functions. -// This file included only by platform_impl.cpp, do not include it directly in code! - - -#pragma once - -#ifdef AZ_MONOLITHIC_BUILD - #include // <> required for Interfuscator -#endif // AZ_MONOLITHIC_BUILD - -#include "CryLibrary.h" - -#include - -#define DLL_ENTRY_GETMEMMANAGER "CryGetIMemoryManagerInterface" - -// Resolve IMemoryManager by looking in this DLL, then loading and rummaging through -// CrySystem. Cache the result per DLL, because this is not quick. -IMemoryManager* CryGetIMemoryManager() -{ - static AZ::EnvironmentVariable memMan = nullptr; - if (!memMan) - { - memMan = AZ::Environment::FindVariable("CryIMemoryManagerInterface"); - AZ_Assert(memMan, "Unable to find CryIMemoryManagerInterface via AZ::Environment"); - } - return *memMan; -} diff --git a/Code/CryEngine/CryCommon/CryName.h b/Code/CryEngine/CryCommon/CryName.h index 699525f958..0fb34c9532 100644 --- a/Code/CryEngine/CryCommon/CryName.h +++ b/Code/CryEngine/CryCommon/CryName.h @@ -19,7 +19,6 @@ #include #include #include -#include #include class CNameTable; diff --git a/Code/CryEngine/CryCommon/CrySizer.h b/Code/CryEngine/CryCommon/CrySizer.h index fc45438209..62b1acf489 100644 --- a/Code/CryEngine/CryCommon/CrySizer.h +++ b/Code/CryEngine/CryCommon/CrySizer.h @@ -48,8 +48,6 @@ struct SPipTangents; #include // workaround for Amd64 compiler #endif -#include // <> required for Interfuscator. IResourceCollector - namespace AZ { class Vector3; @@ -335,20 +333,6 @@ public: } } - template - void AddObject(const TArray& rVector) - { - if (!this->AddObject(rVector.begin(), rVector.capacity() * sizeof(T))) - { - return; - } - - for (int i = 0, end = rVector.size(); i < end; ++i) - { - this->AddObject(rVector[i]); - } - } - template void AddObject(const PodArray& rVector) { @@ -427,11 +411,6 @@ public: return AddObject (&rObject, sizeof(T)); } - // used to collect the assets needed for streaming and to gather statistics - // always returns a valid reference - virtual IResourceCollector* GetResourceCollector() = 0; - virtual void SetResourceCollector(IResourceCollector* pColl) = 0; - bool Add (const char* szText) { return AddObject(szText, strlen(szText) + 1); diff --git a/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h b/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h deleted file mode 100644 index aaf5a0889f..0000000000 --- a/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h +++ /dev/null @@ -1,634 +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 : Specialized Container for Renderer data with the following proberties: -// - Created during the 3DEngine Update, comsumed in the renderer in the following frame -// - This Container is very restricted and likely not optimal for other situations - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H -#pragma once - - -// This container is specialized for data which is generated in the 3DEngine and consumed by the renderer -// in the following frame due to multithreaded rendering. To be useable by Jobs as well as other Threads -// some very specific desing choices were taken: -// First of the underlying continous memory block is only resized during a call to 'CoalesceMemory' -// to prevent freeing a memory block which could be used by another thread. -// If new memory is requiered, a page of 4 KB is allocated and used as a temp storage till the next -// call to 'CoalesceMemory' which then copies all page memory into one continous block. -// Also all threading relevant functions are implemented LockLess to prevent lock contention and make -// this container useable from Jobs -// -// Right now, the main usage pattern of this container is by the RenderThread, who calls at the beginning -// of its frame 'CoalesceMemory', since then we can be sure that the 3DEngine has finished creating it's elements. -// -// Since the main purpose of this container is multi-threading adding of elements, a slight change was done to the -// push_back interface compared to std::vector: -// All implemented push_back variants can return a pointer into the storage (safe since no memory is freed during adding) -// and a index for this elements. This is done since calling operator[] could be expensive when called before 'CoalesceMemory' -// -// For ease of implementation (and a little bit of speed), this container only supports POD types (which can be copied with memcpy) -// also note that this container only supports push_back (and resize back to 0) and no pop back due cost (performance and code complexity) of supporting lock-free in parallel pop_back -#define TSRC_ALIGN _MS_ALIGN(128) - -template -class TSRC_ALIGN CThreadSafeRendererContainer -{ -public: - CThreadSafeRendererContainer(); - ~CThreadSafeRendererContainer(); - - //NOTE: be aware that these valus can potentially change if some objects are added in parallel - size_t size() const; - size_t empty() const; - size_t capacity() const; - - //NOTE: be aware that this operator can be more expensive if the memory was not coalesced before - T& operator[](size_t n); - const T& operator[](size_t n) const; - - T* push_back_new(); - T* push_back_new(size_t& nIndex); - - void push_back(const T&); - void push_back(const T&, size_t& nIndex); - - // NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe - void clear(); - void resize(size_t n); - void reserve(size_t n); - - void CoalesceMemory(); - - void GetMemoryUsage(ICrySizer*) const; - - // disable copy/assignment - CThreadSafeRendererContainer(const CThreadSafeRendererContainer& rOther) = delete; - CThreadSafeRendererContainer& operator=(const CThreadSafeRendererContainer& rOther) = delete; - -private: - - ///////////////////////////////////// - // Struct to represent a memory chunk - // used in fallback allocations during 'Fill' phase - class CMemoryPage - { - public: - // size of a page to allocate, the CMemoryPage is just the header, - // the actual object data is stored in the 4KB chunk right - // after the header (while keeping the requiered alignment and so on) - enum - { - nMemoryPageSize = 4096 - }; - - CMemoryPage(); - - // allocation functions - static CMemoryPage* AllocateNewPage(); - bool TryAllocateElement(size_t& nIndex, T*& pObj); - - // access to the elements - T& GetElement(size_t n); - T* GetData() const; - - // information about the page (NOTE: not thread-safe in all combinations) - size_t Size() const; - size_t Capacity() const; - size_t GetDataSize() const; - - CMemoryPage* m_pNext; // Pointer to next entry in single-linked list of CMemoryPages - - private: - LONG m_nSize; // Number of elements currently in the page - LONG m_nCapacity; // Number of elements which could fit into the page - T* m_arrData; // Element memory, from the same memory chunk right after the CMemoryPage class - }; - - - ///////////////////////////////////// - // Private functions which do the lock-less updating - T* push_back_impl(size_t& nIndex); - bool try_append_to_continous_memory(size_t& nIndex, T*& pObj); - - T& GetMemoryPageElement(size_t n); - - - ///////////////////////////////////// - // Private Member Variables - T* m_arrData; // Storage for the continous memory part, during coalescing resized to hold all page memory - LONG m_nCapacity; // Avaible Memory in continous memory part, if exhausted during 'Fill' phase, pages as temp memory chunks are allocated - - CMemoryPage* m_pMemoryPages; // Single linked list of memory chunks, used for fallback allocations during 'Fill' phase (to prevent changing the continous memory block during 'Fill' - - LONG m_nSize; // Number of elements currently in the container, can be larger than m_nCapacity due the nonContinousPages - - bool m_bElementAccessSafe; // bool to indicate if we are currently doing a 'CoalasceMemory' step, during which some operations are now allowed -} _ALIGN(128); - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::CThreadSafeRendererContainer() - : m_arrData(NULL) - , m_nCapacity(0) - , m_pMemoryPages(NULL) - , m_nSize(0) - , m_bElementAccessSafe(true) -{ -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::~CThreadSafeRendererContainer() -{ - clear(); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::size() const -{ - return *const_cast(&m_nSize); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::empty() const -{ - return *const_cast(&m_nSize) == 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::capacity() const -{ - // capacity of continous memory block - LONG nCapacity = m_nCapacity; - - // add capacity of all memory pages - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - nCapacity += pCurrentMemoryPage->Capacity(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - - return nCapacity; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeRendererContainer::operator[](size_t n) -{ - assert(m_bElementAccessSafe); - T* pRet = NULL; - -#if !defined(NULL_RENDERER) - assert((LONG)n < m_nSize); -#endif - if ((LONG)n < m_nCapacity) - { - pRet = &m_arrData[n]; - } - else - { - pRet = &GetMemoryPageElement(n); - } - return *pRet; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline const T& CThreadSafeRendererContainer::operator[](size_t n) const -{ - return const_cast(const_cast*>(this)->operator[](n)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_new() -{ - assert(m_bElementAccessSafe); - size_t nUnused = ~0; - return push_back_impl(nUnused); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_new(size_t& nIndex) -{ - assert(m_bElementAccessSafe); - return push_back_impl(nIndex); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::push_back(const T& rObj) -{ - assert(m_bElementAccessSafe); - size_t nUnused = ~0; - T* pObj = push_back_impl(nUnused); - *pObj = rObj; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::push_back(const T& rObj, size_t& nIndex) -{ - assert(m_bElementAccessSafe); - T* pObj = push_back_impl(nIndex); - *pObj = rObj; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::clear() -{ - assert(m_bElementAccessSafe); - // free continous part - CryModuleMemalignFree(m_arrData); - m_arrData = NULL; - - // free non-continous pages if we have some - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - CMemoryPage* pOldPage = pCurrentMemoryPage; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - CryModuleFree(pOldPage); - } - m_pMemoryPages = NULL; - - m_nSize = 0; - m_nCapacity = 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::resize(size_t n) -{ - assert(m_bElementAccessSafe); - CoalesceMemory(); - size_t nOldSize = m_nSize; - m_nSize = n; - - if ((LONG)n <= m_nCapacity) - { - return; - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, nOldSize * sizeof(T)); - memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - m_nCapacity = n; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::reserve(size_t n) -{ - assert(m_bElementAccessSafe); - CoalesceMemory(); - if ((LONG)n <= m_nCapacity) - { - return; - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, m_nSize * sizeof(T)); - memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - m_nCapacity = n; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline bool CThreadSafeRendererContainer::try_append_to_continous_memory(size_t& nIndex, T*& pObj) -{ - assert(m_bElementAccessSafe); - LONG nSize = ~0; - LONG nCapacity = ~0; - do - { - // read volatile the new size - nSize = *const_cast(&m_nSize); - nCapacity = *const_cast(&m_nCapacity); - - if (nSize >= nCapacity) - { - return false; - } - } while (CryInterlockedCompareExchange(alias_cast(&m_nSize), nSize + 1, nSize) != nSize); - nIndex = nSize; - pObj = &m_arrData[nSize]; - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_impl(size_t& nIndex) -{ - assert(m_bElementAccessSafe); - T* pObj = NULL; - - // non atomic check to see if there is space in the continous array - if (try_append_to_continous_memory(nIndex, pObj)) - { - return pObj; - } - - // exhausted continous memory, falling back to page allocation - for (;; ) - { - assert(m_bElementAccessSafe); - size_t nPageBaseIndex = 0; - - // traverse the page list till the first page with free memory - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - size_t nAvaibleElements = pCurrentMemoryPage->Capacity() - pCurrentMemoryPage->Size(); - if (nAvaibleElements) - { - break; - } - - // no memory in this page, go to the next one - nPageBaseIndex += pCurrentMemoryPage->Capacity(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - - // try to allocate a element on this page - if (pCurrentMemoryPage && pCurrentMemoryPage->TryAllocateElement(nIndex, pObj)) - { - // update global elements counter - CryInterlockedIncrement(alias_cast(&m_nSize)); - - // adjust in-page-index to global index - nIndex += nPageBaseIndex + m_nCapacity; - return pObj; - } - else - { - // all pages are empty, allocate and link a new one - CMemoryPage* pNewPage = CMemoryPage::AllocateNewPage(); - - void* volatile* ppLastMemoryPageAddress = NULL; - do - { - // find place to link in page - CMemoryPage* pLastMemoryPage = m_pMemoryPages; - ppLastMemoryPageAddress = alias_cast(&m_pMemoryPages); - - while (pLastMemoryPage) - { - ppLastMemoryPageAddress = alias_cast(&(pLastMemoryPage->m_pNext)); - pLastMemoryPage = pLastMemoryPage->m_pNext; - } - } while (CryInterlockedCompareExchangePointer(ppLastMemoryPageAddress, pNewPage, NULL) != NULL); - } - } -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeRendererContainer::GetMemoryPageElement(size_t n) -{ - assert(m_bElementAccessSafe); - size_t nFirstListIndex = m_nCapacity; - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - - size_t nPageCapacity = pCurrentMemoryPage->Capacity(); - while (n >= (nFirstListIndex + nPageCapacity)) - { - // this is threadsafe because we assume that if we want to get element 'n' - // the clientcode did already fill the container up to element 'n' - // thus up to 'n', m_pNonContinousList will have valid pages - // NOTE: This is not safe when trying to read a element behind the valid - // range (same as std::vector) - nFirstListIndex += nPageCapacity; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - - // update page capacity, since it can differe due alignment - nPageCapacity = pCurrentMemoryPage->Capacity(); - } - - return pCurrentMemoryPage->GetElement(n - nFirstListIndex); -} - -/////////////////////////////////////////////////////////////////////////////// -// When not not in the 'Fill' phase, it is safe to colace all page entries into one continous memory block -template -inline void CThreadSafeRendererContainer::CoalesceMemory() -{ - assert(m_bElementAccessSafe); - if (m_pMemoryPages == NULL) - { - return; // nothing to do - } - // mark state as not accessable - m_bElementAccessSafe = false; - -#if !defined(NDEBUG) - size_t nOldSize = m_nSize; -#endif - - // compute required memory - size_t nRequieredElements = 0; - { - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - nRequieredElements += pCurrentMemoryPage->Size(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign((m_nCapacity + nRequieredElements) * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, m_nCapacity * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - // copy page data into continous memory block - { - size_t nBeginToFillIndex = m_nCapacity; - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - // copy data - memcpy(&m_arrData[nBeginToFillIndex], pCurrentMemoryPage->GetData(), pCurrentMemoryPage->GetDataSize()); - nBeginToFillIndex += pCurrentMemoryPage->Size(); - - // free page - CMemoryPage* pOldPage = pCurrentMemoryPage; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - CryModuleFree(pOldPage); - } - - m_pMemoryPages = NULL; - } - - assert(nOldSize == m_nSize); - m_nCapacity += nRequieredElements; - - // the container can be used again - m_bElementAccessSafe = true; -} - -/////////////////////////////////////////////////////////////////////////////// -// Collect information about used memory -template -void CThreadSafeRendererContainer::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_arrData, m_nCapacity * sizeof(T)); - - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - pSizer->AddObject(pCurrentMemoryPage, CMemoryPage::nMemoryPageSize); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::CMemoryPage::CMemoryPage() - : m_pNext(NULL) - , m_nSize(0) -{ - // compute offset for actual data - size_t nObjectAlignment = alignof(T); - UINT_PTR nMemoryBlockBegin = alias_cast(this); - UINT_PTR nMemoryBlockEnd = alias_cast(this) + nMemoryPageSize; - - nMemoryBlockBegin += sizeof(CMemoryPage); - nMemoryBlockBegin = (nMemoryBlockBegin + nObjectAlignment - 1) & ~(nObjectAlignment - 1); - - // compute number of avaible elements - assert(nMemoryBlockEnd > nMemoryBlockBegin); - m_nCapacity = (LONG)((nMemoryBlockEnd - nMemoryBlockBegin) / sizeof(T)); - - // store pointer to store data to - m_arrData = alias_cast(nMemoryBlockBegin); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline typename CThreadSafeRendererContainer::CMemoryPage * CThreadSafeRendererContainer::CMemoryPage::AllocateNewPage() -{ - void* pNewPageMemoryChunk = CryModuleMalloc(nMemoryPageSize); - assert(pNewPageMemoryChunk != NULL); - - memset(pNewPageMemoryChunk, 0, nMemoryPageSize); - CMemoryPage* pNewPage = new(pNewPageMemoryChunk) CMemoryPage(); - return pNewPage; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline bool CThreadSafeRendererContainer::CMemoryPage::TryAllocateElement(size_t & nIndex, T * &pObj) -{ - LONG nSize = ~0; - LONG nCapacity = ~0; - do - { - // read volatile the new size - nSize = *const_cast(&m_nSize); - nCapacity = *const_cast(&m_nCapacity); - // stop trying if this page is full - if (nSize >= nCapacity) - { - return false; - } - } while (CryInterlockedCompareExchange(alias_cast(&m_nSize), nSize + 1, nSize) != nSize); - - //Note: this is the index in the page and it is adjusted in the calling context - nIndex = nSize; - pObj = &m_arrData[nSize]; - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T&CThreadSafeRendererContainer::CMemoryPage::GetElement(size_t n) -{ - assert((LONG)n < m_nSize); - assert(m_nSize <= m_nCapacity); - return m_arrData[n]; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T * CThreadSafeRendererContainer::CMemoryPage::GetData() const -{ - return m_arrData; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::Size() const -{ - return m_nSize; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::GetDataSize() const -{ - return m_nSize * sizeof(T); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::Capacity() const -{ - return m_nCapacity; -} - -#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H diff --git a/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h b/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h deleted file mode 100644 index 418b363ca1..0000000000 --- a/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h +++ /dev/null @@ -1,602 +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 : Specialized Container for Renderer data with the following properties: -// Created during the 3DEngine Update, consumed in the renderer in the following frame -// This Container is very restricted and likely not optimal for other situations - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H -#pragma once - - -#include "platform.h" -#include - -#include -#include -#include - - -// -// !!! BE CAREFULL WHEN USING THIS CONTAINER !!! -// -// --- Properties: --- -// - Stores data local to worker thread to avoid thread-safety semantics -// - Allows for a single non-worker thread to be tracked which is stored in m_workers[0] -// Hence: As m_workers[0] is shared between all non-worker threads, ensure that only one additional non-worker thread may access this container e.g. MainThread -// - Coalesce memory to obtain a continues memory block -// - Coalesce memory to for faster element access to a continues memory block -// -// --- Restrictions:--- -// - The workers own the memory structure -// - The coalesced memory stores a copy of the workers used memory -// Hence: Be careful when altering data within the coalesced memory. -// If the templated element is a pointer type than altering the memory pointed to, is not be an issue -// If the templated element is of type class or struct than ensure that data changes are done on the worker local data and not on the coalesced memory. Use worker encoded indices to do so. -// - -template -class CThreadSafeWorkerContainer -{ -public: - struct SDefaultNoOpFunctor - { - ILINE void operator()(T* pData) const{} - }; - - struct SDefaultDestructorFunctor - { - ILINE void operator()(T* pData) const - { - pData->~T(); - } - }; - -public: - CThreadSafeWorkerContainer(); - ~CThreadSafeWorkerContainer(); - - void Init(); - void SetNonWorkerThreadID(threadID nThreadId) { m_foreignThreadId = nThreadId; } - - // Safe access of elements for calling thread via operator[] - uint32 ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const; - - // Returns the number of threads that can use this container, including the one non-worker-thread. - uint32 GetNumWorkers() const; - - // Returns the Worker ID for the current thread. Ranges from 0 to GetNumWorkers()-1. - // Note, WorkerId is not the same thing as JobManager's WorkerThreadId. - uint32 GetWorkerId_threadlocal() const; - - //NOTE: be aware that these values can potentially change if some objects are added in parallel - size_t size() const; - size_t empty() const; - size_t capacity() const; - - size_t size_threadlocal() const; - size_t empty_threadlocal() const; - size_t capacity_threadlocal() const; - - //NOTE: be aware that this operator is more expensive if the memory was not coalesced before - T& operator[](size_t n); - const T& operator[](size_t n) const; - - T* push_back_new(); - T* push_back_new(size_t& nIndex); - - void push_back(const T& rObj); - void push_back(const T& rObj, size_t& nIndex); - - // NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe - void clear(); - template< class OnElementDeleteFunctor> - void clear(const OnElementDeleteFunctor& rFunctor = CThreadSafeWorkerContainer::SDefaultNoOpFunctor()); - void erase(const T& rObj); - void resize(size_t n); - void reserve(size_t n); - - // *not* thread-safe functions - void PrefillContainer(T* pElement, size_t numElements); - void CoalesceMemory(); - - void GetMemoryUsage(ICrySizer* pSizer) const; - -private: - - void clear(AZStd::true_type); - void clear(AZStd::false_type); - - class SWorker - { - public: - AZ_CLASS_ALLOCATOR(SWorker, AZ::LegacyAllocator, 0); - - SWorker() - : m_dataSize(0) {} - - uint32 m_dataSize; - AZStd::vector m_data; - } _ALIGN(128); - - T* push_back_impl(size_t& nIndex); - void ReserverCoalescedMemory(size_t n); - - threadID m_foreignThreadId; // OS thread ID of the non-job-manager-worker-thread allowed to use this container, too. - - AZStd::vector m_workers; // Holds data for each thread that can use this container. A non-worker-thread (Main) has data stored at 0. Actual worker threads range from 1 to m_nNumWorkers-1 - uint32 m_nNumWorkers = 0; // The number of threads that can use this container, including one non-worker-thread. - - uint32 m_coalescedArrCapacity; - T* m_coalescedArr; - bool m_isCoalesced; -}; - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeWorkerContainer::CThreadSafeWorkerContainer() - : m_nNumWorkers(0) - , m_coalescedArrCapacity(0) - , m_coalescedArr(0) - , m_isCoalesced(false) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeWorkerContainer::~CThreadSafeWorkerContainer() -{ - clear(); - m_workers.clear(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::Init() -{ - m_nNumWorkers = AZ::JobContext::GetGlobalContext()->GetJobManager().GetNumWorkerThreads() + 1; - m_workers.resize(m_nNumWorkers); - - m_foreignThreadId = THREADID_NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::size() const -{ - uint32 totalSize = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - totalSize += m_workers[i].m_dataSize; - } - return totalSize; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::empty() const -{ - return size() == 0; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::capacity() const -{ - uint32 totalCapacity = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - totalCapacity += m_workers[i].m_data.capacity(); - } - return totalCapacity; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::size_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_dataSize; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::empty_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_data.empty(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::capacity_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_data.capacity(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeWorkerContainer::operator[](size_t n) -{ - const uint32 nHasWorkerEncodedIndex = (n & 0x80000000) >> 31; - - IF ((m_isCoalesced && !nHasWorkerEncodedIndex), 1) - { - AZ_Assert(m_coalescedArr, "null array"); - AZ_Assert(n < m_coalescedArrCapacity, "Index out of bounds"); - return m_coalescedArr[n]; - } - else - { - const uint32 nWorkerThreadId = (n & 0x7F00007F) >> 24; // Mask bit 24-30 (0 is starting bit) - const uint32 nOffset = (n & ~0xFF000000); // Mask out top 8 bits - - // Encoded offset into worker local array - if (nHasWorkerEncodedIndex) - { - return m_workers[nWorkerThreadId].m_data[nOffset]; - } - else // None-coalesced and none worker encoded offset - { - uint32 nTotalOffset = nOffset; - for (int i = 0; i < m_nNumWorkers; ++i) - { - SWorker& worker = m_workers[i]; - - if (nTotalOffset < worker.m_dataSize) - { - return worker.m_data[nTotalOffset]; - } - else - { - nTotalOffset -= worker.m_dataSize; - } - } - - // Out of bound access detected! - CRY_ASSERT_MESSAGE(false, "CThreadSafeWorkerContainer::operator[] - Out of bounds access"); - __debugbreak(); - AZ_Assert(m_coalescedArr, "null array"); - AZ_Assert(m_coalescedArrCapacity > 0, "Index out of bounds"); - return m_coalescedArr[0]; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline const T& CThreadSafeWorkerContainer::operator[](size_t n) const -{ - return const_cast(const_cast*>(this)->operator[](n)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_new() -{ - size_t unused = ~0; - return push_back_impl(unused); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_new(size_t& nIndex) -{ - return push_back_impl(nIndex); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::push_back(const T& rObj) -{ - size_t nUnused = ~0; - T* pObj = push_back_impl(nUnused); - *pObj = rObj; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::push_back(const T& rObj, size_t& nIndex) -{ - T* pObj = push_back_impl(nIndex); - *pObj = rObj; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::clear() -{ - clear(typename std::is_destructible::type()); -} - -template -void CThreadSafeWorkerContainer::clear(AZStd::true_type) -{ - clear(SDefaultDestructorFunctor()); -} - -template -void CThreadSafeWorkerContainer::clear(AZStd::false_type) -{ - clear(SDefaultNoOpFunctor()); -} -/////////////////////////////////////////////////////////////////////////////// -template -template -inline void CThreadSafeWorkerContainer::clear(const OnElementDeleteFunctor& rFunctor) -{ - // Reset worker data - for (int i = 0; i < m_nNumWorkers; ++i) - { - // Delete elements - uint32 nSize = m_workers[i].m_data.size(); - for (int j = 0; j < nSize; ++j) - { - // Call on element delete functor - // Note: Default functor will do nothing with the element - rFunctor(&m_workers[i].m_data[j]); - } - - m_workers[i].m_data.clear(); - m_workers[i].m_dataSize = 0; - } - - // Reset container data - if (m_coalescedArr) - { - CryModuleMemalignFree(m_coalescedArr); - } - - m_coalescedArr = 0; - m_coalescedArrCapacity = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::erase(const T& rObj) -{ - for (int i = 0; i < m_nNumWorkers; ++i) - { - typename std::vector::iterator iter = m_workers[i].m_data.begin(); - typename std::vector::iterator iterEnd = m_workers[i].m_data.end(); - - for (; iter != iterEnd; ++iter) - { - if (rObj == *iter) - { - m_workers[i].m_data.erase(iter); - --m_workers[i].m_dataSize; - m_isCoalesced = false; - return; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::resize(size_t n) -{ - CoalesceMemory(); - - uint32 nSizePerWorker = n / m_nNumWorkers; - uint32 nExcessSize = n % m_nNumWorkers; - - // Resize workers evenly - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nWorkerSize = nSizePerWorker + nExcessSize; - - if (nWorkerSize > m_workers[i].m_data.size()) - { - m_workers[i].m_data.resize(nWorkerSize); - } - - m_workers[i].m_dataSize = nWorkerSize; - nExcessSize = 0; // First worker creates excess items - } - - ReserverCoalescedMemory(n); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::reserve(size_t n) -{ - CoalesceMemory(); - - uint32 nSizePerWorker = n / m_nNumWorkers; - uint32 nExcessSize = n % m_nNumWorkers; - - // Resize workers evenly - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nWorkerSize = nSizePerWorker + nExcessSize; - - if (nWorkerSize > m_workers[i].m_data.size()) - { - m_workers[i].m_data.resize(nWorkerSize); - } - - nExcessSize = 0; // First worker creates excess items - } - - ReserverCoalescedMemory(n); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::PrefillContainer(T* pElement, size_t numElements) -{ - reserve(numElements); - - uint32 nOffset = 0; - uint32 nNumItemPerWorker = numElements / m_nNumWorkers; - uint32 nNumExcessItems = numElements % m_nNumWorkers; - - // Store items evenly in workers - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nNumItems = nNumItemPerWorker + nNumExcessItems; - for (int j = 0; j < nNumItems; ++j) - { - m_workers[i].m_data[j] = pElement[nOffset + j]; - } - - m_workers[i].m_dataSize = nNumItems; - nOffset += nNumItems; - nNumExcessItems = 0; // First worker stores excess items - } - - m_isCoalesced = false; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::CoalesceMemory() -{ - if (m_isCoalesced) - { - return; - } - - // Ensure enough memory exists - uint32 minSizeNeeded = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - minSizeNeeded += m_workers[i].m_dataSize; - } - - IF (minSizeNeeded >= m_coalescedArrCapacity, 0) - { - ReserverCoalescedMemory(minSizeNeeded + (minSizeNeeded / 4)); - } - - // Copy data to coalesced array - uint32 nOffest = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - SWorker& rWorker = m_workers[i]; - if (rWorker.m_dataSize == 0) - { - continue; - } - AZ_Assert((nOffest + rWorker.m_dataSize) <= m_coalescedArrCapacity, "Index out of bounds"); - memcpy(m_coalescedArr + nOffest, &rWorker.m_data[0], sizeof(T) * rWorker.m_dataSize); - nOffest += rWorker.m_dataSize; - } - - m_isCoalesced = true; -} - -/////////////////////////////////////////////////////////////////////////////// -template -uint32 CThreadSafeWorkerContainer::ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const -{ - const uint32 workerId = GetWorkerId_threadlocal(); - assert(nIndex < m_workers[workerId].m_dataSize); - return (uint32)((1 << 31) | (workerId << 24) | nIndex); -} - -////////////////////////////////////////////////////////////////////////// -template -uint32 CThreadSafeWorkerContainer::GetNumWorkers() const -{ - return m_nNumWorkers; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_coalescedArr, m_coalescedArrCapacity * sizeof(T)); - - for (int i = 0; i < m_nNumWorkers; ++i) - { - pSizer->AddContainer(m_workers[i].m_data); - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::ReserverCoalescedMemory(size_t n) -{ - if (n <= m_coalescedArrCapacity) - { - return; - } - - T* arrOldData = m_coalescedArr; - m_coalescedArr = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_coalescedArr, arrOldData, m_coalescedArrCapacity * sizeof(T)); - if (arrOldData) - { - CryModuleMemalignFree(arrOldData); - } - m_coalescedArrCapacity = n; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_impl(size_t& nIndex) -{ - // Avoid writing to thread share resource and take hit of 'if statement to avoid false-sharing between threads - IF (m_isCoalesced, 0) - { - m_isCoalesced = false; - } - - // Get worker id - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - - SWorker& activeWorker = m_workers[nWorkerThreadId]; - - // Ensure enough space - if (activeWorker.m_dataSize >= activeWorker.m_data.size()) - { - activeWorker.m_data.resize(activeWorker.m_data.size() + (activeWorker.m_data.size() / 2) + 1); - } - - // Encode worker local offset into index and return - T* retItem = &activeWorker.m_data[activeWorker.m_dataSize]; - nIndex = (size_t)((1 << 31) | (nWorkerThreadId << 24) | activeWorker.m_dataSize); - ++activeWorker.m_dataSize; - return retItem; -} - -template -uint32 CThreadSafeWorkerContainer::GetWorkerId_threadlocal() const -{ - const uint32 workerThreadId = AZ::JobContext::GetGlobalContext()->GetJobManager().GetWorkerThreadId(); - - if (workerThreadId == AZ::JobManager::InvalidWorkerThreadId) - { - // Only one non-worker thread is allowed, so check to see if this is that thread. - - const threadID currentThreadId = CryGetCurrentThreadId(); - if (m_foreignThreadId != currentThreadId) - { - CryFatalError("Trying to access CThreadSafeWorkerContainer from an unspecified non-worker thread. The only non-worker threadId with access rights: %" PRI_THREADID ". Current threadId: %" PRI_THREADID, m_foreignThreadId, currentThreadId); - } - } - - // Non-worker has id of ~0 ... add +1 to shift to 0. Worker0 will use slot 1 etc. - static_assert(AZ::JobManager::InvalidWorkerThreadId == ~0u, "Assumptions about InvalidWorkerId no longer hold true"); - return workerThreadId + 1; -} - - -#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H diff --git a/Code/CryEngine/CryCommon/CustomMemoryHeap.h b/Code/CryEngine/CryCommon/CustomMemoryHeap.h deleted file mode 100644 index 2cb0c70713..0000000000 --- a/Code/CryEngine/CryCommon/CustomMemoryHeap.h +++ /dev/null @@ -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. - -#ifndef __CustomMemoryHeap_h__ -#define __CustomMemoryHeap_h__ -#pragma once - -#include "IMemory.h" - -class CCustomMemoryHeap; - -////////////////////////////////////////////////////////////////////////// -class CCustomMemoryHeapBlock - : public ICustomMemoryBlock -{ -public: - CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap); - virtual ~CCustomMemoryHeapBlock(); - - ////////////////////////////////////////////////////////////////////////// - // IMemoryBlock - ////////////////////////////////////////////////////////////////////////// - virtual void* GetData(); - virtual int GetSize() { return m_nSize; } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ICustomMemoryBlock - ////////////////////////////////////////////////////////////////////////// - virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize); - ////////////////////////////////////////////////////////////////////////// - -private: - friend class CCustomMemoryHeap; - CCustomMemoryHeap* m_pHeap; - string m_sUsage; - void* m_pData; - uint32 m_nGPUHandle; - size_t m_nSize; -}; - -////////////////////////////////////////////////////////////////////////// -class CCustomMemoryHeap - : public ICustomMemoryHeap -{ -public: - - explicit CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy); - ~CCustomMemoryHeap(); - - ////////////////////////////////////////////////////////////////////////// - // ICustomMemoryHeap - ////////////////////////////////////////////////////////////////////////// - virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16); - virtual void GetMemoryUsage(ICrySizer* pSizer); - virtual size_t GetAllocated(); - ////////////////////////////////////////////////////////////////////////// - - void DeallocateBlock(CCustomMemoryHeapBlock* pBlock); - -private: - - friend class CCustomMemoryHeapBlock; - int m_nAllocatedSize; - IMemoryManager::EAllocPolicy m_eAllocPolicy; - IMemoryManager::HeapHandle m_nTraceHeapHandle; -}; - -#endif // __CustomMemoryHeap_h__ diff --git a/Code/CryEngine/CryCommon/HeapAllocator.h b/Code/CryEngine/CryCommon/HeapAllocator.h index c0001ea497..4dfd9f66ec 100644 --- a/Code/CryEngine/CryCommon/HeapAllocator.h +++ b/Code/CryEngine/CryCommon/HeapAllocator.h @@ -420,7 +420,6 @@ namespace stl { nInterval++; nCount = 0; - assert(CryMemory::IsHeapValid()); } #endif } diff --git a/Code/CryEngine/CryCommon/IEntityRenderState.h b/Code/CryEngine/CryCommon/IEntityRenderState.h index 29b1bdc463..3e8f1dce4e 100644 --- a/Code/CryEngine/CryCommon/IEntityRenderState.h +++ b/Code/CryEngine/CryCommon/IEntityRenderState.h @@ -572,7 +572,6 @@ struct IVoxelObject : public IRenderNode { // - virtual struct IMemoryBlock* GetCompiledData(EEndian eEndian) = 0; virtual void SetCompiledData(void* pData, int nSize, uint8 ucChildId, EEndian eEndian) = 0; virtual void SetObjectName(const char* pName) = 0; virtual void SetMatrix(const Matrix34& mat) = 0; diff --git a/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h b/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h deleted file mode 100644 index 7a9c0c8ebf..0000000000 --- a/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h +++ /dev/null @@ -1,52 +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_CRYCOMMON_IGENERALMEMORYHEAP_H -#define CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H -#pragma once - -namespace AZ -{ - class IAllocator; -} - -class IGeneralMemoryHeap -{ -public: - // - virtual bool Cleanup() = 0; - - virtual int AddRef() = 0; - virtual int Release() = 0; - - virtual bool IsInAddressRange(void* ptr) const = 0; - - virtual void* Calloc(size_t nmemb, size_t size, const char* sUsage) = 0; - virtual void* Malloc(size_t sz, const char* sUsage) = 0; - - // Attempts to free the allocation. Returns the size of the allocation if successful, 0 if the heap doesn't own the address. - virtual size_t Free(void* ptr) = 0; - virtual void* Realloc(void* ptr, size_t sz, const char* sUsage) = 0; - virtual void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage) = 0; - virtual void* Memalign(size_t boundary, size_t size, const char* sUsage) = 0; - - virtual AZ::IAllocator* GetAllocator() const = 0; - - // Get the size of the allocation. Returns 0 if the ptr doesn't belong to the heap. - virtual size_t UsableSize(void* ptr) const = 0; - // -protected: - virtual ~IGeneralMemoryHeap() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H diff --git a/Code/CryEngine/CryCommon/IImageHandler.h b/Code/CryEngine/CryCommon/IImageHandler.h deleted file mode 100644 index 3f2e0c871b..0000000000 --- a/Code/CryEngine/CryCommon/IImageHandler.h +++ /dev/null @@ -1,41 +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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H -#define CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H -#pragma once - -#include - -/** -Utility for loading and saving images. only works with RGB data(no alpha), and lossless compressed tiff files for now. -*/ -struct IImageHandler -{ - struct IImage - { - virtual ~IImage() {} - - virtual const std::vector& GetData() const = 0; - virtual int GetWidth() const = 0; - virtual int GetHeight() const = 0; - }; - - virtual ~IImageHandler() {} - - ///data must be RGB, 3 bytes per pixel. - virtual std::unique_ptr CreateImage(std::vector&& data, int width, int height) const = 0; - virtual std::unique_ptr LoadImage(const char* filename) const = 0; - virtual bool SaveImage(IImage* image, const char* filename) const = 0; - virtual std::unique_ptr CreateDiffImage(IImage* image1, IImage* image2) const = 0; - virtual float CalculatePSNR(IImage* diffIimage) const = 0; -}; -#endif // CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H diff --git a/Code/CryEngine/CryCommon/IMemory.h b/Code/CryEngine/CryCommon/IMemory.h deleted file mode 100644 index a3b1dc1c2c..0000000000 --- a/Code/CryEngine/CryCommon/IMemory.h +++ /dev/null @@ -1,86 +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_CRYCOMMON_IMEMORY_H -#define CRYINCLUDE_CRYCOMMON_IMEMORY_H -#pragma once - -#include -#include // <> required for Interfuscator -#include - -struct IMemoryBlock - : public CMultiThreadRefCount -{ - // - virtual void* GetData() = 0; - virtual int GetSize() = 0; - // -}; -TYPEDEF_AUTOPTR(IMemoryBlock); - -////////////////////////////////////////////////////////////////////////// -struct ICustomMemoryBlock - : public IMemoryBlock -{ - // Copy region from from source memory to the specified output buffer - virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) = 0; -}; - -////////////////////////////////////////////////////////////////////////// -struct ICustomMemoryHeap - : public CMultiThreadRefCount -{ - // - virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16) = 0; - virtual void GetMemoryUsage(ICrySizer* pSizer) = 0; - virtual size_t GetAllocated() = 0; - // -}; - -class IMemoryAddressRange -{ -public: - // - virtual void Release() = 0; - - virtual char* GetBaseAddress() const = 0; - virtual size_t GetPageCount() const = 0; - virtual size_t GetPageSize() const = 0; - - virtual void* MapPage(size_t pageIdx) = 0; - virtual void UnmapPage(size_t pageIdx) = 0; - // -protected: - virtual ~IMemoryAddressRange() {} -}; - -class IPageMappingHeap -{ -public: - // - virtual void Release() = 0; - - virtual size_t GetGranularity() const = 0; - virtual bool IsInAddressRange(void* ptr) const = 0; - - virtual size_t FindLargestFreeBlockSize() const = 0; - - virtual void* Map(size_t sz) = 0; - virtual void Unmap(void* ptr, size_t sz) = 0; - // -protected: - virtual ~IPageMappingHeap() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IMEMORY_H diff --git a/Code/CryEngine/CryCommon/IRenderer.h b/Code/CryEngine/CryCommon/IRenderer.h index bb8f8fa572..be72e69864 100644 --- a/Code/CryEngine/CryCommon/IRenderer.h +++ b/Code/CryEngine/CryCommon/IRenderer.h @@ -1510,7 +1510,6 @@ struct IRenderer // Summary: // Loads lightmap for name. virtual int EF_LoadLightmap (const char* name) = 0; - virtual bool EF_RenderEnvironmentCubeHDR (int size, Vec3& Pos, TArray& vecData) = 0; // Summary: // Starts using of the shaders (return first index for allow recursions). @@ -1547,7 +1546,6 @@ struct IRenderer virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0; virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight) = 0; virtual void EF_ClearDeferredLightsList() = 0; - virtual TArray* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight) = 0; virtual uint8 EF_AddDeferredClipVolume(const IClipVolume* pClipVolume) = 0; virtual bool EF_SetDeferredClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo) = 0; diff --git a/Code/CryEngine/CryCommon/IResourceCollector.h b/Code/CryEngine/CryCommon/IResourceCollector.h deleted file mode 100644 index a3c88f507b..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCollector.h +++ /dev/null @@ -1,64 +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_CRYCOMMON_IRESOURCECOLLECTOR_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H -#pragma once - - -// used to collect the assets needed for streaming and to gather statistics -struct IResourceCollector -{ - // - // Arguments: - // dwMemSize 0xffffffff if size is unknown - // Returns: - // true=new resource was added, false=resource was already registered - virtual bool AddResource(const char* szFileName, const uint32 dwMemSize) = 0; - - // Arguments: - // szFileName - needs to be registered before with AddResource() - // pInstance - must not be 0 - virtual void AddInstance(const char* szFileName, void* pInstance) = 0; - // - // Arguments: - // szFileName - needs to be registered before with AddResource() - virtual void OpenDependencies(const char* szFileName) = 0; - // - virtual void CloseDependencies() = 0; - - // Resets the internal data structure for the resource collector. - virtual void Reset() = 0; - // -protected: - virtual ~IResourceCollector() {} -}; - - -class NullResCollector - : public IResourceCollector -{ -public: - virtual bool AddResource([[maybe_unused]] const char* szFileName, [[maybe_unused]] const uint32 dwMemSize) { return true; } - virtual void AddInstance([[maybe_unused]] const char* szFileName, [[maybe_unused]] void* pInstance) {} - virtual void OpenDependencies([[maybe_unused]] const char* szFileName) {} - virtual void CloseDependencies() {} - virtual void Reset() {} - - virtual ~NullResCollector() {} -}; - - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H - - diff --git a/Code/CryEngine/CryCommon/IResourceManager.h b/Code/CryEngine/CryCommon/IResourceManager.h deleted file mode 100644 index 482cb30a5e..0000000000 --- a/Code/CryEngine/CryCommon/IResourceManager.h +++ /dev/null @@ -1,84 +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 Resource Manager - - -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H -#pragma once - -namespace AZ::IO -{ - struct IResourceList; -} - -struct SLayerPakStats -{ - struct SEntry - { - string name; - size_t nSize; - string status; - bool bStreaming; - }; - typedef std::vector TEntries; - TEntries m_entries; - - size_t m_MaxSize; - size_t m_UsedSize; -}; - -////////////////////////////////////////////////////////////////////////// -// IResource manager interface -////////////////////////////////////////////////////////////////////////// -struct IResourceManager -{ - // - virtual ~IResourceManager(){} - // Called by level system to set the level folder - virtual void PrepareLevel(const char* sLevelFolder, const char* sLevelName) = 0; - // Called by level system after the level has been unloaded. - virtual void UnloadLevel() = 0; - // Call to get current level resource list. - virtual AZ::IO::IResourceList* GetLevelResourceList() = 0; - // Load pak file from level cache to memory. - // sBindRoot is a path in virtual file system, where new pak will be mapper to (ex. LevelCache/mtl) - virtual bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading = true) = 0; - // Unloads level cache pak file from memory. - virtual void UnloadLevelCachePak(const char* sPakName) = 0; - - //Loads the pak file for mode switching into memory e.g. Single player mode to Multiplayer mode - virtual bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer) = 0; - //Unloads the mode switching pak file - virtual void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) = 0; - - // Load general pak file to memory. - virtual bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) = 0; - // Unload all aync paks - virtual void UnloadAllAsyncPaks() = 0; - // Load pak file from active layer to memory. - virtual bool LoadLayerPak(const char* sLayerName) = 0; - // Unloads layer pak file from memory if no more references. - virtual void UnloadLayerPak(const char* sLayerName) = 0; - // Retrieve stats on the layer pak - virtual void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const = 0; - - // Return time it took to load and precache the level. - virtual CTimeValue GetLastLevelLoadTime() const = 0; - - virtual void GetMemoryStatistics(ICrySizer* pSizer) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H diff --git a/Code/CryEngine/CryCommon/ISerialize.h b/Code/CryEngine/CryCommon/ISerialize.h index 9ca4fb665c..5fb0d9a3aa 100644 --- a/Code/CryEngine/CryCommon/ISerialize.h +++ b/Code/CryEngine/CryCommon/ISerialize.h @@ -20,7 +20,6 @@ #include #include -#include "CountedValue.h" #include "MiniQueue.h" #include #include @@ -471,58 +470,6 @@ public: } } - template - void Value(const char* name, CountedValue& countedValue) - { - if (!BeginOptionalGroup(name, true)) - { - return; - } - if (IsWriting()) - { - T rawValue = countedValue.Peek(); - Value("Value", rawValue); - typename CountedValue::TCountedID rawId = countedValue.GetLatestID(); - Value("Id", rawId, 'ui32'); - } - - if (IsReading()) - { - T rawValue; - Value("Value", rawValue); - typename CountedValue::TCountedID rawId; - Value("Id", rawId, 'ui32'); - countedValue.UpdateDuringSerializationOnly(rawValue, rawId); - } - EndGroup(); - } - - template - void Value(const char* name, CountedValue& countedValue, int policy) - { - if (!BeginOptionalGroup(name, true)) - { - return; - } - if (IsWriting()) - { - T rawValue = countedValue.Peek(); - Value("Value", rawValue, policy); - typename CountedValue::TCountedID rawId = countedValue.GetLatestID(); - Value("Id", rawId, 'ui32'); - } - - if (IsReading()) - { - T rawValue; - Value("Value", rawValue, policy); - typename CountedValue::TCountedID rawId; - Value("Id", rawId, 'ui32'); - countedValue.UpdateDuringSerializationOnly(rawValue, rawId); - } - EndGroup(); - } - bool ValueChar(const char* name, char* buffer, int len) { string temp; diff --git a/Code/CryEngine/CryCommon/IShader.h b/Code/CryEngine/CryCommon/IShader.h index 5f5209992e..c74d981864 100644 --- a/Code/CryEngine/CryCommon/IShader.h +++ b/Code/CryEngine/CryCommon/IShader.h @@ -36,8 +36,6 @@ #include #include -#include - struct IMaterial; class CRendElementBase; class CRenderObject; @@ -2238,74 +2236,6 @@ struct SShaderTexSlots } }; -struct SShaderGenBit -{ - SShaderGenBit() - { - m_Mask = 0; - m_Flags = 0; - m_nDependencySet = 0; - m_nDependencyReset = 0; - m_NameLength = 0; - m_dwToken = 0; - } - string m_ParamName; - string m_ParamProp; - string m_ParamDesc; - int m_NameLength; - uint64 m_Mask; - uint32 m_Flags; - uint32 m_dwToken; - std::vector m_PrecacheNames; - std::vector m_DependSets; - std::vector m_DependResets; - uint32 m_nDependencySet; - uint32 m_nDependencyReset; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_ParamName); - pSizer->AddObject(m_ParamProp); - pSizer->AddObject(m_ParamDesc); - pSizer->AddObject(m_PrecacheNames); - pSizer->AddObject(m_DependSets); - pSizer->AddObject(m_DependResets); - } -}; - -struct SShaderGen -{ - uint32 m_nRefCount; - TArray m_BitMask; - SShaderGen() - { - m_nRefCount = 1; - } - ~SShaderGen() - { - uint32 i; - for (i = 0; i < m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = m_BitMask[i]; - SAFE_DELETE(pBit); - } - m_BitMask.Free(); - } - void Release() - { - m_nRefCount--; - if (!m_nRefCount) - { - delete this; - } - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_BitMask); - } -}; - //=================================================================================== enum EShaderType @@ -2570,7 +2500,6 @@ public: virtual void SetFlags2(int Flags) = 0; virtual void ClearFlags2(int Flags) = 0; virtual bool Reload(int nFlags, const char* szShaderName) = 0; - virtual TArray* GetREs (int nTech) = 0; virtual AZStd::vector& GetPublicParams() = 0; virtual int GetTexId () = 0; virtual ITexture* GetBaseTexture(int* nPass, int* nTU) = 0; @@ -2579,7 +2508,6 @@ public: virtual ECull GetCull(void) = 0; virtual int Size(int Flags) = 0; virtual uint64 GetGenerationMask() = 0; - virtual SShaderGen* GetGenerationParams() = 0; virtual size_t GetNumberOfUVSets() = 0; virtual int GetTechniqueID(int nTechnique, int nRegisteredTechnique) = 0; virtual AZ::Vertex::Format GetVertexFormat(void) = 0; diff --git a/Code/CryEngine/CryCommon/IStreamEngine.h b/Code/CryEngine/CryCommon/IStreamEngine.h deleted file mode 100644 index 0536e1f486..0000000000 --- a/Code/CryEngine/CryCommon/IStreamEngine.h +++ /dev/null @@ -1,493 +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. - -// This is the prototypes of interfaces that will be used for asynchronous -// I/O (streaming). -// THIS IS NOT FINAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE - -// Some excerpts explaining basic ideas behind streaming design here: - -/* - * The idea is that the data loaded is ready for usage and ideally doesn't need further transformation, - * therefore the client allocates the buffer (to avoid extra copy). All the data transformations should take place in the Resource Compiler. If you have to allocate a lot of small memory objects, you should revise this strategy in favor of one big allocation (again, that will be read directly from the compiled file). - * Anyway, we can negotiate that the streaming engine allocates this memory. - * In the end, it could make use of a memory pool, and copying data is not the bottleneck in our engine - * - * The client should take care of all fast operations. Looking up file size should be fast on the virtual - * file system in a pak file, because the directory should be preloaded in memory - */ - -#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H -#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H -#pragma once - - -#include -#include "smartptr.h" -#include "CryThread.h" - -#include "IStreamEngineDefs.h" - -class IStreamCallback; -class ICrySizer; - -#define STREAM_TASK_TYPE_AUDIO_ALL ((1 << eStreamTaskTypeMusic) | (1 << eStreamTaskTypeSound) | (1 << eStreamTaskTypeFSBCache)) - -// Description: -// This is used as parameter to the asynchronous read function -// all the unnecessary parameters go here, because there are many of them. -struct StreamReadParams -{ -public: - StreamReadParams() - { - memset(this, 0, sizeof(*this)); - ePriority = estpNormal; - } - - StreamReadParams ( - DWORD_PTR _dwUserData, - EStreamTaskPriority _ePriority = estpNormal, - unsigned _nLoadTime = 0, - unsigned _nMaxLoadTime = 0, - unsigned _nOffset = 0, - unsigned _nSize = 0, - void* _pBuffer = NULL, - unsigned _nFlags = 0 - ) - : dwUserData (_dwUserData) - , ePriority(_ePriority) - , nPerceptualImportance(0) - , nLoadTime(_nLoadTime) - , nMaxLoadTime(_nMaxLoadTime) - , pBuffer (_pBuffer) - , nOffset (_nOffset) - , nSize (_nSize) - , eMediaType(eStreamSourceTypeUnknown) - , nFlags (_nFlags) - { - } - - // Summary: - // File name. - //const char* szFile; - - // Summary: - // The callback. - //IStreamCallback* pAsyncCallback; - - // Summary: - // The user data that'll be used to call the callback. - DWORD_PTR dwUserData; - - // The priority of this read - EStreamTaskPriority ePriority; - - // Value from 0-255 of the perceptual importance of the task (used for debugging task sheduling) - uint8 nPerceptualImportance; - - // Description: - // The desirable loading time, in milliseconds, from the time of call - // 0 means as fast as possible (desirably in this frame). - unsigned nLoadTime; - - // Description: - // The maximum load time, in milliseconds. 0 means forever. If the read lasts longer, it can be discarded. - // WARNING: avoid too small max times, like 1-10 ms, because many loads will be discarded in this case. - unsigned nMaxLoadTime; - - // Description: - // The buffer into which to read the file or the file piece - // if this is NULL, the streaming engine will supply the buffer. - // Notes: - // DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption! - void* pBuffer; - - // Description: - // Offset in the file to read; if this is not 0, then the file read - // occurs beginning with the specified offset in bytes. - // The callback interface receives the size of already read data as nSize - // and generally behaves as if the piece of file would be a file of its own. - unsigned nOffset; - - // Description: - // Number of bytes to read; if this is 0, then the whole file is read, - // if nSize == 0 && nOffset != 0, then the file from the offset to the end is read. - // If nSize != 0, then the file piece from nOffset is read, at most nSize bytes - // (if less, an error is reported). So, from nOffset byte to nOffset + nSize - 1 byte in the file. - unsigned nSize; - - // Description: - // Media type to use when starting file request - if wrong, the request may take longer to complete - EStreamSourceMediaType eMediaType; - - // Description: - // The combination of one or several flags from the stream engine general purpose flags. - // See also: - // IStreamEngine::EFlags - unsigned nFlags; -}; - -struct StreamReadBatchParams -{ - StreamReadBatchParams() - : tSource((EStreamTaskType)0) - , szFile(NULL) - , pCallback(NULL) - { - } - - EStreamTaskType tSource; - const char* szFile; - IStreamCallback* pCallback; - StreamReadParams params; -}; - -struct IStreamEngineListener -{ - // - virtual ~IStreamEngineListener() {} - - virtual void OnStreamEnqueue(const void* pReq, const char* filename, EStreamTaskType source, const StreamReadParams& readParams) = 0; - virtual void OnStreamComputedSortKey(const void* pReq, uint64 key) = 0; - virtual void OnStreamBeginIO(const void* pReq, uint32 compressSize, uint32 readSize, EStreamSourceMediaType mediaType) = 0; - virtual void OnStreamEndIO(const void* pReq) = 0; - virtual void OnStreamBeginInflate(const void* pReq) = 0; - virtual void OnStreamEndInflate(const void* pReq) = 0; - virtual void OnStreamBeginAsyncCallback(const void* pReq) = 0; - virtual void OnStreamEndAsyncCallback(const void* pReq) = 0; - virtual void OnStreamDone(const void* pReq) = 0; - virtual void OnStreamPreempted(const void* pReq) = 0; - virtual void OnStreamResumed(const void* pReq) = 0; - // -}; - -// Description: -// The highest level. There is only one StreamingEngine in the application -// and it controls all I/O streams. -struct IStreamEngine -{ -public: - - - enum EJobType - { - ejtStarted = 1 << 0, - ejtPending = 1 << 1, - ejtFinished = 1 << 2, - }; - - // Summary: - // General purpose flags. - enum EFlags - { - // Description: - // If this is set only asynchronous callback will be called. - FLAGS_NO_SYNC_CALLBACK = BIT(0), - // Description: - // If this is set the file will be read from disc directly, instead of from the pak system. - FLAGS_FILE_ON_DISK = BIT(1), - // Description: - // Ignore the tmp out of streaming memory for this request - FLAGS_IGNORE_TMP_OUT_OF_MEM = BIT(2), - // Description: - // External buffer is write only - FLAGS_WRITE_ONLY_EXTERNAL_BUFFER = BIT(3), - }; - - // - // Description: - // Starts asynchronous read from the specified file (the file may be on a - // virtual file system, in pak or zip file or wherever). - // Reads the file contents into the given buffer, up to the given size. - // Upon success, calls success callback. If the file is truncated or for other - // reason can not be read, calls error callback. The callback can be NULL (in this case, the client should poll - // the returned IReadStream object; the returned object must be locked for that) - // NOTE: the error/success/ progress callbacks can also be called from INSIDE this function. - // Arguments: - // tSource - - // szFile - - // pCallback - - // pParams - PLACEHOLDER for the future additional parameters (like priority), or really - // a pointer to a structure that will hold the parameters if there are too many of them. - // Return Value: - // IReadStream is reference-counted and will be automatically deleted if you don't refer to it; - // if you don't store it immediately in an auto-pointer, it may be deleted as soon as on the next line of code, - // because the read operation may complete immediately inside StartRead() and the object is self-disposed - // as soon as the callback is called. - // Remarks: - // In some implementations disposal of the old pointers happen synchronously - // (in the main thread) outside StartRead() (it happens in the entity update), - // so you're guaranteed that it won't trash inside the calling function. However, this may change in the future - // and you'll be required to assign it to IReadStream immediately (StartRead will return IReadStream_AutoPtr then). - // See also: - // IReadStream,IReadStream_AutoPtr - virtual IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback = NULL, const StreamReadParams* pParams = NULL) = 0; - - // Pass a callback to preRequestCallback if you need to execute code right before the requests get enqueued; the callback is called only once per execution - virtual size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback = nullptr) = 0; - - // Call this methods before/after submitting large number of new requests. - virtual void BeginReadGroup() = 0; - virtual void EndReadGroup() = 0; - - // Pause/resumes streaming of specific data types. - // nPauseTypesBitmask is a bit mask of data types (ex, 1< -}; - -// Description: -// This is the file "handle" that can be used to query the status -// of the asynchronous operation on the file. The same object may be returned -// for the same file to multiple clients. -// Notes: -// It will actually represent the asynchronous object in memory, and will be -// thread-safe reference-counted (both AddRef() and Release() will be virtual -// and thread-safe, just like the others) -// Example: -// USE: -// IReadStream_AutoPtr pReadStream = pStreamEngine->StartRead ("bla.xxx", this); -// OR: -// pStreamEngine->StartRead ("MusicSystem","bla.xxx", this); -class IReadStream -{ -public: - // - // Summary: - // Increment ref count, returns new count - virtual int AddRef() = 0; - // Summary: - // Decrement ref count, returns new count - virtual int Release() = 0; - // Summary: - // Returns true if the file read was not successful. - virtual bool IsError() = 0; - // Return Value: - // True if the file read was completed successfully. - // Summary: - // Checks IsError to check if the whole requested file (piece) was read. - virtual bool IsFinished() = 0; - // Description: - // Returns the number of bytes read so far (the whole buffer size if IsFinished()) - // Arguments: - // bWait - if == true, then waits until the pending I/O operation completes. - // Return Value: - // The total number of bytes read (if it completes successfully, returns the size of block being read) - virtual unsigned int GetBytesRead(bool bWait = false) = 0; - // Description: - // Returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read. - // Notes: - // DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption! - virtual const void* GetBuffer () = 0; - - // Description: - // Returns the transparent DWORD that was passed in the StreamReadParams::dwUserData field - // of the structure passed in the call to IStreamEngine::StartRead. - // See also: - // StreamReadParams::dwUserData,IStreamEngine::StartRead - virtual DWORD_PTR GetUserData() = 0; - - // Summary: - // Set user defined data into stream's params. - virtual void SetUserData(DWORD_PTR dwUserData) = 0; - - // Description: - // Tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - virtual void Abort() = 0; - - // Description: - // Tries to stop reading the stream, as long as IO or the async callback is not currently - // in progress. - virtual bool TryAbort() = 0; - - // Summary: - // Unconditionally waits until the callback is called. - // if nMaxWaitMillis is not negative wait for the specified ammount of milliseconds then exit. - // Example: - // If the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified). - virtual void Wait(int nMaxWaitMillis = -1) = 0; - - // Summary: - // Returns stream params. - virtual const StreamReadParams& GetParams() const = 0; - - // Summary: - // Returns caller type. - virtual const EStreamTaskType GetCallerType() const = 0; - - // Summary: - // Returns media type used to satisfy request - only valid once stream has begun read. - virtual EStreamSourceMediaType GetMediaType() const = 0; - - // Summary: - // Returns pointer to callback routine(can be NULL). - virtual IStreamCallback* GetCallback() const = 0; - - // Summary: - // Returns IO error #. - virtual unsigned GetError() const = 0; - - // Summary: - // Returns IO error name - virtual const char* GetErrorName() const = 0; - - // Summary: - // Returns stream name. - virtual const char* GetName() const = 0; - - // Summary: - // Free temporary memory allocated for this stream, when not needed anymore. - // Can be called from Async callback, to free memory earlier, not waiting for synchrounus callback. - virtual void FreeTemporaryMemory() = 0; - // - -protected: - // Summary: - // The clients are not allowed to destroy this object directly; only via Release(). - virtual ~IReadStream() {} -}; - -TYPEDEF_AUTOPTR(IReadStream); - -// Description: -// CryPak supports asynchronous reading through this interface. The callback -// is called from the main thread in the frame update loop. -// -// The callback receives packets through StreamOnComplete() and -// StreamOnProgress(). The second one can be used to update the asset based -// on the partial data that arrived. the callback that will be called by the -// streaming engine must be implemented by all clients that want to use -// StreamingEngine services -// Remarks: -// the pStream interface is guaranteed to be locked (have reference count > 0) -// while inside the function, but can vanish any time outside the function. -// If you need it, keep it from the beginning (after call to StartRead()) -// some or all callbacks MAY be called from inside IStreamEngine::StartRead() -// -// Example: -// -// IStreamEngine *pStreamEngine = g_pISystem->GetStreamEngine(); // get streaming engine -// IStreamCallback *pAsyncCallback = &MyClass; // user -// -// StreamReadParams params; -// -// params.dwUserData = 0; -// params.nSize = 0; -// params.pBuffer = NULL; -// params.nLoadTime = 10000; -// params.nMaxLoadTime = 10000; -// -// pStreamEngine->StartRead( .. pAsyncCallback .. params .. ); // registers callback -// -class IStreamCallback -{ -public: - // - virtual ~IStreamCallback(){} - - // Description: - // Signals that the file length for the request has been found, and that storage is needed - // Either a pointer to a block of nSize bytes can be returned, into which the file will be - // streamed, or NULL can be returned, in which case temporary memory will be allocated - // internally by the stream engine (which will be freed upon job completion). - virtual void* StreamOnNeedStorage ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nSize, [[maybe_unused]] bool& bAbortOnFailToAlloc) {return NULL; } - - // Description: - // Signals that reading the requested data has completed (with or without error). - // This callback is always called, whether an error occurs or not. - // pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released. - // GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end - // or the size of partially read data in case of error (0 if nothing was read). - // Pending status is true during this callback, because the callback itself is the part of IO operation. - // nError == 0 : Success - // nError != 0 : Error code - virtual void StreamAsyncOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - - // Description: - // Signals that reading the requested data has completed (with or without error). - // This callback is always called, whether an error occurs or not. - // pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released. - // GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end - // or the size of partially read data in case of error (0 if nothing was read). - // Pending status is true during this callback, because the callback itself is the part of IO operation. - // nError == 0 : Success - // nError != 0 : Error code - virtual void StreamOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H diff --git a/Code/CryEngine/CryCommon/IStreamEngineDefs.h b/Code/CryEngine/CryCommon/IStreamEngineDefs.h deleted file mode 100644 index e931a6201e..0000000000 --- a/Code/CryEngine/CryCommon/IStreamEngineDefs.h +++ /dev/null @@ -1,236 +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_CRYCOMMON_ISTREAMENGINEDEFS_H -#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H -#pragma once - - -#if defined(ENABLE_PROFILING_CODE) -#define STREAMENGINE_ENABLE_LISTENER -#define STREAMENGINE_ENABLE_STATS -#endif - -enum : unsigned int -{ - ERROR_UNKNOWN_ERROR = 0xF0000000, - ERROR_UNEXPECTED_DESTRUCTION = 0xF0000001, - ERROR_INVALID_CALL = 0xF0000002, - ERROR_CANT_OPEN_FILE = 0xF0000003, - ERROR_REFSTREAM_ERROR = 0xF0000004, - ERROR_OFFSET_OUT_OF_RANGE = 0xF0000005, - ERROR_REGION_OUT_OF_RANGE = 0xF0000006, - ERROR_SIZE_OUT_OF_RANGE = 0xF0000007, - ERROR_CANT_START_READING = 0xF0000008, - ERROR_OUT_OF_MEMORY = 0xF0000009, - ERROR_ABORTED_ON_SHUTDOWN = 0xF000000A, - ERROR_OUT_OF_MEMORY_QUOTA = 0xF000000B, - ERROR_ZIP_CACHE_FAILURE = 0xF000000C, - ERROR_USER_ABORT = 0xF000000D, - ERROR_MISSCHEDULED = 0xF000000F, - ERROR_VERIFICATION_FAIL = 0xF0000010, - ERROR_PREEMPTED = 0xF0000011, - ERROR_DECOMPRESSION_FAIL = 0xF0000012 -}; - -// Summary: -// Types of streaming tasks -// Affects priority directly -enum EStreamTaskType -{ - eStreamTaskTypeCount = 14, - eStreamTaskTypeGeomCache = 13, - eStreamTaskTypePak = 12, - eStreamTaskTypeFlash = 11, - eStreamTaskTypeVideo = 10, - - eStreamTaskTypeMergedMesh = 9, - eStreamTaskTypeShader = 8, - eStreamTaskTypeSound = 7, - eStreamTaskTypeMusic = 6, - eStreamTaskTypeFSBCache = 5, - eStreamTaskTypeAnimation = 4, - eStreamTaskTypeTerrain = 3, - eStreamTaskTypeGeometry = 2, - eStreamTaskTypeTexture = 1, -}; - -// Summary: -// Priority types of streaming tasks -// Affects priority directly -// Limiting number of priority values allows streaming system to minimize seek time -enum EStreamTaskPriority -{ - estpUrgent = 0, - estpPreempted = 1, //For internal use only - estpAboveNormal = 2, - estpNormal = 3, - estpBelowNormal = 4, - estpIdle = 5, -}; - -enum EStreamSourceMediaType : int32_t -{ - eStreamSourceTypeUnknown = 0, - eStreamSourceTypeHDD, - eStreamSourceTypeDisc, - eStreamSourceTypeMemory, -}; - -#if defined(STREAMENGINE_ENABLE_STATS) -struct SStreamEngineStatistics -{ - struct SMediaTypeInfo - { - SMediaTypeInfo() - { - ResetStats(); - } - void ResetStats() - { - memset(this, 0, sizeof(SMediaTypeInfo)); - } - - float fActiveDuringLastSecond; // Amount of time media device was active during last second - float fAverageActiveTime; // Average time since last reset that the media device was active - - uint32 nBytesRead; // Bytes read during last second. - uint32 nRequestCount; // Amount of requests during last second. - uint64 nTotalBytesRead; // Read bytes total from reset. - uint32 nTotalRequestCount; // Number of request from reset. - - uint64 nSeekOffsetLastSecond; // Average seek offset during the last second - uint64 nAverageSeekOffset; // Average seek offset since last reset - - uint32 nCurrentReadBandwidth; // Bytes/second for last second - uint32 nSessionReadBandwidth; // Bytes/second for last second - - uint32 nActualReadBandwidth; // Bytes/second for last second - only taking actual reading into account - uint32 nAverageActualReadBandwidth; // Average read bandwidth in total from reset - only taking actual read time into account - }; - - SMediaTypeInfo hddInfo; - SMediaTypeInfo memoryInfo; - SMediaTypeInfo discInfo; - - uint32 nTotalSessionReadBandwidth;// Average read bandwidth in total from reset - taking full time into account from reset - uint32 nTotalCurrentReadBandwidth;// Total bytes/sec over all types and systems. - - int nPendingReadBytes; // How many bytes still need to be read - float fAverageCompletionTime; // Time in seconds on average takes to complete file request. - float fAverageRequestCount; // Average requests per second being done to streaming engine - - uint64 nMainStreamingThreadWait; - - uint64 nTotalBytesRead; // Read bytes total from reset. - uint32 nTotalRequestCount; // Number of request from reset to the streaming engine. - uint32 nTotalStreamingRequestCount; // Number of request from reset which actually resulted in streaming data. - - int nCurrentDecompressCount; // Number of requests currently waiting to be decompresses - int nCurrentAsyncCount; // Number of requests currently waiting to be async callback - int nCurrentFinishedCount; // Number of requests currently waiting to be finished by mainthread - - uint32 nDecompressBandwidth; // Bytes/second for last second - uint32 nVerifyBandwidth; // Bytes/second for last second - uint32 nDecompressBandwidthAverage; // Bytes/second in total. - uint32 nVerifyBandwidthAverage; // Bytes/second in total. - - bool bTempMemOutOfBudget; // Was the temporary streaming memory out of budget during the last second - int nMaxTempMemory; // Maximum temporary memory used by the streaming system - int nTempMemory; - - struct SRequestTypeInfo - { - SRequestTypeInfo() - : nPendingReadBytes(0) - { - ResetStats(); - } - void ResetStats() - { - nTmpReadBytes = 0; - nTotalStreamingRequestCount = 0; - nTotalReadBytes = 0; - nTotalRequestDataSize = 0; - nTotalRequestCount = 0; - nCurrentReadBandwidth = 0; - nSessionReadBandwidth = 0; - fTotalCompletionTime = .0f; - fAverageCompletionTime = .0f; - } - - void Merge(const SRequestTypeInfo& _other) - { - nPendingReadBytes += _other.nPendingReadBytes; - nTmpReadBytes += _other.nTmpReadBytes; - nTotalStreamingRequestCount += _other.nTotalStreamingRequestCount; - nTotalReadBytes += _other.nTotalReadBytes; - nTotalRequestDataSize += _other.nTotalRequestDataSize; - nTotalRequestCount += _other.nTotalRequestCount; - fTotalCompletionTime += _other.fTotalCompletionTime; - } - - int nPendingReadBytes; // How many bytes still need to be read from media - - uint64 nTmpReadBytes; // Read bytes since last update to compute current bandwidth - - uint32 nTotalStreamingRequestCount; // Total actual streaming requests of this type - uint64 nTotalReadBytes; // Total actual read bytes (compressed data) - uint64 nTotalRequestDataSize; // Total requested bytes from client (uncompressed data) - uint32 nTotalRequestCount; // Total number of finished requests - - uint32 nCurrentReadBandwidth; // Bytes/second for this type during last second - uint32 nSessionReadBandwidth; // Average read bandwidth in total from reset - taking full time into account from reset - - float fTotalCompletionTime; // Time it took to finish all current requests - float fAverageCompletionTime; // Average time it takes to fully complete a request of this type - float fAverageRequestCount; // Average amount of requests made per second - }; - - SRequestTypeInfo typeInfo[eStreamTaskTypeCount]; - - struct SAsset - { - CryStringLocal m_sName; - int m_nSize; - const bool operator<(const SAsset& a) const { return m_nSize > a.m_nSize; } - SAsset() {} - SAsset(const CryStringLocal& sName, const int nSize) - : m_sName(sName) - , m_nSize(nSize) { } - - friend void swap(SAsset& a, SAsset& b) - { - using std::swap; - - a.m_sName.swap(b.m_sName); - swap(a.m_nSize, b.m_nSize); - } - }; - DynArray vecHeavyAssets; -}; -#endif - -struct SStreamEngineOpenStats -{ - int nOpenRequestCount; - int nOpenRequestCountByType[eStreamTaskTypeCount]; -}; - -class IReadStream; -TYPEDEF_AUTOPTR(IReadStream); - -// typedef IReadStream_AutoPtr auto ptr wrapper -typedef IReadStream_AutoPtr IReadStreamPtr; - -#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H diff --git a/Code/CryEngine/CryCommon/ISystem.h b/Code/CryEngine/CryCommon/ISystem.h index 4c6bd73b61..73341dd16f 100644 --- a/Code/CryEngine/CryCommon/ISystem.h +++ b/Code/CryEngine/CryCommon/ISystem.h @@ -65,12 +65,10 @@ struct IProcess; struct ITimer; struct ICryFont; struct IMovieSystem; -struct IMemoryManager; namespace Audio { struct IAudioSystem; } // namespace Audio -struct IStreamEngine; struct SFileVersion; struct INameTable; struct ILevelSystem; @@ -78,7 +76,6 @@ struct IViewSystem; class ICrySizer; class IXMLBinarySerializer; struct IReadWriteXMLSink; -struct IResourceManager; struct ITextModeConsole; struct IAVI_Reader; class CPNoise3; @@ -89,7 +86,6 @@ struct ILZ4Decompressor; class IZStdDecompressor; struct IOutputPrintSink; struct IWindowMessageHandler; -struct IImageHandler; namespace AZ { @@ -828,10 +824,6 @@ struct ISystem virtual void DoWorkDuringOcclusionChecks() = 0; virtual bool NeedDoWorkDuringOcclusionChecks() = 0; - // Summary: - // Returns the current used memory. - virtual uint32 GetUsedMemory() = 0; - // Summary: // Retrieve the name of the user currently logged in to the computer. virtual const char* GetUserName() = 0; @@ -905,27 +897,18 @@ struct ISystem virtual ILevelSystem* GetILevelSystem() = 0; virtual INameTable* GetINameTable() = 0; virtual IValidator* GetIValidator() = 0; - virtual IStreamEngine* GetStreamEngine() = 0; virtual ICmdLine* GetICmdLine() = 0; virtual ILog* GetILog() = 0; virtual AZ::IO::IArchive* GetIPak() = 0; virtual ICryFont* GetICryFont() = 0; - virtual IMemoryManager* GetIMemoryManager() = 0; virtual IMovieSystem* GetIMovieSystem() = 0; virtual ::IConsole* GetIConsole() = 0; virtual IRemoteConsole* GetIRemoteConsole() = 0; - // Returns: - // Can be NULL, because it only exists when running through the editor, not in pure game mode. - virtual IResourceManager* GetIResourceManager() = 0; virtual IProfilingSystem* GetIProfilingSystem() = 0; virtual ISystemEventDispatcher* GetISystemEventDispatcher() = 0; virtual ITimer* GetITimer() = 0; - virtual void DebugStats(bool checkpoint, bool leaks) = 0; - virtual void DumpWinHeaps() = 0; - virtual int DumpMMStats(bool log) = 0; - // Arguments: // bValue - Set to true when running on a cheat protected server or a client that is connected to it (not used in singleplayer). virtual void SetForceNonDevMode(bool bValue) = 0; @@ -1166,8 +1149,6 @@ struct ISystem // Initializes Steam if needed and returns if it was successful virtual bool SteamInit() = 0; - virtual const IImageHandler* GetImageHandler() const = 0; - // Summary: // Gets the root window message handler function // The returned pointer is platform-specific: diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp b/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp deleted file mode 100644 index 8cf29bcb2a..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp +++ /dev/null @@ -1,86 +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 - -namespace CImageExtensionHelper -{ - ColorF GetAverageColor(uint8 const* pMem) - { - pMem = _findChunkStart(pMem, FOURCC_AvgC); - - if (pMem) - { - ColorF ret = ColorF(SwapEndianValue(*(uint32*)pMem)); - //flip red and blue - const float cRed = ret.r; - ret.r = ret.b; - ret.b = cRed; - return ret; - } - - return Col_White; // chunk does not exist - } - - bool IsRangeless(ETEX_Format eTF) - { - return (eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_R9G9B9E5 || - eTF == eTF_R16G16B16A16F || - eTF == eTF_R32G32B32A32F || - eTF == eTF_R16F || - eTF == eTF_R32F || - eTF == eTF_R16G16F || - eTF == eTF_R11G11B10F); - } - - bool IsQuantized(ETEX_Format eTF) - { - return (eTF == eTF_B4G4R4A4 || - eTF == eTF_B5G6R5 || - eTF == eTF_B5G5R5 || - eTF == eTF_BC1 || - eTF == eTF_BC2 || - eTF == eTF_BC3 || - eTF == eTF_BC4U || - eTF == eTF_BC4S || - eTF == eTF_BC5U || - eTF == eTF_BC5S || - eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_BC7 || - eTF == eTF_R9G9B9E5 || - eTF == eTF_ETC2 || - eTF == eTF_EAC_R11 || - eTF == eTF_ETC2A || - eTF == eTF_EAC_RG11 || - eTF == eTF_PVRTC2 || - eTF == eTF_PVRTC4 || - eTF == eTF_ASTC_4x4 || - eTF == eTF_ASTC_5x4 || - eTF == eTF_ASTC_5x5 || - eTF == eTF_ASTC_6x5 || - eTF == eTF_ASTC_6x6 || - eTF == eTF_ASTC_8x5 || - eTF == eTF_ASTC_8x6 || - eTF == eTF_ASTC_8x8 || - eTF == eTF_ASTC_10x5 || - eTF == eTF_ASTC_10x6 || - eTF == eTF_ASTC_10x8 || - eTF == eTF_ASTC_10x10 || - eTF == eTF_ASTC_12x10 || - eTF == eTF_ASTC_12x12 - ); - } -} diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper.h b/Code/CryEngine/CryCommon/ImageExtensionHelper.h deleted file mode 100644 index 71e58074c9..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper.h +++ /dev/null @@ -1,2155 +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 -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#undef AZ_RESTRICTED_SECTION -#define IMAGEEXTENSIONHELPER_H_SECTION_1 1 -#define IMAGEEXTENSIONHELPER_H_SECTION_2 2 -#define IMAGEEXTENSIONHELPER_H_SECTION_CONSTS 3 -#define IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE 4 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_1 - #include AZ_RESTRICTED_FILE(ImageExtensionHelper_h) -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_2 - #include AZ_RESTRICTED_FILE(ImageExtensionHelper_h) -#endif - -#ifndef MAKEFOURCC - #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \ - ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24)) -#endif /* defined(MAKEFOURCC) */ - - -// This header defines constants and structures that are useful when parsing -// DDS files. DDS files were originally designed to use several structures -// and constants that are native to DirectDraw and are defined in ddraw.h, -// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar -// (compatible) constants and structures so that one can use DDS files -// without needing to include ddraw.h. - -// Crytek specific image extensions -// -// usually added to the end of DDS files - -//Needed to write out DDS files on Mac -#if AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) -#define DDPF_ALPHAPIXELS 0x00000001 // Texture contains alpha data -#define DDPF_ALPHA 0x00000002 // For alpha channel only uncompressed data -#define DDPF_FOURCC 0x00000004 // Texture contains compressed RGB data -#define DDPF_RGB 0x00000040 // Texture contains uncompressed RGB data -#define DDPF_YUV 0x00000200 // For YUV uncompressed data -#define DDPF_LUMINANCE 0x00020000 // For single channel color uncompressed data - -#define DDSCAPS_COMPLEX 0x00000008 // Must be used on any file that contains more than one surface -#define DDSCAPS_MIPMAP 0x00400000 // Should be used for a mipmap -#define DDSCAPS_TEXTURE 0x00001000 // Required -#endif - -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE -#define DDS_SIGNED 0x00080000 // DDPF_SIGNED -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS -#define DDS_LUMINANCEA 0x00020001 // DDS_LUMINANCE | DDPF_ALPHAPIXELS -#define DDS_A 0x00000001 // DDPF_ALPHAPIXELS -#define DDS_A_ONLY 0x00000002 // DDPF_ALPHA - -#define DDS_FOURCC_A16B16G16R16 0x00000024 // FOURCC A16B16G16R16 -#define DDS_FOURCC_V16U16 0x00000040 // FOURCC V16U16 -#define DDS_FOURCC_Q16W16V16U16 0x0000006E // FOURCC Q16W16V16U16 -#define DDS_FOURCC_R16F 0x0000006F // FOURCC R16F -#define DDS_FOURCC_G16R16F 0x00000070 // FOURCC G16R16F -#define DDS_FOURCC_A16B16G16R16F 0x00000071 // FOURCC A16B16G16R16F -#define DDS_FOURCC_R32F 0x00000072 // FOURCC R32F -#define DDS_FOURCC_G32R32F 0x00000073 // FOURCC G32R32F -#define DDS_FOURCC_A32B32G32R32F 0x00000074 // FOURCC A32B32G32R32F - -#define DDSD_CAPS 0x00000001l // default -#define DDSD_PIXELFORMAT 0x00001000l -#define DDSD_WIDTH 0x00000004l -#define DDSD_HEIGHT 0x00000002l -#define DDSD_LINEARSIZE 0x00080000l - -#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT -#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT -#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH -#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH -#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE - -#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE -#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP -#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX - -#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX -#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX -#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY -#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY -#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ -#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ - -#define DDS_CUBEMAP_ALLFACES (DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX | \ - DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY | \ - DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ) - -#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME - -#define DDS_RESF1_NORMALMAP 0x01000000 -#define DDS_RESF1_DSDT 0x02000000 - -#define CRY_DDS_DX10_SUPPORT - -#include - -#if defined(WIN32) && !defined(DXGI_FORMAT_DEFINED) -#include // DX10+ formats -#endif // #if defined(WIN32) && !defined(DXGI_FORMAT_DEFINED) - - -namespace CImageExtensionHelper -{ - struct DDS_PIXELFORMAT - { - DWORD dwSize; - DWORD dwFlags; - DWORD dwFourCC; - DWORD dwRGBBitCount; - DWORD dwRBitMask; - DWORD dwGBitMask; - DWORD dwBBitMask; - DWORD dwABitMask; - - const bool operator == (const DDS_PIXELFORMAT& fmt) const - { - return dwFourCC == fmt.dwFourCC && - dwFlags == fmt.dwFlags && - dwRGBBitCount == fmt.dwRGBBitCount && - dwRBitMask == fmt.dwRBitMask && - dwGBitMask == fmt.dwGBitMask && - dwBBitMask == fmt.dwBBitMask && - dwABitMask == fmt.dwABitMask && - dwSize == fmt.dwSize; - } - - AUTO_STRUCT_INFO - }; - - struct DDS_HEADER_DXT10 - { - // we're unable to use native enums because of TypeInfo(), so we use DWORD instead. - DWORD /*DXGI_FORMAT*/ dxgiFormat; - DWORD /*D3D10_RESOURCE_DIMENSION*/ resourceDimension; - unsigned int miscFlag; - unsigned int arraySize; - unsigned int reserved; - - AUTO_STRUCT_INFO - }; - - struct DDS_HEADER - { - DWORD dwSize; - DWORD dwHeaderFlags; - DWORD dwHeight; - DWORD dwWidth; - DWORD dwPitchOrLinearSize; - DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags - DWORD dwMipMapCount; - DWORD dwAlphaBitDepth; - DWORD dwReserved1; // Crytek image flags - float fAvgBrightness; // Average top mip brightness. Could be f16/half - ColorF cMinColor; - ColorF cMaxColor; - DDS_PIXELFORMAT ddspf; - DWORD dwSurfaceFlags; - DWORD dwCubemapFlags; - BYTE bNumPersistentMips; - BYTE bTileMode; - BYTE bReserved2[6]; - DWORD dwTextureStage; - - AUTO_STRUCT_INFO - - inline const bool IsValid() const { return sizeof(*this) == dwSize; } - inline const bool IsDX10Ext() const { return ddspf.dwFourCC == MAKEFOURCC('D', 'X', '1', '0'); } - inline const uint32 GetMipCount() const { return max(1u, (uint32)dwMipMapCount); } - - inline const size_t GetFullHeaderSize() const - { - if (IsDX10Ext()) - { - return sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - } - - return sizeof(DDS_HEADER); - } - }; - - // standard description of file header - struct DDS_FILE_DESC - { - DWORD dwMagic; - DDS_HEADER header; - - AUTO_STRUCT_INFO - - inline const bool IsValid() const { return dwMagic == MAKEFOURCC('D', 'D', 'S', ' ') && header.IsValid(); } - inline const size_t GetFullHeaderSize() const { return sizeof(dwMagic) + header.GetFullHeaderSize(); } - }; - - // chunk identifier - const static uint32 FOURCC_CExt = MAKEFOURCC('C', 'E', 'x', 't'); // Crytek extension start - const static uint32 FOURCC_AvgC = MAKEFOURCC('A', 'v', 'g', 'C'); // average color - const static uint32 FOURCC_CEnd = MAKEFOURCC('C', 'E', 'n', 'd'); // Crytek extension end - const static uint32 FOURCC_AttC = MAKEFOURCC('A', 't', 't', 'C'); // Chunk Attached Channel - - // flags to propagate from the RC to the engine through GetImageFlags() - // 32bit bitmask, numbers should not change as engine relies on them - const static uint32 EIF_Cubemap = 0x1; - const static uint32 EIF_Volumetexture = 0x2; - const static uint32 EIF_Decal = 0x4; // this is usually set through the preset - const static uint32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color - const static uint32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture - const static uint32 EIF_UNUSED_BIT = 0x40; // Free to use - const static uint32 EIF_AttachedAlpha = 0x400; // info for the engine: it's a texture with attached alpha channel - const static uint32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear) - const static uint32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized with r_TexResolution - const static uint32 EIF_RenormalizedTexture = 0x10000; // info for the engine: for dds textures that have renormalized color range - const static uint32 EIF_CafeNative = 0x20000; // info for the engine: native Cafe texture format - const static uint32 EIF_Tiled = 0x80000; // info for the engine: texture has been tiled for the platform - const static uint32 EIF_Splitted = 0x200000; // info for the engine: this texture is splitted - const static uint32 EIF_Colormodel = 0x7000000; // info for the engine: bitmask: colormodel used in the texture - const static uint32 EIF_Colormodel_RGB = 0x0000000; // info for the engine: colormodel is RGB (default) - const static uint32 EIF_Colormodel_CIE = 0x1000000; // info for the engine: colormodel is CIE (used for terrain) - const static uint32 EIF_Colormodel_YCC = 0x2000000; // info for the engine: colormodel is Y'CbCr (used for reflectance) - const static uint32 EIF_Colormodel_YFF = 0x3000000; // info for the engine: colormodel is Y'FbFr (used for reflectance) - const static uint32 EIF_Colormodel_IRB = 0x4000000; // info for the engine: colormodel is IRB (used for reflectance) - -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, jasper) - #undef AZ_RESTRICTED_SECTION -#endif - -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, provo) - #undef AZ_RESTRICTED_SECTION -#endif - -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, salem) - #undef AZ_RESTRICTED_SECTION -#endif - - enum ETileMode - { - eTM_None = 0, - eTM_LinearPadded, - eTM_Optimal, - }; - - // Arguments: - // pDDSHeader - must not be 0 - // Returns: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - inline uint32 GetImageFlags(DDS_HEADER* pDDSHeader) - { - assert(pDDSHeader); - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - if (pDDSHeader->dwSize >= sizeof(DDS_HEADER)) - { - if (pDDSHeader->dwTextureStage == 'CRYF') - { - return pDDSHeader->dwReserved1; - } - } - - return 0; - } - - // Arguments: - // pDDSHeader - must not be 0 - // Returns: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - inline bool SetImageFlags(DDS_HEADER* pDDSHeader, uint32 flags) - { - assert(pDDSHeader); - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - if (pDDSHeader->dwSize >= sizeof(DDS_HEADER)) - { - if (pDDSHeader->dwTextureStage == 'CRYF') - { - pDDSHeader->dwReserved1 = flags; - return true; - } - } - - return false; - } - - // Arguments: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - // Returns: - // true, if this texture is ready for this platform - inline const bool IsImageNative(const uint32 nFlags) - { - return (nFlags & (0 -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, salem) -#endif - )) == 0; - } - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - // Returns: - // 0 if not existing - inline uint8 const* _findChunkStart(uint8 const* pMem, const uint32 dwChunkName, uint32* dwOutSize = NULL) - { - if (pMem) - { - if (*(uint32*)pMem == SwapEndianValue(FOURCC_CExt)) - { - pMem += 4; // jump over chunk name - while (*(uint32*)pMem != SwapEndianValue(FOURCC_CEnd)) - { - if (*(uint32*)pMem == SwapEndianValue(dwChunkName)) - { - pMem += 4; // jump over chunk name - const uint32 size = SwapEndianValue(*(uint32*)(pMem)); - if (dwOutSize) - { - *dwOutSize = size; - } - pMem += 4; // jump over chunk size - return size > 0 ? pMem : NULL; - } - - pMem += 8 + SwapEndianValue(*(uint32*)(&pMem[4])); // jump over chunk - } - } - } - - return 0; // chunk does not exist - } - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - ColorF GetAverageColor(uint8 const* pMem); - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - // Returns: - // pointer to the DDS header - inline DDS_HEADER* GetAttachedImage(uint8 const* pMem, uint32* dwOutSize = NULL) - { - pMem = _findChunkStart(pMem, FOURCC_AttC, dwOutSize); - if (pMem) - { - return (DDS_HEADER*)(pMem + 4); - } - - if (dwOutSize) - { - *dwOutSize = 0; - } - return 0; // chunk does not exist - } - - static ILINE Vec2i GetBlockDim(const ETEX_Format eTF) - { - if (eTF == eTF_BC1 || eTF == eTF_BC2 || eTF == eTF_BC3 || eTF == eTF_BC5U || eTF == eTF_BC5S || eTF == eTF_BC4U || eTF == eTF_BC4S || eTF == eTF_CTX1 || eTF == eTF_BC6UH || eTF == eTF_BC6SH || eTF == eTF_BC7 || eTF == eTF_EAC_R11 || eTF == eTF_EAC_RG11 || eTF == eTF_ETC2 || eTF == eTF_ETC2A) - { - return Vec2i(4, 4); - } - // Apple requires the following for the texture: - // Height and width must be a power of 2 - // Height and width must be at least 8 - // Must be square - switch (eTF) - { - case eTF_PVRTC2: - return Vec2i(8, 4); - case eTF_PVRTC4: - return Vec2i(4, 4); - case eTF_ASTC_4x4: - return Vec2i(4, 4); - case eTF_ASTC_5x4: - return Vec2i(5, 4); - case eTF_ASTC_5x5: - return Vec2i(5, 5); - case eTF_ASTC_6x5: - return Vec2i(6, 5); - case eTF_ASTC_6x6: - return Vec2i(6, 6); - case eTF_ASTC_8x5: - return Vec2i(8, 5); - case eTF_ASTC_8x6: - return Vec2i(8, 6); - case eTF_ASTC_8x8: - return Vec2i(8, 8); - case eTF_ASTC_10x5: - return Vec2i(10, 5); - case eTF_ASTC_10x6: - return Vec2i(10, 6); - case eTF_ASTC_10x8: - return Vec2i(10, 8); - case eTF_ASTC_10x10: - return Vec2i(10, 10); - case eTF_ASTC_12x10: - return Vec2i(12, 10); - case eTF_ASTC_12x12: - return Vec2i(12, 12); - } - - return Vec2i(1, 1); - } - - inline int BytesPerBlock(ETEX_Format eTF) - { - switch (eTF) - { - case eTF_R8G8B8A8S: - return 32 / 8; - case eTF_R8G8B8A8: - return 32 / 8; - - case eTF_A8: - return 8 / 8; - case eTF_R8: - return 8 / 8; - case eTF_R8S: - return 8 / 8; - case eTF_R16: - return 16 / 8; - case eTF_R16U: - return 16 / 8; - case eTF_R16G16U: - return 32 / 8; - case eTF_R10G10B10A2UI: - return 32 / 8; - case eTF_R16F: - return 16 / 8; - case eTF_R32F: - return 32 / 8; - case eTF_R8G8: - return 16 / 8; - case eTF_R8G8S: - return 16 / 8; - case eTF_R16G16: - return 32 / 8; - case eTF_R16G16S: - return 32 / 8; - case eTF_R16G16F: - return 32 / 8; - case eTF_R11G11B10F: - return 32 / 8; - case eTF_R10G10B10A2: - return 32 / 8; - case eTF_R16G16B16A16: - return 64 / 8; - case eTF_R16G16B16A16S: - return 64 / 8; - case eTF_R16G16B16A16F: - return 64 / 8; - case eTF_R32G32B32A32F: - return 128 / 8; - - case eTF_R9G9B9E5: - return 32 / 8; - - case eTF_D16: - return 16 / 8; - case eTF_D24S8: - return 32 / 8; - case eTF_D32F: - return 32 / 8; - case eTF_D32FS8: - return 32 / 8; - - case eTF_B5G6R5: - return 16 / 8; - case eTF_B5G5R5: - return 16 / 8; - case eTF_B4G4R4A4: - return 16 / 8; - - case eTF_A8L8: - return 16 / 8; - case eTF_L8: - return 8 / 8; - case eTF_L8V8U8: - return 24 / 8; - case eTF_B8G8R8: - return 24 / 8; - case eTF_L8V8U8X8: - return 32 / 8; - case eTF_B8G8R8X8: - return 32 / 8; - case eTF_B8G8R8A8: - return 32 / 8; - - case eTF_CTX1: - case eTF_BC1: - case eTF_BC4U: - case eTF_BC4S: - case eTF_ETC2: - case eTF_EAC_R11: - return 8; - - case eTF_BC2: - case eTF_BC3: - case eTF_BC5U: - case eTF_BC5S: - case eTF_BC6UH: - case eTF_BC6SH: - case eTF_BC7: - case eTF_ETC2A: - case eTF_EAC_RG11: - return 16; - - case eTF_PVRTC2: - case eTF_PVRTC4: - return 8; - - case eTF_ASTC_4x4: - case eTF_ASTC_5x4: - case eTF_ASTC_5x5: - case eTF_ASTC_6x5: - case eTF_ASTC_6x6: - case eTF_ASTC_8x5: - case eTF_ASTC_8x6: - case eTF_ASTC_8x8: - case eTF_ASTC_10x5: - case eTF_ASTC_10x6: - case eTF_ASTC_10x8: - case eTF_ASTC_10x10: - case eTF_ASTC_12x10: - case eTF_ASTC_12x12: - return 16; - default: - assert(0); - } - return 0; - } - - - inline bool IsBlockCompressed(ETEX_Format eTF) - { - return (eTF == eTF_BC1 || - eTF == eTF_BC2 || - eTF == eTF_BC3 || - eTF == eTF_BC4U || - eTF == eTF_BC4S || - eTF == eTF_BC5S || - eTF == eTF_BC5U || - eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_BC7 || - eTF == eTF_CTX1 || - eTF == eTF_ETC2 || - eTF == eTF_EAC_R11 || - eTF == eTF_ETC2A || - eTF == eTF_EAC_RG11 || - eTF == eTF_PVRTC2 || - eTF == eTF_PVRTC4 || - eTF == eTF_ASTC_4x4 || - eTF == eTF_ASTC_5x4 || - eTF == eTF_ASTC_5x5 || - eTF == eTF_ASTC_6x5 || - eTF == eTF_ASTC_6x6 || - eTF == eTF_ASTC_8x5 || - eTF == eTF_ASTC_8x6 || - eTF == eTF_ASTC_8x8 || - eTF == eTF_ASTC_10x5 || - eTF == eTF_ASTC_10x6 || - eTF == eTF_ASTC_10x8 || - eTF == eTF_ASTC_10x10 || - eTF == eTF_ASTC_12x10 || - eTF == eTF_ASTC_12x12 - ); - } - - bool IsRangeless(ETEX_Format eTF); - - bool IsQuantized(ETEX_Format eTF); - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const char* NameForTextureFormat(ETEX_Format ETF) - { - switch (ETF) - { - case eTF_Unknown: - return "Unknown"; - - case eTF_R8G8B8A8S: - return "R8G8B8A8S"; - case eTF_R8G8B8A8: - return "R8G8B8A8"; - - case eTF_A8: - return "A8"; - case eTF_R8: - return "R8"; - case eTF_R8S: - return "R8S"; - case eTF_R16: - return "R16"; - case eTF_R16F: - return "R16F"; - case eTF_R32F: - return "R32F"; - case eTF_R8G8: - return "R8G8"; - case eTF_R8G8S: - return "R8G8S"; - case eTF_R16G16: - return "R16G16"; - case eTF_R16G16S: - return "R16G16S"; - case eTF_R16G16F: - return "R16G16F"; - case eTF_R11G11B10F: - return "R11G11B10F"; - case eTF_R10G10B10A2: - return "R10G10B10A2"; - case eTF_R16G16B16A16: - return "R16G16B16A16"; - case eTF_R16G16B16A16S: - return "R16G16B16A16S"; - case eTF_R16G16B16A16F: - return "R16G16B16A16F"; - case eTF_R32G32B32A32F: - return "R32G32B32A32F"; - - case eTF_CTX1: - return "CTX1"; - case eTF_BC1: - return "BC1"; - case eTF_BC2: - return "BC2"; - case eTF_BC3: - return "BC3"; - case eTF_BC4U: - return "BC4"; - case eTF_BC4S: - return "BC4S"; - case eTF_BC5U: - return "BC5"; - case eTF_BC5S: - return "BC5S"; - case eTF_BC6UH: - return "BC6UH"; - case eTF_BC6SH: - return "BC6SH"; - case eTF_BC7: - return "BC7"; - case eTF_R9G9B9E5: - return "R9G9B9E5"; - - case eTF_D16: - return "D16"; - case eTF_D24S8: - return "D24S8"; - case eTF_D32F: - return "D32F"; - case eTF_D32FS8: - return "D32FS8"; - - case eTF_B5G6R5: - return "R5G5B5"; - case eTF_B5G5R5: - return "R5G6B5"; - case eTF_B4G4R4A4: - return "B4G4R4A4"; - - case eTF_EAC_R11: - return "EAC_R11"; - case eTF_EAC_RG11: - return "EAC_RG11"; - case eTF_ETC2: - return "ETC2"; - case eTF_ETC2A: - return "ETC2A"; - - case eTF_PVRTC2: - return "PVRTC2"; - case eTF_PVRTC4: - return "PVRTC4"; - - case eTF_ASTC_4x4: - return "ASTC_4x4"; - case eTF_ASTC_5x4: - return "ASTC_5x4"; - case eTF_ASTC_5x5: - return "ASTC_5x5"; - case eTF_ASTC_6x5: - return "ASTC_6x5"; - case eTF_ASTC_6x6: - return "ASTC_6x6"; - case eTF_ASTC_8x5: - return "ASTC_8x5"; - case eTF_ASTC_8x6: - return "ASTC_8x6"; - case eTF_ASTC_8x8: - return "ASTC_8x8"; - case eTF_ASTC_10x5: - return "ASTC_10x5"; - case eTF_ASTC_10x6: - return "ASTC_10x6"; - case eTF_ASTC_10x8: - return "ASTC_10x8"; - case eTF_ASTC_10x10: - return "ASTC_10x10"; - case eTF_ASTC_12x10: - return "ASTC_12x10"; - case eTF_ASTC_12x12: - return "ASTC_12x12"; - - case eTF_A8L8: - return "A8L8"; - case eTF_L8: - return "L8"; - case eTF_L8V8U8: - return "L8V8U8"; - case eTF_B8G8R8: - return "B8G8R8"; - case eTF_L8V8U8X8: - return "L8V8U8X8"; - case eTF_B8G8R8X8: - return "B8G8R8X8"; - case eTF_B8G8R8A8: - return "B8G8R8A8"; - - default: - assert(0); // pass through for better behaviour in non debug - } - - return "Unknown"; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline ETEX_Format TextureFormatForName(const char* sETF) - { - if (!azstricmp(sETF, "Unknown")) - { - return eTF_Unknown; - } - - if (!azstricmp(sETF, "R8G8B8A8S")) - { - return eTF_R8G8B8A8S; - } - if (!azstricmp(sETF, "R8G8B8A8")) - { - return eTF_R8G8B8A8; - } - - if (!azstricmp(sETF, "A8")) - { - return eTF_A8; - } - if (!azstricmp(sETF, "R8")) - { - return eTF_R8; - } - if (!azstricmp(sETF, "R8S")) - { - return eTF_R8S; - } - if (!azstricmp(sETF, "R16")) - { - return eTF_R16; - } - if (!azstricmp(sETF, "R16F")) - { - return eTF_R16F; - } - if (!azstricmp(sETF, "R32F")) - { - return eTF_R32F; - } - if (!azstricmp(sETF, "R8G8")) - { - return eTF_R8G8; - } - if (!azstricmp(sETF, "R8G8S")) - { - return eTF_R8G8S; - } - if (!azstricmp(sETF, "R16G16")) - { - return eTF_R16G16; - } - if (!azstricmp(sETF, "R16G16S")) - { - return eTF_R16G16S; - } - if (!azstricmp(sETF, "R16G16F")) - { - return eTF_R16G16F; - } - if (!azstricmp(sETF, "R11G11B10F")) - { - return eTF_R11G11B10F; - } - if (!azstricmp(sETF, "R10G10B10A2")) - { - return eTF_R10G10B10A2; - } - if (!azstricmp(sETF, "R16G16B16A16")) - { - return eTF_R16G16B16A16; - } - if (!azstricmp(sETF, "R16G16B16A16S")) - { - return eTF_R16G16B16A16S; - } - if (!azstricmp(sETF, "R16G16B16A16F")) - { - return eTF_R16G16B16A16F; - } - if (!azstricmp(sETF, "R32G32B32A32F")) - { - return eTF_R32G32B32A32F; - } - - if (!azstricmp(sETF, "CTX1")) - { - return eTF_CTX1; - } - if (!azstricmp(sETF, "BC1")) - { - return eTF_BC1; - } - if (!azstricmp(sETF, "BC2")) - { - return eTF_BC2; - } - if (!azstricmp(sETF, "BC3")) - { - return eTF_BC3; - } - if (!azstricmp(sETF, "BC4")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "BC4S")) - { - return eTF_BC4S; - } - if (!azstricmp(sETF, "BC5")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "BC5S")) - { - return eTF_BC5S; - } - if (!azstricmp(sETF, "BC6UH")) - { - return eTF_BC6UH; - } - if (!azstricmp(sETF, "BC6SH")) - { - return eTF_BC6SH; - } - if (!azstricmp(sETF, "BC7")) - { - return eTF_BC7; - } - if (!azstricmp(sETF, "R9G9B9E5")) - { - return eTF_R9G9B9E5; - } - - if (!azstricmp(sETF, "D16")) - { - return eTF_D16; - } - if (!azstricmp(sETF, "D24S8")) - { - return eTF_D24S8; - } - if (!azstricmp(sETF, "D32F")) - { - return eTF_D32F; - } - if (!azstricmp(sETF, "D32FS8")) - { - return eTF_D32FS8; - } - - if (!azstricmp(sETF, "R5G5B5")) - { - return eTF_B5G6R5; - } - if (!azstricmp(sETF, "R5G6B5")) - { - return eTF_B5G5R5; - } - if (!azstricmp(sETF, "B4G4R4A4")) - { - return eTF_B4G4R4A4; - } - - if (!azstricmp(sETF, "EAC_R11")) - { - return eTF_EAC_R11; - } - if (!azstricmp(sETF, "EAC_RG11")) - { - return eTF_EAC_RG11; - } - if (!azstricmp(sETF, "ETC2")) - { - return eTF_ETC2; - } - if (!azstricmp(sETF, "ETC2A")) - { - return eTF_ETC2A; - } - - if (!azstricmp(sETF, "PVRTC2")) - { - return eTF_PVRTC2; - } - if (!azstricmp(sETF, "PVRTC4")) - { - return eTF_PVRTC4; - } - - if (!azstricmp(sETF, "ASTC_4x4")) - { - return eTF_ASTC_4x4; - } - if (!azstricmp(sETF, "ASTC_5x4")) - { - return eTF_ASTC_5x4; - } - if (!azstricmp(sETF, "ASTC_5x5")) - { - return eTF_ASTC_5x5; - } - if (!azstricmp(sETF, "ASTC_6x5")) - { - return eTF_ASTC_6x5; - } - if (!azstricmp(sETF, "ASTC_6x6")) - { - return eTF_ASTC_6x6; - } - if (!azstricmp(sETF, "ASTC_8x5")) - { - return eTF_ASTC_8x5; - } - if (!azstricmp(sETF, "ASTC_8x6")) - { - return eTF_ASTC_8x6; - } - if (!azstricmp(sETF, "ASTC_8x8")) - { - return eTF_ASTC_8x8; - } - if (!azstricmp(sETF, "ASTC_10x5")) - { - return eTF_ASTC_10x5; - } - if (!azstricmp(sETF, "ASTC_10x6")) - { - return eTF_ASTC_10x6; - } - if (!azstricmp(sETF, "ASTC_10x8")) - { - return eTF_ASTC_10x8; - } - if (!azstricmp(sETF, "ASTC_10x10")) - { - return eTF_ASTC_10x10; - } - if (!azstricmp(sETF, "ASTC_12x10")) - { - return eTF_ASTC_12x10; - } - if (!azstricmp(sETF, "ASTC_12x12")) - { - return eTF_ASTC_12x12; - } - - if (!azstricmp(sETF, "A8L8")) - { - return eTF_A8L8; - } - if (!azstricmp(sETF, "L8")) - { - return eTF_L8; - } - if (!azstricmp(sETF, "L8V8U8")) - { - return eTF_L8V8U8; - } - if (!azstricmp(sETF, "B8G8R8")) - { - return eTF_B8G8R8; - } - if (!azstricmp(sETF, "L8V8U8X8")) - { - return eTF_L8V8U8X8; - } - if (!azstricmp(sETF, "B8G8R8X8")) - { - return eTF_B8G8R8X8; - } - if (!azstricmp(sETF, "B8G8R8A8")) - { - return eTF_B8G8R8A8; - } - - if (!azstricmp(sETF, "V8U8")) - { - return eTF_R8G8S; - } - if (!azstricmp(sETF, "V16U16")) - { - return eTF_R16G16S; - } - - if (!azstricmp(sETF, "DXT1")) - { - return eTF_BC1; - } - if (!azstricmp(sETF, "DXT3")) - { - return eTF_BC2; - } - if (!azstricmp(sETF, "DXT5")) - { - return eTF_BC3; - } - if (!azstricmp(sETF, "ATI1")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "ATI2")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "3DCp")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "3DC")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "RGBE")) - { - return eTF_R9G9B9E5; - } - - assert (0); - return eTF_Unknown; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const char* NameForTextureType(ETEX_Type eTT) - { - const char* sETT; - switch (eTT) - { - case eTT_1D: - sETT = "1D"; - break; - case eTT_2D: - sETT = "2D"; - break; - case eTT_2DArray: - sETT = "2D array"; - break; - case eTT_2DMS: - sETT = "2D multi-sampled"; - break; - case eTT_3D: - sETT = "3D"; - break; - case eTT_Cube: - sETT = "Cube"; - break; - case eTT_CubeArray: - sETT = "CubeArray"; - break; - case eTT_Auto2D: - sETT = "Auto2D"; - break; - case eTT_Dyn2D: - sETT = "Dyn2D"; - break; - default: - assert(0); - sETT = "Unknown"; // for better behaviour in non debug - break; - } - return sETT; - } - - inline ETEX_Type TextureTypeForName(const char* sETT) - { - if (!azstricmp(sETT, "1D")) - { - return eTT_1D; - } - if (!azstricmp(sETT, "2D")) - { - return eTT_2D; - } - if (!azstricmp(sETT, "3D")) - { - return eTT_3D; - } - if (!azstricmp(sETT, "Cube")) - { - return eTT_Cube; - } - if (!azstricmp(sETT, "Auto2D")) - { - return eTT_Auto2D; - } - if (!azstricmp(sETT, "Dyn2D")) - { - return eTT_Dyn2D; - } - if (!azstricmp(sETT, "User")) - { - return eTT_User; - } - assert(0); - return eTT_2D; - } - - inline bool HasAlphaForName(const char* sETF) - { - if (!azstricmp(sETF, "R8G8B8A8S")) - { - return true; - } - if (!azstricmp(sETF, "R8G8B8A8")) - { - return true; - } - if (!azstricmp(sETF, "A8")) - { - if (!azstricmp(sETF, "A8L8")) - { - if (!azstricmp(sETF, "BC1") || !azstricmp(sETF, "DXT1")) - { - if (!azstricmp(sETF, "BC2") || !azstricmp(sETF, "DXT3")) - { - if (!azstricmp(sETF, "BC3") || !azstricmp(sETF, "DXT5")) - { - if (!azstricmp(sETF, "BC7")) - { - if (!azstricmp(sETF, "A8")) - { - return true; - } - } - } - } - } - } - } - if (!azstricmp(sETF, "R10G10B10A2")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16S")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16F")) - { - return true; - } - if (!azstricmp(sETF, "R32G32B32A32F")) - { - return true; - } - - if (!azstricmp(sETF, "BC2")) - { - return true; - } - if (!azstricmp(sETF, "BC3")) - { - return true; - } - if (!azstricmp(sETF, "BC7")) - { - return true; - } - - if (!azstricmp(sETF, "B4G4R4A4")) - { - return true; - } - - if (!azstricmp(sETF, "ETC2A")) - { - return true; - } - - if (!azstricmp(sETF, "A8L8")) - { - return true; - } - if (!azstricmp(sETF, "B8G8R8A8")) - { - return true; - } - - if (!azstricmp(sETF, "DXT3")) - { - return true; - } - if (!azstricmp(sETF, "DXT5")) - { - return true; - } - - return false; - } - - inline bool HasAlphaForTextureFormat(ETEX_Format ETF) - { - if (ETF == eTF_R8G8B8A8S) - { - return true; - } - if (ETF == eTF_R8G8B8A8) - { - return true; - } - - if (ETF == eTF_A8) - { - return true; - } - if (ETF == eTF_R10G10B10A2) - { - return true; - } - if (ETF == eTF_R16G16B16A16) - { - return true; - } - if (ETF == eTF_R16G16B16A16S) - { - return true; - } - if (ETF == eTF_R16G16B16A16F) - { - return true; - } - if (ETF == eTF_R32G32B32A32F) - { - return true; - } - - if (ETF == eTF_BC2) - { - return true; - } - if (ETF == eTF_BC3) - { - return true; - } - if (ETF == eTF_BC7) - { - return true; - } - - if (ETF == eTF_B4G4R4A4) - { - return true; - } - - if (ETF == eTF_ETC2A) - { - return true; - } - - if (ETF == eTF_A8L8) - { - return true; - } - if (ETF == eTF_B8G8R8A8) - { - return true; - } - - return false; - } - - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf, DWORD /*DXGI_FORMAT*/ dxgif); -}; - -namespace DDSFormats -{ - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DX10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', '1', '0'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT1 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT3 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_CTX1 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('C', 'T', 'X', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_3DC = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_3DCP = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_EAC_R11 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'A', 'R', ' '), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_EAC_RG11 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'A', 'R', 'G'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ETC2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'T', '2', ' '), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ETC2A = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'T', '2', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_PVRTC2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('P', 'V', 'R', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_PVRTC4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('P', 'V', 'R', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_4x4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '4', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_5x4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '5', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_5x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '5', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_6x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '6', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_6x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '6', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '8'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '8'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_12x10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'C', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_12x12 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'C', 'C'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_R32F, 32, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G32R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_G32R32F, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A32B32G32R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A32B32G32R32F, 128, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_R16F, 16, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G16R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_G16R16F, 32, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A16B16G16R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A16B16G16R16F, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_U16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_SIGNED, 0, 16, 0x0000ffff, 0x00000000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_V16U16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_SIGNED, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_Q16W16V16U16 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_Q16W16V16U16, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000ffff, 0x00000000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G16R16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A16B16G16R16 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A16B16G16R16, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8B8G8R8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A1R5G5B5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A4R4G4B4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_X8R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R5G6B5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_A, 0, 8, 0x00000000, 0x00000000, 0x00000000, 0x000000ff }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_L8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0x000000ff, 0x000000ff, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8L8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 8, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff }; - - inline ETEX_Format GetFormatByDesc(const CImageExtensionHelper::DDS_PIXELFORMAT& ddspf) - { - if (ddspf.dwFourCC == DDSPF_DXT1.dwFourCC) - { - return eTF_BC1; - } - else if (ddspf.dwFourCC == DDSPF_DXT3.dwFourCC) - { - return eTF_BC2; - } - else if (ddspf.dwFourCC == DDSPF_DXT5.dwFourCC) - { - return eTF_BC3; - } - else if (ddspf.dwFourCC == DDSPF_3DCP.dwFourCC) - { - return eTF_BC4U; - } - else if (ddspf.dwFourCC == DDSPF_3DC.dwFourCC) - { - return eTF_BC5U; - } - else if (ddspf.dwFourCC == DDSPF_CTX1.dwFourCC) - { - return eTF_CTX1; - } - else if (ddspf.dwFourCC == DDSPF_R32F.dwFourCC) - { - return eTF_R32F; - } - // else if( ddspf.dwFourCC == DDSPF_G32R32F.dwFourCC) - // return eTF_R32G32F; // TODO: add to engine - else if (ddspf.dwFourCC == DDSPF_A32B32G32R32F.dwFourCC) - { - return eTF_R32G32B32A32F; - } - else if (ddspf.dwFourCC == DDSPF_R16F.dwFourCC) - { - return eTF_R16F; - } - else if (ddspf.dwFourCC == DDSPF_G16R16F.dwFourCC) - { - return eTF_R16G16F; - } - else if (ddspf.dwFourCC == DDSPF_A16B16G16R16F.dwFourCC) - { - return eTF_R16G16B16A16F; - } - // else if( ddspf == DDSPF_U16) - // return eTF_R16S; // TODO: add to engine - else if (ddspf == DDSPF_V16U16) - { - return eTF_R16G16S; - } - else if (ddspf.dwFourCC == DDSPF_Q16W16V16U16.dwFourCC) - { - return eTF_R16G16B16A16S; - } - else if (ddspf == DDSPF_R16) - { - return eTF_R16; - } - else if (ddspf == DDSPF_G16R16) - { - return eTF_R16G16; - } - else if (ddspf.dwFourCC == DDSPF_A16B16G16R16.dwFourCC) - { - return eTF_R16G16B16A16; - } - else if (ddspf.dwFourCC == DDSPF_EAC_R11.dwFourCC) - { - return eTF_EAC_R11; - } - else if (ddspf.dwFourCC == DDSPF_EAC_RG11.dwFourCC) - { - return eTF_EAC_RG11; - } - else if (ddspf.dwFourCC == DDSPF_ETC2.dwFourCC) - { - return eTF_ETC2; - } - else if (ddspf.dwFourCC == DDSPF_ETC2A.dwFourCC) - { - return eTF_ETC2A; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x000000ff && ddspf.dwABitMask == 0xff000000) - { - return eTF_R8G8B8A8; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x00ff0000 && ddspf.dwABitMask == 0xff000000) - { - return eTF_B8G8R8A8; - } - else if (ddspf.dwFlags == DDS_RGB && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x00ff0000) - { - return eTF_B8G8R8X8; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 16) - { - return eTF_B4G4R4A4; - } - else if (ddspf.dwFlags == DDS_RGB && ddspf.dwRGBBitCount == 24) - { - return eTF_B8G8R8; - } - else if (ddspf.dwFlags == DDS_LUMINANCEA && ddspf.dwRGBBitCount == 8) - { - return eTF_A8L8; - } - else if (ddspf.dwFlags == DDS_LUMINANCE && ddspf.dwRGBBitCount == 8) - { - return eTF_L8; - } - else if ((ddspf.dwFlags == DDS_A || ddspf.dwFlags == DDS_A_ONLY || ddspf.dwFlags == (DDS_A | DDS_A_ONLY)) && ddspf.dwRGBBitCount == 8) - { - return eTF_A8; - } - else if (ddspf.dwFourCC == DDSPF_PVRTC2.dwFourCC) - { - return eTF_PVRTC2; - } - else if (ddspf.dwFourCC == DDSPF_PVRTC4.dwFourCC) - { - return eTF_PVRTC4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_4x4.dwFourCC) - { - return eTF_ASTC_4x4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_5x4.dwFourCC) - { - return eTF_ASTC_5x4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_5x5.dwFourCC) - { - return eTF_ASTC_5x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_6x5.dwFourCC) - { - return eTF_ASTC_6x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_6x6.dwFourCC) - { - return eTF_ASTC_6x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x5.dwFourCC) - { - return eTF_ASTC_8x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x6.dwFourCC) - { - return eTF_ASTC_8x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x8.dwFourCC) - { - return eTF_ASTC_8x8; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x5.dwFourCC) - { - return eTF_ASTC_10x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x6.dwFourCC) - { - return eTF_ASTC_10x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x8.dwFourCC) - { - return eTF_ASTC_10x8; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x10.dwFourCC) - { - return eTF_ASTC_10x10; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_12x10.dwFourCC) - { - return eTF_ASTC_12x10; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_12x12.dwFourCC) - { - return eTF_ASTC_12x12; - } - - assert(0); - return eTF_Unknown; - } - - inline ETEX_Format GetFormatByDesc(const CImageExtensionHelper::DDS_PIXELFORMAT& ddspf, const DWORD /*DXGI_FORMAT*/ dxgif) - { - // 'DX10' indicates the format is not in the FourCC, but in the extended header - if (ddspf.dwFourCC == DDSPF_DX10.dwFourCC) - { -#if defined(CRY_DDS_DX10_SUPPORT) - switch (dxgif) - { - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_SNORM: - return eTF_R8G8B8A8S; - - case DXGI_FORMAT_A8_UNORM: - return eTF_A8; - case DXGI_FORMAT_R8_UNORM: - return eTF_R8; - case DXGI_FORMAT_R8_SNORM: - return eTF_R8S; - case DXGI_FORMAT_R16_UNORM: - return eTF_R16; - // case DXGI_FORMAT_R16_SNORM: return eTF_R16S; - case DXGI_FORMAT_R16_FLOAT: - return eTF_R16F; - case DXGI_FORMAT_R16_TYPELESS: - return eTF_R16F; // arbitrary choice for F - case DXGI_FORMAT_R32_FLOAT: - return eTF_R32F; - case DXGI_FORMAT_R32_TYPELESS: - return eTF_R32F; - case DXGI_FORMAT_R8G8_UNORM: - return eTF_R8G8; - case DXGI_FORMAT_R8G8_SNORM: - return eTF_R8G8S; - case DXGI_FORMAT_R16G16_UNORM: - return eTF_R16G16; - case DXGI_FORMAT_R16G16_SNORM: - return eTF_R16G16S; - case DXGI_FORMAT_R16G16_FLOAT: - return eTF_R16G16F; - // case DXGI_FORMAT_R32G32_FLOAT: return eTF_R32G32F; - case DXGI_FORMAT_R11G11B10_FLOAT: - return eTF_R11G11B10F; - case DXGI_FORMAT_R10G10B10A2_UNORM: - return eTF_R10G10B10A2; - case DXGI_FORMAT_R16G16B16A16_UNORM: - return eTF_R16G16B16A16; - case DXGI_FORMAT_R16G16B16A16_SNORM: - return eTF_R16G16B16A16S; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return eTF_R16G16B16A16F; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return eTF_R32G32B32A32F; - - case DXGI_FORMAT_BC1_TYPELESS: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM_SRGB: - return eTF_BC1; - case DXGI_FORMAT_BC2_TYPELESS: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM_SRGB: - return eTF_BC2; - case DXGI_FORMAT_BC3_TYPELESS: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM_SRGB: - return eTF_BC3; - case DXGI_FORMAT_BC4_TYPELESS: - return eTF_BC4U; - case DXGI_FORMAT_BC4_UNORM: - return eTF_BC4U; - case DXGI_FORMAT_BC4_SNORM: - return eTF_BC4S; - case DXGI_FORMAT_BC5_TYPELESS: - return eTF_BC5U; - case DXGI_FORMAT_BC5_UNORM: - return eTF_BC5U; - case DXGI_FORMAT_BC5_SNORM: - return eTF_BC5S; - case DXGI_FORMAT_BC6H_UF16: - return eTF_BC6UH; - case DXGI_FORMAT_BC6H_SF16: - return eTF_BC6SH; - case DXGI_FORMAT_BC7_TYPELESS: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM_SRGB: - return eTF_BC7; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - return eTF_R9G9B9E5; - - // only available as hardware format under DX11.1 with DXGI 1.2 - case DXGI_FORMAT_B5G6R5_UNORM: - return eTF_B5G6R5; - case DXGI_FORMAT_B5G5R5A1_UNORM: - return eTF_B5G5R5; - // case DXGI_FORMAT_B4G4R4A4_UNORM: return eTF_B4G4R4A4; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - // only available as hardware format under OpenGL - case DXGI_FORMAT_EAC_R11_TYPELESS: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_R11_UNORM: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_R11_SNORM: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_RG11_TYPELESS: - return eTF_EAC_RG11; - case DXGI_FORMAT_EAC_RG11_UNORM: - return eTF_EAC_RG11; - case DXGI_FORMAT_EAC_RG11_SNORM: - return eTF_EAC_RG11; - case DXGI_FORMAT_ETC2_TYPELESS: - return eTF_ETC2; - case DXGI_FORMAT_ETC2_UNORM: - return eTF_ETC2; - case DXGI_FORMAT_ETC2_UNORM_SRGB: - return eTF_ETC2; - case DXGI_FORMAT_ETC2A_TYPELESS: - return eTF_ETC2A; - case DXGI_FORMAT_ETC2A_UNORM: - return eTF_ETC2A; - case DXGI_FORMAT_ETC2A_UNORM_SRGB: - return eTF_ETC2A; -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_TYPELESS: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC2_UNORM: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC2_UNORM_SRGB: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC4_TYPELESS: - return eTF_PVRTC4; - case DXGI_FORMAT_PVRTC4_UNORM: - return eTF_PVRTC4; - case DXGI_FORMAT_PVRTC4_UNORM_SRGB: - return eTF_PVRTC4; -#endif -#if defined(ANDROID) //|| defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_TYPELESS: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_4x4_UNORM: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_4x4_UNORM_SRGB: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_5x4_TYPELESS: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x4_UNORM: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x4_UNORM_SRGB: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x5_TYPELESS: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_5x5_UNORM: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_5x5_UNORM_SRGB: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_6x5_TYPELESS: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x5_UNORM: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x5_UNORM_SRGB: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x6_TYPELESS: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_6x6_UNORM: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_6x6_UNORM_SRGB: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_8x5_TYPELESS: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x5_UNORM: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x5_UNORM_SRGB: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x6_TYPELESS: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x6_UNORM: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x6_UNORM_SRGB: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x8_TYPELESS: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_8x8_UNORM: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_8x8_UNORM_SRGB: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_10x5_TYPELESS: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x5_UNORM: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x5_UNORM_SRGB: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x6_TYPELESS: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x6_UNORM: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x6_UNORM_SRGB: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x8_TYPELESS: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x8_UNORM: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x8_UNORM_SRGB: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x10_TYPELESS: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_10x10_UNORM: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_10x10_UNORM_SRGB: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_12x10_TYPELESS: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x10_UNORM: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x10_UNORM_SRGB: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x12_TYPELESS: - return eTF_ASTC_12x12; - case DXGI_FORMAT_ASTC_12x12_UNORM: - return eTF_ASTC_12x12; - case DXGI_FORMAT_ASTC_12x12_UNORM_SRGB: - return eTF_ASTC_12x12; -#endif - // only available as hardware format under DX9 - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return eTF_B8G8R8X8; - } -#endif - return eTF_Unknown; - } - else - { - return GetFormatByDesc(ddspf); - } - } - - inline const bool IsNormalMap(const ETEX_Format eTF) - { - if (eTF == eTF_BC5U || eTF == eTF_BC5S || eTF == eTF_CTX1 || eTF == eTF_EAC_RG11) - { - return true; - } - return false; - } - - inline const bool IsSigned(const ETEX_Format eTF) - { - if (eTF == eTF_BC4S || eTF == eTF_BC5S || eTF == eTF_BC6SH || eTF == eTF_R8S || eTF == eTF_R8G8S || eTF == eTF_R16G16S || eTF == eTF_R8G8B8A8S || eTF == eTF_R16G16B16A16S) - { - return true; - } - return false; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const CImageExtensionHelper::DDS_PIXELFORMAT& GetDescByFormat(const ETEX_Format eTF) - { - switch (eTF) - { - case eTF_BC1: - return DDSPF_DXT1; - case eTF_BC2: - return DDSPF_DXT3; - case eTF_BC3: - return DDSPF_DXT5; - case eTF_BC4U: - return DDSPF_3DCP; - case eTF_BC5U: - return DDSPF_3DC; - case eTF_CTX1: - return DDSPF_CTX1; - case eTF_R32F: - return DDSPF_R32F; - // case eTF_R32G32F: - // return DDSPF_G32R32F; - case eTF_R32G32B32A32F: - return DDSPF_A32B32G32R32F; - case eTF_R16F: - return DDSPF_R16F; - case eTF_R16G16F: - return DDSPF_G16R16F; - case eTF_R16G16B16A16F: - return DDSPF_A16B16G16R16F; - case eTF_R16: - return DDSPF_R16; - case eTF_R16G16: - return DDSPF_G16R16; - case eTF_R16G16B16A16: - return DDSPF_A16B16G16R16; - // case eTF_R16S: - // return DDSPF_U16; - case eTF_R16G16S: - return DDSPF_V16U16; - case eTF_R16G16B16A16S: - return DDSPF_Q16W16V16U16; - case eTF_B8G8R8: - case eTF_L8V8U8: - return DDSPF_R8G8B8; - case eTF_R8G8B8A8: - return DDSPF_A8B8G8R8; - case eTF_B8G8R8X8: - case eTF_L8V8U8X8: - return DDSPF_X8R8G8B8; - case eTF_B8G8R8A8: - return DDSPF_A8R8G8B8; - case eTF_B5G6R5: - return DDSPF_R5G6B5; - case eTF_A8: - return DDSPF_A8; - case eTF_L8: - return DDSPF_L8; - case eTF_A8L8: - return DDSPF_A8L8; - case eTF_EAC_R11: - return DDSPF_EAC_R11; - case eTF_EAC_RG11: - return DDSPF_EAC_RG11; - case eTF_ETC2: - return DDSPF_ETC2; - case eTF_ETC2A: - return DDSPF_ETC2A; - case eTF_PVRTC2: - return DDSPF_PVRTC2; - case eTF_PVRTC4: - return DDSPF_PVRTC4; - - case eTF_ASTC_4x4: - return DDSPF_ASTC_4x4; - case eTF_ASTC_5x4: - return DDSPF_ASTC_5x4; - case eTF_ASTC_5x5: - return DDSPF_ASTC_5x5; - case eTF_ASTC_6x5: - return DDSPF_ASTC_6x5; - case eTF_ASTC_6x6: - return DDSPF_ASTC_6x6; - case eTF_ASTC_8x5: - return DDSPF_ASTC_8x5; - case eTF_ASTC_8x6: - return DDSPF_ASTC_8x6; - case eTF_ASTC_8x8: - return DDSPF_ASTC_8x8; - case eTF_ASTC_10x5: - return DDSPF_ASTC_10x5; - case eTF_ASTC_10x6: - return DDSPF_ASTC_10x6; - case eTF_ASTC_10x8: - return DDSPF_ASTC_10x8; - case eTF_ASTC_10x10: - return DDSPF_ASTC_10x10; - case eTF_ASTC_12x10: - return DDSPF_ASTC_12x10; - case eTF_ASTC_12x12: - return DDSPF_ASTC_12x12; - default: - assert(0); - return DDSPF_A8B8G8R8; - } - } - - inline const CImageExtensionHelper::DDS_PIXELFORMAT& GetDescByFormat(DWORD& dxgifOut, const ETEX_Format eTF) - { - dxgifOut = 0; - - switch (eTF) - { -#if defined(CRY_DDS_DX10_SUPPORT) - case eTF_R8: - dxgifOut = DXGI_FORMAT_R8_UNORM; - return DDSPF_DX10; - case eTF_R8S: - dxgifOut = DXGI_FORMAT_R8_SNORM; - return DDSPF_DX10; - case eTF_R16: - dxgifOut = DXGI_FORMAT_R16_UNORM; - return DDSPF_DX10; - case eTF_R16F: - dxgifOut = DXGI_FORMAT_R16_FLOAT; - return DDSPF_DX10; - case eTF_R8G8: - dxgifOut = DXGI_FORMAT_R8G8_UNORM; - return DDSPF_DX10; - case eTF_R8G8S: - dxgifOut = DXGI_FORMAT_R8G8_SNORM; - return DDSPF_DX10; - case eTF_R16G16: - dxgifOut = DXGI_FORMAT_R16G16_UNORM; - return DDSPF_DX10; - case eTF_R11G11B10F: - dxgifOut = DXGI_FORMAT_R11G11B10_FLOAT; - return DDSPF_DX10; - case eTF_R10G10B10A2: - dxgifOut = DXGI_FORMAT_R10G10B10A2_UNORM; - return DDSPF_DX10; - case eTF_R16G16B16A16: - dxgifOut = DXGI_FORMAT_R16G16B16A16_UNORM; - return DDSPF_DX10; - case eTF_R16G16B16A16S: - dxgifOut = DXGI_FORMAT_R16G16B16A16_SNORM; - return DDSPF_DX10; - case eTF_R32G32B32A32F: - dxgifOut = DXGI_FORMAT_R32G32B32A32_FLOAT; - return DDSPF_DX10; - case eTF_R8G8B8A8S: - dxgifOut = DXGI_FORMAT_R8G8B8A8_SNORM; - return DDSPF_DX10; - - case eTF_BC4S: - dxgifOut = DXGI_FORMAT_BC4_SNORM; - return DDSPF_DX10; - case eTF_BC5S: - dxgifOut = DXGI_FORMAT_BC5_SNORM; - return DDSPF_DX10; - case eTF_BC6SH: - dxgifOut = DXGI_FORMAT_BC6H_SF16; - return DDSPF_DX10; - case eTF_BC6UH: - dxgifOut = DXGI_FORMAT_BC6H_UF16; - return DDSPF_DX10; - case eTF_BC7: - dxgifOut = DXGI_FORMAT_BC7_UNORM; - return DDSPF_DX10; - case eTF_R9G9B9E5: - dxgifOut = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - return DDSPF_DX10; -#endif - - default: - return GetDescByFormat(eTF); - } - } -}; - -namespace CImageExtensionHelper -{ - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf) - { - ETEX_Format nFormat = DDSFormats::GetFormatByDesc(ddspf); - return NameForTextureFormat(nFormat); - } - - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf, DWORD /*DXGI_FORMAT*/ dxgif) - { - ETEX_Format nFormat = DDSFormats::GetFormatByDesc(ddspf, dxgif); - return NameForTextureFormat(nFormat); - } -}; diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h b/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h deleted file mode 100644 index dae6f9cb2d..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h +++ /dev/null @@ -1,69 +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_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H -#define CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H -#pragma once - -#include "CryString.h" -#include "TypeInfo_decl.h" -#include "ImageExtensionHelper.h" - -// Crytek specific image extensions -// -// usually added to the end of DDS files - - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_PIXELFORMAT) -STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwFourCC, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwRGBBitCount, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwRBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwGBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwBBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwABitMask, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_PIXELFORMAT) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER_DXT10) -STRUCT_VAR_INFO(dxgiFormat, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(resourceDimension, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(miscFlag, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(arraySize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(reserved, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER_DXT10) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER) -STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwHeaderFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwHeight, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwWidth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwPitchOrLinearSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwDepth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwMipMapCount, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwAlphaBitDepth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwReserved1, TYPE_ARRAY(10, TYPE_INFO(DWORD))) -STRUCT_VAR_INFO(ddspf, TYPE_INFO(CImageExtensionHelper::DDS_PIXELFORMAT)) -STRUCT_VAR_INFO(dwSurfaceFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwCubemapFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(bNumPersistentMips, TYPE_INFO(BYTE)) -STRUCT_VAR_INFO(bReserved2, TYPE_ARRAY(7, TYPE_INFO(BYTE))) -STRUCT_VAR_INFO(dwTextureStage, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_FILE_DESC) -STRUCT_VAR_INFO(dwMagic, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(header, TYPE_INFO(CImageExtensionHelper::DDS_HEADER)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_FILE_DESC) - -#endif // CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H diff --git a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h index 74d072c48c..a3fae96310 100644 --- a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h +++ b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h @@ -330,8 +330,6 @@ public: ITexture * (const char* nameTex)); MOCK_METHOD1(EF_LoadLightmap, int(const char* name)); - MOCK_METHOD3(EF_RenderEnvironmentCubeHDR, - bool(int size, Vec3 & Pos, TArray&vecData)); MOCK_METHOD1(EF_StartEf, void(const SRenderingPassInfo& passInfo)); MOCK_METHOD3(EF_GetObjData, @@ -360,8 +358,6 @@ public: uint32(eDeferredLightType)); MOCK_METHOD0(EF_ClearDeferredLightsList, void()); - MOCK_METHOD2(EF_GetDeferredLights, - TArray*(const SRenderingPassInfo&, const eDeferredLightType)); MOCK_METHOD1(EF_AddDeferredClipVolume, uint8(const IClipVolume * pClipVolume)); MOCK_METHOD2(EF_SetDeferredClipVolumeBlendData, diff --git a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h index cfe150c1df..acd7492398 100644 --- a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h +++ b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h @@ -37,8 +37,6 @@ public: bool()); MOCK_METHOD0(RenderStatistics, void()); - MOCK_METHOD0(GetUsedMemory, - uint32()); MOCK_METHOD0(GetUserName, const char*()); MOCK_METHOD0(GetCPUFlags, @@ -88,8 +86,6 @@ public: INameTable * ()); MOCK_METHOD0(GetIValidator, IValidator * ()); - MOCK_METHOD0(GetStreamEngine, - IStreamEngine * ()); MOCK_METHOD0(GetICmdLine, ICmdLine * ()); MOCK_METHOD0(GetILog, @@ -98,8 +94,6 @@ public: AZ::IO::IArchive * ()); MOCK_METHOD0(GetICryFont, ICryFont * ()); - MOCK_METHOD0(GetIMemoryManager, - IMemoryManager * ()); MOCK_METHOD0(GetIMovieSystem, IMovieSystem * ()); MOCK_METHOD0(GetIAudioSystem, @@ -108,20 +102,12 @@ public: ::IConsole * ()); MOCK_METHOD0(GetIRemoteConsole, IRemoteConsole * ()); - MOCK_METHOD0(GetIResourceManager, - IResourceManager * ()); MOCK_METHOD0(GetIProfilingSystem, IProfilingSystem * ()); MOCK_METHOD0(GetISystemEventDispatcher, ISystemEventDispatcher * ()); MOCK_METHOD0(GetITimer, ITimer * ()); - MOCK_METHOD2(DebugStats, - void(bool checkpoint, bool leaks)); - MOCK_METHOD0(DumpWinHeaps, - void()); - MOCK_METHOD1(DumpMMStats, - int(bool log)); MOCK_METHOD1(SetForceNonDevMode, void(bool bValue)); MOCK_CONST_METHOD0(GetForceNonDevMode, @@ -237,8 +223,6 @@ public: MOCK_METHOD0(SteamInit, bool()); - MOCK_CONST_METHOD0(GetImageHandler, - const IImageHandler * ()); MOCK_METHOD0(GetRootWindowMessageHandler, void*()); MOCK_METHOD1(RegisterWindowMessageHandler, diff --git a/Code/CryEngine/CryCommon/PoolAllocator.h b/Code/CryEngine/CryCommon/PoolAllocator.h index d6037289a7..110d25153e 100644 --- a/Code/CryEngine/CryCommon/PoolAllocator.h +++ b/Code/CryEngine/CryCommon/PoolAllocator.h @@ -36,9 +36,6 @@ // require a pointer to the bucket be stored, whereas now no memory is used // while the block is allocated. // -// This allocator is suitable for use with STL lists - see STLPoolAllocator -// for an STL-compatible interface. -// // The class can optionally support multi-threading, using the second // template parameter. By default it is multithread-safe. // See Synchronization.h. diff --git a/Code/CryEngine/CryCommon/STLGlobalAllocator.h b/Code/CryEngine/CryCommon/STLGlobalAllocator.h deleted file mode 100644 index 2067c9b2e9..0000000000 --- a/Code/CryEngine/CryCommon/STLGlobalAllocator.h +++ /dev/null @@ -1,185 +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_CRYCOMMON_STLGLOBALALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for an std::allocator using the global heap. -//--------------------------------------------------------------------------- - -#include -#include - -#include "CryMemoryManager.h" - -#include -#include -#include - -struct CryLegacySTLAllocatorDescriptor - : public AZ::HphaSchema::Descriptor -{ - CryLegacySTLAllocatorDescriptor() - { - m_systemChunkSize = 4 * 1024 * 1024; // Ask the OS for 4MB at a time - } -}; - -class CryLegacySTLAllocator - : public AZ::SimpleSchemaAllocator -{ -public: - AZ_TYPE_INFO(CryLegacySTLAllocator, "{87EE21F1-8215-4979-B493-AF13D8D91DAD}"); - using Descriptor = CryLegacySTLAllocatorDescriptor; - using Base = AZ::SimpleSchemaAllocator; - CryLegacySTLAllocator() - : Base("CryLegacySTLAllocator", "Allocator used to dodge limits on static init time allocations") - { - } -}; - -// Specialize for the CryLegacySTLAllocator to provide one per module that does not use the -// environment for its storage, since this thing is designed to get around the lack -// of static allocators -namespace AZ -{ - template <> - class AllocatorInstance : public Internal::AllocatorInstanceBase> - { - }; -} - - -class ICrySizer; -namespace stl -{ - template - class STLGlobalAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLGlobalAllocator other; - }; - - STLGlobalAllocator() throw() - { - } - - STLGlobalAllocator(const STLGlobalAllocator&) throw() - { - } - - template - STLGlobalAllocator(const STLGlobalAllocator&) throw() - { - } - - ~STLGlobalAllocator() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - (void)hint; - pointer ret = static_cast(AZ::AllocatorInstance::Get().Allocate(n * sizeof(T), 0)); - return ret; - } - - void deallocate(pointer p, [[maybe_unused]] size_type n = 1) - { - AZ::AllocatorInstance::Get().DeAllocate(p); - } - - size_type max_size() const throw() - { - return INT_MAX; - } -#if !defined(_LIBCPP_VERSION) - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } -#endif // !_LIBCPP_VERSION - void destroy(pointer p) - { - p->~T(); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLGlobalAllocator&) const { return true; } - bool operator!=(const STLGlobalAllocator&) const { return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) - { - } - }; - - template <> - class STLGlobalAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template - struct rebind - { - typedef STLGlobalAllocator other; - }; - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/STLPoolAllocator.h b/Code/CryEngine/CryCommon/STLPoolAllocator.h deleted file mode 100644 index 564720bc02..0000000000 --- a/Code/CryEngine/CryCommon/STLPoolAllocator.h +++ /dev/null @@ -1,208 +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_CRYCOMMON_STLPOOLALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for the pool allocator (see PoolAllocator.h). -// -// This class is suitable for use as an allocator for STL lists. Note it will -// not work with vectors, since it allocates fixed-size blocks, while vectors -// allocate elements in variable-sized contiguous chunks. -// -// To create a list of type UserDataType using this allocator, use the -// following syntax: -// -// std::list > myList; -//--------------------------------------------------------------------------- - -#include "PoolAllocator.h" -#include "MetaUtils.h" -#include -#include - -namespace stl -{ - namespace STLPoolAllocatorHelper - { - inline void destruct(char*) {} - inline void destruct(wchar_t*) {} - template - inline void destruct(T* t) {t->~T(); } - } - - template - struct STLPoolAllocatorStatic - { - // Non-freeing stl pool allocators should just go on the global heap - only if they've been explicitly - // set to cleanup should they go on the default heap. - typedef SizePoolAllocator< - HeapAllocator< - L, - typename metautils::select::type> - > AllocatorType; - - static AllocatorType* GetOrCreateAllocator() - { - if (allocator) - { - return allocator; - } - - allocator = new AllocatorType(S, A, FHeap().FreeWhenEmpty(FreeWhenEmpty)); - return allocator; - } - - static AllocatorType* allocator; - }; - - template - struct STLPoolAllocatorKungFu - : public STLPoolAllocatorStatic - { - }; - - template - class STLPoolAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLPoolAllocator other; - }; - - STLPoolAllocator() throw() - { - } - - STLPoolAllocator(const STLPoolAllocator&) throw() - { - } - - template - STLPoolAllocator(const STLPoolAllocator&) throw() - { - } - - ~STLPoolAllocator() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate([[maybe_unused]] size_type n = 1, [[maybe_unused]] const void* hint = 0) - { - assert(n == 1); - typename STLPoolAllocatorKungFu::AllocatorType * allocator = STLPoolAllocatorKungFu::GetOrCreateAllocator(); - return static_cast(allocator->Allocate()); - } - - void deallocate(pointer p, [[maybe_unused]] size_type n = 1) - { - assert(n == 1); - typename STLPoolAllocatorKungFu::AllocatorType * allocator = STLPoolAllocatorKungFu::allocator; - allocator->Deallocate(p); - } - - size_type max_size() const throw() - { - return INT_MAX; - } -#ifndef _LIBCPP_VERSION - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } -#endif // !(_LIBCPP_VERSION) - void destroy(pointer p) - { - STLPoolAllocatorHelper::destruct(p); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLPoolAllocator&) {return true; } - bool operator!=(const STLPoolAllocator&) {return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) - { - pSizer->AddObject(STLPoolAllocatorKungFu::allocator); - } - }; - - template - class STLPoolAllocatorNoMT - : public STLPoolAllocator - { - }; - - template <> - class STLPoolAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template - struct rebind - { - typedef STLPoolAllocator other; - }; - }; - - template - typename STLPoolAllocatorStatic::AllocatorType * STLPoolAllocatorStatic::allocator; -} - - - -#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h b/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h deleted file mode 100644 index 28fff38917..0000000000 --- a/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h +++ /dev/null @@ -1,107 +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_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H -#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for the pool allocator (see PoolAllocator.h). -// -// this class acts like STLPoolAllocator, but it is also usable for vectors -// which means that it can be used as a more efficient allocator for many -// implementations of hash_map (typically this uses internally a vector and -// a list with the same allocator) -//--------------------------------------------------------------------------- - -#include "STLPoolAllocator.h" - -namespace stl -{ - template - struct STLPoolAllocator_ManyElemsStatic - { - static PoolAllocator* allocator; - }; - - template - class STLPoolAllocator_ManyElems - : public STLPoolAllocator - { - typedef STLPoolAllocator Super; - typedef PoolAllocator LargeAllocator; - - public: - typedef typename Super::pointer pointer; - typedef typename Super::pointer pointer_type; - typedef typename Super::size_type size_type; - typedef AZStd::false_type allow_memory_leaks; - - template - struct rebind - { - typedef STLPoolAllocator_ManyElems other; - }; - - STLPoolAllocator_ManyElems() throw() - { - } - - template - STLPoolAllocator_ManyElems(const STLPoolAllocator_ManyElems&) throw() - { - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - if (n == 1) - { - return Super::allocate(n, hint); - } - else if (n * sizeof(T) <= LargeAllocationSizeThreshold) - { - if (!STLPoolAllocator_ManyElemsStatic::allocator) - { - STLPoolAllocator_ManyElemsStatic::allocator = new LargeAllocator(); - } - return static_cast(STLPoolAllocator_ManyElemsStatic::allocator->Allocate()); - } - else - { - return static_cast(CryModuleMalloc(n * sizeof(T))); - } - } - - void deallocate(pointer p, size_type n = 1) - { - if (n == 1) - { - Super::deallocate(p); - } - else if (n * sizeof(T) <= LargeAllocationSizeThreshold) - { - STLPoolAllocator_ManyElemsStatic::allocator->Deallocate(p); - } - else - { - CryModuleFree(p); - } - } - }; - - template - PoolAllocator* STLPoolAllocator_ManyElemsStatic::allocator; -} - -#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H diff --git a/Code/CryEngine/CryCommon/StlUtils.h b/Code/CryEngine/CryCommon/StlUtils.h index df88a14196..9d6090502f 100644 --- a/Code/CryEngine/CryCommon/StlUtils.h +++ b/Code/CryEngine/CryCommon/StlUtils.h @@ -27,7 +27,6 @@ #endif #define STATIC_ASSERT(condition, errMessage) static_assert(condition, errMessage) -#include "STLGlobalAllocator.h" #include #include diff --git a/Code/CryEngine/CryCommon/Tarray.h b/Code/CryEngine/CryCommon/Tarray.h index 035a4b3e0e..32bb249f7c 100644 --- a/Code/CryEngine/CryCommon/Tarray.h +++ b/Code/CryEngine/CryCommon/Tarray.h @@ -19,7 +19,6 @@ #include #include #include -#include #ifndef CLAMP #define CLAMP(X, mn, mx) ((X) < (mn) ? (mn) : ((X) < (mx) ? (X) : (mx))) @@ -58,400 +57,4 @@ } #endif - -// General array class. -// Can refer to a general (unowned) region of memory (m_nAllocatedCount = 0). -// Can allocate, grow, and shrink an array. -// Does not deep copy. - -template -class TArray -{ -protected: - T* m_pElements; - unsigned int m_nCount; - unsigned int m_nAllocatedCount; - -public: - typedef T value_type; - - // Empty array. - TArray() - { - ClearArr(); - } - - // Create a new array, delete it on destruction. - TArray(int Count) - { - m_nCount = Count; - m_nAllocatedCount = Count; - m_pElements = NULL; - Realloc(0); - } - TArray(int Use, int Max) - { - m_nCount = Use; - m_nAllocatedCount = Max; - m_pElements = NULL; - Realloc(0); - } - - // Reference pre-existing memory. Does not delete it. - TArray(T* Elems, int Count) - { - m_pElements = Elems; - m_nCount = Count; - m_nAllocatedCount = 0; - } - ~TArray() - { - Free(); - } - - void Free() - { - m_nCount = 0; - if (m_nAllocatedCount && AZ::AllocatorInstance::IsReady()) - { - AZ::AllocatorInstance::Get().DeAllocate(m_pElements); - } - m_nAllocatedCount = 0; - m_pElements = NULL; - } - - void Create (int Count) - { - m_pElements = NULL; - m_nCount = Count; - m_nAllocatedCount = Count; - Realloc(0); - Clear(); - } - void Copy (const TArray& src) - { - m_pElements = NULL; - m_nCount = m_nAllocatedCount = src.Num(); - Realloc(0); - PREFAST_ASSUME(m_pElements); // realloc asserts if it fails - so this is safe - memcpy(m_pElements, src.m_pElements, src.Num() * sizeof(T)); - } - void Copy (const T* src, unsigned int numElems) - { - int nOffs = m_nCount; - Grow(numElems); - memcpy(&m_pElements[nOffs], src, numElems * sizeof(T)); - } - void Align4Copy (const T* src, unsigned int& numElems) - { - int nOffs = m_nCount; - Grow((numElems + 3) & ~3); - memcpy(&m_pElements[nOffs], src, numElems * sizeof(T)); - if (numElems & 3) - { - int nSet = 4 - (numElems & 3); - memset(&m_pElements[nOffs + numElems], 0, nSet); - numElems += nSet; - } - } - - void Realloc([[maybe_unused]] int nOldAllocatedCount) - { - if (!m_nAllocatedCount) - { - m_pElements = NULL; - } - else - { - m_pElements = static_cast(AZ::AllocatorInstance::Get().ReAllocate(m_pElements, m_nAllocatedCount * sizeof(T), alignof(T))); - assert (m_pElements); - } - } - - void Remove(unsigned int Index, unsigned int Count = 1) - { - if (Count) - { - memmove(m_pElements + Index, m_pElements + (Index + Count), sizeof(T) * (m_nCount - Index - Count)); - m_nCount -= Count; - } - } - - void Shrink() - { - if (m_nCount == 0 || m_nAllocatedCount == 0) - { - return; - } - assert(m_nAllocatedCount >= m_nCount); - if (m_nAllocatedCount != m_nCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount; - Realloc(nOldAllocatedCount); - } - } - - void _Remove(unsigned int Index, unsigned int Count) - { - assert (Index >= 0); - assert (Index <= m_nCount); - assert ((Index + Count) <= m_nCount); - - Remove(Index, Count); - } - - unsigned int Num(void) const { return m_nCount; } - unsigned int Capacity(void) const { return m_nAllocatedCount; } - unsigned int MemSize(void) const { return m_nCount * sizeof(T); } - void SetNum(unsigned int n) { m_nCount = m_nAllocatedCount = n; } - void SetUse(unsigned int n) { m_nCount = n; } - void Alloc(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; m_nAllocatedCount = n; Realloc(nOldAllocatedCount); } - void Reserve(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; SetNum(n); Realloc(nOldAllocatedCount); Clear(); } - void ReserveNoClear(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; SetNum(n); Realloc(nOldAllocatedCount); } - void Expand(unsigned int n) - { - if (n > m_nAllocatedCount) - { - ReserveNew(n); - } - } - void ReserveNew(unsigned int n) - { - int num = m_nCount; - if (n > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = n * 2; - Realloc(nOldAllocatedCount); - } - m_nCount = n; - memset(&m_pElements[num], 0, sizeof(T) * (m_nCount - num)); - } - T* Grow(unsigned int n) - { - int nStart = m_nCount; - m_nCount += n; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount * 2; - Realloc(nOldAllocatedCount); - } - return &m_pElements[nStart]; - } - T* GrowReset(unsigned int n) - { - int num = m_nAllocatedCount; - T* Obj = AddIndex(n); - if (num != m_nAllocatedCount) - { - memset(&m_pElements[num], 0, sizeof(T) * (m_nAllocatedCount - num)); - } - return Obj; - } - - unsigned int* GetNumAddr(void) { return &m_nCount; } - T** GetDataAddr(void) { return &m_pElements; } - - T* Data(void) const { return m_pElements; } - T& Get(unsigned int id) const { return m_pElements[id]; } - - - void Assign(TArray& fa) - { - m_pElements = fa.m_pElements; - m_nCount = fa.m_nCount; - m_nAllocatedCount = fa.m_nAllocatedCount; - } - - - /*const TArray operator=(TArray fa) const - { - TArray t = TArray(fa.m_nCount,fa.m_nAllocatedCount); - for ( int i=0; i 0); return *m_pElements; } - - TArray operator()(unsigned int Start) - { - assert(Start < m_nCount); - return TArray(m_pElements + Start, m_nCount - Start); - } - TArray operator()(unsigned int Start, unsigned int Count) - { - assert(Start < m_nCount); - assert(Start + Count <= m_nCount); - return TArray(m_pElements + Start, Count); - } - - // For simple types only - TArray(const TArray& cTA) - { - m_pElements = NULL; - m_nCount = m_nAllocatedCount = cTA.Num(); - Realloc(0); - if (m_pElements) - { - memcpy(m_pElements, &cTA[0], m_nCount * sizeof(T)); - } - /*for (unsigned int i=0; i m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = nNewCount + (nNewCount >> 1) + 10; - Realloc(nOldAllocatedCount); - } - - m_nCount = nNewCount; - return &m_pElements[nIndex]; - } - - T& Insert(unsigned int nIndex, unsigned int inc = 1) - { - m_nCount += inc; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount + (m_nCount >> 1) + 32; - Realloc(nOldAllocatedCount); - } - memmove(&m_pElements[nIndex + inc], &m_pElements[nIndex], (m_nCount - inc - nIndex) * sizeof(T)); - - return m_pElements[nIndex]; - } - - void AddIndexNoCache(unsigned int inc) - { - m_nCount += inc; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount; - Realloc(nOldAllocatedCount); - } - } - - void Add(const T& elem){AddElem(elem); } - void AddElem(const T& elem) - { - unsigned int m = m_nCount; - AddIndex(1); - m_pElements[m] = elem; - } - void AddElemNoCache(const T& elem) - { - unsigned int m = m_nCount; - AddIndexNoCache(1); - m_pElements[m] = elem; - } - - int Find(const T& p) - { - for (unsigned int i = 0; i < m_nCount; i++) - { - if (p == (*this)[i]) - { - return i; - } - } - return -1; - } - - void Delete(unsigned int n){DelElem(n); } - void DelElem(unsigned int n) - { - // memset(&m_pElements[n],0,sizeof(T)); - _Remove(n, 1); - } - - // Standard compliance interface - // - // This is for those who don't want to learn the non standard and - // thus not very convenient interface of TArray, but are unlucky - // enough not to be able to avoid using it. - void clear(){Free(); } - void resize(unsigned int nSize) { reserve(nSize); m_nCount = nSize; } - void reserve(unsigned int nSize) - { - if (nSize > m_nAllocatedCount) - { - Alloc(nSize); - } - } - unsigned size() const {return m_nCount; } - unsigned capacity() const {return m_nAllocatedCount; } - bool empty() const {return size() == 0; } - void push_back (const T& rSample) {Add(rSample); } - void pop_back () {m_nCount--; } - void erase (T* pElem) - { - int n = int(pElem - m_pElements); - assert(n >= 0 && n < m_nCount); - _Remove(n, 1); - } - T* begin() {return m_pElements; } - T* end() {return m_pElements + m_nCount; } - T last() {return m_pElements[m_nCount - 1]; } - const T* begin() const {return m_pElements; } - const T* end() const {return m_pElements + m_nCount; } - - int GetMemoryUsage() const { return (int)(m_nAllocatedCount * sizeof(T)); } -}; - -template -inline void Exchange(T& X, T& Y) -{ - const T Tmp = X; - X = Y; - Y = Tmp; -} - #endif // CRYINCLUDE_CRYCOMMON_TARRAY_H diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index dff4ca66e7..47e57633b4 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -12,7 +12,6 @@ set(FILES QTangent.h CryCommon.cpp - Allocator.h FinalizingSpline.h IAudioInterfacesCommonData.h IAudioSystem.h @@ -26,10 +25,8 @@ set(FILES IFunctorBase.h IFuncVariable.h IGem.h - IGeneralMemoryHeap.h IGeomCache.h IImage.h - IImageHandler.h IIndexedMesh.h IIndexedMesh_info.cpp ILevelSystem.h @@ -39,7 +36,6 @@ set(FILES ILog.h ILZ4Decompressor.h IMaterial.h - IMemory.h IMeshBaking.h IMiniLog.h IMovieSystem.h @@ -51,8 +47,6 @@ set(FILES IRenderAuxGeom.h IRenderer.h IRenderMesh.h - IResourceCollector.h - IResourceManager.h ISerialize.h IShader.h IShader_info.h @@ -60,8 +54,6 @@ set(FILES IStatObj.h StatObjBus.h IStereoRenderer.h - IStreamEngine.h - IStreamEngineDefs.h ISurfaceType.h ISystem.h ITextModeConsole.h @@ -85,10 +77,8 @@ set(FILES IObjManager.h INavigationSystem.h IMNM.h - AzDXGIFormat.h SFunctor.h FunctorBaseFunction.h - CustomMemoryHeap.h FunctorBaseMember.h stridedptr.h Options.h @@ -102,31 +92,21 @@ set(FILES CryTypeInfo.cpp BaseTypes.h CompileTimeAssert.h - CryThreadSafeWorkerContainer.h - CryThreadSafeRendererContainer.h intrusive_list.hpp MemoryAccess.h - Algorithm.h AnimKey.h BitFiddling.h - CGFContent.h - CGFContent_info.cpp Common_TypeInfo.cpp - CountedValue.h - CrtDebugStats.h CryArray.h CryArray2d.h CryAssert.h CryCrc32.h CryCustomTypes.h CryFile.h - CryFixedArray.h CryFixedString.h CryHeaders.h CryHeaders_info.cpp CryListenerSet.h - CryMemoryAllocator.h - CryMemoryManager.h CryLegacyAllocator.h CryName.h CryPath.h @@ -145,9 +125,6 @@ set(FILES HashGrid.h HeapAllocator.h HeapContainer.h - ImageExtensionHelper.cpp - ImageExtensionHelper.h - ImageExtensionHelper_info.h InplaceFactory.h LegacyAllocator.h MetaUtils.h @@ -172,8 +149,6 @@ set(FILES SmartPointersHelpers.h smartptr.h StackContainer.h - STLGlobalAllocator.h - STLPoolAllocator.h StlUtils.h StringUtils.h Synchronization.h @@ -203,7 +178,6 @@ set(FILES Cry_Matrix44.h Cry_MatrixDiag.h Cry_Vector4.h - AABBSV.h Cry_Camera.h Cry_Color.h Cry_Geo.h @@ -224,7 +198,6 @@ set(FILES Cry_HWVector3.h AndroidSpecific.h AppleSpecific.h - Console_std.h CryAssert_Android.h CryAssert_impl.h CryAssert_iOS.h @@ -232,7 +205,6 @@ set(FILES CryAssert_Mac.h CryLibrary.cpp CryLibrary.h - CryMemoryManager_impl.h CryThread_dummy.h CryThread_pthreads.h CryThread_windows.h diff --git a/Code/CryEngine/CryCommon/platform.h b/Code/CryEngine/CryCommon/platform.h index f7361db11d..df8fb125b2 100644 --- a/Code/CryEngine/CryCommon/platform.h +++ b/Code/CryEngine/CryCommon/platform.h @@ -479,15 +479,7 @@ ILINE DestinationType alias_cast(SourceType pPtr) return conv_union.pDst; } -////////////////////////////////////////////////////////////////////////// - -#include "CryMemoryManager.h" - -// Memory manager breaks strdup -// Use something higher level, like CryString - #undef strdup - #define strdup dont_use_strdup - +#include "CryLegacyAllocator.h" ////////////////////////////////////////////////////////////////////////// #ifndef DEPRECATED diff --git a/Code/CryEngine/CryCommon/platform_impl.cpp b/Code/CryEngine/CryCommon/platform_impl.cpp index 885ea2984d..1d784ed8a0 100644 --- a/Code/CryEngine/CryCommon/platform_impl.cpp +++ b/Code/CryEngine/CryCommon/platform_impl.cpp @@ -20,6 +20,7 @@ #include #include +#include #include // Section dictionary @@ -194,11 +195,6 @@ void __stl_debug_message(const char* format_str, ...) #include #endif -// If we use cry memory manager this should be also included in every module. -#if defined(USING_CRY_MEMORY_MANAGER) -#include -#endif - #if defined(APPLE) || defined(LINUX) #include "CryAssert_impl.h" #endif diff --git a/Code/CryEngine/CrySystem/AsyncPakManager.cpp b/Code/CryEngine/CrySystem/AsyncPakManager.cpp deleted file mode 100644 index 40928715d8..0000000000 --- a/Code/CryEngine/CrySystem/AsyncPakManager.cpp +++ /dev/null @@ -1,516 +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 : Manage async pak files - - -#include "CrySystem_precompiled.h" -#include "AsyncPakManager.h" -#include "System.h" -#include "IStreamEngine.h" -#include -#include -#include "ResourceManager.h" - -#define MEGA_BYTE 1024* 1024 - -////////////////////////////////////////////////////////////////////////// - -string& CAsyncPakManager::SAsyncPak::GetStatus(string& status) const -{ - switch (eState) - { - case STATE_UNLOADED: - status = "Unloaded"; - break; - case STATE_REQUESTED: - status = "Requested"; - break; - case STATE_REQUESTUNLOAD: - status = "RequestUnload"; - break; - case STATE_LOADED: - status = "Loaded"; - break; - default: - status = "Unknown"; - break; - } - - return status; -} - -////////////////////////////////////////////////////////////////////////// - -CAsyncPakManager::CAsyncPakManager() -{ - m_nTotalOpenLayerPakSize = 0; - m_bRequestLayerUpdate = false; -} - -CAsyncPakManager::~CAsyncPakManager() -{ - Clear(); -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::Clear() -{ - //float startTime = gEnv->pTimer->GetAsyncCurTime(); - - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - if (layerPak.bStreaming) - { - // wait until finished - layerPak.pReadStream->Abort(); - } - - ReleaseData(&layerPak); - } - m_paks.clear(); - m_bRequestLayerUpdate = false; - - assert(m_nTotalOpenLayerPakSize == 0); - m_nTotalOpenLayerPakSize = 0; - - //printf("CAsyncPakManager::Clear() %0.4f secs\n", gEnv->pTimer->GetAsyncCurTime() - startTime); -} - -void CAsyncPakManager::UnloadLevelLoadPaks() -{ - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - - if (layerPak.eLifeTime == SAsyncPak::LIFETIME_LOAD_ONLY) - { - if (layerPak.bStreaming) - { - // wait until finished - layerPak.pReadStream->Abort(); - } - - ReleaseData(&layerPak); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::ParseLayerPaks(const string& levelCachePath) -{ - string layerPath = levelCachePath + "/"; // "/layers/"; - string search = layerPath + "*"; - auto pPak = gEnv->pCryPak; - - - // allow this find first to actually touch the file system - AZ::IO::ArchiveFileIterator fileIterator= pPak->FindFirst(search.c_str(), 0, true); - - if (fileIterator) - { - do - { - if ((fileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory || fileIterator.m_filename == "." || fileIterator.m_filename == "..") - { - continue; - } - - string pakName(fileIterator.m_filename.data(), fileIterator.m_filename.size()); - size_t findPos = pakName.find_last_of('.'); - if (findPos == string::npos) - { - continue; - } - - string extension = pakName.substr(findPos + 1, pakName.size()); - if (extension != "pak") - { - continue; - } - - SAsyncPak layerPak; - layerPak.layername = pakName.substr(0, findPos); - layerPak.filename = layerPath + pakName; - layerPak.nSize = pPak->FGetSize(layerPak.filename.c_str(), true); // allow to go to disc for this access - layerPak.bClosePakOnRelease = true; - - m_paks[layerPak.layername] = layerPak; - } while (fileIterator = pPak->FindNext(fileIterator)); - - pPak->FindClose(fileIterator); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StartStreaming(SAsyncPak* pLayerPak) -{ - StreamReadParams params; - params.dwUserData = (DWORD_PTR) pLayerPak; - params.nSize = 0; - params.pBuffer = NULL; - params.nFlags = IStreamEngine::FLAGS_FILE_ON_DISK; - params.ePriority = estpIdle; - - pLayerPak->pReadStream = gEnv->pSystem->GetStreamEngine()->StartRead(eStreamTaskTypePak, pLayerPak->filename.c_str(), this, ¶ms); - - if (pLayerPak->pReadStream) - { - pLayerPak->bStreaming = true; - } - else - { - pLayerPak->eState = SAsyncPak::STATE_UNLOADED; - pLayerPak->pData.reset(); - } -} - -void CAsyncPakManager::ReleaseData(SAsyncPak* pLayerPak) -{ - if (pLayerPak->eState == SAsyncPak::STATE_LOADED) - { - if (pLayerPak->bClosePakOnRelease) - { - gEnv->pCryPak->ClosePack(pLayerPak->filename.c_str(), 0); - //printf("Unload pak from mem: %s\n", pLayerPak->filename.c_str()); - } - else - { - gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_Unload); - //printf("Close pak: %s\n", pLayerPak->filename.c_str()); - } - - m_nTotalOpenLayerPakSize -= pLayerPak->nSize; - } - - if (pLayerPak->pData) - { - assert(pLayerPak->pData->use_count() == 1); - } - - assert((!pLayerPak->pData) || (pLayerPak->pData && pLayerPak->pData->use_count() == 1)); - pLayerPak->pData.reset(); - pLayerPak->eState = SAsyncPak::STATE_UNLOADED; - - m_bRequestLayerUpdate = true; -} - -////////////////////////////////////////////////////////////////////////// - -bool CAsyncPakManager::LoadLayerPak(const char* sLayerName) -{ - // only load layer paks from valid files - TPakMap::iterator findResult = m_paks.find(sLayerName); - if (findResult != m_paks.end()) - { - return LoadPak(findResult->second); - } - - return false; -} - - -bool CAsyncPakManager::LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) -{ - //check if pak reference exists - TPakMap::iterator findResult = m_paks.find(pPath); - if (findResult != m_paks.end()) - { - return LoadPak(findResult->second); - } - else - { - char szFullPathBuf[AZ::IO::IArchive::MaxPath]; - const char* szFullPath = gEnv->pCryPak->AdjustFileName(pPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FLAGS_PATH_REAL); - - // Check if the pak file actually exists before trying to load - if (!gEnv->pCryPak->IsFileExist(szFullPath, AZ::IO::IArchive::eFileLocation_Any)) - { - // Cached file does not exist - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Level cache pak file %s does not exist", szFullPath); - return false; - } - - SAsyncPak layerPak; - layerPak.layername = pPath; - layerPak.filename = szFullPathBuf; - layerPak.nSize = 0; - layerPak.eLifeTime = bLevelLoadOnly ? SAsyncPak::LIFETIME_LOAD_ONLY : SAsyncPak::LIFETIME_LEVEL_COMPLETE; - - m_paks[layerPak.layername] = layerPak; - - return LoadPak(m_paks[layerPak.layername]); - } - return false; -} - -bool CAsyncPakManager::LoadPak(SAsyncPak& layerPak) -{ - layerPak.nRequestCount++; - if (layerPak.eState == SAsyncPak::STATE_LOADED || layerPak.bStreaming || - layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - return true; - } - - layerPak.eState = SAsyncPak::STATE_REQUESTED; - - //printf("Streaming level pak: %s\n", layerPak.layername.c_str()); - - StartStreaming(&layerPak); - - return false; -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::UnloadLayerPak(const char* sLayerName) -{ - TPakMap::iterator findResult = m_paks.find(sLayerName); - if (findResult == m_paks.end()) - { - return; - } - - SAsyncPak& layerPak = findResult->second; - layerPak.nRequestCount--; - assert(layerPak.nRequestCount >= 0); - if (layerPak.nRequestCount > 0) - { - return; - } - - if (layerPak.bStreaming) - { - if (layerPak.pReadStream) - { - layerPak.pReadStream->Abort(); - } - layerPak.eState = SAsyncPak::STATE_REQUESTUNLOAD; - return; - } - - if (layerPak.eState == SAsyncPak::STATE_LOADED) - { - ReleaseData(&layerPak); - m_bRequestLayerUpdate = true; - } - - if (layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - layerPak.eState = SAsyncPak::STATE_UNLOADED; - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::GetLayerPakStats( - SLayerPakStats& stats, bool bCollectAllStats) const -{ - stats.m_MaxSize = (g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE); - stats.m_UsedSize = m_nTotalOpenLayerPakSize; - - for (TPakMap::const_iterator it = m_paks.begin(); it != m_paks.end(); ++it) - { - const SAsyncPak& layerPak = it->second; - if (bCollectAllStats || layerPak.eState != SAsyncPak::STATE_UNLOADED) - { - SLayerPakStats::SEntry entry; - entry.name = it->first; - entry.nSize = layerPak.nSize; - entry.bStreaming = layerPak.bStreaming; - layerPak.GetStatus(entry.status); - - stats.m_entries.push_back(entry); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StreamAsyncOnComplete( - IReadStream* pStream, unsigned nError) -{ - if (nError != 0) - { - return; - } - - SAsyncPak* pLayerPak = (SAsyncPak*) pStream->GetUserData(); - - //Check is pak is already open, if so, just assign mem - if (gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData)) - { - pLayerPak->bPakAlreadyOpen = true; - } - else - { - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, - &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (usePrefabSystemForLevels) - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL); - } - else - { - // - // ugly hack - depending on the pak file pak may need special root info / open flags - // - if (pLayerPak->layername.find("level.pak") != string::npos) - { - gEnv->pCryPak->OpenPack( - {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL); - } - else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos) - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL); - } - else - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, - NULL); - } - } - gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData); - } - - pLayerPak->eState = SAsyncPak::STATE_LOADED; - - //printf("Finished streaming level pak: %s\n", pLayerPak->layername.c_str()); -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StreamOnComplete( - IReadStream* pStream, unsigned nError) -{ - SAsyncPak* pLayerPak = (SAsyncPak*) pStream->GetUserData(); - - if (nError != 0) - { - ReleaseData(pLayerPak); - } - - pLayerPak->bStreaming = false; - pLayerPak->pReadStream = NULL; - - m_bRequestLayerUpdate = true; -} - -void* CAsyncPakManager::StreamOnNeedStorage(IReadStream* pStream, unsigned nSize, bool& bAbortOnFailToAlloc) -{ - SAsyncPak* pAsyncPak = (SAsyncPak*)pStream->GetUserData(); - - pAsyncPak->nSize = nSize; - - if ((m_nTotalOpenLayerPakSize + nSize) > (size_t)(g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE)) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Not enough space to load in memory layer pak %s (Current: %" PRISIZE_T " Required: %d)", - pAsyncPak->filename.c_str(), m_nTotalOpenLayerPakSize, nSize); - - //printf("Not enough space to load in memory layer pak %s (Current: %d Required: %d)\n", pAsyncPak->filename.c_str(), m_nTotalOpenLayerPakSize, nSize); - - pAsyncPak->eState = SAsyncPak::STATE_UNLOADED; - pAsyncPak->bStreaming = false; - pAsyncPak->pReadStream = NULL; - - bAbortOnFailToAlloc = true; - - return NULL; - } - - if (nSize) - { - auto pCryPak = static_cast(gEnv->pCryPak); - - // allocate the data - const char* szUsage = "In Memory Zip File"; - pAsyncPak->pData = pCryPak->PoolAllocMemoryBlock(nSize, szUsage, alignof(uint8_t)); - - m_nTotalOpenLayerPakSize += nSize; - - return pAsyncPak->pData->m_address.get(); - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::Update() -{ - if (!m_bRequestLayerUpdate) - { - return; - } - - m_bRequestLayerUpdate = false; - - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - if (!layerPak.bStreaming) - { - if (layerPak.eState == SAsyncPak::STATE_REQUESTUNLOAD) - { - // done streaming and not interested in it anymore, then release it again - ReleaseData(&layerPak); - } - else if (layerPak.eState == SAsyncPak::STATE_REQUESTED && - (m_nTotalOpenLayerPakSize + layerPak.nSize <= ((size_t)g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE))) - { - // do we have enough memory now to start streaming the pak - StartStreaming(&layerPak); - } - } - } -} - -// Abort streaming jobs and prevent any more requests -// Paks which are loaded remain, they will be cleaned up as usual -void CAsyncPakManager::CancelPendingJobs() -{ - for (TPakMap::iterator it = m_paks.begin(); it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - - if (layerPak.bStreaming) - { - layerPak.pReadStream->Abort(); - ReleaseData(&layerPak); - - //printf("Pak %s Aborted\n", layerPak.filename.c_str()); - } - else if (layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - layerPak.eState = SAsyncPak::STATE_UNLOADED; - ReleaseData(&layerPak); - - //printf("Pak %s Cancelled\n", layerPak.filename.c_str()); - } - } -} - -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/AsyncPakManager.h b/Code/CryEngine/CrySystem/AsyncPakManager.h deleted file mode 100644 index 92a319c73c..0000000000 --- a/Code/CryEngine/CrySystem/AsyncPakManager.h +++ /dev/null @@ -1,116 +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 : Manage async pak files - -#ifndef CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H -#pragma once - -#include -#include -#include - -namespace AZ::IO -{ - struct MemoryBlock; -} - -class CAsyncPakManager - : public IStreamCallback -{ -protected: - - struct SAsyncPak - { - enum EState - { - STATE_UNLOADED, - STATE_REQUESTED, - STATE_REQUESTUNLOAD, - STATE_LOADED, - }; - - enum ELifeTime - { - LIFETIME_LOAD_ONLY, - LIFETIME_LEVEL_COMPLETE, - LIFETIME_PERMANENT - }; - - SAsyncPak() - : nRequestCount(0) - , eState(STATE_UNLOADED) - , eLifeTime(LIFETIME_LOAD_ONLY) - , nSize(0) - , pData(0) - , bStreaming(false) - , bPakAlreadyOpen(false) - , bClosePakOnRelease(false) - , pReadStream(0) {} - - string& GetStatus(string&) const; - - string layername; - string filename; - size_t nSize; - AZStd::intrusive_ptr pData; - EState eState; - ELifeTime eLifeTime; - bool bStreaming; - bool bPakAlreadyOpen; - bool bClosePakOnRelease; - int nRequestCount; - IReadStreamPtr pReadStream; - }; - typedef std::map TPakMap; - -public: - - CAsyncPakManager(); - ~CAsyncPakManager(); - - void ParseLayerPaks(const string& levelCachePath); - - bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly); - void UnloadLevelLoadPaks(); - bool LoadLayerPak(const char* sLayerName); - void UnloadLayerPak(const char* sLayerName); - void CancelPendingJobs(); - - void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const; - - void Clear(); - void Update(); - -protected: - - bool LoadPak(SAsyncPak& layerPak); - - void StartStreaming(SAsyncPak* pLayerPak); - void ReleaseData(SAsyncPak* pLayerPak); - - ////////////////////////////////////////////////////////////////////////// - // IStreamCallback interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); - virtual void StreamOnComplete (IReadStream* pStream, unsigned nError); - virtual void* StreamOnNeedStorage(IReadStream* pStream, unsigned nSize, bool& bAbortOnFailToAlloc); - ////////////////////////////////////////////////////////////////////////// - - TPakMap m_paks; - size_t m_nTotalOpenLayerPakSize; - bool m_bRequestLayerUpdate; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H diff --git a/Code/CryEngine/CrySystem/CrashHandler.rc b/Code/CryEngine/CrySystem/CrashHandler.rc deleted file mode 100644 index 01afa72550..0000000000 --- a/Code/CryEngine/CrySystem/CrashHandler.rc +++ /dev/null @@ -1,114 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CRITICAL_ERROR, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 260 - BOTTOMMARGIN, 223 - END - - IDD_EXCEPTION, DIALOG - BEGIN - END - - IDD_CONFIRM_SAVE_LEVEL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 239 - TOPMARGIN, 7 - BOTTOMMARGIN, 96 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CRITICAL_ERROR DIALOGEX 0, 0, 267, 230 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Critical Exception" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "&Abort",IDB_EXIT,100,207,58,14 - EDITTEXT IDC_CALLSTACK,10,95,245,102,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL - EDITTEXT IDC_EXCEPTION_CODE,10,25,50,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Call Stack Trace",IDC_STATIC,13,85,54,8 - LTEXT "Code",IDC_STATIC,10,15,18,8 - LTEXT "Address:",IDC_STATIC,66,15,28,8 - EDITTEXT IDC_EXCEPTION_ADDRESS,65,25,75,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Description",IDC_STATIC,10,40,36,8 - GROUPBOX "Exception Info",IDC_STATIC,5,5,255,200 - EDITTEXT IDC_EXCEPTION_MODULE,145,25,110,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Module",IDC_STATIC,145,15,24,8 - EDITTEXT IDC_EXCEPTION_DESC,10,50,245,30,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY - PUSHBUTTON "&Ignore",IDB_IGNORE,160,207,59,14,WS_DISABLED -END - -IDD_EXCEPTION DIALOG 0, 0, 138, 52 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Exception" -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Exception Intercepted\r\nRetrieving Info...",IDC_STATIC,33,18,71,19 -END - -IDD_CONFIRM_SAVE_LEVEL DIALOGEX 0, 0, 280, 123 -STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -EXSTYLE WS_EX_TOPMOST -CAPTION "Engine, Game or Editor Crash" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Save",IDB_CONFIRM_SAVE,4,96,68,20 - PUSHBUTTON "Cancel",IDB_DONT_SAVE,206,96,68,20 - LTEXT "Open 3D Engine has encountered an error and needs to close.\n\nA backup has been saved to the '_savebackup' subfolder.\n\nIf you are unable to save your file, you can recover by copying the contents of the _savebackup folder over the broken files.",IDC_STATIC,60,8,210,61 - LTEXT "Attempt save?",IDC_STATIC,60,72,180,21 - CONTROL 128,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE,8,8,48,40 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_CRASH_FACE BITMAP "crash_face.bmp" -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp b/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp deleted file mode 100644 index efc03779de..0000000000 --- a/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp +++ /dev/null @@ -1,155 +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 "CustomMemoryHeap.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CUSTOMMEMORYHEAP_CPP_SECTION_1 1 -#define CUSTOMMEMORYHEAP_CPP_SECTION_2 2 -#define CUSTOMMEMORYHEAP_CPP_SECTION_3 3 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeapBlock::CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap) - : m_pHeap(pHeap) - , m_pData(0) - , m_nSize(0) - , m_nGPUHandle(0) -{ -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeapBlock::~CCustomMemoryHeapBlock() -{ - m_pHeap->DeallocateBlock(this); -} - -////////////////////////////////////////////////////////////////////////// -void* CCustomMemoryHeapBlock::GetData() -{ - return m_pData; -} - -////////////////////////////////////////////////////////////////////////// -void CCustomMemoryHeapBlock::CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) -{ - assert(nOffset + nSize <= m_nSize); - if (nOffset + nSize <= m_nSize) - { - memcpy(pOutputBuffer, (uint8*)m_pData + nOffset, nSize); - } - else - { - CryFatalError("Bad CopyMemoryRegion range"); - } -} - -////////////////////////////////////////////////////////////////////////// -ICustomMemoryBlock* CCustomMemoryHeap::AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment /* = 16 */) -{ - CCustomMemoryHeapBlock* pBlock = new CCustomMemoryHeapBlock(this); - pBlock->m_sUsage = sUsage; - pBlock->m_nSize = nAllocateSize; - - switch (m_eAllocPolicy) - { - case IMemoryManager::eapDefaultAllocator: - { - size_t allocated = 0; - pBlock->m_pData = CryMalloc(nAllocateSize, allocated, nAlignment); - break; - } - case IMemoryManager::eapPageMapped: - pBlock->m_pData = CryMemory::AllocPages(nAllocateSize); - break; - case IMemoryManager::eapCustomAlignment: -#if defined(DEBUG) - if (nAlignment == 0) - { - CryFatalError("CCustomMemoryHeap: trying to allocate memory via eapCustomAlignment with an alignment of zero!"); - } -#endif - pBlock->m_pData = CryModuleMemalign(nAllocateSize, nAlignment); - break; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - default: - CryFatalError("CCustomMemoryHeap: unknown allocation policy during AllocateBlock!"); - break; - } - - CryInterlockedAdd(&m_nAllocatedSize, nAllocateSize); - - return pBlock; -} - -void CCustomMemoryHeap::DeallocateBlock(CCustomMemoryHeapBlock* pBlock) -{ - switch (m_eAllocPolicy) - { - case IMemoryManager::eapDefaultAllocator: - CryFree(pBlock->m_pData, 0); - break; - case IMemoryManager::eapPageMapped: - CryMemory::FreePages(pBlock->m_pData, pBlock->GetSize()); - break; - case IMemoryManager::eapCustomAlignment: - CryModuleMemalignFree(pBlock->m_pData); - break; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - default: - CryFatalError("CCustomMemoryHeap: unknown allocation policy during DeallocateBlock!"); - break; - } - - int nAllocateSize = (int)pBlock->m_nSize; - CryInterlockedAdd(&m_nAllocatedSize, -nAllocateSize); -} - -////////////////////////////////////////////////////////////////////////// -void CCustomMemoryHeap::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->AddObject(this, m_nAllocatedSize); -} - -////////////////////////////////////////////////////////////////////////// -size_t CCustomMemoryHeap::GetAllocated() -{ - return m_nAllocatedSize; -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeap::CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy) -{ - m_nAllocatedSize = 0; - m_eAllocPolicy = eAllocPolicy; - m_nTraceHeapHandle = 0; -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeap::~CCustomMemoryHeap() -{ -} diff --git a/Code/CryEngine/CrySystem/DllMain.cpp b/Code/CryEngine/CrySystem/DllMain.cpp index c3a15812ce..7fd620835b 100644 --- a/Code/CryEngine/CrySystem/DllMain.cpp +++ b/Code/CryEngine/CrySystem/DllMain.cpp @@ -62,46 +62,6 @@ AZ_POP_DISABLE_WARNING } #endif -////////////////////////////////////////////////////////////////////////// -struct CSystemEventListner_System - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_LOAD_START: - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - CryCleanup(); - break; - } - - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - CryCleanup(); - STLALLOCATOR_CLEANUP; - break; - } - } - } -}; - -static CSystemEventListner_System g_system_event_listener_system; - -static AZ::EnvironmentVariable s_cryMemoryManager; - - -// Force the CryMemoryManager into the AZ::Environment for exposure to other DLLs -void ExportCryMemoryManager() -{ - IMemoryManager* cryMemoryManager = nullptr; - CryGetIMemoryManagerInterface((void**)&cryMemoryManager); - AZ_Assert(cryMemoryManager, "Unable to resolve CryMemoryManager"); - s_cryMemoryManager = AZ::Environment::CreateVariable("CryIMemoryManagerInterface", cryMemoryManager); -} - extern "C" { CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupParams) @@ -113,8 +73,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar // Environment should have been attached via InjectEnvironment AZ_Assert(AZ::Environment::IsReady(), "Environment is not attached, must be attached before CreateSystemInterface can be called"); - ExportCryMemoryManager(); - pSystem = new CSystem(startupParams.pSharedEnvironment); ModuleInitISystem(pSystem, "CrySystem"); @@ -146,8 +104,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar return 0; } - pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_system); - return pSystem; } }; diff --git a/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp b/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp deleted file mode 100644 index 22a9fa1793..0000000000 --- a/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp +++ /dev/null @@ -1,188 +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 "GeneralMemoryHeap.h" - -#include -#include - -class GeneralMemoryHeapAllocator - : public AZ::SimpleSchemaAllocator -{ - using Base = AZ::SimpleSchemaAllocator; -public: - static const size_t DEFAULT_ALIGNMENT = sizeof(void*); - - GeneralMemoryHeapAllocator(const char* desc) - : Base("GeneralMemoryHeapAllocator", desc) - { - } - - void Reserve(size_t size) - { - // Allocate a block, then free it, forcing it into the page tree/cache - void* block = m_schema->Allocate(size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, "GeneralMemoryHeapAllocator Reserve", __FILE__, __LINE__); - m_schema->DeAllocate(block); - } -}; - -CGeneralMemoryHeap::CGeneralMemoryHeap([[maybe_unused]] UINT_PTR base, [[maybe_unused]] size_t upperLimit, size_t reserveSize, const char* sUsage) - : m_refCount(0) - , m_block(nullptr) - , m_blockSize(0) -{ - AZ::HphaSchema::Descriptor desc; - desc.m_subAllocator = &AZ::AllocatorInstance::Get(); - m_allocator.reset(new AZ::AllocatorWrapper); - m_allocator->Create(desc, sUsage); - if (reserveSize) - { - (*m_allocator)->Reserve(reserveSize); - } -} - -CGeneralMemoryHeap::CGeneralMemoryHeap(void* base, size_t size, const char* sUsage) - : m_refCount(0) - , m_block(base) - , m_blockSize(size) -{ - AZ::HphaSchema::Descriptor desc; - desc.m_fixedMemoryBlock = base; - desc.m_fixedMemoryBlockByteSize = size; - desc.m_fixedMemoryBlockAlignment = GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT; - m_allocator.reset(new AZ::AllocatorWrapper); - m_allocator->Create(desc, sUsage); -} - -CGeneralMemoryHeap::~CGeneralMemoryHeap() -{ -} - -bool CGeneralMemoryHeap::Cleanup() -{ - (*m_allocator)->GarbageCollect(); - return true; -} - -int CGeneralMemoryHeap::AddRef() -{ - return m_refCount.fetch_add(1); -} - -int CGeneralMemoryHeap::Release() -{ - int nRef = m_refCount.fetch_sub(1); - - if (nRef <= 1) - { - delete this; - } - - return nRef; -} - -void CGeneralMemoryHeap::RecordAlloc(void* ptr, size_t size) -{ - if (m_block == nullptr) - { - m_allocs.emplace(ptr, size); - } -} - -void CGeneralMemoryHeap::RecordFree(void* ptr, size_t size) -{ - if (m_block == nullptr) - { - m_allocs.erase(Alloc(ptr, size)); - } -} - -bool CGeneralMemoryHeap::IsInAddressRange(void* ptr) const -{ - if (m_block) - { - return (static_cast(ptr) - static_cast(m_block)) <= m_blockSize; - } - auto it = m_allocs.find(Alloc(ptr)); - return it != m_allocs.end(); -} - -void* CGeneralMemoryHeap::Calloc(size_t numElements, size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(numElements * size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, sUsage, __FILE__, __LINE__); - memset(ptr, 0, numElements * size); - RecordAlloc(ptr, numElements * size); - return ptr; -} - -void* CGeneralMemoryHeap::Malloc(size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, sUsage, __FILE__, __LINE__); - RecordAlloc(ptr, size); - return ptr; -} - -size_t CGeneralMemoryHeap::Free(void* ptr) -{ - // The client code using these heaps tend to use a guesswork algorithm to freeing - // which involves handing the pointer to every known heap until it frees, so - // it's necessary to validate that the ptr belongs to this heap before attempting to free - if (IsInAddressRange(ptr)) - { - size_t size = (*m_allocator)->AllocationSize(ptr); - RecordFree(ptr, size); - (*m_allocator)->DeAllocate(ptr); - return size; - } - return 0; -} - -void* CGeneralMemoryHeap::Realloc(void* ptr, size_t size, const char* /*sUsage*/) -{ - RecordFree(ptr, (*m_allocator)->AllocationSize(ptr)); - void* newPtr = (*m_allocator)->ReAllocate(ptr, size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT); - RecordAlloc(newPtr, size); - return newPtr; -} - -void* CGeneralMemoryHeap::ReallocAlign(void* ptr, size_t size, size_t alignment, const char* /*sUsage*/) -{ - RecordFree(ptr, (*m_allocator)->AllocationSize(ptr)); - void* newPtr = (*m_allocator)->ReAllocate(ptr, size, alignment); - RecordAlloc(newPtr, size); - return newPtr; -} - -void* CGeneralMemoryHeap::Memalign(size_t boundary, size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(size, boundary, 0, sUsage, __FILE__, __LINE__); - RecordAlloc(ptr, size); - return ptr; -} - -size_t CGeneralMemoryHeap::UsableSize(void* ptr) const -{ - // The client code using these heaps tend to use a guesswork algorithm to determine - // which heap owns the pointer. Calls to UsableSize() are a part of this guesswork. - // The overrun detector doesn't play nicely on AllocationSize() lookups for pointers that - // don't belong to the heap, so validate that we're in the correct address range before trying - // to look up the size. - return IsInAddressRange(ptr) ? (*m_allocator)->AllocationSize(ptr) : 0; -} - -AZ::IAllocator* CGeneralMemoryHeap::GetAllocator() const -{ - return m_allocator->Get(); -} diff --git a/Code/CryEngine/CrySystem/GeneralMemoryHeap.h b/Code/CryEngine/CrySystem/GeneralMemoryHeap.h deleted file mode 100644 index a09556055d..0000000000 --- a/Code/CryEngine/CrySystem/GeneralMemoryHeap.h +++ /dev/null @@ -1,94 +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_GENERALMEMORYHEAP_H -#define CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H -#pragma once - - -#include "IMemory.h" -#include -#include -#include - -class GeneralMemoryHeapAllocator; - -class CGeneralMemoryHeap - : public IGeneralMemoryHeap -{ - struct Alloc - { - void* m_base; - size_t m_size; - - Alloc(void* base = nullptr, size_t size = 0) - : m_base(base) - , m_size(size) - {} - - bool operator==(const Alloc& rhs) const - { - // size doesn't matter - return m_base == rhs.m_base; - } - - bool operator<(const Alloc& rhs) const - { - // this will cause allocs to be sorted by address - return m_base < rhs.m_base; - } - }; - -public: - // Create a heap that will map/unmap pages in the range [baseAddress, baseAddress + upperLimit). - CGeneralMemoryHeap(UINT_PTR baseAddress, size_t upperLimit, size_t reserveSize, const char* sUsage); - - // Create a heap that will assumes all memory in the range [base, base + size) is already mapped. - CGeneralMemoryHeap(void* base, size_t size, const char* sUsage); - - ~CGeneralMemoryHeap(); - -public: // IGeneralMemoryHeap Members - bool Cleanup(); - - int AddRef(); - int Release(); - - bool IsInAddressRange(void* ptr) const; - - void* Calloc(size_t nmemb, size_t size, const char* sUsage = NULL); - void* Malloc(size_t sz, const char* sUsage = NULL); - size_t Free(void* ptr); - void* Realloc(void* ptr, size_t sz, const char* sUsage = NULL); - void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage = NULL); - void* Memalign(size_t boundary, size_t size, const char* sUsage = NULL); - size_t UsableSize(void* ptr) const; - - AZ::IAllocator* GetAllocator() const override; - -private: - CGeneralMemoryHeap(const CGeneralMemoryHeap&) = delete; - CGeneralMemoryHeap& operator = (const CGeneralMemoryHeap&) = delete; - - void RecordAlloc(void* ptr, size_t size); - void RecordFree(void* ptr, size_t size); - -private: - AZStd::unique_ptr> m_allocator; - AZStd::atomic_int m_refCount; - void* m_block; - size_t m_blockSize; - AZStd::set, AZ::AZStdAlloc> m_allocs; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H diff --git a/Code/CryEngine/CrySystem/ImageHandler.cpp b/Code/CryEngine/CrySystem/ImageHandler.cpp deleted file mode 100644 index 7444aebdc0..0000000000 --- a/Code/CryEngine/CrySystem/ImageHandler.cpp +++ /dev/null @@ -1,280 +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 -#include "ImageHandler.h" -#include -#include "ScopeGuard.h" -#include "Algorithm.h" -#include "System.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ImageHandler_cpp) -#endif - -#if !(defined(ANDROID) || defined(IOS) || defined(LINUX)) && AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO // Rally US1050 - Compile libtiff for Android and IOS - #include - -static_assert(sizeof(thandle_t) >= sizeof(AZ::IO::HandleType), "Platform defines thandle_t to be smaller than required"); -#endif - -namespace -{ - class Image - : public IImageHandler::IImage - { - public: - Image(std::vector&& data, int width, int height) - { - CRY_ASSERT(data.size() == width * height * ImageHandler::c_BytesPerPixel); - m_data = std::move(data); - m_width = width; - m_height = height; - } - private: - virtual const std::vector& GetData() const override { return m_data; } - virtual int GetWidth() const override { return m_width; } - virtual int GetHeight() const override { return m_height; } - - unsigned int m_width; - unsigned int m_height; - std::vector m_data; - }; -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - struct TiffIO - { - static tsize_t Read(thandle_t handle, tdata_t buffer, tsize_t size) - { - AZ::u64 bytesRead = 0; - AZ::IO::FileIOBase::GetDirectInstance()->Read(static_cast(reinterpret_cast(handle)), buffer, size, false, &bytesRead); - return static_cast(bytesRead); - }; - - static tsize_t Write(thandle_t handle, tdata_t buffer, tsize_t size) - { - AZ::u64 sizeWritten; - if (AZ::IO::FileIOBase::GetDirectInstance()->Write(static_cast(reinterpret_cast(handle)), buffer, size, &sizeWritten)) - { - return static_cast(sizeWritten); - } - else - { - return 0; - } - }; - - static int Close(thandle_t handle) - { - AZ::IO::FileIOBase::GetDirectInstance()->Close(static_cast(reinterpret_cast(handle))); - return 0; - }; - - static toff_t Seek(thandle_t handle, toff_t pos, int mode) - { - if (AZ::IO::FileIOBase::GetDirectInstance()->Seek(static_cast(reinterpret_cast(handle)), static_cast(pos), AZ::IO::GetSeekTypeFromFSeekMode(mode))) - { - if (mode == SEEK_SET) - { - return pos; - } - else - { - AZ::u64 offsetFromBegin; - if (AZ::IO::FileIOBase::GetDirectInstance()->Tell(static_cast(reinterpret_cast(handle)), offsetFromBegin)) - { - return static_cast(offsetFromBegin); - } - else - { - return -1; - } - } - } - return -1; - }; - - static toff_t Size(thandle_t handle) - { - AZ::u64 fileSize = 0; - AZ::IO::FileIOBase::GetDirectInstance()->Size(static_cast(reinterpret_cast(handle)), fileSize); - return static_cast(fileSize); - }; - - static int Map(thandle_t, tdata_t*, toff_t*) - { - return 0; - }; - - static void Unmap(thandle_t, tdata_t, toff_t) - { - return; - }; - }; -#endif -} - -std::unique_ptr ImageHandler::CreateImage(std::vector&& data, int width, int height) const -{ - return std::make_unique(std::move(data), width, height); -} - -std::unique_ptr ImageHandler::LoadImage([[maybe_unused]] const char* filename) const -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - - AZ::IO::HandleType fileHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode("rb"), fileHandle); - - if (fileHandle == AZ::IO::InvalidHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to open image file %s", filename); - return nullptr; - } - - auto tifHandle = std17::unique_resource_checked(TIFFClientOpen(filename, "rb", reinterpret_cast(static_cast(fileHandle)), TiffIO::Read, TiffIO::Write, TiffIO::Seek, TiffIO::Close, &TiffIO::Size, TiffIO::Map, TiffIO::Unmap), (TIFF*)nullptr, TIFFClose); - if (!tifHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load image %s", filename); - return nullptr; - } - - int width = 0; - int height = 0; - TIFFGetField(tifHandle, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tifHandle, TIFFTAG_IMAGELENGTH, &height); - std::vector data(4 * width * height); - if (!TIFFReadRGBAImageOriented(tifHandle, width, height, reinterpret_cast(data.data()), ORIENTATION_TOPLEFT)) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load image %s", filename); - return nullptr; - } - - //strip alpha - int every4th = 0; - data.erase(std::remove_if(begin(data), end(data), [&](unsigned char) - { - return (every4th++ & 3) == 3; - }), end(data)); - - return std::make_unique(std::move(data), width, height); -#else - CRY_ASSERT(0); // UNIMPLEMENTED - return nullptr; -#endif -} - -bool ImageHandler::SaveImage([[maybe_unused]] IImageHandler::IImage* image, [[maybe_unused]] const char* filename) const -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - - AZ::IO::HandleType fileHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode("wb"), fileHandle); - - if (fileHandle == AZ::IO::InvalidHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to open image file for write %s", filename); - return false; - } - - auto tifHandle = std17::unique_resource_checked(TIFFClientOpen(filename, "wb", reinterpret_cast(static_cast(fileHandle)), TiffIO::Read, TiffIO::Write, TiffIO::Seek, TiffIO::Close, &TiffIO::Size, TiffIO::Map, TiffIO::Unmap), (TIFF*)nullptr, TIFFClose); - if (!tifHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to save image %s", filename); - return false; - } - - TIFFSetField(tifHandle, TIFFTAG_IMAGEWIDTH, image->GetWidth()); - TIFFSetField(tifHandle, TIFFTAG_IMAGELENGTH, image->GetHeight()); - TIFFSetField(tifHandle, TIFFTAG_SAMPLESPERPIXEL, c_BytesPerPixel); - TIFFSetField(tifHandle, TIFFTAG_BITSPERSAMPLE, 8); - TIFFSetField(tifHandle, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(tifHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(tifHandle, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField(tifHandle, TIFFTAG_COMPRESSION, COMPRESSION_LZW); - - tsize_t bytesPerLine = c_BytesPerPixel * image->GetWidth(); - std::vector lineBuffer; - if (TIFFScanlineSize(tifHandle) != bytesPerLine) - { - lineBuffer.resize(bytesPerLine); - } - else - { - lineBuffer.resize(TIFFScanlineSize(tifHandle)); - } - TIFFSetField(tifHandle, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tifHandle, image->GetWidth() * c_BytesPerPixel)); - auto srcData = image->GetData().data(); - - for (uint32 row = 0; row < image->GetHeight(); row++) - { - memcpy(lineBuffer.data(), &srcData[row * bytesPerLine], bytesPerLine); - if (TIFFWriteScanline(tifHandle, lineBuffer.data(), row, 0) < 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Failed to write part of image %s", filename); - return false; - } - } - - return true; -#else - CRY_ASSERT(0); // UNIMPLEMENTED - return false; -#endif -} - -std::unique_ptr ImageHandler::CreateDiffImage(IImageHandler::IImage* image1, IImageHandler::IImage* image2) const -{ - if (!image1 || !image2) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, null arguments"); - return nullptr; - } - if (image1->GetWidth() != image2->GetWidth() || image1->GetHeight() != image2->GetHeight()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, 2 images were not the same size"); - return nullptr; - } - CRY_ASSERT(image1->GetData().size() == image1->GetWidth() * image1->GetHeight() * ImageHandler::c_BytesPerPixel); - CRY_ASSERT(image2->GetData().size() == image2->GetWidth() * image2->GetHeight() * ImageHandler::c_BytesPerPixel); - - std::vector resultRGBData; - - auto iter1 = image1->GetData().data(); - auto iter2 = image2->GetData().data(); - for (int i = 0; i < image1->GetWidth() * image1->GetHeight() * c_BytesPerPixel; ++i) - { - resultRGBData.push_back(static_cast(abs(static_cast(iter1[i]) - static_cast(iter2[i])))); - } - - return std::make_unique(std::move(resultRGBData), image1->GetWidth(), image1->GetHeight()); -} - -float ImageHandler::CalculatePSNR(IImageHandler::IImage* diffIimage) const -{ - if (!diffIimage) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, null arguments"); - return 0; - } - CRY_ASSERT(diffIimage->GetData().size() == diffIimage->GetWidth() * diffIimage->GetHeight() * ImageHandler::c_BytesPerPixel); - - auto mse = std17::accumulate(diffIimage->GetData(), 0.0, [](double result, unsigned char value) -> double { return result += (double)value * (double)value; }); - mse /= (c_BytesPerPixel * diffIimage->GetWidth() * diffIimage->GetHeight()); - - if (mse <= 0) - { - return std::numeric_limits::max(); - } - - // see http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio for a derivation of this formula and source for magic numbers - return static_cast(20 * log10(255) - 10 * log10(mse)); -} diff --git a/Code/CryEngine/CrySystem/ImageHandler.h b/Code/CryEngine/CrySystem/ImageHandler.h deleted file mode 100644 index bba596a266..0000000000 --- a/Code/CryEngine/CrySystem/ImageHandler.h +++ /dev/null @@ -1,30 +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. -* -*/ -#pragma once -#ifndef CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H - -#include "IImageHandler.h" - -class ImageHandler - : public IImageHandler -{ -public: - static const int c_BytesPerPixel = 3; //This only deals with RGB data for now, no alpha -private: - virtual std::unique_ptr CreateImage(std::vector&& rgbData, int width, int height) const override; - virtual std::unique_ptr LoadImage(const char* filename) const override; - virtual bool SaveImage(IImageHandler::IImage* image, const char* filename) const override; - virtual std::unique_ptr CreateDiffImage(IImageHandler::IImage* image1, IImageHandler::IImage* image2) const override; - virtual float CalculatePSNR(IImageHandler::IImage* diffIimage) const override; -}; -#endif // CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H diff --git a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp index 0af52d8cc4..8d9c0dd8e8 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp @@ -17,7 +17,6 @@ #include "LevelSystem.h" #include #include "IMovieSystem.h" -#include #include #include "CryPath.h" #include @@ -778,9 +777,6 @@ void CLevelSystem::PrepareNextLevel(const char* levelName) // switched to level heap, so now imm start the loading screen (renderer will be reinitialized in the levelheap) gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN, 0, 0); gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PREPARE); - - // Inform resource manager about loading of the new level. - GetISystem()->GetIResourceManager()->PrepareLevel(pLevelInfo->GetPath(), pLevelInfo->GetName()); } for (AZStd::vector::const_iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) @@ -987,8 +983,6 @@ void CLevelSystem::UnloadLevel() m_lastLevelName.clear(); - GetISystem()->GetIResourceManager()->UnloadLevel(); - SAFE_RELEASE(m_pCurrentLevel); // Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed). diff --git a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp index 8b3c75cce2..ff6ebc0d17 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp @@ -14,7 +14,6 @@ #include "SpawnableLevelSystem.h" #include #include "IMovieSystem.h" -#include #include @@ -566,8 +565,6 @@ namespace LegacyLevelSystem m_lastLevelName.clear(); - GetISystem()->GetIResourceManager()->UnloadLevel(); - // Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed). // 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); diff --git a/Code/CryEngine/CrySystem/Log.cpp b/Code/CryEngine/CrySystem/Log.cpp index c51947d8bc..63aee4422f 100644 --- a/Code/CryEngine/CrySystem/Log.cpp +++ b/Code/CryEngine/CrySystem/Log.cpp @@ -20,7 +20,6 @@ //this should not be included here #include #include -#include #include "System.h" #include "CryPath.h" // PathUtil::ReplaceExtension() #include @@ -1439,22 +1438,6 @@ void CLog::UpdateLoadingScreen(const char* szFormat, ...) va_end(args); } #endif - - if (CryGetCurrentThreadId() == m_nMainThreadId) - { -#ifndef LINUX - // Take this opportunity to update streaming engine. - if (IStreamEngine* pStreamEngine = GetISystem()->GetStreamEngine()) - { - const float curTime = m_pSystem->GetITimer()->GetAsyncCurTime(); - if (curTime - m_fLastLoadingUpdateTime > .1f) // not frequent than once in 100ms - { - m_fLastLoadingUpdateTime = curTime; - pStreamEngine->Update(); - } - } -#endif - } } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/MTSafeAllocator.cpp b/Code/CryEngine/CrySystem/MTSafeAllocator.cpp deleted file mode 100644 index 7d9c08d3c4..0000000000 --- a/Code/CryEngine/CrySystem/MTSafeAllocator.cpp +++ /dev/null @@ -1,163 +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 "MTSafeAllocator.h" -#include - -extern CMTSafeHeap* g_pPakHeap; - -// Uncomment this define to enable time tracing of the MTSAFE heap -#define MTSAFE_PROFILE 1 -//#undef MTSAFE_PROFILE - -namespace -{ - class CSimpleTimer - { - LARGE_INTEGER& m_result; - LARGE_INTEGER m_start; - public: - - CSimpleTimer(LARGE_INTEGER& li) - : m_result(li) - { QueryPerformanceCounter(&m_start); } - - ~CSimpleTimer() - { - LARGE_INTEGER end; - QueryPerformanceCounter(&end); - m_result.QuadPart = end.QuadPart - m_start.QuadPart; - } - }; -}; - -////////////////////////////////////////////////////////////////////////// -CMTSafeHeap::CMTSafeHeap() - : m_LiveTempAllocations() - , m_TotalAllocations() - , m_TempAllocationsFailed() - , m_TempAllocationsTime() -{ - size_t allocated = 0; - m_pGeneralHeapStorage = (char*)CryMalloc(MTSAFE_GENERAL_HEAP_SIZE, allocated, MTSAFE_DEFAULT_ALIGNMENT); - m_pGeneralHeapStorageEnd = m_pGeneralHeapStorage + MTSAFE_GENERAL_HEAP_SIZE; - m_pGeneralHeap = CryGetIMemoryManager()->CreateGeneralMemoryHeap(m_pGeneralHeapStorage, MTSAFE_GENERAL_HEAP_SIZE, "MTSafeHeap"); -} - -////////////////////////////////////////////////////////////////////////// -CMTSafeHeap::~CMTSafeHeap() -{ - SAFE_RELEASE(m_pGeneralHeap); - CryFree(m_pGeneralHeapStorage, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -size_t CMTSafeHeap::PersistentAllocSize(size_t nSize) -{ - return nSize; -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::PersistentAlloc(size_t nSize) -{ - size_t allocated = 0; - return CryMalloc(nSize, allocated, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::FreePersistent(void* p) -{ - CryFree(p, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::TempAlloc(size_t nSize, const char* szDbgSource, bool& bFallBackToMalloc, uint32 align) -{ -# if MTSAFE_PROFILE - CSimpleTimer timer(m_TempAllocationsTime); -# endif - - void* ptr = NULL; - if (align) - { - ptr = m_pGeneralHeap->Memalign(align, nSize, szDbgSource); - } - else - { - ptr = m_pGeneralHeap->Malloc(nSize, szDbgSource); - } - - //explicit alignment not supported beyond this point, safer to return NULL - if (ptr || !bFallBackToMalloc) - { - bFallBackToMalloc = false; - return ptr; - } - - bFallBackToMalloc = true; - -# if MTSAFE_PROFILE - CryInterlockedAdd((volatile int*)&m_TempAllocationsFailed, (int)nSize); -# endif - - return CryModuleMemalign(nSize, align > 0 ? align : MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::FreeTemporary(void* p) -{ -# if MTSAFE_PROFILE - CSimpleTimer timer(m_TempAllocationsTime); -# endif - - if (m_pGeneralHeap->IsInAddressRange(p)) - { - m_pGeneralHeap->Free(p); - return; - } - - // Fallback to free - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::StaticAlloc([[maybe_unused]] void* pOpaque, unsigned nItems, unsigned nSize) -{ - return g_pPakHeap->TempAlloc(nItems * nSize, "StaticAlloc"); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::StaticFree ([[maybe_unused]] void* pOpaque, void* pAddress) -{ - g_pPakHeap->FreeTemporary(pAddress); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::GetMemoryUsage(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "FileSystem Pool"); -} - -void CMTSafeHeap::PrintStats() -{ -# if MTSAFE_PROFILE - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - const double rFreq = 1. / static_cast(freq.QuadPart); - - CryLogAlways("mtsafe temporary pool failed for %" PRISIZE_T " bytes, time spent in allocations %3.08f seconds", - m_TempAllocationsFailed, static_cast(m_TempAllocationsTime.QuadPart) * rFreq); -# endif -} - diff --git a/Code/CryEngine/CrySystem/MTSafeAllocator.h b/Code/CryEngine/CrySystem/MTSafeAllocator.h deleted file mode 100644 index eeee5ff501..0000000000 --- a/Code/CryEngine/CrySystem/MTSafeAllocator.h +++ /dev/null @@ -1,108 +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 - - -#if defined(LINUX) -# include "Linux_Win32Wrapper.h" -#endif -#include - -//////////////////////////////////////////////////////////////////////////////// -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(MTSafeAllocator_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(MOBILE) // IOS/Android -# define MTSAFE_DEFAULT_ALIGNMENT 8 -# define MTSAFE_GENERAL_HEAP_SIZE ((1U << 20) + (1U << 19)) -#elif defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(MAC) -# define MTSAFE_GENERAL_HEAP_SIZE (12U << 20) -# define MTSAFE_DEFAULT_ALIGNMENT 8 -#else -# error Unknown target platform -#endif - -class CMTSafeHeap -{ -public: - // Constructor - CMTSafeHeap(); - - // Destructor - ~CMTSafeHeap(); - - // Performs a persisistent (in other words, non-temporary) allocation. - void* PersistentAlloc(size_t nSize); - - // Retrieves system memory allocation size for any call to PersistentAlloc. - // Required to not count virtual memory usage inside CrySizer - size_t PersistentAllocSize(size_t nSize); - - // Frees memory allocation - void FreePersistent(void* p); - - // Perform a allocation that is considered temporary and will be handled by - // the pool itself. - // Note: It is important that these temporary allocations are actually - // temporary and do not persist for a long persiod of time. - void* TempAlloc (size_t nSize, const char* szDbgSource, uint32 align = 0) - { - bool bFallbackToMalloc = true; - return TempAlloc(nSize, szDbgSource, bFallbackToMalloc, align); - } - - void* TempAlloc (size_t nSize, const char* szDbgSource, bool& bFallBackToMalloc, uint32 align = 0); - - bool IsInGeneralHeap(const void* p) - { - return m_pGeneralHeapStorage <= p && p < m_pGeneralHeapStorageEnd; - } - - // Free a temporary allocaton. - void FreeTemporary(void* p); - - // The number of live allocations allocation within the temporary pool - size_t NumAllocations() const { return m_LiveTempAllocations; } - - // The memory usage of the mtsafe allocator - void GetMemoryUsage(ICrySizer* pSizer); - - // zlib-compatible stubs - static void* StaticAlloc (void* pOpaque, unsigned nItems, unsigned nSize); - static void StaticFree (void* pOpaque, void* pAddress); - - // Dump some statistics to the cry log - void PrintStats(); - - -private: - friend class CSystem; - - IGeneralMemoryHeap* m_pGeneralHeap; - char* m_pGeneralHeapStorage; - char* m_pGeneralHeapStorageEnd; - - // The number of temporary allocations currently active within the pool - size_t m_LiveTempAllocations; - - // The total number of allocations performed in the pool - size_t m_TotalAllocations; - - // The total bytes that weren't temporarily allocated - size_t m_TempAllocationsFailed; - // The total number of temporary allocations that fell back to global system memory - LARGE_INTEGER m_TempAllocationsTime; -}; diff --git a/Code/CryEngine/CrySystem/MemoryAddressRange.cpp b/Code/CryEngine/CrySystem/MemoryAddressRange.cpp deleted file mode 100644 index bb547d80cc..0000000000 --- a/Code/CryEngine/CrySystem/MemoryAddressRange.cpp +++ /dev/null @@ -1,145 +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 "MemoryAddressRange.h" -#include "System.h" - -#if defined(APPLE) || defined(LINUX) -#include -#endif - -CMemoryAddressRange::CMemoryAddressRange(char* pBaseAddress, size_t nPageSize, size_t nPageCount, [[maybe_unused]] const char* sName) - : m_pBaseAddress(pBaseAddress) - , m_nPageSize(nPageSize) - , m_nPageCount(nPageCount) -{ -} - -void CMemoryAddressRange::Release() -{ - delete this; -} - -char* CMemoryAddressRange::GetBaseAddress() const -{ - return m_pBaseAddress; -} - -size_t CMemoryAddressRange::GetPageCount() const -{ - return m_nPageCount; -} - -size_t CMemoryAddressRange::GetPageSize() const -{ - return m_nPageSize; -} - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_MEMADDRESSRANGE_WINDOWS_STYLE - -void* CMemoryAddressRange::ReserveSpace(size_t capacity) -{ - return VirtualAlloc(NULL, capacity, MEM_RESERVE, PAGE_READWRITE); -} - -size_t CMemoryAddressRange::GetSystemPageSize() -{ - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -} - -CMemoryAddressRange::CMemoryAddressRange(size_t capacity, [[maybe_unused]] const char* name) -{ - m_nPageSize = GetSystemPageSize(); - - size_t algnCap = Align(capacity, m_nPageSize); - m_pBaseAddress = (char*)ReserveSpace(algnCap); - m_nPageCount = algnCap / m_nPageSize; -} - -CMemoryAddressRange::~CMemoryAddressRange() -{ - VirtualFree(m_pBaseAddress, 0, MEM_RELEASE); -} - -void* CMemoryAddressRange::MapPage(size_t pageIdx) -{ - void* pRet = VirtualAlloc(m_pBaseAddress + pageIdx * m_nPageSize, m_nPageSize, MEM_COMMIT, PAGE_READWRITE); - return pRet; -} - -void CMemoryAddressRange::UnmapPage(size_t pageIdx) -{ - char* pBase = m_pBaseAddress + pageIdx * m_nPageSize; - - // Disable warning about only decommitting pages, and not releasing them - VirtualFree(pBase, m_nPageSize, MEM_DECOMMIT); -} - -#elif defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(MemoryAddressRange_cpp) -#elif defined(APPLE) || defined(LINUX) - -void* CMemoryAddressRange::ReserveSpace(size_t capacity) -{ - return mmap(0, capacity, PROT_NONE, MAP_ANON | MAP_NORESERVE | MAP_PRIVATE, -1, 0); -} - -size_t CMemoryAddressRange::GetSystemPageSize() -{ - return sysconf(_SC_PAGESIZE); -} - -CMemoryAddressRange::CMemoryAddressRange(size_t capacity, const char* name) -{ - m_nPageSize = GetSystemPageSize(); - - m_allocatedSpace = Align(capacity, m_nPageSize); - m_pBaseAddress = (char*)ReserveSpace(m_allocatedSpace); - assert(m_pBaseAddress != MAP_FAILED); - m_nPageCount = m_allocatedSpace / m_nPageSize; -} - -CMemoryAddressRange::~CMemoryAddressRange() -{ - int ret = munmap(m_pBaseAddress, m_allocatedSpace); - (void) ret; - assert(ret == 0); -} - -void* CMemoryAddressRange::MapPage(size_t pageIdx) -{ - // There is no equivalent to this function with mmap, this - // happens automatically in the OS. We just return the - // correct address. - void* pRet = NULL; - if (0 == mprotect(m_pBaseAddress + (pageIdx * m_nPageSize), m_nPageSize, PROT_READ | PROT_WRITE)) - { - pRet = m_pBaseAddress + (pageIdx * m_nPageSize); - } - - return pRet; -} - -void CMemoryAddressRange::UnmapPage(size_t pageIdx) -{ - char* pBase = m_pBaseAddress + pageIdx * m_nPageSize; - int ret = mprotect(pBase, m_nPageSize, PROT_NONE); - (void) ret; - assert(ret == 0); -} - - -#endif diff --git a/Code/CryEngine/CrySystem/MemoryAddressRange.h b/Code/CryEngine/CrySystem/MemoryAddressRange.h deleted file mode 100644 index b2679f6667..0000000000 --- a/Code/CryEngine/CrySystem/MemoryAddressRange.h +++ /dev/null @@ -1,61 +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_MEMORYADDRESSRANGE_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H -#pragma once - - -#include "IMemory.h" - -class CMemoryAddressRange - : public IMemoryAddressRange -{ -public: - static void* ReserveSpace(size_t sz); - static size_t GetSystemPageSize(); - -public: - CMemoryAddressRange(char* pBaseAddress, size_t nPageSize, size_t nPageCount, const char* sName); - CMemoryAddressRange(size_t capacity, const char* name); - ~CMemoryAddressRange(); - - ILINE bool IsInRange(void* p) const - { - return m_pBaseAddress <= p && p < (m_pBaseAddress + m_nPageSize * m_nPageCount); - } - -public: - void Release(); - - char* GetBaseAddress() const; - size_t GetPageCount() const; - size_t GetPageSize() const; - - void* MapPage(size_t pageIdx); - void UnmapPage(size_t pageIdx); - -private: - CMemoryAddressRange(const CMemoryAddressRange&); - CMemoryAddressRange& operator = (const CMemoryAddressRange&); - -private: - char* m_pBaseAddress; - size_t m_nPageSize; - size_t m_nPageCount; -#if defined(APPLE) || defined(LINUX) - size_t m_allocatedSpace; // Required to unmap latter on -#endif -}; - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H diff --git a/Code/CryEngine/CrySystem/MemoryManager.cpp b/Code/CryEngine/CrySystem/MemoryManager.cpp deleted file mode 100644 index 3021d68539..0000000000 --- a/Code/CryEngine/CrySystem/MemoryManager.cpp +++ /dev/null @@ -1,226 +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 "MemoryManager.h" -#include "platform.h" -#include "CustomMemoryHeap.h" -#include "GeneralMemoryHeap.h" -#include "PageMappingHeap.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define MEMORYMANAGER_CPP_SECTION_1 1 -#endif - -#if defined(WIN32) - #define WIN32_LEAN_AND_MEAN - #include - #include -#endif - -#if defined(APPLE) -#include // task_info -#endif - -#if defined(APPLE) || defined(LINUX) -#include // required by mman.h -#include //mmap - virtual memory manager -#endif - -#ifdef MEMMAN_STATIC -CCryMemoryManager g_memoryManager; -#endif - -////////////////////////////////////////////////////////////////////////// -CCryMemoryManager* CCryMemoryManager::GetInstance() -{ -#ifdef MEMMAN_STATIC - return &g_memoryManager; -#else - static CCryMemoryManager memman; - return &memman; -#endif -} - -////////////////////////////////////////////////////////////////////////// -bool CCryMemoryManager::GetProcessMemInfo(SProcessMemInfo& minfo) -{ - ZeroStruct(minfo); -#if defined(WIN32) - - MEMORYSTATUSEX mem; - mem.dwLength = sizeof(mem); - GlobalMemoryStatusEx (&mem); - - minfo.TotalPhysicalMemory = mem.ullTotalPhys; - minfo.FreePhysicalMemory = mem.ullAvailPhys; - - ////////////////////////////////////////////////////////////////////////// - typedef BOOL (WINAPI * GetProcessMemoryInfoProc)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD); - - PROCESS_MEMORY_COUNTERS pc; - ZeroStruct(pc); - pc.cb = sizeof(pc); - static HMODULE hPSAPI = LoadLibraryA("psapi.dll"); - if (hPSAPI) - { - static GetProcessMemoryInfoProc pGetProcessMemoryInfo = (GetProcessMemoryInfoProc)GetProcAddress(hPSAPI, "GetProcessMemoryInfo"); - if (pGetProcessMemoryInfo) - { - if (pGetProcessMemoryInfo(GetCurrentProcess(), &pc, sizeof(pc))) - { - minfo.PageFaultCount = pc.PageFaultCount; - minfo.PeakWorkingSetSize = pc.PeakWorkingSetSize; - minfo.WorkingSetSize = pc.WorkingSetSize; - minfo.QuotaPeakPagedPoolUsage = pc.QuotaPeakPagedPoolUsage; - minfo.QuotaPagedPoolUsage = pc.QuotaPagedPoolUsage; - minfo.QuotaPeakNonPagedPoolUsage = pc.QuotaPeakNonPagedPoolUsage; - minfo.QuotaNonPagedPoolUsage = pc.QuotaNonPagedPoolUsage; - minfo.PagefileUsage = pc.PagefileUsage; - minfo.PeakPagefileUsage = pc.PeakPagefileUsage; - - return true; - } - } - } - return false; - -#else - -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION MEMORYMANAGER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(MemoryManager_cpp) -#endif - - bool retVal = true; - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(LINUX) - - MEMORYSTATUS MemoryStatus; - GlobalMemoryStatus(&MemoryStatus); - minfo.PagefileUsage = minfo.PeakPagefileUsage = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; - - minfo.FreePhysicalMemory = MemoryStatus.dwAvailPhys; - minfo.TotalPhysicalMemory = MemoryStatus.dwTotalPhys; - -#if defined(ANDROID) - // On Android, mallinfo() is an EXTREMELY time consuming operation. Nearly 80% CPU time will be spent - // on this operation once -memreplay is given. Since WorkingSetSize is only used for statistics and - // debugging purpose, it's simply ignored. - minfo.WorkingSetSize = 0; -#else - struct mallinfo meminfo = mallinfo(); - minfo.WorkingSetSize = meminfo.usmblks + meminfo.uordblks; -#endif - -#elif defined(APPLE) - - MEMORYSTATUS MemoryStatus; - GlobalMemoryStatus(&MemoryStatus); - minfo.PagefileUsage = minfo.PeakPagefileUsage = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; - - minfo.FreePhysicalMemory = MemoryStatus.dwAvailPhys; - minfo.TotalPhysicalMemory = MemoryStatus.dwTotalPhys; - - // Retrieve WorkingSetSize from task_info - task_basic_info kTaskInfo; - mach_msg_type_number_t uInfoCount(sizeof(kTaskInfo) / sizeof(natural_t)); - if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&kTaskInfo, &uInfoCount) != 0) - { - gEnv->pLog->LogError("task_info failed\n"); - return false; - } - minfo.WorkingSetSize = kTaskInfo.resident_size; - -#else - - retVal = false; - -#endif - - return retVal; -#endif -} - -////////////////////////////////////////////////////////////////////////// -CCryMemoryManager::HeapHandle CCryMemoryManager::TraceDefineHeap([[maybe_unused]] const char* heapName, [[maybe_unused]] size_t size, [[maybe_unused]] const void* pBase) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapAlloc([[maybe_unused]] HeapHandle heap, [[maybe_unused]] void* mem, [[maybe_unused]] size_t size, [[maybe_unused]] size_t blockSize, [[maybe_unused]] const char* sUsage, [[maybe_unused]] const char* sNameHint) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapFree([[maybe_unused]] HeapHandle heap, [[maybe_unused]] void* mem, [[maybe_unused]] size_t blockSize) -{ -} - - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapSetColor([[maybe_unused]] uint32 color) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapSetLabel([[maybe_unused]] const char* sLabel) -{ -} - -////////////////////////////////////////////////////////////////////////// -uint32 CCryMemoryManager::TraceHeapGetColor() -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -ICustomMemoryHeap* const CCryMemoryManager::CreateCustomMemoryHeapInstance(IMemoryManager::EAllocPolicy const eAllocPolicy) -{ - return new CCustomMemoryHeap(eAllocPolicy); -} - -IGeneralMemoryHeap* CCryMemoryManager::CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) -{ - return new CGeneralMemoryHeap(static_cast(0), upperLimit, reserveSize, sUsage); -} - -IGeneralMemoryHeap* CCryMemoryManager::CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) -{ - return new CGeneralMemoryHeap(base, sz, sUsage); -} - -IMemoryAddressRange* CCryMemoryManager::ReserveAddressRange(size_t capacity, const char* sName) -{ - return new CMemoryAddressRange(capacity, sName); -} - -IPageMappingHeap* CCryMemoryManager::CreatePageMappingHeap(size_t addressSpace, const char* sName) -{ - return new CPageMappingHeap(addressSpace, sName); -} - -extern "C" -{ - CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager) - { - // Static instance of the memory manager - *pIMemoryManager = CCryMemoryManager::GetInstance(); - } -}; diff --git a/Code/CryEngine/CrySystem/MemoryManager.h b/Code/CryEngine/CrySystem/MemoryManager.h deleted file mode 100644 index e29d5404d8..0000000000 --- a/Code/CryEngine/CrySystem/MemoryManager.h +++ /dev/null @@ -1,52 +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_MEMORYMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H -#pragma once - -#include "ISystem.h" - -////////////////////////////////////////////////////////////////////////// -// Class that implements IMemoryManager interface. -////////////////////////////////////////////////////////////////////////// -#ifndef MEMMAN_STATIC -class CCryMemoryManager - : public IMemoryManager -{ -public: - // Singleton - static CCryMemoryManager* GetInstance(); - - ////////////////////////////////////////////////////////////////////////// - virtual bool GetProcessMemInfo(SProcessMemInfo& minfo); - - virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase); - virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0); - virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize); - virtual void TraceHeapSetColor(uint32 color); - virtual uint32 TraceHeapGetColor(); - virtual void TraceHeapSetLabel(const char* sLabel); - - virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(IMemoryManager::EAllocPolicy const eAllocPolicy); - virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage); - virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage); - - virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName); - virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName); -}; -#else -typedef IMemoryManager CCryMemoryManager; -#endif - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H diff --git a/Code/CryEngine/CrySystem/PageMappingHeap.cpp b/Code/CryEngine/CrySystem/PageMappingHeap.cpp deleted file mode 100644 index d42d75db5b..0000000000 --- a/Code/CryEngine/CrySystem/PageMappingHeap.cpp +++ /dev/null @@ -1,258 +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 "PageMappingHeap.h" - -namespace -{ - template - inline void FindZeroRanges(const uint32* str, size_t strLen, Func& yield) - { - size_t carry = 0; - size_t bitIdx = 0; - - for (size_t wordIdx = 0; wordIdx < strLen; ++wordIdx) - { - size_t wordBitIdx = 0; - int64 word = str[wordIdx]; - - // Set up sign extension to insert bits that are the last bit, inverted. - - if (!(word & 0x80000000)) - { - reinterpret_cast(word) |= 0xffffffff00000000ULL; - } - - do - { - size_t wordZeroRunLen = countTrailingZeroes(word); - - wordBitIdx += wordZeroRunLen; - carry += wordZeroRunLen; - - if (wordBitIdx == 32) - { - break; - } - - yield(bitIdx, carry); - word >>= wordZeroRunLen; - bitIdx += carry; - carry = 0; - - size_t wordOneRunLen = countTrailingZeroes(~word); - bitIdx += wordOneRunLen; - wordBitIdx += wordOneRunLen; - - if (wordBitIdx == 32) - { - break; - } - - word >>= wordOneRunLen; - } - while (true); - } - - if (carry) - { - yield(bitIdx, carry); - } - } - - struct DLMMapFindBest - { - DLMMapFindBest(size_t size) - : requiredLength(size) - , bestPosition(-1) - , bestFragmentLength(INT_MAX) - { - } - - bool operator () (size_t position, size_t length) - { - if (length == requiredLength) - { - bestPosition = position; - bestFragmentLength = 0; - return false; - } - else if (length > requiredLength) - { - size_t fragment = length - requiredLength; - if (fragment < bestFragmentLength) - { - bestPosition = position; - bestFragmentLength = fragment; - } - } - - return true; - } - - size_t requiredLength; - ptrdiff_t bestPosition; - size_t bestFragmentLength; - }; - - struct FindLargest - { - FindLargest() - : largest(0) - { - } - bool operator () (size_t, size_t length) - { - largest = max(largest, length); - return true; - } - - size_t largest; - }; -} - -CPageMappingHeap::CPageMappingHeap(char* pAddressSpace, size_t nNumPages, size_t nPageSize, const char* sName) - : m_addrRange(pAddressSpace, nPageSize, nNumPages, sName) -{ - Init(); -} - -CPageMappingHeap::CPageMappingHeap(size_t addressSpace, const char* sName) - : m_addrRange(addressSpace, sName) -{ - Init(); -} - -CPageMappingHeap::~CPageMappingHeap() -{ -} - -void CPageMappingHeap::Release() -{ - delete this; -} - -size_t CPageMappingHeap::GetGranularity() const -{ - return m_addrRange.GetPageSize(); -} - -bool CPageMappingHeap::IsInAddressRange(void* ptr) const -{ - return m_addrRange.IsInRange(ptr); -} - -size_t CPageMappingHeap::FindLargestFreeBlockSize() const -{ - CryAutoLock lock(m_lock); - - const size_t pageSize = m_addrRange.GetPageSize(); - - FindLargest findLargest; - FindZeroRanges(&m_pageBitmap[0], m_pageBitmap.size(), findLargest); - - return findLargest.largest * pageSize; -} - -void* CPageMappingHeap::Map(size_t length) -{ - CryAutoLock lock(m_lock); - - const size_t pageBitmapElemBitSize = (sizeof(uint32) * 8); - const size_t pageSize = m_addrRange.GetPageSize(); - const size_t numPages = m_addrRange.GetPageCount(); - - if (length % pageSize) - { - __debugbreak(); - length = (length + (pageSize - 1)) & ~(pageSize - 1); - } - - DLMMapFindBest findBest(length / pageSize); - FindZeroRanges(&m_pageBitmap[0], m_pageBitmap.size(), findBest); - - if ((findBest.bestPosition == -1) || (findBest.bestPosition >= (int)numPages)) - { - return NULL; - } - - void* mapAddress = m_addrRange.GetBaseAddress() + pageSize * findBest.bestPosition; - - for (size_t pageIdx = findBest.bestPosition, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - if (!m_addrRange.MapPage(pageIdx)) - { - // Unwind the pages we've already mapped. - for (; pageIdx > static_cast(findBest.bestPosition); --pageIdx) - { - m_addrRange.UnmapPage(pageIdx - 1); - } - - return NULL; - } - } - - for (size_t pageIdx = findBest.bestPosition, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - size_t pageSegment = pageIdx / pageBitmapElemBitSize; - uint32 pageMask = 1U << static_cast(pageIdx % pageBitmapElemBitSize); - - m_pageBitmap[pageSegment] |= pageMask; - } - - return mapAddress; -} - -void CPageMappingHeap::Unmap(void* mem, size_t length) -{ - CryAutoLock lock(m_lock); - const size_t pageSize = m_addrRange.GetPageSize(); - - if (length % pageSize) - { - __debugbreak(); - length = (length + (pageSize - 1)) & ~(pageSize - 1); - } - - char* mapAddress = reinterpret_cast(mem); - for (size_t pageIdx = (mapAddress - m_addrRange.GetBaseAddress()) / pageSize, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - m_addrRange.UnmapPage(pageIdx); - - const size_t pageBitmapElemBitSize = (sizeof(uint32) * 8); - - size_t pageSegment = pageIdx / pageBitmapElemBitSize; - uint32 pageMask = ~(1U << static_cast(pageIdx % pageBitmapElemBitSize)); - - m_pageBitmap[pageSegment] &= pageMask; - } -} - -void CPageMappingHeap::Init() -{ - UINT_PTR start = (UINT_PTR)m_addrRange.GetBaseAddress(); - UINT_PTR end = start + m_addrRange.GetPageCount() * m_addrRange.GetPageSize(); - - size_t addressSpace = end - start; - size_t pageSize = m_addrRange.GetPageSize(); - size_t numPages = (addressSpace + pageSize - 1) / pageSize; - m_pageBitmap.resize((numPages + 31) / 32); - - size_t pageCapacity = m_pageBitmap.size() * 32; - size_t numUnavailablePages = pageCapacity - numPages; - if (numUnavailablePages > 0) - { - m_pageBitmap.back() = ~((1 << (32 - numUnavailablePages)) - 1); - } -} diff --git a/Code/CryEngine/CrySystem/PageMappingHeap.h b/Code/CryEngine/CrySystem/PageMappingHeap.h deleted file mode 100644 index 8cd3a7a315..0000000000 --- a/Code/CryEngine/CrySystem/PageMappingHeap.h +++ /dev/null @@ -1,55 +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_PAGEMAPPINGHEAP_H -#define CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H -#pragma once - - -#include "MemoryAddressRange.h" - -#include "IMemory.h" - -class CPageMappingHeap - : public IPageMappingHeap -{ -public: - CPageMappingHeap(char* pAddressSpace, size_t nNumPages, size_t nPageSize, const char* sName); - CPageMappingHeap(size_t addressSpace, const char* sName); - ~CPageMappingHeap(); - -public: // IPageMappingHeap Members - virtual void Release(); - - virtual size_t GetGranularity() const; - virtual bool IsInAddressRange(void* ptr) const; - - virtual size_t FindLargestFreeBlockSize() const; - - virtual void* Map(size_t sz); - virtual void Unmap(void* ptr, size_t sz); - -private: - CPageMappingHeap(const CPageMappingHeap&); - CPageMappingHeap& operator = (const CPageMappingHeap&); - -private: - void Init(); - -private: - mutable CryCriticalSectionNonRecursive m_lock; - CMemoryAddressRange m_addrRange; - std::vector m_pageBitmap; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H diff --git a/Code/CryEngine/CrySystem/ResourceManager.cpp b/Code/CryEngine/CrySystem/ResourceManager.cpp deleted file mode 100644 index 5e9477a99c..0000000000 --- a/Code/CryEngine/CrySystem/ResourceManager.cpp +++ /dev/null @@ -1,868 +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 Resource Manager - - -#include "CrySystem_precompiled.h" -#include "ResourceManager.h" -#include "System.h" -#include "MaterialUtils.h" -#include -#include -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RESOURCEMANAGER_CPP_SECTION_1 1 -#define RESOURCEMANAGER_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ResourceManager_cpp) -#endif - -#define LEVEL_PAK_FILENAME "level.pak" -#define LEVEL_PAK_INMEMORY_MAXSIZE 10 * 1024 * 1024 - -#define ENGINE_PAK_FILENAME "engine.pak" -#define LEVEL_CACHE_PAK_FILENAME "xml.pak" - -#define GAME_DATA_PAK_FILENAME "gamedata.pak" -#define FAST_LOADING_PAKS_SRC_FOLDER "_fastload/" -#define FRONTEND_COMMON_PAK_FILENAME_SP "modes/menucommon_sp.pak" -#define FRONTEND_COMMON_PAK_FILENAME_MP "modes/menucommon_mp.pak" -#define FRONTEND_COMMON_LIST_FILENAME "menucommon" -#define LEVEL_CACHE_SRC_FOLDER "_levelcache/" -#define LEVEL_CACHE_BIND_ROOT "LevelCache" -#define LEVEL_RESOURCE_LIST "resourcelist.txt" -#define AUTO_LEVEL_RESOURCE_LIST "auto_resourcelist.txt" -#define AUTO_LEVEL_SEQUENCE_RESOURCE_LIST "auto_resources_sequence.txt" -#define AUTO_LEVEL_TOTAL_RESOURCE_LIST "auto_resourcelist_total.txt" -#define AUTO_LEVEL_TOTAL_SEQUENCE_RESOURCE_LIST "auto_resources_total_sequence.txt" - -////////////////////////////////////////////////////////////////////////// -// IResourceList implementation class. -////////////////////////////////////////////////////////////////////////// -class CLevelResourceList - : public AZ::IO::IResourceList -{ -public: - CLevelResourceList() - { - m_pFileBuffer = 0; - m_nBufferSize = 0; - m_nCurrentLine = 0; - }; - ~CLevelResourceList() - { - Clear(); - }; - - uint32 GetFilenameHash(const char* sResourceFile) - { - char filename[512]; - azstrcpy(filename, AZ_ARRAY_SIZE(filename), sResourceFile); - MaterialUtils::UnifyMaterialName(filename); - - uint32 code = CCrc32::ComputeLowercase(filename); - return code; - } - - virtual void Add([[maybe_unused]] AZStd::string_view sResourceFile) - { - assert(0); // Not implemented. - } - virtual void Clear() - { - delete [] m_pFileBuffer; - m_pFileBuffer = 0; - m_nBufferSize = 0; - stl::free_container(m_lines); - stl::free_container(m_resources_crc32); - m_nCurrentLine = 0; - } - - struct ComparePredicate - { - bool operator()(const char* s1, const char* s2) - { - return strcmp(s1, s2) < 0; - } - }; - - virtual bool IsExist(AZStd::string_view sResourceFile) - { - uint32 nHash = GetFilenameHash(sResourceFile.data()); - if (stl::binary_find(m_resources_crc32.begin(), m_resources_crc32.end(), nHash) != m_resources_crc32.end()) - { - return true; - } - return false; - } - virtual bool Load(AZStd::string_view sResourceListFilename) - { - Clear(); - CCryFile file; - if (file.Open(sResourceListFilename.data(), "rb", AZ::IO::IArchive::FOPEN_ONDISK)) // File access can happen from disk as well. - { - m_nBufferSize = file.GetLength(); - if (m_nBufferSize > 0) - { - m_pFileBuffer = new char[m_nBufferSize]; - size_t numBytesRead = file.ReadRaw(m_pFileBuffer, file.GetLength()); - - if (numBytesRead <= 0 || numBytesRead != file.GetLength()) - { - AZ_Error("ResourceManager", false, "Unable to read data for: %.*s", aznumeric_cast(sResourceListFilename.size()), sResourceListFilename.data()); - return false; - } - m_pFileBuffer[m_nBufferSize - 1] = 0; - - char seps[] = "\r\n"; - - m_lines.reserve(5000); - - // Parse file, every line in a file represents a resource filename. - char* nextToken = nullptr; - char* token = azstrtok(m_pFileBuffer, 0, seps, &nextToken); - while (token != NULL) - { - m_lines.push_back(token); - token = azstrtok(NULL, 0, seps, &nextToken); - } - - m_resources_crc32.resize(m_lines.size()); - for (int i = 0, numlines = m_lines.size(); i < numlines; i++) - { - MaterialUtils::UnifyMaterialName(const_cast(m_lines[i])); - m_resources_crc32[i] = CCrc32::ComputeLowercase(m_lines[i]); - } - std::sort(m_resources_crc32.begin(), m_resources_crc32.end()); - } - return true; - } - return false; - } - virtual const char* GetFirst() - { - m_nCurrentLine = 0; - if (!m_lines.empty()) - { - return m_lines[0]; - } - return NULL; - } - virtual const char* GetNext() - { - m_nCurrentLine++; - if (m_nCurrentLine < (int)m_lines.size()) - { - return m_lines[m_nCurrentLine]; - } - return NULL; - } - - void GetMemoryStatistics(ICrySizer* pSizer) - { - pSizer->Add(this, sizeof(*this)); - pSizer->Add(m_pFileBuffer, m_nBufferSize); - pSizer->AddContainer(m_lines); - pSizer->AddContainer(m_resources_crc32); - } - -public: - char* m_pFileBuffer; - int m_nBufferSize; - typedef std::vector Lines; - Lines m_lines; - int m_nCurrentLine; - std::vector m_resources_crc32; -}; - - -////////////////////////////////////////////////////////////////////////// -CResourceManager::CResourceManager() -{ - m_bRegisteredFileOpenSink = false; - m_bOwnResourceList = false; - m_bLevelTransitioning = false; - - m_fastLoadPakPaths.reserve(8); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::PrepareLevel(const char* sLevelFolder, const char* sLevelName) -{ - LOADING_TIME_PROFILE_SECTION; - - m_sLevelFolder = sLevelFolder; - m_sLevelName = sLevelName; - m_bLevelTransitioning = false; - m_currentLevelCacheFolder = CryPathString(LEVEL_CACHE_SRC_FOLDER) + sLevelName; - - if (g_cvars.archiveVars.nLoadCache) - { - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - // The prefab system doesn't use level.pak - if (!usePrefabSystemForLevels) - { - CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME); - size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str()); - if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs. - { - // Force level.pak from this level in memory. - gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - } - } - - gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - - // - // Load _levelCache paks in the order they are stored on the disk - reduce seek time - // - - if (gEnv->pConsole->GetCVar("e_StreamCgf") && gEnv->pConsole->GetCVar("e_StreamCgf")->GetIVal() != 0) - { - LoadLevelCachePak("cga.pak", "", true); - LoadLevelCachePak("cgf.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("cgf_cache.pak", "", false); - } - } - - LoadLevelCachePak("chr.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("chr_cache.pak", "", false); - } - - LoadLevelCachePak("dds0.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("dds_cache.pak", "", false); - } - - LoadLevelCachePak("skin.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("skin_cache.pak", "", false); - } - - LoadLevelCachePak(LEVEL_CACHE_PAK_FILENAME, "", true); - } - - AZStd::intrusive_ptr pResList = new CLevelResourceList; - gEnv->pCryPak->SetResourceList(AZ::IO::IArchive::RFOM_Level, pResList.get()); - m_bOwnResourceList = true; - - // Load resourcelist.txt, TODO: make sure there are no duplicates - if (g_cvars.archiveVars.nSaveLevelResourceList == 0) - { - string filename = PathUtil::Make(sLevelFolder, AUTO_LEVEL_RESOURCE_LIST); - if (!pResList->Load(filename.c_str())) // If we saving resource list do not use auto_resourcelist.txt - { - // Try resource list created by the editor. - filename = PathUtil::Make(sLevelFolder, LEVEL_RESOURCE_LIST); - pResList->Load(filename.c_str()); - } - } - //LoadFastLoadPaks(); - - if (g_cvars.archiveVars.nStreamCache) - { - m_AsyncPakManager.ParseLayerPaks(GetCurrentLevelCacheFolder()); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadFastLoadPaks(bool bToMemory) -{ - if (g_cvars.archiveVars.nSaveFastloadResourceList != 0) - { - // Record a file list for _FastLoad/startup.pak - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return false; - } - else - { - LOADING_TIME_PROFILE_SECTION; - - // Load a special _fastload paks - int nPakPreloadFlags = AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32 | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK; - if (bToMemory && g_cvars.archiveVars.nLoadCache) - { - nPakPreloadFlags |= AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY; - } - - const char* const assetsDir = "@assets@"; - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ResourceManager_cpp) -#endif - - gEnv->pCryPak->OpenPacks(assetsDir, AZ::IO::PathString(FAST_LOADING_PAKS_SRC_FOLDER) + "*.pak", nPakPreloadFlags, &m_fastLoadPakPaths); - gEnv->pCryPak->OpenPack(assetsDir, "Engine.pak", AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY); - return !m_fastLoadPakPaths.empty(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadFastLoadPaks() -{ - for (uint32 i = 0; i < m_fastLoadPakPaths.size(); i++) - { - // Unload a special _fastload paks - gEnv->pCryPak->ClosePack(m_fastLoadPakPaths[i].c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL); - } - m_fastLoadPakPaths.clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadLevel() -{ - gEnv->pCryPak->SetResourceList(AZ::IO::IArchive::RFOM_Level, NULL); - - if (m_bRegisteredFileOpenSink) - { - if (g_cvars.archiveVars.nSaveTotalResourceList) - { - SaveRecordedResources(true); - m_recordedFiles.clear(); - } - } - - stl::free_container(m_sLevelFolder); - stl::free_container(m_sLevelName); - stl::free_container(m_currentLevelCacheFolder); - - // should always be empty, since it is freed at the end of - // the level loading process, if it is not - // something went wrong and we have a levelheap leak - assert(m_openedPaks.capacity() == 0); - - m_pSequenceResourceList = NULL; -} - -////////////////////////////////////////////////////////////////////////// -AZ::IO::IResourceList* CResourceManager::GetLevelResourceList() -{ - auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level); - return pResList; -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading) -{ - LOADING_TIME_PROFILE_SECTION; - CryPathString pakPath = GetCurrentLevelCacheFolder() + "/" + sPakName; - - pakPath.MakeLower(); - pakPath.replace(AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - // Check if pak is already loaded - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if (strstr(m_openedPaks[i].filename.c_str(), pakPath.c_str())) - { - return true; - } - } - - // check pak file size. - size_t nFileSize = gEnv->pCryPak->FGetSize(pakPath.c_str(), true); - - if (nFileSize <= 0) - { - // Cached file does not exist - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Level cache pak file %s does not exist", pakPath.c_str()); - return false; - } - - //set these flags as DLC LevelCache Paks are found via the mod paths, - //and the paks can never be inside other paks so we optimise the search - uint32 nOpenPakFlags = AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32 | AZ::IO::IArchive::FLAGS_CHECK_MOD_PATHS | AZ::IO::IArchive::FLAGS_NEVER_IN_PAK; - - if (nFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs. - { - if (!(nOpenPakFlags & AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY_CPU)) - { - nOpenPakFlags |= AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY; - } - } - - SOpenedPak op; - - if (gEnv->pCryPak->OpenPack(sBindRoot, { pakPath.c_str(), pakPath.size() }, nOpenPakFlags | AZ::IO::IArchive::FOPEN_HINT_QUIET, NULL, &op.filename)) - { - op.bOnlyDuringLevelLoading = bOnlyDuringLevelLoading; - m_openedPaks.push_back(op); - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadModeSwitchPak(const char* sPakName, const bool multiplayer) -{ - if (g_cvars.archiveVars.nSaveLevelResourceList) - { - //Don't load the pak if we're trying to save a resourcelist in order to build it. - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return true; - } - else - { - if (g_cvars.archiveVars.nLoadModePaks) - { - // Unload SP common pak if switching to multiplayer - if (multiplayer) - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - } - else - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP, FRONTEND_COMMON_LIST_FILENAME "_mp"); - } - //Load the mode switching pak. If this is available and up to date it speeds up this process considerably - bool bOpened = gEnv->pCryPak->OpenPack("@assets@", sPakName, 0); - bool bLoaded = gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - return (bOpened && bLoaded); - } - else - { - return true; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) -{ - if (g_cvars.archiveVars.nSaveLevelResourceList && m_bRegisteredFileOpenSink) - { - m_sLevelFolder = sResourceListName; - SaveRecordedResources(); - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - else - { - if (g_cvars.archiveVars.nLoadModePaks) - { - //Unload the mode switching pak. - gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - gEnv->pCryPak->ClosePack(sPakName, 0); - //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc, currently SP only - if (!multiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); - } - else if (multiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_MP); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadMenuCommonPak(const char* sPakName) -{ - if (g_cvars.archiveVars.nSaveMenuCommonResourceList) - { - //Don't load the pak if we're trying to save a resourcelist in order to build it. - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return true; - } - else - { - //Load the mode switching pak. If this is available and up to date it speeds up this process considerably - bool bOpened = gEnv->pCryPak->OpenPack("@assets@", sPakName, 0); - bool bLoaded = gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - return (bOpened && bLoaded); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadMenuCommonPak(const char* sPakName, const char* sResourceListName) -{ - if (g_cvars.archiveVars.nSaveMenuCommonResourceList) - { - m_sLevelFolder = sResourceListName; - SaveRecordedResources(); - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - else - { - //Unload the mode switching pak. - gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - gEnv->pCryPak->ClosePack(sPakName, 0); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadLevelCachePak(const char* sPakName) -{ - LOADING_TIME_PROFILE_SECTION; - CryPathString pakPath = GetCurrentLevelCacheFolder() + "/" + sPakName; - pakPath.MakeLower(); - pakPath.replace(AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if (strstr(m_openedPaks[i].filename.c_str(), pakPath.c_str())) - { - gEnv->pCryPak->ClosePack(m_openedPaks[i].filename.c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL); - m_openedPaks.erase(m_openedPaks.begin() + i); - break; - } - } - - if (m_openedPaks.empty()) - { - stl::free_container(m_openedPaks); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadAllLevelCachePaks(bool bLevelLoadEnd) -{ - LOADING_TIME_PROFILE_SECTION; - - if (!bLevelLoadEnd) - { - m_AsyncPakManager.Clear(); - UnloadFastLoadPaks(); - } - else - { - m_AsyncPakManager.UnloadLevelLoadPaks(); - } - - uint32 nClosePakFlags = AZ::IO::IArchive::FLAGS_PATH_REAL; //AZ::IO::IArchive::FLAGS_CHECK_MOD_PATHS | AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL; - - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if ((m_openedPaks[i].bOnlyDuringLevelLoading && bLevelLoadEnd) || - !bLevelLoadEnd) - { - gEnv->pCryPak->ClosePack(m_openedPaks[i].filename.c_str(), nClosePakFlags); - } - } - - if (g_cvars.archiveVars.nLoadCache) - { - gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (!usePrefabSystemForLevels) - { - // Force level.pak out of memory. - gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - } - } - if (!bLevelLoadEnd) - { - stl::free_container(m_openedPaks); - } -} - -////////////////////////////////////////////////////////////////////////// - -bool CResourceManager::LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) -{ - return m_AsyncPakManager.LoadPakToMemAsync(pPath, bLevelLoadOnly); -} - -bool CResourceManager::LoadLayerPak(const char* sLayerName) -{ - return m_AsyncPakManager.LoadLayerPak(sLayerName); -} - -void CResourceManager::UnloadLayerPak(const char* sLayerName) -{ - m_AsyncPakManager.UnloadLayerPak(sLayerName); -} - -void CResourceManager::GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const -{ - m_AsyncPakManager.GetLayerPakStats(stats, bCollectAllStats); -} - -void CResourceManager::UnloadAllAsyncPaks() -{ - m_AsyncPakManager.Clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Update() -{ - m_AsyncPakManager.Update(); -} -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Init() -{ - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Shutdown() -{ - UnloadAllLevelCachePaks(false); - if (GetISystem() && GetISystem()->GetISystemEventDispatcher()) - { - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::IsStreamingCachePak(const char* filename) const -{ - const char* cachePaks[] = { - "dds_cache.pak", - "cgf_cache.pak", - "skin_cache.pak", - "chr_cache.pak" - }; - - for (int i = 0; i < sizeof(cachePaks) / sizeof(cachePaks[0]); ++i) - { - if (strstr(filename, cachePaks[i])) - { - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_FRONTEND_INITIALISED: - { - GetISystem()->GetStreamEngine()->PauseStreaming(false, -1); - } - break; - - case ESYSTEM_EVENT_GAME_POST_INIT_DONE: - { - if (g_cvars.archiveVars.nSaveFastloadResourceList != 0) - { - SaveRecordedResources(); - - if (g_cvars.archiveVars.nSaveLevelResourceList == 0 && g_cvars.archiveVars.nSaveTotalResourceList == 0) - { - m_recordedFiles.clear(); - } - } - // Unload all paks from memory, after game init. - UnloadAllLevelCachePaks(false); - gEnv->pCryPak->LoadPaksToMemory(0, false); - - if (g_cvars.archiveVars.nLoadCache) - { - //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc - if (LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); - } - } - - break; - } - - case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - - m_bLevelTransitioning = !m_sLevelName.empty(); - - m_lastLevelLoadTime.SetValue(0); - m_beginLevelLoadTime = gEnv->pTimer->GetAsyncTime(); - if (g_cvars.archiveVars.nSaveLevelResourceList || g_cvars.archiveVars.nSaveTotalResourceList) - { - if (!g_cvars.archiveVars.nSaveTotalResourceList) - { - m_recordedFiles.clear(); - } - - if (!m_bRegisteredFileOpenSink) - { - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - } - } - - // Cancel any async pak loading, it will fight with the impending sync IO - m_AsyncPakManager.CancelPendingJobs(); - - // Pause streaming engine for anything but sound, music, video and flash. - uint32 nMask = (1 << eStreamTaskTypeFlash) | (1 << eStreamTaskTypeVideo) | STREAM_TASK_TYPE_AUDIO_ALL; // Unblock specified streams - nMask = ~nMask; // Invert mask, bit set means blocking type. - GetISystem()->GetStreamEngine()->PauseStreaming(true, nMask); - } - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - if (m_bOwnResourceList) - { - m_bOwnResourceList = false; - // Clear resource list, after level loading. - auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level); - if (pResList) - { - pResList->Clear(); - } - } - } - - break; - - case ESYSTEM_EVENT_LEVEL_UNLOAD: - UnloadAllLevelCachePaks(false); - - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - { - // Unpause all streams in streaming engine. - GetISystem()->GetStreamEngine()->PauseStreaming(false, -1); - } - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_FIRST_FRAME: - { - UnloadAllLevelCachePaks(true); - } - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_END: - { - CTimeValue t = gEnv->pTimer->GetAsyncTime(); - m_lastLevelLoadTime = t - m_beginLevelLoadTime; - - if (g_cvars.archiveVars.nSaveLevelResourceList && m_bRegisteredFileOpenSink) - { - SaveRecordedResources(); - - if (!g_cvars.archiveVars.nSaveTotalResourceList) - { - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - } - - UnloadAllLevelCachePaks(true); - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::GetMemoryStatistics(ICrySizer* pSizer) -{ - pSizer->AddContainer(m_openedPaks); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::ReportFileOpen([[maybe_unused]] AZ::IO::HandleType inFileHandle, AZStd::string_view szFullPath) -{ - if (!g_cvars.archiveVars.nSaveLevelResourceList && !g_cvars.archiveVars.nSaveFastloadResourceList && !g_cvars.archiveVars.nSaveMenuCommonResourceList && !g_cvars.archiveVars.nSaveTotalResourceList) - { - return; - } - - string file = PathUtil::MakeGamePath(string(szFullPath.data(), szFullPath.size())); - file.replace('\\', '/'); - file.MakeLower(); - { - CryAutoCriticalSection lock(recordedFilesLock); - m_recordedFiles.push_back(file); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::SaveRecordedResources(bool bTotalList) -{ - CryAutoCriticalSection lock(recordedFilesLock); - - std::set fileset; - - // eliminate duplicate values - std::vector::iterator endLocation = std::unique(m_recordedFiles.begin(), m_recordedFiles.end()); - m_recordedFiles.erase(endLocation, m_recordedFiles.end()); - - fileset.insert(m_recordedFiles.begin(), m_recordedFiles.end()); - - string sSequenceFilename = PathUtil::AddSlash(m_sLevelFolder) + (bTotalList ? AUTO_LEVEL_TOTAL_SEQUENCE_RESOURCE_LIST : AUTO_LEVEL_SEQUENCE_RESOURCE_LIST); - { - AZ::IO::HandleType fileHandle = fxopen(sSequenceFilename, "wb", true); - if (fileHandle != AZ::IO::InvalidHandle) - { - for (std::vector::iterator it = m_recordedFiles.begin(); it != m_recordedFiles.end(); ++it) - { - const char* str = it->c_str(); - AZ::IO::Print(fileHandle, "%s\n", str); - } - gEnv->pFileIO->Close(fileHandle); - } - } - - string sResourceSetFilename = PathUtil::AddSlash(m_sLevelFolder) + (bTotalList ? AUTO_LEVEL_TOTAL_RESOURCE_LIST : AUTO_LEVEL_RESOURCE_LIST); - { - AZ::IO::HandleType fileHandle = fxopen(sResourceSetFilename, "wb", true); - if (fileHandle != AZ::IO::InvalidHandle) - { - for (std::set::iterator it = fileset.begin(); it != fileset.end(); ++it) - { - const char* str = it->c_str(); - AZ::IO::Print(fileHandle, "%s\n", str); - } - gEnv->pFileIO->Close(fileHandle); - } - } -} - -////////////////////////////////////////////////////////////////////////// -CTimeValue CResourceManager::GetLastLevelLoadTime() const -{ - return m_lastLevelLoadTime; -} diff --git a/Code/CryEngine/CrySystem/ResourceManager.h b/Code/CryEngine/CrySystem/ResourceManager.h deleted file mode 100644 index aa697b3927..0000000000 --- a/Code/CryEngine/CrySystem/ResourceManager.h +++ /dev/null @@ -1,116 +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 Resource Manager - - -#ifndef CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H -#pragma once - - -#include -#include "AsyncPakManager.h" - -////////////////////////////////////////////////////////////////////////// -// IResource manager interface -////////////////////////////////////////////////////////////////////////// -class CResourceManager - : public IResourceManager - , public ISystemEventListener - , public AZ::IO::IArchiveFileAccessSink -{ -public: - CResourceManager(); - - void Init(); - void Shutdown(); - - bool IsStreamingCachePak(const char* filename) const; - - ////////////////////////////////////////////////////////////////////////// - // IResourceManager interface implementation. - ////////////////////////////////////////////////////////////////////////// - void PrepareLevel(const char* sLevelFolder, const char* sLevelName); - void UnloadLevel(); - AZ::IO::IResourceList* GetLevelResourceList(); - bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading); - void UnloadLevelCachePak(const char* sPakName); - bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer); - void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer); - bool LoadMenuCommonPak(const char* sPakName); - void UnloadMenuCommonPak(const char* sPakName, const char* sResourceListName); - bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly); - void UnloadAllAsyncPaks(); - bool LoadLayerPak(const char* sLayerName); - void UnloadLayerPak(const char* sLayerName); - void UnloadAllLevelCachePaks(bool bLevelLoadEnd); - void GetMemoryStatistics(ICrySizer* pSizer); - bool LoadFastLoadPaks(bool bToMemory); - void UnloadFastLoadPaks(); - CTimeValue GetLastLevelLoadTime() const; - void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // IArchiveFileAccessSink interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void ReportFileOpen(AZ::IO::HandleType inFileHandle, AZStd::string_view szFullPath); - ////////////////////////////////////////////////////////////////////////// - - // Per frame update of the resource manager. - void Update(); - - CryPathString GetCurrentLevelCacheFolder() const { return m_currentLevelCacheFolder; }; - void SaveRecordedResources(bool bTotalList = false); - -private: - - ////////////////////////////////////////////////////////////////////////// - - CryPathString m_currentLevelCacheFolder; - - struct SOpenedPak - { - AZStd::fixed_string filename; - bool bOnlyDuringLevelLoading; - }; - std::vector m_openedPaks; - - CAsyncPakManager m_AsyncPakManager; - - string m_sLevelFolder; - string m_sLevelName; - bool m_bLevelTransitioning; - - bool m_bRegisteredFileOpenSink; - bool m_bOwnResourceList; - - CTimeValue m_beginLevelLoadTime; - CTimeValue m_lastLevelLoadTime; - - AZStd::intrusive_ptr m_pSequenceResourceList; - - CryCriticalSection recordedFilesLock; - std::vector m_recordedFiles; - - AZStd::vector< AZStd::fixed_string > m_fastLoadPakPaths; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp b/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp deleted file mode 100644 index 4344af45dc..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp +++ /dev/null @@ -1,410 +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 : Streaming Engine - - -#include "CrySystem_precompiled.h" -#include -#include - -#include "AZRequestReadStream.h" -#include -#include -#include -#include "StreamEngine.h" - -AZRequestReadStream* AZRequestReadStream::Allocate(const EStreamTaskType tSource, const char* filename, IStreamCallback* callback, - const StreamReadParams* params) -{ - //Once an async method is available to read file sizes this code should be removed: - // and the file size should be known before calling this method and pass it as a - // parameter to this method. - //REMOVE In the Future START. - AZ::IO::SizeType fileSize = 0; - if (params && params->nSize) - { - fileSize = params->nSize; - } - else - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::Result res = fileIO->Size(filename, fileSize); - if (!res) - { - AZ_Error("AZRequestReadStream", false, "Failed to read file size of %s", filename); - return nullptr; - } - //REMOVE In the Future END. - } - - auto streamer = AZ::Interface::Get(); - - AZRequestReadStream* retReq; - retReq = aznew AZRequestReadStream(); - - retReq->m_Type = tSource; - retReq->m_fileName = filename; - retReq->m_callback = callback; - retReq->m_fileSize = fileSize; - //REMARK: if params->pBuffer is NOT NULL, then retReq->m_buffer - //should become params->pBuffer, this is called stream-in-place. - //The only reason we are not doing this here is because - //some platforms support stream-in-place to WRITE ONLY buffers. - //Because there are no guarantees that low level streaming and decompression apis - //would treat the output buffer as WRITE ONLY, we still allocate the buffer and memcpy - //to params->pBuffer upon the completion callback being called. - //Once LY-98089 is complete/fixed, we should be able to safely - //set retReq->m_buffer = params->pBuffer and skip the memory allocation. - retReq->m_buffer = azmalloc(fileSize, streamer->GetRecommendations().m_memoryAlignment); - if (params) - { - retReq->m_params = *params; - } - - return retReq; -} - -////////////////////////////////////////////////////////////////////////// -AZRequestReadStream::AZRequestReadStream() : m_fileName(""), m_fileRequest(nullptr), - m_buffer(nullptr), m_Type(eStreamTaskTypeTexture), - m_callback(nullptr), m_fileSize(0), m_numBytesRead(0), m_isAsyncCallbackExecuted(false), - m_isSyncCallbackExecuted(false), m_isFileRequestComplete(false), m_isError(false), m_isFinished(false), - m_IOError(0) -{ - AZStd::atomic_init(&m_refCount, 0); - m_params = StreamReadParams(); -} - -////////////////////////////////////////////////////////////////////////// -AZRequestReadStream::~AZRequestReadStream() -{ - azfree(m_buffer); -} - -// tries to stop reading the stream; this is advisory and may have no effect -// all the callbacks will be called after this. If you just destructing object, -// dereference this object and it will automatically abort and release all associated resources. -void AZRequestReadStream::Abort() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - // Increase ref counting to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (m_isFileRequestComplete || m_isError) - { - // It is possible the file I/O request to be completed by AZ::IO::Streamer, - // but if the completion callback is deferred for the main thread then - // the stream is not finished. So, only if it is finished then - // it is safe to do nothing. - if (m_isFinished) - { - return; - } - } - - m_isError = true; - m_IOError = ERROR_USER_ABORT; - m_isFileRequestComplete = true; - m_numBytesRead = 0; - - if (m_fileRequest) - { - auto streamer = AZ::Interface::Get(); - streamer->QueueRequest(streamer->Cancel(m_fileRequest)); - } - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_callback = nullptr; - } - -} - -bool AZRequestReadStream::TryAbort() -{ - // Increase ref counting to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (!m_callbackLock.TryLock()) - { - return false; - } - - if (m_isFileRequestComplete || m_isError) - { - // It is possible the file I/O request to be completed by AZ::IO::Streamer, - // but if the completion callback is deferred for the main thread then - // the stream is not finished. So, only if it is finished then - // it is safe to do nothing. - if (m_isFinished) - { - m_callbackLock.Unlock(); - return false; - } - } - - m_isError = true; - m_IOError = ERROR_USER_ABORT; - m_isFileRequestComplete = true; - m_numBytesRead = 0; - - if (m_fileRequest) - { - auto streamer = AZ::Interface::Get(); - streamer->QueueRequest(streamer->Cancel(m_fileRequest)); - } - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_callback = nullptr; - - m_callbackLock.Unlock(); - - return true; -} - -// tries to raise the priority of the read; this is advisory and may have no effect -void AZRequestReadStream::SetPriority(EStreamTaskPriority ePriority) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (m_params.ePriority != ePriority) - { - m_params.ePriority = ePriority; - if (m_fileRequest) - { - AZ::Interface::Get()->RescheduleRequest(m_fileRequest, AZ::IO::IStreamerTypes::s_noDeadline, - CStreamEngine::CryStreamPriorityToAZStreamPriority(ePriority)); - } - } -} - -// unconditionally waits until the callback is called -// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback -// is called before return from this function (unless no callback was specified) -void AZRequestReadStream::Wait(int maxWaitMillis) -{ - // lock this object to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (!m_isFinished && !m_isError && !m_fileRequest) - { - AZ_Error("AZRequestReadStream", false, "Stream for file %s is unwaitable", m_fileName.c_str()); - return; - } - - if (maxWaitMillis > 0) - { - m_wait.try_acquire_for(AZStd::chrono::milliseconds(maxWaitMillis)); - } - else - { - m_wait.acquire(); - } -} - -////////////////////////////////////////////////////////////////////////// -const char* AZRequestReadStream::GetErrorName() const -{ - switch (m_IOError) - { - case ERROR_UNKNOWN_ERROR: - return "Unknown error"; - case ERROR_UNEXPECTED_DESTRUCTION: - return "Unexpected destruction"; - case ERROR_INVALID_CALL: - return "Invalid call"; - case ERROR_CANT_OPEN_FILE: - return "Cannot open the file"; - case ERROR_REFSTREAM_ERROR: - return "Refstream error"; - case ERROR_OFFSET_OUT_OF_RANGE: - return "Offset out of range"; - case ERROR_REGION_OUT_OF_RANGE: - return "Region out of range"; - case ERROR_SIZE_OUT_OF_RANGE: - return "Size out of range"; - case ERROR_CANT_START_READING: - return "Cannot start reading"; - case ERROR_OUT_OF_MEMORY: - return "Out of memory"; - case ERROR_ABORTED_ON_SHUTDOWN: - return "Aborted on shutdown"; - case ERROR_OUT_OF_MEMORY_QUOTA: - return "Out of memory quota"; - case ERROR_ZIP_CACHE_FAILURE: - return "ZIP cache failure"; - case ERROR_USER_ABORT: - return "User aborted"; - } - return "Unrecognized error"; -} - -int AZRequestReadStream::AddRef() -{ - return m_refCount.fetch_add(1) + 1; -} - -int AZRequestReadStream::Release() -{ - int refCount = m_refCount.fetch_sub(1); - -#ifndef _RELEASE - if (refCount < 1) - { - __debugbreak(); - } -#endif - - if (refCount == 1) - { - //UNUSUAL, yet necessary. - //Why "delete this"? - //So, AZRequestReadStream is a replacement of CReadStream. The original design of - //Cry Texture Mips Streaming makes use of CReadStream through IReadStreamPtr, which - //is a smart pointer design that calls AddRef() and Release() but never calls "delete", - //like AZStd::shared_ptr<> does. This means the original Cry design had a memory leak - //because it never called delete on IReadStream objects. If you look at the original - //code of CReadStream (StreamReadStream.cpp) , the static Allocate method has two paths - //to allocate memory, one used a stack based memory allocation hack, and the other path - //was doing a "new CReadStream". Using VS2017 debugger I found both paths to be used, but - //"delete" and hence the destructor of CReadStream is never called causing minor memory leaks. - //The best solution I found was to call "delete this" here and later when we chnage IReadStreamPtr - //for AZstd::smart_ptr then AddRef() and Release() won't be needed anymore and this "delete this" - //hack won't be necessary either. - delete this; - } - - return refCount - 1; -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::ExecuteAsyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_isAsyncCallbackExecuted && m_callback) - { - m_isAsyncCallbackExecuted = true; - m_callback->StreamAsyncOnComplete(this, m_IOError); - } -} - -void AZRequestReadStream::ExecuteSyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_isSyncCallbackExecuted && m_callback && (0 == (m_params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK))) - { - m_isSyncCallbackExecuted = true; - - AZRequestReadStream_AutoPtr refCountLock(this); // Stream can be freed inside the callback! - - m_callback->StreamOnComplete(this, m_IOError); - - m_isFinished = true; - FreeTemporaryMemory(); - } - -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::FreeTemporaryMemory() -{ - // Make sure m_buffer is not freed if the file request is still in flight, as Streamer can still write to m_buffer in that case - if (!m_fileRequest || AZ::Interface::Get()->HasRequestCompleted(m_fileRequest)) - { - azfree(m_buffer); - m_buffer = nullptr; - m_numBytesRead = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::OnRequestComplete(AZ::IO::SizeType numBytesRead, [[maybe_unused]] void* buffer, AZ::IO::IStreamerTypes::RequestStatus requestState) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (!m_isFileRequestComplete) - { - switch (requestState) - { - case AZ::IO::IStreamerTypes::RequestStatus::Completed: - m_IOError = 0; - m_numBytesRead = static_cast(numBytesRead); - m_isError = false; - if (m_params.pBuffer) - { - //In some systems, streaming-in-place is supported. The caveat - //is that in some cases, the destination buffer is write-only. This is why - //a final memcpy must be done here until support is added to AZ::IO::Streamer API - //to decompress/load data into write-only buffers. SEE: LY-98089 - AZ_Assert(m_params.pBuffer != m_buffer, "Streaming-In-Place requires destination and source buffers to be different"); - memcpy(m_params.pBuffer, m_buffer, numBytesRead); - } - break; - case AZ::IO::IStreamerTypes::RequestStatus::Canceled: - m_IOError = ERROR_USER_ABORT; - m_numBytesRead = 0; - m_isError = true; - break; - default: - m_IOError = ERROR_UNKNOWN_ERROR; - m_numBytesRead = 0; - m_isError = true; - break; - } - - ExecuteAsyncCallback_CBLocked(); - m_isFileRequestComplete = true; - - if (m_params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) - { - // We do not need FileRequest here anymore, and not its temporary memory. - m_fileRequest = nullptr; - m_isFinished = true; - } - else - { - //The completion must be triggered from MainThread. (Typically only happens when loading Terrain Macro Textures - AddRef(); - AZ::SystemTickBus::QueueFunction([this] { - RequestCompleteOnMainThread(); - }); - } - } - - m_wait.release(); -} - - -void AZRequestReadStream::RequestCompleteOnMainThread() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - // call asynchronous callback function if needed synchronously - { - CryAutoCriticalSection lock(m_callbackLock); - ExecuteSyncCallback_CBLocked(); - } - - //Always called because before enqueuing this call was called AddRef() - Release(); -} - diff --git a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h b/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h deleted file mode 100644 index be925ad6c0..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h +++ /dev/null @@ -1,151 +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. -* -*/ - -// Description : An IReadStream implementation designed to work with AZ::IO::Streamer -// instead of CStreamEngine. - -#pragma once - -#include -#include -#include -#include -#include "IStreamEngine.h" - -namespace AZ -{ - namespace IO - { - class Request; - } -} - -//This class is a wrapper of AZ::IO::Request so Cry Classes can use AZ::IO::Streamer. -//Basicallythis replaces CReadStream. -class AZRequestReadStream - : public IReadStream -{ -public: - AZ_CLASS_ALLOCATOR(AZRequestReadStream, AZ::SystemAllocator, 0); - - static AZRequestReadStream* Allocate(const EStreamTaskType tSource, const char* filename, IStreamCallback* callback, - const StreamReadParams* params); - - int AddRef() override; - int Release() override; - - DWORD_PTR GetUserData() override {return m_params.dwUserData; } - - // set user defined data into stream's params - void SetUserData(DWORD_PTR userData) override { m_params.dwUserData = userData; }; - - // returns true if the file read was not successful. - bool IsError() override { return m_isError; }; - - // returns true if the file read was completed (successfully or unsuccessfully) - // check IsError to check if the whole requested file (piece) was read - bool IsFinished() override { return m_isFinished; }; - - // returns the number of bytes read so far (the whole buffer size if IsFinished()) - unsigned int GetBytesRead([[maybe_unused]] bool bWait) override { return static_cast(m_numBytesRead); }; - - // returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read - const void* GetBuffer() override { return m_buffer; }; - - // tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - void Abort() override; - bool TryAbort() override; - - - - // unconditionally waits until the callback is called - // i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified) - void Wait(int maxWaitMillis = -1) override; - - const StreamReadParams& GetParams() const override {return m_params; } - - const EStreamTaskType GetCallerType() const override { return m_Type; } - - //We must define this one. But it is never used in the context of AZ::IO::Streamer. - //Legacy Cry StreamEngine stuff. - EStreamSourceMediaType GetMediaType() const override { return EStreamSourceMediaType::eStreamSourceTypeUnknown; } - - // return pointer to callback routine(can be NULL) - IStreamCallback* GetCallback() const override { return m_callback; }; - - // return IO error # - unsigned GetError() const override { return m_IOError; }; - - // Returns IO error name - const char* GetErrorName() const override; - - // return stream name - const char* GetName() const override { return m_fileName.c_str(); }; - - void FreeTemporaryMemory() override; - - // tries to raise the priority of the read; this is advisory and may have no effect - void SetPriority(EStreamTaskPriority EPriority); - uint64 GetPriority() const { return m_params.ePriority; }; - - void* GetFileReadBuffer() { return m_buffer; } //GetBuffer from IReadStream is "const void *" - AZStd::size_t GetFileSize() { return m_fileSize; } - - void SetFileRequest(AZ::IO::FileRequestPtr request) { m_fileRequest = AZStd::move(request); } - AZ::IO::FileRequestPtr GetFileRequest() { return m_fileRequest; } - - void OnRequestComplete(AZ::IO::SizeType numBytesRead, void* buffer, AZ::IO::IStreamerTypes::RequestStatus requestState); - -private: - AZRequestReadStream(); - virtual ~AZRequestReadStream(); - - // call the async callback - void ExecuteAsyncCallback_CBLocked(); - void ExecuteSyncCallback_CBLocked(); - void RequestCompleteOnMainThread(); - - AZStd::atomic_int m_refCount; - - CryCriticalSection m_callbackLock; - StreamReadParams m_params; - AZStd::semaphore m_wait; - - CryStringLocal m_fileName; - AZ::IO::FileRequestPtr m_fileRequest; - - // Bytes actually read from media. - void* m_buffer; - - // the type of the task - EStreamTaskType m_Type; - // the initial data from the user - // the callback; may be NULL - IStreamCallback* m_callback; - - AZ::IO::SizeType m_fileSize; //Expected number of bytes to be read. - AZ::IO::SizeType m_numBytesRead; //On a successful read m_nBytesRead == m_fileSize; - - bool m_isAsyncCallbackExecuted; - bool m_isSyncCallbackExecuted; - bool m_isFileRequestComplete; - - bool m_isError; - bool m_isFinished; - unsigned int m_IOError; -}; - -TYPEDEF_AUTOPTR(AZRequestReadStream); diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp deleted file mode 100644 index 61052bc991..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp +++ /dev/null @@ -1,1027 +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 "StreamAsyncFileRequest.h" - -#include - -#include "StreamEngine.h" -#include "../System.h" -#include -#include - -extern CMTSafeHeap* g_pPakHeap; - -#if defined(STREAMENGINE_ENABLE_STATS) -extern SStreamEngineStatistics* g_pStreamingStatistics; -#endif - -extern SStreamEngineOpenStats* g_pStreamingOpenStatistics; - -volatile int CAsyncIOFileRequest::s_nLiveRequests; -SLockFreeSingleLinkedListHeader CAsyncIOFileRequest::s_freeRequests; - - -#ifdef STREAMENGINE_ENABLE_LISTENER - -class NotifyListenerIO -{ -public: - NotifyListenerIO(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq, AZ::IO::CCachedFileData* pZipEntry, uint32 readSize) - : m_pL(pL) - , m_pReq(pReq) - { - if (m_pL) - { - m_pL->OnStreamBeginIO( - m_pReq, - (pZipEntry && pZipEntry->m_pFileEntry->nMethod) ? pZipEntry->GetFileEntry()->desc.lSizeCompressed : m_pReq->m_nFileSize, - readSize, - pReq->m_eMediaType); - } - } - ~NotifyListenerIO() - { - End(); - } - void End() - { - if (m_pL) - { - m_pL->OnStreamEndIO(m_pReq); - m_pL = NULL; - } - } - -private: - NotifyListenerIO(const NotifyListenerIO&); - NotifyListenerIO& operator = (const NotifyListenerIO&); - -private: - IStreamEngineListener* m_pL; - CAsyncIOFileRequest* m_pReq; -}; - -#endif //STREAMENGINE_ENABLE_LISTENER - -////////////////////////////////////////////////////////////////////////// - -void* CAsyncIOFileRequest::operator new (size_t sz) -{ - return CryModuleMemalign(sz, alignof(CAsyncIOFileRequest)); -} - -void CAsyncIOFileRequest::operator delete(void* p) -{ - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest::CAsyncIOFileRequest() - : m_nRefCount(0) - , m_pMemoryBuffer(NULL) -{ - Reset(); -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest::~CAsyncIOFileRequest() -{ -#ifndef _RELEASE - if (m_pMemoryBuffer) - { - __debugbreak(); - } - if (m_eType) - { - __debugbreak(); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -uint32 CAsyncIOFileRequest::ConfigureRead(AZ::IO::CCachedFileData* pFileData) -{ - AZ::IO::ZipDir::FileEntry* pFileEntry = pFileData ? pFileData->m_pFileEntry : NULL; - - if (!pFileData || !pFileEntry->IsCompressed()) - { - m_bCompressedBuffer = false; - m_nFileSizeCompressed = m_nFileSize; - m_nSizeOnMedia = m_nRequestedSize; - - m_nPageReadStart = m_nRequestedOffset; - m_nPageReadEnd = m_nRequestedOffset + m_nRequestedSize; - } - else - { - m_bCompressedBuffer = true; - m_nFileSize = pFileEntry->desc.lSizeUncompressed; - m_nFileSizeCompressed = pFileEntry->desc.lSizeCompressed; - m_nSizeOnMedia = m_nFileSizeCompressed; - - m_nPageReadStart = 0; - m_nPageReadEnd = m_nFileSizeCompressed; - } - - if (pFileData && !m_bWriteOnlyExternal) - { - m_crc32FromHeader = pFileEntry->desc.lCRC32; - } - - m_nPageReadCurrent = 0; - - m_bStreamInPlace = !m_bCompressedBuffer || ((!m_pExternalMemoryBuffer || !m_bWriteOnlyExternal) && (m_nFileSize > m_nFileSizeCompressed)); - m_bReadBegun = 1; - - return 0; -} - -bool CAsyncIOFileRequest::CanReadInPages() -{ - bool bReadInBlocks = false; - - if (g_cvars.sys_streaming_in_blocks) - { - //stream is compressed and uncompressed size is greater than one page - if (!m_bCompressedBuffer || m_nFileSizeCompressed > STREAMING_BLOCK_SIZE) - { - bReadInBlocks = true; - } - } - - return bReadInBlocks; -} - -uint32 CAsyncIOFileRequest::AllocateOutput([[maybe_unused]] AZ::IO::CCachedFileData* pZipEntry) -{ - if (!m_bOutputAllocated) - { - uint32 nAllocSize = 0; - uint32 nReadAllocSize = 0; - uint32 nZStreamOffs = 0; - uint32 nLookaheadOffs = 0; - - if (m_pExternalMemoryBuffer) - { - nReadAllocSize = m_bCompressedBuffer - ? (m_nRequestedSize < m_nFileSize ? m_nFileSize : 0) - : 0; - } - else - { - nReadAllocSize = m_bCompressedBuffer - ? m_nFileSize - : m_nRequestedSize; - } - - nAllocSize = Align(nReadAllocSize, BUFFER_ALIGNMENT); - - bool bReadInBlocks = CanReadInPages(); - bool bNeedsLookahead = m_bStreamInPlace; - bool bBlockDecompress = m_bCompressedBuffer && bReadInBlocks; - - if (bBlockDecompress) - { - nZStreamOffs = nAllocSize; - nAllocSize += Align(sizeof(z_stream), BUFFER_ALIGNMENT); - - if (bNeedsLookahead) - { - nLookaheadOffs = nAllocSize; - nAllocSize += Align(sizeof(*m_pLookahead), BUFFER_ALIGNMENT); - } - } - - char* pBuffer = NULL; - - if (nAllocSize) - { - const char* usageHint = "AsyncIO TempBuffer"; - pBuffer = (char*)GetStreamEngine()->TempAlloc(nAllocSize, usageHint, true, IgnoreOutofTmpMem(), BUFFER_ALIGNMENT); - if (!pBuffer) - { - return ERROR_OUT_OF_MEMORY; - } - } - - if (pBuffer) - { - m_pMemoryBuffer = pBuffer; - m_nMemoryBufferSize = nAllocSize; - } - - if (nReadAllocSize) - { - m_pReadMemoryBuffer = pBuffer; - m_nReadMemoryBufferSize = nReadAllocSize; - } - else - { - m_pReadMemoryBuffer = m_pExternalMemoryBuffer; - m_nReadMemoryBufferSize = m_nRequestedSize; - } - - m_pOutputMemoryBuffer = m_pExternalMemoryBuffer - ? m_pExternalMemoryBuffer - : m_pReadMemoryBuffer; - - if (bBlockDecompress) - { - m_pZlibStream = (z_stream*)&pBuffer[nZStreamOffs]; - memset(m_pZlibStream, 0, sizeof(z_stream)); - - if (bNeedsLookahead) - { - m_pLookahead = new (&pBuffer[nLookaheadOffs]) AZ::IO::ZipDir::UncompressLookahead; - } - - m_pZlibStream->zalloc = CMTSafeHeap::StaticAlloc; - m_pZlibStream->zfree = CMTSafeHeap::StaticFree; - m_pZlibStream->opaque = g_pPakHeap; - } - - if (m_bCompressedBuffer) - { - m_pDecompQueue = new SStreamJobQueue; - } - - // Doesn't need to be atomic, as there's no concurrency yet. - int nMemoryBufferUsers = 0; - if (nReadAllocSize > 0) - { - ++nMemoryBufferUsers; - } - if (m_bCompressedBuffer) - { - ++nMemoryBufferUsers; - } - m_nMemoryBufferUsers = nMemoryBufferUsers; - - m_bOutputAllocated = 1; - } - - return 0; -} - -byte* CAsyncIOFileRequest::AllocatePage(size_t sz, bool bOnlyPakMem, SStreamPageHdr*& pHdrOut) -{ - const char* usageHint = "streaming page"; - size_t nSzAligned = Align(sz, BUFFER_ALIGNMENT); - size_t nToAlloc = nSzAligned + sizeof(SStreamPageHdr); - byte* pRet = (byte*)GetStreamEngine()->TempAlloc(nToAlloc, usageHint, true, !bOnlyPakMem, BUFFER_ALIGNMENT); - if (pRet) - { - pHdrOut = new (pRet + nSzAligned)SStreamPageHdr(nToAlloc); - } - - return pRet; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::Cancel() -{ - if (!HasFailed()) - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - CryOptionalAutoLock decompLock(m_externalBufferLockDecompress, m_pExternalMemoryBuffer != NULL); - - Failed(ERROR_USER_ABORT); - } -} - -void CAsyncIOFileRequest::SyncWithDecompress() -{ - m_decompJobExecutor.reset(); // destructor waits on job completion -} - -////////////////////////////////////////////////////////////////////////// -bool CAsyncIOFileRequest::TryCancel() -{ - if (!HasFailed()) - { - bool bExt = false; - if (m_pExternalMemoryBuffer != NULL) - { - if (!m_externalBufferLockRead.TryLock()) - { - return false; - } - if (!m_externalBufferLockDecompress.TryLock()) - { - m_externalBufferLockRead.Unlock(); - return false; - } - bExt = true; - } - - Failed(ERROR_USER_ABORT); - - if (bExt) - { - m_externalBufferLockDecompress.Unlock(); - m_externalBufferLockRead.Unlock(); - } - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::FreeBuffer() -{ - if (m_pZlibStream) - { - //if the stream was cancelled in flight, inform zlib to free internal allocs - if (m_pZlibStream->state) - { - inflateEnd(m_pZlibStream); - } - - m_pZlibStream = NULL; - } - - m_pLookahead = NULL; - - SStreamEngineTempMemStats& tms = GetStreamEngine()->GetTempMemStats(); - - if (m_pDecompQueue) - { - m_pDecompQueue->Flush(tms); - delete m_pDecompQueue; - m_pDecompQueue = NULL; - } - - if (m_pMemoryBuffer) - { - CStreamEngine* pStreamEngine = GetStreamEngine(); - - pStreamEngine->TempFree(m_pMemoryBuffer, m_nMemoryBufferSize); - m_pMemoryBuffer = 0; - } - -#ifdef STREAMENGINE_ENABLE_STATS - // Update Streaming statistics. - if (g_pStreamingStatistics && m_nSizeOnMedia != 0 && m_bStatsUpdated) - { - m_bStatsUpdated = false; - int nSize = (int)m_nSizeOnMedia; - SStreamEngineStatistics& stats = *g_pStreamingStatistics; - CryInterlockedAdd(&stats.nPendingReadBytes, -nSize); - CryInterlockedAdd(&stats.typeInfo[m_eType].nPendingReadBytes, -nSize); - } -#endif -} - -CAsyncIOFileRequest* CAsyncIOFileRequest::Allocate(EStreamTaskType eType) -{ - CAsyncIOFileRequest* pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests)); - IF_UNLIKELY (!pReq) - { - pReq = new CAsyncIOFileRequest; - } - - pReq->Init(eType); - - return pReq; -} - -void CAsyncIOFileRequest::Flush() -{ - for (CAsyncIOFileRequest* pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests)); - pReq; - pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests))) - { - delete pReq; - } -} - -void CAsyncIOFileRequest::Reset() -{ - m_decompJobExecutor.reset(); // destructor waits on job completion - -#ifndef _RELEASE - if (m_pMemoryBuffer) - { - __debugbreak(); - } -#endif - - m_pReadStream = NULL; - m_strFileName.resize(0); - m_pakFile.resize(0); - - // Reset POD members of the structure - memset(&m_nSortKey, 0, ((char*)(this + 1) - (char*)&m_nSortKey)); -} - -void CAsyncIOFileRequest::Init(EStreamTaskType eType) -{ -#ifndef _RELEASE - if (!eType) - { - __debugbreak(); - } -#endif - - m_eType = eType; - -#ifdef STREAMENGINE_ENABLE_STATS - m_startTime = gEnv->pTimer->GetAsyncTime(); -#endif - - if (g_pStreamingOpenStatistics) - { - SStreamEngineOpenStats& stats = *g_pStreamingOpenStatistics; - CryInterlockedIncrement(&stats.nOpenRequestCount); - CryInterlockedIncrement(&stats.nOpenRequestCountByType[eType]); - } - - CryInterlockedIncrement(&s_nLiveRequests); -} - -void CAsyncIOFileRequest::Finalize() -{ -#ifndef _RELEASE - if (!m_eType) - { - __debugbreak(); - } -#endif - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamDone(this); - } -#endif - - if (g_pStreamingOpenStatistics) - { - SStreamEngineOpenStats& stats = *g_pStreamingOpenStatistics; - CryInterlockedDecrement(&stats.nOpenRequestCount); - CryInterlockedDecrement(&stats.nOpenRequestCountByType[m_eType]); - } - - CryInterlockedDecrement(&s_nLiveRequests); - - FreeBuffer(); - Reset(); -} - -uint32 CAsyncIOFileRequest::OpenFile(CCryFile& file) -{ - auto* pIPak = gEnv ? gEnv->pCryPak : NULL; - PREFAST_ASSUME(pIPak); - - if (m_pReadStream && m_pReadStream->GetParams().nFlags & IStreamEngine::FLAGS_FILE_ON_DISK) - { - pIPak = 0; - } - - file = CCryFile(pIPak); - if (!file.Open(m_strFileName.c_str(), "rb", AZ::IO::IArchive::FOPEN_FORSTREAMING)) - { - return ERROR_CANT_OPEN_FILE; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -uint32 CAsyncIOFileRequest::ReadFile(CStreamingIOThread* pIOThread) -{ - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - CCryFile file; - nError = OpenFile(file); - if (nError) - { - return nError; - } - - m_nFileSize = file.GetLength(); - - if (m_nRequestedOffset >= m_nFileSize) - { - return ERROR_OFFSET_OUT_OF_RANGE; - } - - if (m_nRequestedOffset + m_nRequestedSize > m_nFileSize) - { - return ERROR_SIZE_OUT_OF_RANGE; - } - - if (m_nRequestedSize == 0) - { - // by default, we read the whole file - m_nRequestedSize = m_nFileSize - m_nRequestedOffset; - } - - if (!m_pExternalMemoryBuffer && m_pReadStream) - { - bool bAbortOnFailToAlloc = false; - CReadStream* pReadStream = static_cast(&*m_pReadStream); - m_pExternalMemoryBuffer = pReadStream->OnNeedStorage(m_nFileSize, bAbortOnFailToAlloc); - - if (!m_pExternalMemoryBuffer && bAbortOnFailToAlloc) - { - Cancel(); - m_pReadStream->Abort(); - return ERROR_USER_ABORT; - } - } - - if (HasFailed()) - { - return m_nError; - } - - auto pZipEntry = ((AZ::IO::Archive*)(gEnv->pCryPak))->GetOpenedFileDataInZip(file.GetHandle()); - nError = ConfigureRead(pZipEntry.get()); - if (nError) - { - return nError; - } - - nError = AllocateOutput(pZipEntry.get()); - if (nError) - { - return nError; - } - - return ReadFileInPages(pIOThread, file); -} - -uint32 CAsyncIOFileRequest::ReadFileResume(CStreamingIOThread* pIOThread) -{ - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - CCryFile file; - nError = OpenFile(file); - if (nError) - { - return nError; - } - - auto pZipEntry = ((AZ::IO::Archive*)(gEnv->pCryPak))->GetOpenedFileDataInZip(file.GetHandle()); - - nError = AllocateOutput(pZipEntry.get()); - if (nError) - { - return nError; - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamResumed(this); - } -#endif - - return ReadFileInPages(pIOThread, file); -} - -uint32 CAsyncIOFileRequest::ReadFileInPages(CStreamingIOThread* pIOThread, CCryFile& file) -{ - auto pCryPak = static_cast(gEnv->pCryPak); - auto pZipEntry = pCryPak->GetOpenedFileDataInZip(file.GetHandle()); - - AZ::IO::ZipDir::Cache* pZip = NULL; - unsigned int nZipFlags = 0; - if (pZipEntry) - { - pZip = pZipEntry->GetZip(); - nZipFlags = pZipEntry->m_nArchiveFlags; - } - - if (pIOThread->IsMisscheduled(EStreamSourceMediaType::eStreamSourceTypeHDD)) - { - // We're on the wrong IO thread! - return ERROR_MISSCHEDULED; - } - - bool bReadInPages = CanReadInPages(); - - uint32 nPageReadLen = (m_nPageReadEnd - m_nPageReadStart); - - bool const bCompressed = m_bCompressedBuffer; - bool const bInPlace = m_bStreamInPlace; - bool const bIgnoreOutOfTmp = IgnoreOutofTmpMem(); - - size_t const nReadStartOffset = bCompressed - ? (m_nFileSize - m_nFileSizeCompressed) - : 0; - - byte* const pReadBase = (byte*)m_pReadMemoryBuffer + nReadStartOffset; - byte* const pReadEnd = (byte*)m_pReadMemoryBuffer + m_nReadMemoryBufferSize; - - CStreamEngine* pStreamEngine = static_cast(gEnv->pSystem->GetStreamEngine()); - - uint32 nPageSize = bReadInPages - ? min((uint32)STREAMING_PAGE_SIZE, nPageReadLen - m_nPageReadCurrent) - : nPageReadLen - m_nPageReadCurrent; - - while (nPageSize > 0) - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - //check if job needs to be pre-empted - nError = ReadFileCheckPreempt(pIOThread); - if (nError) - { - return nError; - } - - byte* pReadTarget = pReadBase + m_nPageReadCurrent; - byte* pReadTargetEnd = pReadTarget + nPageSize; - bool bTemporaryReadTarget = false; - SStreamPageHdr* pTemporaryPageHdr = NULL; - - if (bInPlace) - { - if (pReadTargetEnd > pReadEnd) - { - __debugbreak(); - } - } - else - { - pReadTarget = AllocatePage(nPageSize, !bIgnoreOutOfTmp, pTemporaryPageHdr); - - if (!pReadTarget) - { - return ERROR_OUT_OF_MEMORY; - } - - bTemporaryReadTarget = true; - pTemporaryPageHdr->nRefs = 1; - } - -#ifndef _RELEASE - if (m_nPageReadCurrent + nPageSize > nPageReadLen) - { - __debugbreak(); - } -#endif - - { -#ifdef STREAMENGINE_ENABLE_LISTENER - NotifyListenerIO IOListener(gEnv->pSystem->GetStreamEngine()->GetListener(), this, pZipEntry.get(), nPageSize); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); -#endif - - //printf("[StreamRead] %p %i %p %i %i\n", this, m_bCompressedBuffer, pReadTarget, m_nPageReadStart + m_nPageReadCurrent, nPageSize); - - bool bReadOk = false; - - if (pZipEntry) - { - bReadOk = pZipEntry->m_pZip->ReadFile(pZipEntry->m_pFileEntry, pReadTarget, nullptr) == AZ::IO::ZipDir::ZD_ERROR_SUCCESS; - } - else - { - file.Seek(m_nPageReadStart + m_nPageReadCurrent, SEEK_SET); - bReadOk = file.ReadRaw(pReadTarget, nPageSize) == nPageSize; - } - - if (bReadOk) - { - //send each block to listener -#ifdef STREAMENGINE_ENABLE_LISTENER - IOListener.End(); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - m_readTime += gEnv->pTimer->GetAsyncTime() - t0; -#endif - - //release external mem lock, allows jobs to be cancelled mid stream - readLock.Release(); - } - else - { - if (bTemporaryReadTarget) - { - GetStreamEngine()->TempFree(pReadTarget, pTemporaryPageHdr->nSize); - } - - return ERROR_REFSTREAM_ERROR; - } - - bool bLastBlock = (m_nPageReadCurrent + nPageSize) == nPageReadLen; - - if (bCompressed) - { - PushDecompressPage(pStreamEngine->GetJobEngineState(), pReadTarget, pTemporaryPageHdr, nPageSize, bLastBlock); - } - else if (bTemporaryReadTarget) - { - __debugbreak(); - } - - if (pTemporaryPageHdr && CryInterlockedDecrement(&pTemporaryPageHdr->nRefs) == 0) - { - GetStreamEngine()->TempFree(pReadTarget, pTemporaryPageHdr->nSize); - } - - m_nPageReadCurrent += nPageSize; - nPageSize = min((uint32)STREAMING_PAGE_SIZE, nPageReadLen - m_nPageReadCurrent); - } - } - - return 0; -} - -uint32 CAsyncIOFileRequest::ReadFileCheckPreempt(CStreamingIOThread* pIOThread) -{ - if (m_ePriority != estpUrgent) - { - if (pIOThread->HasUrgentRequests()) - { - //printf("Read Job %s pre-empted mid stream. Progress %d / %d bytes\n", m_strFileName.c_str(), m_nBytesRead, m_nFileSizeCompressed); -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamPreempted(this); - } -#endif - return ERROR_PREEMPTED; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -CStreamEngine* CAsyncIOFileRequest::GetStreamEngine() -{ - return (CStreamEngine*)GetISystem()->GetStreamEngine(); -} - -////////////////////////////////////////////////////////////////////////// -EStreamSourceMediaType CAsyncIOFileRequest::GetMediaType() -{ - EStreamSourceMediaType mediaType = m_eMediaType; - - if (mediaType == eStreamSourceTypeUnknown) - { - if (m_bSortKeyComputed) - { - return mediaType; - } - - if (m_strFileName.empty()) - { - mediaType = eStreamSourceTypeMemory; - return mediaType; - } - - mediaType = gEnv->pCryPak->GetFileMediaType(m_strFileName.c_str()); - } - - return mediaType; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::ComputeSortKey(uint64 nCurrentKeyInProgress) -{ - if (m_bSortKeyComputed) - { - return; - } - - m_bSortKeyComputed = true; - - if (m_strFileName.empty()) - { - m_eMediaType = eStreamSourceTypeMemory; - m_nSortKey = m_ePriority; - return; - } - if (HasFailed()) - { - m_nSortKey = 0; - return; - } - - const int MaxPath = 0x800; - char szFullPathBuf[MaxPath]; - const char* szFullPath = gEnv->pCryPak->AdjustFileName(m_strFileName.c_str(), szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), AZ::IO::IArchive::FOPEN_HINT_QUIET); - - auto pCryPak = static_cast(gEnv->pCryPak); - - AZ::IO::ZipDir::CachePtr pZip = 0; - unsigned int archFlags = 0; - AZ::IO::ZipDir::FileEntry* pFileEntry = NULL; - - // tests if the given file path refers to an existing file inside registered (opened) packs - // the path must be absolute normalized lower-case with forward-slashes - AZ::IO::ArchiveLocationPriority varPakPriority = pCryPak->GetPakPriority(); - bool willOpenFromPak = (varPakPriority != AZ::IO::ArchiveLocationPriority::ePakPriorityFileFirst) - || !AZ::IO::FileIOBase::GetDirectInstance()->Exists(szFullPath); - - if (willOpenFromPak) - { - pFileEntry = pCryPak->FindPakFileEntry(szFullPath, archFlags, &pZip, false); - } - - EStreamSourceMediaType ssmt = pCryPak->GetFileMediaType(szFullPath); - - if (pFileEntry) - { - pZip->Refresh(pFileEntry); - m_nDiskOffset = (uint64)pFileEntry->nFileDataOffset; - - m_nSizeOnMedia = pFileEntry->desc.lSizeCompressed; - m_nFileSize = pFileEntry->desc.lSizeUncompressed; - - m_pakFile = pZip->GetFilePath(); - } - - m_eMediaType = ssmt; - - if (ssmt != eStreamSourceTypeMemory) - { - int32 nCurrentSweep = (nCurrentKeyInProgress >> 30) & ((1 << 10) - 1); - int32 nCurrentTG = (nCurrentKeyInProgress >> 40) & ((1 << 20) - 1); - - if (pFileEntry && !pFileEntry->IsCompressed()) - { - m_nDiskOffset += m_nRequestedOffset; - } - - // group items by priority, then by snapped request time, then sort by disk offset - m_nTimeGroup = (uint64)(gEnv->pTimer->GetAsyncTime().GetSeconds() / max(1, g_cvars.sys_streaming_requests_grouping_time_period)); - m_nSweep = (m_nTimeGroup == nCurrentTG) - ? nCurrentSweep - : 0; - uint64 nPrioriry = m_ePriority; - - int64 nDiskOffsetKB = m_nDiskOffset >> 10; // KB - m_nSortKey = (nDiskOffsetKB) | (((uint64)m_nTimeGroup) << 40) | ((uint64)m_nSweep << 30) | (nPrioriry << 60); - - // make sure we do not break incremental head movement within time group on every new request - if (m_nSortKey <= nCurrentKeyInProgress) - { - ++m_nSweep; - m_nSortKey = (nDiskOffsetKB) | (((uint64)m_nTimeGroup) << 40) | ((uint64)m_nSweep << 30) | (nPrioriry << 60); - } - } - else - { - m_nSortKey = m_ePriority; - } - -#if defined(STREAMENGINE_ENABLE_STATS) - // Update Streaming statistics. - if (!m_bStatsUpdated && g_pStreamingStatistics && m_nSizeOnMedia != 0) - { - m_bStatsUpdated = true; - SStreamEngineStatistics& stats = *g_pStreamingStatistics; - - // if the file is not compressed then it will only read the requested size - uint32 nReadSize = m_nSizeOnMedia; - if (m_nSizeOnMedia == m_nFileSize) - { - nReadSize = m_nRequestedSize; - } - - CryInterlockedAdd(&stats.nPendingReadBytes, nReadSize); - CryInterlockedAdd(&stats.typeInfo[m_eType].nPendingReadBytes, nReadSize); - } -#endif -} - -void CAsyncIOFileRequest::SetPriority(EStreamTaskPriority estp) -{ - m_ePriority = estp; - - if (m_eMediaType != eStreamSourceTypeMemory) - { - m_nSortKey &= ~(15ULL << 60); - m_nSortKey |= static_cast(estp) << 60; - } - else - { - m_nSortKey = m_ePriority; - } -} - -void CAsyncIOFileRequest::BumpSweep() -{ - ++m_nSweep; - if (m_eMediaType != eStreamSourceTypeMemory) - { - m_nSortKey += 1 << 30; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CAsyncIOFileRequest::IgnoreOutofTmpMem() const -{ - if (m_pReadStream && - (m_pReadStream->GetParams().ePriority == estpUrgent || - m_pReadStream->GetParams().nFlags & IStreamEngine::FLAGS_IGNORE_TMP_OUT_OF_MEM)) - { - return true; - } - - return false; -} - -SStreamRequestQueue::SStreamRequestQueue() -{ - m_requests.reserve(4096); -} - -SStreamRequestQueue::~SStreamRequestQueue() -{ - Reset(); -} - -void SStreamRequestQueue::Reset() -{ - CryAutoLock l(m_lock); - for (size_t i = 0, c = m_requests.size(); i != c; ++i) - { - m_requests[i]->Release(); - } - m_requests.clear(); -} - -bool SStreamRequestQueue::IsEmpty() const -{ - return m_requests.empty(); -} - -bool SStreamRequestQueue::TryPopRequest(CAsyncIOFileRequest_AutoPtr& pOut) -{ - CryAutoLock l(m_lock); - if (!m_requests.empty()) - { - pOut = m_requests.front(); - pOut->Release(); - m_requests.erase(m_requests.begin()); - return true; - } - return false; -} - -void* SStreamEngineTempMemStats::TempAlloc(CMTSafeHeap* pHeap, size_t nSize, const char* szDbgSource, bool bFallBackToMalloc, bool bUrgent, uint32 align) -{ - // Only allow falling back to malloc if the size fits within the stream budget, the request is urgent, or the temp memory is 0 - for those files that are over budget on their own. - long nInUse = m_nTempAllocatedMemory; - bFallBackToMalloc = - bUrgent - || (bFallBackToMalloc && ((nInUse == 0) || (nInUse + static_cast(nSize) <= m_nTempMemoryBudget))) - ; - - void* p = pHeap->TempAlloc(nSize, szDbgSource, bFallBackToMalloc, align); -#if MTSAFE_USE_GENERAL_HEAP - bool bInGenHeap = pHeap->IsInGeneralHeap(p); -#else - bool bInGenHeap = false; -#endif - if (p && !bInGenHeap) - { - ReportTempMemAlloc(nSize, 0, false); - } - - return p; -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h deleted file mode 100644 index 4a112ef68f..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h +++ /dev/null @@ -1,571 +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 : Streaming Thread for IO - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H -#pragma once - -#include -#include -#include "TimeValue.h" - -#define STREAMENGINE_LL_ALIGN _MS_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) - -class CStreamEngine; -class CAsyncIOFileRequest; -struct z_stream_s; -class CStreamingIOThread; -namespace AZ::IO -{ - struct CCachedFileData; -} -class CCryFile; -struct SStreamJobEngineState; -class CMTSafeHeap; -class CAsyncIOFileRequest_TransferPtr; -struct SStreamEngineTempMemStats; - -#if !defined(USE_EDGE_ZLIB) -// Prevent compilation conflicts - zconf.h (included by zlib.h) defines WINDOWS and WIN32 - those -// definitions conflict with CryEngine's definitions. - -# if defined(CRY_TMP_DEFINED_WINDOWS) || defined(CRY_TMP_DEFINED_WIN32) -# error CRY_TMP_DEFINED_WINDOWS and/or CRY_TMP_DEFINED_WIN32 already defined -# endif - -# if defined(WINDOWS) -# define CRY_TMP_DEFINED_WINDOWS 1 -# endif -# if defined(WIN32) -# define CRY_TMP_DEFINED_WIN32 1 -# endif - -# include - -# if !defined(CRY_TMP_DEFINED_WINDOWS) -# undef WINDOWS -#endif -# undef CRY_TMP_DEFINED_WINDOWS -# if !defined(CRY_TMP_DEFINED_WIN32) -# undef WIN32 -# endif -# undef CRY_TMP_DEFINED_WIN32 - -// Undefine macros defined in zutil.h to prevent compilation errors in 'steamclientpublic.h', 'OVR_Math.h' etc. -# undef Assert -# undef Trace -# undef Tracev -# undef Tracevv -# undef Tracec -# undef Tracecv - -#endif // !defined(USE_EDGE_ZLIB) - -namespace AZ::IO::ZipDir { - struct UncompressLookahead; -} - -struct IAsyncIOFileCallback -{ - virtual ~IAsyncIOFileCallback(){} - // Asynchronous finished event. - // Must be thread safe, can be called from a different thread. - virtual void OnAsyncFinished(CAsyncIOFileRequest* pFileRequest) = 0; -}; - -struct SStreamPageHdr -{ - explicit SStreamPageHdr(int size) - : nRefs() - , nSize(size) - {} - - volatile int nRefs; - int nSize; -}; - -struct SStreamJobQueue -{ - enum - { - MaxJobs = 256, - }; - - struct Job - { - void* pSrc; - SStreamPageHdr* pSrcHdr; - uint32 nOffs; - uint32 nBytes : 31; - uint32 bLast : 1; - }; - - SStreamJobQueue() - : m_sema(MaxJobs, MaxJobs) - { - m_nQueueLen = 0; - m_nPush = 0; - m_nPop = 0; - memset(m_jobs, 0, sizeof(m_jobs)); - } - - void Flush(SStreamEngineTempMemStats& tms); - - int Push(void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast); - int Pop(); - - CryFastSemaphore m_sema; - Job m_jobs[MaxJobs]; - volatile int m_nQueueLen; - volatile int m_nPush; - volatile int m_nPop; -}; - -// This class represent a request to read some file from disk asynchronously via one of the IO threads. -class CAsyncIOFileRequest -{ -public: - enum EStatus - { - eStatusNotReady, - eStatusInFileQueue, - eStatusFailed, - eStatusUnzipComplete, - eStatusDone, - }; - - enum - { - BUFFER_ALIGNMENT = 128, - WINDOW_SIZE = 1 << 15, - -#if defined(ANDROID) - STREAMING_PAGE_SIZE = (128 * 1024), -#else - STREAMING_PAGE_SIZE = (1 * 1024 * 1024), -#endif - -#if defined(ANDROID) - STREAMING_BLOCK_SIZE = (64 * 1024), -#else - STREAMING_BLOCK_SIZE = (32 * 1024), -#endif - }; - -public: - static CAsyncIOFileRequest* Allocate(EStreamTaskType eType); - static void Flush(); - -public: - void AddRef(); - int Release(); - -public: - void Init(EStreamTaskType eType); - void Finalize(); - - void Reset(); - - ILINE bool IsCancelled() const { return m_nError == ERROR_USER_ABORT; } - ILINE bool HasFailed() const { return m_nError != 0; } - void Failed(uint32 nError) - { - CryInterlockedCompareExchange(reinterpret_cast(&m_nError), nError, 0); - } - - uint32 OpenFile(CCryFile& file); - - uint32 ReadFile(CStreamingIOThread* pIOThread); - uint32 ReadFileResume(CStreamingIOThread* pIOThread); - uint32 ReadFileInPages(CStreamingIOThread* pIOThread, CCryFile& file); - uint32 ReadFileCheckPreempt(CStreamingIOThread* pIOThread); - - uint32 ConfigureRead(AZ::IO::CCachedFileData* pFileData); - bool CanReadInPages(); - uint32 AllocateOutput(AZ::IO::CCachedFileData* pZipEntry); - unsigned char* AllocatePage(size_t sz, bool bOnlyPakMem, SStreamPageHdr*& pHdrOut); - - static void JobFinalize_Read(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - - uint32 PushDecompressPage(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nBytes, bool bLast); - uint32 PushDecompressBlock(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast); - static void JobStart_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState, int nSlot); - void DecompressBlockEntry(SStreamJobEngineState engineState, int nJob); - - void Cancel(); - bool TryCancel(); - void SyncWithDecompress(); - void ComputeSortKey(uint64 nCurrentKeyInProgress); - void SetPriority(EStreamTaskPriority estp); - void BumpSweep(); - void FreeBuffer(); - - bool IgnoreOutofTmpMem() const; - - CStreamEngine* GetStreamEngine(); - - EStreamSourceMediaType GetMediaType(); - -private: - void* operator new (size_t sz); - void operator delete(void* p); - -private: - static void JobFinalize_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - static void JobFinalize_Transfer(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - -private: - void JobFinalize_Buffer(const SStreamJobEngineState& engineState); - void JobFinalize_Validate(const SStreamJobEngineState& engineState); - -private: - CAsyncIOFileRequest(); - ~CAsyncIOFileRequest(); - -public: - static volatile int s_nLiveRequests; - static SLockFreeSingleLinkedListHeader s_freeRequests; - -public: - // Must be first - STREAMENGINE_LL_ALIGN SLockFreeSingleLinkedListEntry m_nextFree; - - volatile int m_nRefCount; - - // Locks to be held whilst the file is being read, and an external memory buffer is in use - // (to ensure that if cancelled, the stream engine doesn't write to the external buffer) - // Separate locks for read and decomp as they can overlap (block decompress) - // Cancel() must acquire both - CryCriticalSection m_externalBufferLockRead; - CryCriticalSection m_externalBufferLockDecompress; - - CryStringLocal m_strFileName; - string m_pakFile; - - // If request come from stream, it will be not 0. - IReadStreamPtr m_pReadStream; - - AZStd::unique_ptr m_decompJobExecutor; - - // Only POD data should exist beyond this point - will be memsetted to 0 on Reset ! - - uint64 m_nSortKey; - - EStreamTaskPriority m_ePriority; - EStreamSourceMediaType m_eMediaType; - EStreamTaskType m_eType; - - volatile EStatus m_status; - volatile uint32 m_nError; - - uint32 m_nRequestedOffset; - uint32 m_nRequestedSize; - - // the file size, or 0 if the file couldn't be opened - uint32 m_nFileSize; - uint32 m_nFileSizeCompressed; - - void* m_pMemoryBuffer; - uint32 m_nMemoryBufferSize; - volatile int m_nMemoryBufferUsers; - - void* m_pExternalMemoryBuffer; - void* m_pOutputMemoryBuffer; - void* m_pReadMemoryBuffer; - uint32 m_nReadMemoryBufferSize; - - uint32 m_bCompressedBuffer : 1; - uint32 m_bStatsUpdated : 1; - uint32 m_bStreamInPlace : 1; - uint32 m_bWriteOnlyExternal : 1; - uint32 m_bSortKeyComputed : 1; - uint32 m_bOutputAllocated : 1; - uint32 m_bReadBegun : 1; - - // Actual size of the data on the media. - uint32 m_nSizeOnMedia; - - int64 m_nDiskOffset; - int32 m_nReadHeadOffsetKB; // Offset of the Read Head when reading from media. - int32 m_nTimeGroup; - int32 m_nSweep; - - IAsyncIOFileCallback* m_pCallback; - - // - // Block based streaming - // - - uint32 m_nPageReadStart; - uint32 m_nPageReadCurrent; - uint32 m_nPageReadEnd; - - volatile uint32 m_nBytesDecompressed; - - uint32 m_crc32FromHeader; - - volatile LONG m_nFinalised; - - z_stream_s* m_pZlibStream; - AZ::IO::ZipDir::UncompressLookahead* m_pLookahead; - SStreamJobQueue* m_pDecompQueue; - -#ifdef STREAMENGINE_ENABLE_STATS - // Time that read operation took. - CTimeValue m_readTime; - CTimeValue m_unzipTime; - CTimeValue m_verifyTime; - CTimeValue m_startTime; - CTimeValue m_completionTime; - - uint32 m_nReadCounter; -#endif -}; -TYPEDEF_AUTOPTR(CAsyncIOFileRequest); - -struct SStreamRequestQueue -{ - CryCriticalSection m_lock; - std::vector m_requests; - - CryEvent m_awakeEvent; - - SStreamRequestQueue(); - ~SStreamRequestQueue(); - - void Reset(); - bool IsEmpty() const; - - // Transfers ownership (rather than shares ownership) to the queue - void TransferRequest(CAsyncIOFileRequest_TransferPtr& pReq); - bool TryPopRequest(CAsyncIOFileRequest_AutoPtr& pOut); - -private: - SStreamRequestQueue(const SStreamRequestQueue&); - SStreamRequestQueue& operator = (const SStreamRequestQueue&); -}; - -#if defined(STREAMENGINE_ENABLE_STATS) -struct SStreamEngineDecompressStats -{ - uint64 m_nTotalBytesUnziped; - uint64 m_nTempBytesUnziped; - uint64 m_nTotalBytesVerified; - uint64 m_nTempBytesVerified; - - CTimeValue m_totalUnzipTime; - CTimeValue m_tempUnzipTime; - CTimeValue m_totalVerifyTime; - CTimeValue m_tempVerifyTime; -}; -#endif - -class CAsyncIOFileRequest_TransferPtr -{ -public: - explicit CAsyncIOFileRequest_TransferPtr(CAsyncIOFileRequest* p) - : m_p(p) - { - } - - ~CAsyncIOFileRequest_TransferPtr() - { - if (m_p) - { - m_p->Release(); - } - } - - CAsyncIOFileRequest* operator -> () { return m_p; } - CAsyncIOFileRequest& operator * () { return *m_p; } - - const CAsyncIOFileRequest* operator -> () const { return m_p; } - const CAsyncIOFileRequest& operator * () const { return *m_p; } - - operator bool () const { - return m_p != NULL; - } - - CAsyncIOFileRequest* Relinquish() - { - CAsyncIOFileRequest* p = m_p; - m_p = NULL; - return p; - } - - CAsyncIOFileRequest_TransferPtr& operator = (CAsyncIOFileRequest* p) - { -#ifndef _RELEASE - if (m_p) - { - __debugbreak(); - } -#endif - m_p = p; - return *this; - } - -private: - CAsyncIOFileRequest_TransferPtr(const CAsyncIOFileRequest_TransferPtr&); - CAsyncIOFileRequest_TransferPtr& operator = (const CAsyncIOFileRequest_TransferPtr&); - -private: - CAsyncIOFileRequest* m_p; -}; - -class CStreamEngineWakeEvent -{ -public: - CStreamEngineWakeEvent() - : m_state(0) - { - } - - void Set() - { - volatile LONG oldState, newState; - bool bSignalInner; - - do - { - bSignalInner = false; - oldState = m_state; - - newState = oldState | 0x80000000; - if (oldState & 0x7fffffff) - { - bSignalInner = true; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - - if (bSignalInner) - { - m_innerEvent.Set(); - } - } - - bool Wait(uint32 timeout = 0) - { - bool bTimedOut = false; - bool bAcquiredSignal = false; - - while (!bTimedOut && !bAcquiredSignal) - { - volatile long oldState, newState; - do - { - bAcquiredSignal = false; - - oldState = m_state; - if (oldState & 0x80000000) - { - // Signalled - newState = oldState & 0x7fffffff; - bAcquiredSignal = true; - } - else - { - newState = oldState + 1; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - - if (!bAcquiredSignal) - { - if (!timeout) - { - m_innerEvent.Wait(); - } - else - { - bTimedOut = !m_innerEvent.Wait(timeout); - } - - if (!bTimedOut) - { - m_innerEvent.Reset(); - } - - do - { - bAcquiredSignal = false; - - oldState = m_state; - if (!bTimedOut && (oldState & 0x80000000)) - { - newState = (oldState & 0x7fffffff) - 1; - bAcquiredSignal = true; - } - else - { - newState = oldState - 1; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - } - } - - return bAcquiredSignal; - } - -private: - CStreamEngineWakeEvent(const CStreamEngineWakeEvent&); - CStreamEngineWakeEvent& operator = (const CStreamEngineWakeEvent&); - -private: - volatile LONG m_state; - CryEvent m_innerEvent; -}; - -struct SStreamEngineTempMemStats -{ - enum - { - MaxWakeEvents = 8, - }; - - SStreamEngineTempMemStats() - { - memset(this, 0, sizeof(*this)); - } - - void* TempAlloc(CMTSafeHeap* pHeap, size_t nSize, const char* szDbgSource, bool bFallBackToMalloc = true, bool bUrgent = false, uint32 align = 0); - void TempFree(CMTSafeHeap* pHeap, const void* p, size_t nSize); - void ReportTempMemAlloc(uint32 nSizeAlloc, uint32 nSizeFree, bool bTriggerWake); - - volatile LONG m_nTempAllocatedMemory; - volatile LONG m_nTempAllocatedMemoryFrameMax; - int m_nTempMemoryBudget; - CStreamEngineWakeEvent* m_wakeEvents[MaxWakeEvents]; - int m_nWakeEvents; -}; - -struct SStreamJobEngineState -{ - std::vector* pReportQueues; - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics* pStats; - SStreamEngineDecompressStats* pDecompressStats; -#endif - - SStreamEngineTempMemStats* pTempMem; - - CMTSafeHeap* pHeap; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp deleted file mode 100644 index b8bebb49c3..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp +++ /dev/null @@ -1,531 +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 - -#include -#include "StreamAsyncFileRequest.h" - -#include "MTSafeAllocator.h" - -namespace AZ::IO::ZipDir::ZipDirStructuresInternal -{ - extern void ZlibInflateElementPartial_Impl( - int* pReturnCode, z_stream* pZStream, ZipDir::UncompressLookahead* pLookahead, - uint8_t* pOutput, size_t nOutputLen, bool bOutputWriteOnly, - const uint8_t* pInput, size_t nInputLen, size_t* pTotalOut); -} - -#ifdef STREAMENGINE_ENABLE_LISTENER -#include "IStreamEngine.h" -class NotifyListener -{ -public: - NotifyListener(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq) - : m_pL(pL) - , m_pReq(pReq) - , m_bInProgress(false) {} - virtual ~NotifyListener() {} -protected: - IStreamEngineListener* m_pL; - CAsyncIOFileRequest* m_pReq; - bool m_bInProgress; -}; -class NotifyListenerInflate - : NotifyListener -{ -public: - NotifyListenerInflate(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq) - : NotifyListener(pL, pReq) - { - if (m_pL) - { - m_pL->OnStreamBeginInflate(m_pReq); - m_bInProgress = true; - } - } - ~NotifyListenerInflate() - { - End(); - } - void End() - { - if (m_bInProgress) - { - m_pL->OnStreamEndInflate(m_pReq); - m_bInProgress = false; - } - } -}; -#endif - -#if defined(STREAMENGINE_ENABLE_STATS) -#define STREAMENGINE_ENABLE_TIMING -#endif - -//#define STREAM_DECOMPRESS_TRACE(...) OutputDebugString(AZStd::string::format(__VA_ARGS__).c_str()); -#define STREAM_DECOMPRESS_TRACE(...) - -void SStreamJobQueue::Flush(SStreamEngineTempMemStats& tms) -{ - extern CMTSafeHeap* g_pPakHeap; - - for (int c = m_nQueueLen, i = m_nPop % MaxJobs; c; --c, i = (i + 1) % MaxJobs) - { - Job& j = m_jobs[i]; - if (j.pSrcHdr && CryInterlockedDecrement(&j.pSrcHdr->nRefs) == 0) - { - tms.TempFree(g_pPakHeap, j.pSrc, j.pSrcHdr->nSize); - } - j.pSrc = NULL; - } -} - -int SStreamJobQueue::Push(void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast) -{ - m_sema.Acquire(); - - int nSlot = (m_nPush++) % MaxJobs; - - Job& j = m_jobs[nSlot]; - j.pSrc = pSrc; - j.pSrcHdr = pSrcHdr; - j.nOffs = nOffs; - j.nBytes = nBytes; - j.bLast = (uint32)bLast; - - bool bStartNext = CryInterlockedIncrement(&m_nQueueLen) == 1; - return bStartNext ? nSlot : -1; -} - -int SStreamJobQueue::Pop() -{ - int nSlot = (++m_nPop) % MaxJobs; - bool bStartNext = CryInterlockedDecrement(&m_nQueueLen) > 0; - - m_sema.Release(); - - return bStartNext ? nSlot : -1; -} - -void CAsyncIOFileRequest::AddRef() -{ - //int nRef = - CryInterlockedIncrement(&m_nRefCount); - STREAM_DECOMPRESS_TRACE("[StreamDecompress],AddRef,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nRef); -} - -int CAsyncIOFileRequest::Release() -{ - int nRef = CryInterlockedDecrement(&m_nRefCount); - STREAM_DECOMPRESS_TRACE("[StreamDecompress],Release,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nRef); - -#ifndef _RELEASE - if (nRef < 0) - { - __debugbreak(); - } -#endif - - if (nRef == 0) - { - Finalize(); - - CryInterlockedPushEntrySList(s_freeRequests, m_nextFree); - } - - return nRef; -} - -void CAsyncIOFileRequest::DecompressBlockEntry(SStreamJobEngineState engineState, int nJob) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - STREAM_DECOMPRESS_TRACE("[StreamDecompress],DecompressBlockEntry,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nJob); - - CAsyncIOFileRequest_TransferPtr pSelf(this); - - SStreamJobQueue::Job& job = m_pDecompQueue->m_jobs[nJob]; - - void* pSrc = job.pSrc; - SStreamPageHdr* const pSrcHdr = job.pSrcHdr; - const uint32 nOffs = job.nOffs; - const uint32 nBytes = job.nBytes; - const bool bLast = job.bLast; - const bool bFailed = HasFailed(); - - if (!bFailed) - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liStart; - QueryPerformanceCounter(&liStart); -#endif - - //printf("Inflate: %s Avail in: %d, Avail Out: %d, Next In: 0x%p, Next Out: 0x%p\n", m_strFileName.c_str(), m_pZlibStream->avail_in, m_pZlibStream->avail_out, m_pZlibStream->next_in, m_pZlibStream->next_out); - -#ifdef STREAMENGINE_ENABLE_LISTENER - NotifyListenerInflate inflateListener(gEnv->pSystem->GetStreamEngine()->GetListener(), this); -#endif - - size_t nBytesDecomped = m_nBytesDecompressed; - - STREAM_DECOMPRESS_TRACE ("[StreamDecompress],ZlibInflateElementPartial_Impl,0x%x,%s,0x%p,%i,0x%p,%i,%i\n", - CryGetCurrentThreadId(), - m_strFileName.c_str(), - (uint8_t*)m_pReadMemoryBuffer + nBytesDecomped, - m_nFileSize - nBytesDecomped, - (uint8_t*)pSrc + nOffs, - nBytes, - nBytesDecomped); - - int readStatus = Z_OK; - - { - CryOptionalAutoLock decompLock(m_externalBufferLockDecompress, m_pExternalMemoryBuffer != NULL); - - AZ::IO::ZipDir::ZipDirStructuresInternal::ZlibInflateElementPartial_Impl( - &readStatus, - m_pZlibStream, - m_pLookahead, - (uint8_t*)m_pReadMemoryBuffer + nBytesDecomped, - m_nFileSize - nBytesDecomped, - m_bWriteOnlyExternal, - (uint8_t*)pSrc + nOffs, - nBytes, - &nBytesDecomped - ); - } - - m_nBytesDecompressed = nBytesDecomped; - - //inform listen, so aysnc callback does not overlap -#ifdef STREAMENGINE_ENABLE_LISTENER - inflateListener.End(); -#endif - - if (readStatus == Z_OK || readStatus == Z_STREAM_END) - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liEnd, liFreq; - QueryPerformanceCounter(&liEnd); - QueryPerformanceFrequency(&liFreq); - - m_unzipTime += CTimeValue((int64)((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart)); -#endif - } - else - { -#ifndef _RELEASE - AZ_Assert(false, "Decomp Error: %s : %s\n", m_strFileName.c_str(), m_pZlibStream ? m_pZlibStream->msg : "m_pZlibStream == NULL, no message available"); -#endif - Failed(ERROR_DECOMPRESSION_FAIL); - } - } - - if (pSrcHdr) - { - if (CryInterlockedDecrement(&pSrcHdr->nRefs) == 0) - { - engineState.pTempMem->TempFree(engineState.pHeap, pSrc, pSrcHdr->nSize); - } - } - - job.pSrc = NULL; - - int nPopSlot = m_pDecompQueue->Pop(); - - // job is no longer valid - - if (HasFailed() || bLast) - { - JobFinalize_Decompress(pSelf, engineState); - } - else if (nPopSlot >= 0) - { - // Chain start the next job, we're responsible for it. - STREAM_DECOMPRESS_TRACE("[StreamDecompress],Chaining,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nPopSlot); - JobStart_Decompress(pSelf, engineState, nPopSlot); - } - -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedDecrement(&engineState.pStats->nCurrentDecompressCount); -#endif -} - -////////////////////////////////////////////////////////////////////////// - -uint32 CAsyncIOFileRequest::PushDecompressPage(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nBytes, bool bLast) -{ - uint32 nError = 0; - - for (uint32 nBlockPos = 0; !nError && (nBlockPos < nBytes); nBlockPos += STREAMING_BLOCK_SIZE) - { - bool bLastBlock = (nBlockPos + STREAMING_BLOCK_SIZE) >= nBytes; - uint32 nBlockSize = min(nBytes - nBlockPos, (uint32)STREAMING_BLOCK_SIZE); - - nError = PushDecompressBlock(engineState, pSrc, pSrcHdr, nBlockPos, nBlockSize, bLast && bLastBlock); - } - - return nError; -} - -uint32 CAsyncIOFileRequest::PushDecompressBlock(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast) -{ - uint32 nError = m_nError; - - if (!nError) - { - if (pSrcHdr) - { - CryInterlockedIncrement(&pSrcHdr->nRefs); - } - - int nPushJob = m_pDecompQueue->Push(pSrc, pSrcHdr, nOffs, nBytes, bLast); - if (nPushJob >= 0) - { - STREAM_DECOMPRESS_TRACE("[StreamDecompress],PushDecompressBlock,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nPushJob); - - AddRef(); - CAsyncIOFileRequest_TransferPtr pSelf(this); - JobStart_Decompress(pSelf, engineState, nPushJob); - } - } - - return nError; -} - -void CAsyncIOFileRequest::JobStart_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState, int nJob) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],QueueDecompressBlockAppend,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, nJob); - -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedIncrement(&engineState.pStats->nCurrentDecompressCount); -#endif - - CAsyncIOFileRequest* request = pSelf.Relinquish(); - if (!request->m_decompJobExecutor) - { - request->m_decompJobExecutor = AZStd::make_unique(); - } - request->m_decompJobExecutor->StartJob([request, engineState, nJob]() - { - request->DecompressBlockEntry(engineState, nJob); - }); // Legacy JobManager priority: eStreamPriority -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::JobFinalize_Read(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - if (!pSelf->m_bCompressedBuffer || pSelf->HasFailed()) - { - JobFinalize_Transfer(pSelf, engineState); - } -} - -void CAsyncIOFileRequest::JobFinalize_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],FinalizeDecompress,0x%x,%s,0x%p,0x%p,0x%p,0x%p\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, &engineState, engineState.pStats, engineState.pDecompressStats); - - CAsyncIOFileRequest* pReq = &*pSelf; - - if (!pReq->HasFailed()) - { - // Handle reads of subsections of a compressed file, by copying the section to the output - uint8_t* pDst = (uint8_t*)pReq->m_pOutputMemoryBuffer; - uint8_t* pSrc = (uint8_t*)pReq->m_pReadMemoryBuffer + pReq->m_nRequestedOffset; - - if (pDst != pSrc) - { - memmove(pReq->m_pOutputMemoryBuffer, pSrc, pReq->m_nRequestedSize); - } - - pReq->JobFinalize_Validate(engineState); - } - - pReq->JobFinalize_Buffer(engineState); - -#if defined(STREAMENGINE_ENABLE_STATS) && defined(STREAMENGINE_ENABLE_TIMING) - if (pReq->m_unzipTime.GetValue() != 0) - { - engineState.pDecompressStats->m_nTotalBytesUnziped += pReq->m_nFileSize; - engineState.pDecompressStats->m_totalUnzipTime += pReq->m_unzipTime; - - engineState.pDecompressStats->m_nTempBytesUnziped += pReq->m_nFileSize; - engineState.pDecompressStats->m_tempUnzipTime += pReq->m_unzipTime; - } -#endif - - JobFinalize_Transfer(pSelf, engineState); -} - -void CAsyncIOFileRequest::JobFinalize_Buffer(const SStreamJobEngineState& engineState) -{ - if (CryInterlockedDecrement(&m_nMemoryBufferUsers) == 0) - { - z_stream_s* pZlib = m_pZlibStream; - - if (pZlib) - { - //if the stream was cancelled in flight, inform zlib to free internal allocs - if (pZlib->state) - { - inflateEnd(pZlib); - } - - m_pZlibStream = NULL; - } - - if (m_pMemoryBuffer) - { - engineState.pTempMem->TempFree(engineState.pHeap, m_pMemoryBuffer, m_nMemoryBufferSize); - - m_pMemoryBuffer = NULL; - m_nMemoryBufferSize = 0; - } - } -} - -void CAsyncIOFileRequest::JobFinalize_Validate([[maybe_unused]] const SStreamJobEngineState& engineState) -{ -#if defined(SKIP_CHECKSUM_FROM_OPTICAL_MEDIA) - if (m_eMediaType != eStreamSourceTypeDisc) -#endif //SKIP_CHECKSUM_FROM_OPTICAL_MEDIA - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - if (!HasFailed()) - { - if (m_crc32FromHeader != 0 && m_nPageReadStart == 0 && m_nRequestedSize == m_nFileSize) //Compute the CRC32 if appropriate. - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liStart, liEnd, liFreq; - QueryPerformanceCounter(&liStart); -#endif //STREAMENGINE_ENABLE_TIMING - - uint32 nCRC32 = crc32(0, (uint8_t*)m_pReadMemoryBuffer + m_nPageReadStart, m_nRequestedSize); - -#if defined(STREAMENGINE_ENABLE_TIMING) - QueryPerformanceCounter(&liEnd); - QueryPerformanceFrequency(&liFreq); - - m_verifyTime += CTimeValue((int64)((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart)); - - engineState.pDecompressStats->m_nTotalBytesVerified += m_nFileSize; - engineState.pDecompressStats->m_totalVerifyTime += m_verifyTime; - engineState.pDecompressStats->m_nTempBytesVerified += m_nFileSize; - engineState.pDecompressStats->m_tempVerifyTime += m_verifyTime; -#endif //STREAMENGINE_ENABLE_TIMING - - if (m_crc32FromHeader != nCRC32) - { - //The contents of this file don't match what the header expects -#if !defined(_RELEASE) - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR_DBGBRK, "Streaming Engine Failed to verify a file (%s). Computed CRC32 %d does not match stored CRC32 %d", m_strFileName.c_str(), nCRC32, m_crc32FromHeader); -#endif //!_RELEASE - Failed(ERROR_VERIFICATION_FAIL); - } - } - } - } -} - -void CAsyncIOFileRequest::JobFinalize_Transfer(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],FinalizeTransform,0x%x,%s,0x%p,0x%p,0x%p,0x%p\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, &engineState, engineState.pStats, engineState.pDecompressStats); - - if (CryInterlockedCompareExchange(&pSelf->m_nFinalised, 1, 0) == 0) - { -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedIncrement(&engineState.pStats->nCurrentAsyncCount); -#endif - -#if defined(STREAMENGINE_ENABLE_TIMING) - pSelf->m_completionTime = gEnv->pTimer->GetAsyncTime(); -#endif - - int nCallbackThreads = engineState.pReportQueues->size(); - - EStreamTaskType eType = pSelf->m_eType; - if (nCallbackThreads > 1 && eType == eStreamTaskTypeGeometry) - { - // If we have more then 1 call back threads, use this one for geometry only. - (*engineState.pReportQueues)[1]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 2 && eType == eStreamTaskTypeTexture) - { - // If we have more then 1 call back threads, use this one for textures only. - (*engineState.pReportQueues)[2]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 3 && eType == eStreamTaskTypeMergedMesh) - { - // If we have more then 3 call back threads, use this one for merged meshes only. - (*engineState.pReportQueues)[3]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 0) - { - (*engineState.pReportQueues)[0]->TransferRequest(pSelf); - } - else - { - __debugbreak(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void SStreamRequestQueue::TransferRequest(CAsyncIOFileRequest_TransferPtr& pRequest) -{ - { - CryAutoLock l(m_lock); - - m_requests.push_back(pRequest.Relinquish()); - } - - m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void SStreamEngineTempMemStats::TempFree(CMTSafeHeap* pHeap, const void* p, size_t nSize) -{ -#if MTSAFE_USE_GENERAL_HEAP - bool bInGenHeap = pHeap->IsInGeneralHeap(p); -#else - bool bInGenHeap = false; -#endif - pHeap->FreeTemporary(const_cast(p)); - ReportTempMemAlloc(0, bInGenHeap ? 0 : nSize, true); -} - -void SStreamEngineTempMemStats::ReportTempMemAlloc(uint32 nSizeAlloc, uint32 nSizeFree, bool bTriggerWake) -{ - int nAdd = (int)nSizeAlloc - (int)nSizeFree; - int const nOldSize = CryInterlockedExchangeAdd(&m_nTempAllocatedMemory, nAdd); - int const nNewSize = nOldSize + nAdd; - - LONG nNewMax = 0; - LONG nOldMax = 0; - do - { - nOldMax = m_nTempAllocatedMemoryFrameMax; - nNewMax = (LONG)max((int)nNewSize, (int)nOldMax); - } - while (CryInterlockedCompareExchange(&m_nTempAllocatedMemoryFrameMax, nNewMax, nOldMax) != nOldMax); - - if (bTriggerWake) - { - for (int i = 0, c = m_nWakeEvents; i != c; ++i) - { - m_wakeEvents[i]->Set(); - } - } -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp deleted file mode 100644 index 7f8c75b2a8..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp +++ /dev/null @@ -1,1698 +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 : Streaming Engine implementation - - -#include "CrySystem_precompiled.h" -#include "StreamEngine.h" - -//CReadStream is 99% unused since the introduction of AZRequestReadStream. -//In the near future CReadStream will disappear altogether and StreamReadStream cpp/h -// won't be needed anymore. -#include "StreamReadStream.h" - -#include "AZRequestReadStream.h" -#include "Pak/CryPakUtils.h" - -#include "../System.h" - -#include -#include - -#include -#include - -#define MAX_HEAVY_ASSETS 20 - -#if defined(STREAMENGINE_ENABLE_STATS) -SStreamEngineStatistics* g_pStreamingStatistics = 0; -#endif - -SStreamEngineOpenStats* g_pStreamingOpenStatistics = 0; - -extern CMTSafeHeap* g_pPakHeap; - -////////////////////////////////////////////////////////////////////////// -CStreamEngine::CStreamEngine() - : AzFramework::InputChannelEventListener(AzFramework::InputChannelEventListener::GetPriorityDebug()) -{ - m_nBatchMode = 0; - m_bShutDown = false; - m_bUseOpticalDriveThread = g_cvars.sys_streaming_use_optical_drive_thread != 0; - m_nPausedDataTypesMask = 0; - m_bStreamDataOnHDD = gEnv->pCryPak->IsInstalledToHDD(); - -#ifdef STREAMENGINE_ENABLE_STATS - g_pStreamingStatistics = &m_Statistics; - m_Statistics.nPendingReadBytes = 0; - - m_Statistics.nCurrentAsyncCount = 0; - m_Statistics.nCurrentDecompressCount = 0; - m_Statistics.nCurrentFinishedCount = 0; - - memset(&m_decompressStats, 0, sizeof(m_decompressStats)); - - m_nUnzipBandwidth = 0; - m_nUnzipBandwidthAverage = 0; - m_bStreamingStatsPaused = false; - m_bInputCallback = false; - m_bTempMemOutOfBudget = false; - - ClearStatistics(); -#endif - - memset(&m_OpenStatistics, 0, sizeof(m_OpenStatistics)); - g_pStreamingOpenStatistics = &m_OpenStatistics; - -#ifdef STREAMENGINE_ENABLE_LISTENER - m_pListener = NULL; -#endif - - StartThreads(); - - // register system listener - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -////////////////////////////////////////////////////////////////////////// -// MT: Main thread only -CStreamEngine::~CStreamEngine() -{ -#ifdef STREAMENGINE_ENABLE_STATS - g_pStreamingStatistics = 0; - if (m_bInputCallback) - { - AzFramework::InputChannelEventListener::Disconnect(); - } -#endif - g_pStreamingOpenStatistics = NULL; - Shutdown(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::BeginReadGroup() -{ - CryInterlockedIncrement(&m_nBatchMode); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::EndReadGroup() -{ - CryInterlockedDecrement(&m_nBatchMode); - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - // New requests accomulated untill all Start stream requests are submitted and can be properly sorted. - m_pThreadIO[i]->SignalStartWork(false); - } - } -} - -AZ::IO::IStreamerTypes::Priority CStreamEngine::CryStreamPriorityToAZStreamPriority(EStreamTaskPriority cryPriority) -{ - switch (cryPriority) - { - case estpUrgent: - return AZ::IO::IStreamerTypes::s_priorityHighest; - // estpPreempted = 1, //For internal use only - case estpAboveNormal: - return AZ::IO::IStreamerTypes::s_priorityHigh; - case estpNormal: - return AZ::IO::IStreamerTypes::s_priorityMedium; - case estpBelowNormal: - return AZ::IO::IStreamerTypes::s_priorityLow; - case estpIdle: - [[fallthrough]]; - default: - return AZ::IO::IStreamerTypes::s_priorityLowest; - } -} - -AZStd::chrono::milliseconds CStreamEngine::AZDeadlineFromReadParams(const StreamReadParams& params) -{ - - if (params.nLoadTime == 0) - { - // File should be loaded right away. - return AZStd::chrono::milliseconds(0); - } - else - { - return AZStd::chrono::milliseconds(AZStd::max(params.nLoadTime, params.nMaxLoadTime)); - } -} - -////////////////////////////////////////////////////////////////////////// -// Starts asynchronous read from the specified file -// It is expected that the callbacks are called from Main Thread only when -// the async data loading is finished. -IReadStreamPtr CStreamEngine::StartRead (const EStreamTaskType tSource, const char* szFilePath, IStreamCallback* pCallback, const StreamReadParams* pParams) -{ - using namespace AZ::IO; - - if (!szFilePath) - { - CryFatalError("Use of the stream engine without a file is deprecated! Use the job system."); - return NULL; - } - - if (gEnv->IsDedicated()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Attempting to use the stream engine on a dedicated server! Don't do that!"); - return NULL; - } - - if (!m_bShutDown) - { - AZRequestReadStream* pStream = AZRequestReadStream::Allocate(tSource, szFilePath, pCallback, pParams); - if (!pStream) - { - CryFatalError("Failed to create Request Stream for %s", szFilePath); - return nullptr; - } - - size_t offset = pParams ? pParams->nOffset : 0; - AZStd::chrono::microseconds deadline = pParams - ? AZStd::chrono::duration_cast(AZDeadlineFromReadParams(*pParams)) - : AZStd::chrono::microseconds(0); - AZ::IO::IStreamerTypes::Priority priority = pParams - ? CryStreamPriorityToAZStreamPriority(pParams->ePriority) - : AZ::IO::IStreamerTypes::s_priorityHighest; - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - pStream->AddRef(); - - auto callback = [this, pStream](FileRequestHandle request) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRenderDetailed); - auto streamer = AZ::Interface::Get(); - void* buffer = nullptr; - AZ::u64 bytesRead = 0; - [[maybe_unused]] bool result = streamer->GetReadRequestResult(request, buffer, bytesRead); - AZ_Assert(result, "Cry Stream Engine requested a callback on reading, but couldn't retrieve result."); - QueueRequestCompleteJob(pStream, bytesRead, buffer, streamer->GetRequestStatus(request)); - // Release reference that was taken above in order to hold onto stream while job is queued - pStream->Release(); - }; - - // Register stream and start file request. - IReadStreamPtr result = static_cast(pStream); - - auto streamer = AZ::Interface::Get(); - FileRequestPtr azRequest = streamer->Read(szFilePath, pStream->GetFileReadBuffer(), pStream->GetFileSize(), - pStream->GetFileSize(), deadline, priority, offset); - streamer->SetRequestCompleteCallback(azRequest, callback); - pStream->SetFileRequest(azRequest); - streamer->QueueRequest(azRequest); - - return result; - } - - return NULL; -} - -//It is NOT necessary to schedule the callbacks on the main thread. -//Regular async calls is OK. -size_t CStreamEngine::StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback) -{ - using namespace AZ::IO; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - - size_t nValidStreams = 0; - - if (!m_bShutDown) - { - enum - { - MaxStreamsPerBatch = 32 - }; - - size_t nReqIdx = 0; - - // we have requests to evaluate, call the callback before enqueing the requests - if (numReqs > 0 && preRequestCallback != nullptr) - { - (*preRequestCallback)(); - } - - if (numReqs > 0) - { - numReqs = AZStd::min(numReqs, aznumeric_cast(MaxStreamsPerBatch)); - AZStd::vector batch; - - auto streamer = AZ::Interface::Get(); - streamer->CreateRequestBatch(batch, numReqs); - - while (numReqs > 0) - { - const StreamReadBatchParams& args = pReqs[nReqIdx]; - - if (!args.szFile) - { - CryFatalError("Use of the stream engine without a file is deprecated! Use the job system."); - } - - AZRequestReadStream* pStream; - - { - FRAME_PROFILER_FAST("CStreamEngine::StartBatchRead_AllocReadStream", gEnv->pSystem, PROFILE_SYSTEM, gEnv->bProfilerEnabled); - pStream = AZRequestReadStream::Allocate(args.tSource, args.szFile, args.pCallback, &args.params); - } - - if (pStream) - { - FileRequestPtr& request = batch[nValidStreams]; - pStreamsOut[nValidStreams++] = pStream; - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - pStream->AddRef(); - auto callback = [this, pStream](FileRequestHandle request) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRenderDetailed); - auto streamer = AZ::Interface::Get(); - void* buffer = nullptr; - AZ::u64 bytesRead = 0; - [[maybe_unused]] bool result = streamer->GetReadRequestResult(request, buffer, bytesRead); - AZ_Assert(result, "Cry Stream Engine requested a callback on reading, but couldn't retrieve result."); - QueueRequestCompleteJob(pStream, bytesRead, buffer, streamer->GetRequestStatus(request)); - // Release reference that was taken above in order to hold onto stream while job is queued - pStream->Release(); - }; - - streamer->Read(request, args.szFile, pStream->GetFileReadBuffer(), pStream->GetFileSize(), - pStream->GetFileSize(), AZDeadlineFromReadParams(args.params), - CryStreamPriorityToAZStreamPriority(args.params.ePriority), args.params.nOffset); - streamer->SetRequestCompleteCallback(request, callback); - pStream->SetFileRequest(request); - } - else - { - CryFatalError("Failed to create Request Stream for %s at mip number %d", args.szFile, (int)nReqIdx); - } - - --numReqs; - ++nReqIdx; - } - - streamer->QueueRequestBatch(AZStd::move(batch)); - } - } - - return nValidStreams; -} - -void CStreamEngine::QueueRequestCompleteJob(AZRequestReadStream* stream, AZ::IO::SizeType numBytesRead, void* buffer, - AZ::IO::IStreamerTypes::RequestStatus requestState) -{ - // Some graphics APIs don't support multiple threads instancing resources such as textures. To work around this limitation - // the jobs that complete a streaming request are queued and a previous request will kick off the next one. This will cause - // only one job that finishes a streaming request to ever be active without causing mutexes to cause stalls in the job system. - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - stream->AddRef(); - auto jobFunction = [this, stream, numBytesRead, buffer, requestState]() - { - stream->OnRequestComplete(numBytesRead, buffer, requestState); - // Release reference that was taken above in order to hold onto stream while job is queued - stream->Release(); - - CryAutoLock lock(m_pendingRequestCompletionsLock); - AZ_Assert(!m_pendingRequestCompletions.empty(), - "CStreamEngine::QueueRequestCompleteJob expects at least one job in the queue as this is this is the job ran from the callback.") - // The top request is always the one that's running, so pop that one of the queue and start any other pending jobs. - m_pendingRequestCompletions.pop(); - if (!m_pendingRequestCompletions.empty()) - { - m_pendingRequestCompletions.front()->Start(); - } - }; - - AZ::Job* job = AZ::CreateJobFunction(jobFunction, true, AZ::JobContext::GetGlobalContext()); - - CryAutoLock lock(m_pendingRequestCompletionsLock); - if (m_pendingRequestCompletions.empty()) - { - m_pendingRequestCompletions.push(job); - job->Start(); - } - else - { - m_pendingRequestCompletions.push(job); - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::ResumePausedStreams_PauseLocked() -{ - for (size_t i = 0; i < (size_t)m_pausedStreams.size(); ) - { - CReadStream* pStream = (CReadStream*)(IReadStream*)m_pausedStreams[i]; - int nStreamMask = 1 << (uint32)pStream->m_Type; - if (0 == (nStreamMask & m_nPausedDataTypesMask)) - { - if (pStream->GetError() == 0) // If was not aborted - { - // This stream must be resumed - m_streams.insert(pStream); - CAsyncIOFileRequest* pFileRequest = pStream->CreateFileRequest(); - if (!StartFileRequest(pFileRequest)) - { - pFileRequest->Release(); - } - } - m_pausedStreams.erase(m_pausedStreams.begin() + i); - } - else - { - i++; - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CStreamEngine::StartFileRequest(CAsyncIOFileRequest* pFileRequest) -{ - bool bStartImmidietly = m_nBatchMode == 0; - - EStreamSourceMediaType eMediaType = pFileRequest->GetMediaType(); - bool bQueued = false; - - CStreamingIOThread* pIO = m_pThreadIO[0]; - - for (size_t i = 1; i < eIOThread_Last; ++i) - { - CStreamingIOThread* pAltIO = m_pThreadIO[i]; - - if (pAltIO && pAltIO->GetMediaType() == eMediaType) - { - pIO = pAltIO; - break; - } - } - - if (pIO) - { -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamEnqueue(pFileRequest, pFileRequest->m_strFileName.c_str(), pFileRequest->m_pReadStream->GetCallerType(), pFileRequest->m_pReadStream->GetParams()); - } -#endif - - pIO->AddRequest(pFileRequest, bStartImmidietly); - bQueued = true; - } - - if (!bQueued) - { - assert(0); // No IO thread. - return false; - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.typeInfo[pFileRequest->m_eType].nTotalStreamingRequestCount++; - - if (g_cvars.sys_streaming_debug == 3) - { - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!pFileRequest->m_strFileName.empty() && !m_bStreamingStatsPaused) - { - if (!sFileFilter || !sFileFilter[0] || strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - CryAutoCriticalSection lock(m_csStats); - m_statsRequestList.insert(m_statsRequestList.begin(), pFileRequest); - } - } - } -#endif - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::SignalToStartWork(EIOThread e, bool bForce) -{ - if ((e >= 0) && (e < eIOThread_Last)) - { - if (m_pThreadIO[e]) - { - m_pThreadIO[e]->SignalStartWork(bForce); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -#ifdef STREAMENGINE_ENABLE_STATS -void UpdateIOThreadStats( - SStreamEngineStatistics::SMediaTypeInfo* pNotInMemoryInfo, - SStreamEngineStatistics::SMediaTypeInfo* pInMemoryInfo, - CStreamingIOThread* pIOThread, - float fSecSinceLastReset) -{ - if (pNotInMemoryInfo == 0 || pIOThread == 0) - { - return; - } - - // not in memory reading - pNotInMemoryInfo->fActiveDuringLastSecond = pIOThread->m_NotInMemoryStats.m_fReadingDuringLastSecond; - pNotInMemoryInfo->fAverageActiveTime = - pIOThread->m_NotInMemoryStats.m_TotalReadTime.GetSeconds() / fSecSinceLastReset * 100; - - pNotInMemoryInfo->nBytesRead = pIOThread->m_NotInMemoryStats.m_nReadBytesInLastSecond; - pNotInMemoryInfo->nRequestCount = pIOThread->m_NotInMemoryStats.m_nRequestCountInLastSecond; - pNotInMemoryInfo->nTotalBytesRead = pIOThread->m_NotInMemoryStats.m_nTotalReadBytes; - pNotInMemoryInfo->nTotalRequestCount = pIOThread->m_NotInMemoryStats.m_nTotalRequestCount; - - pNotInMemoryInfo->nSeekOffsetLastSecond = pIOThread->m_NotInMemoryStats.m_nReadOffsetInLastSecond; - if (pIOThread->m_NotInMemoryStats.m_nTotalRequestCount > 0) - { - pNotInMemoryInfo->nAverageSeekOffset = pIOThread->m_NotInMemoryStats.m_nTotalReadOffset / - pIOThread->m_NotInMemoryStats.m_nTotalRequestCount; - } - else - { - pNotInMemoryInfo->nAverageSeekOffset = 0; - } - - pNotInMemoryInfo->nCurrentReadBandwidth = pIOThread->m_NotInMemoryStats.m_nCurrentReadBandwith; - pNotInMemoryInfo->nSessionReadBandwidth = (uint32)(pNotInMemoryInfo->nTotalBytesRead / fSecSinceLastReset); - - pNotInMemoryInfo->nActualReadBandwidth = pIOThread->m_NotInMemoryStats.m_nActualReadBandwith; - float fTotalReadTime = pIOThread->m_NotInMemoryStats.m_TotalReadTime.GetSeconds(); - if (fTotalReadTime > 0.0f) - { - pNotInMemoryInfo->nAverageActualReadBandwidth = (uint32)(pNotInMemoryInfo->nTotalBytesRead / fTotalReadTime); - } - - // in memory reading - if (pInMemoryInfo) - { - pInMemoryInfo->nBytesRead = pIOThread->m_InMemoryStats.m_nReadBytesInLastSecond; - pInMemoryInfo->nRequestCount = pIOThread->m_InMemoryStats.m_nRequestCountInLastSecond; - pInMemoryInfo->nTotalBytesRead = pIOThread->m_InMemoryStats.m_nTotalReadBytes; - pInMemoryInfo->nTotalRequestCount = pIOThread->m_InMemoryStats.m_nTotalRequestCount; - } -} -#endif - -void CStreamEngine::Update(uint32 nUpdateTypesBitmask) -{ - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_SYSTEM); - AZ_TRACE_METHOD(); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - // Dispatch completed callbacks. - MainThread_FinalizeIOJobs(nUpdateTypesBitmask); -} - -// Gets called regularly, to finalize those proxies whose jobs have -// already been executed (e.g. to call the callbacks) -// - to be called from the main thread only -// - starts new jobs in the single-threaded model -void CStreamEngine::Update() -{ - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - // Dispatch completed callbacks. - MainThread_FinalizeIOJobs(); - -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_resetstats) - { - ClearStatistics(); - g_cvars.sys_streaming_resetstats = 0; - } - - CTimeValue t = gEnv->pTimer->GetAsyncTime(); - if ((t - m_nLastBandwidthUpdateTime).GetMilliSecondsAsInt64() > 1000) - { - // Repeat every second. - m_nUnzipBandwidth = m_decompressStats.m_tempUnzipTime.GetValue() == 0 ? 0 : (uint32)(m_decompressStats.m_nTempBytesUnziped / m_decompressStats.m_tempUnzipTime.GetSeconds()); - m_nVerifyBandwidth = m_decompressStats.m_tempVerifyTime.GetValue() == 0 ? 0 : (uint32)(m_decompressStats.m_nTempBytesVerified / m_decompressStats.m_tempVerifyTime.GetSeconds()); - - m_decompressStats.m_tempUnzipTime.SetValue(0); - m_decompressStats.m_nTempBytesUnziped = 0; - m_decompressStats.m_tempVerifyTime.SetValue(0); - m_decompressStats.m_nTempBytesVerified = 0; - - m_nLastBandwidthUpdateTime = t; - } - if (m_decompressStats.m_totalUnzipTime.GetValue() != 0) - { - m_nUnzipBandwidthAverage = (uint32)(m_decompressStats.m_nTotalBytesUnziped / m_decompressStats.m_totalUnzipTime.GetSeconds()); - } - if (m_decompressStats.m_totalVerifyTime.GetValue() != 0) - { - m_nVerifyBandwidthAverage = (uint32)(m_decompressStats.m_nTotalBytesVerified / m_decompressStats.m_totalVerifyTime.GetSeconds()); - } - - m_Statistics.nDecompressBandwidth = m_nUnzipBandwidth; - m_Statistics.nVerifyBandwidth = m_nVerifyBandwidth; - m_Statistics.nDecompressBandwidthAverage = m_nUnzipBandwidthAverage; - m_Statistics.nVerifyBandwidthAverage = m_nVerifyBandwidthAverage; - - CTimeValue currentTime = gEnv->pTimer->GetAsyncTime(); - - CTimeValue timeSinceLastReset = currentTime - m_TimeOfLastReset; - float fSecSinceLastReset = timeSinceLastReset.GetSeconds(); - - CTimeValue timeSinceLastUpdate = currentTime - m_TimeOfLastUpdate; - - // update the stats every second - if (timeSinceLastUpdate.GetMilliSecondsAsInt64() > 1000) - { - UpdateIOThreadStats(&m_Statistics.hddInfo, &m_Statistics.memoryInfo, m_pThreadIO[eIOThread_HDD], fSecSinceLastReset); - UpdateIOThreadStats(&m_Statistics.discInfo, 0, m_pThreadIO[eIOThread_Optical], fSecSinceLastReset); - UpdateIOThreadStats(&m_Statistics.memoryInfo, 0, m_pThreadIO[eIOThread_InMemory], fSecSinceLastReset); - - SStreamEngineStatistics::SRequestTypeInfo totals; - - // update stats on all types - for (int i = 0; i < eStreamTaskTypeCount; i++) - { - SStreamEngineStatistics::SRequestTypeInfo& info = m_Statistics.typeInfo[i]; - - if (info.nTotalStreamingRequestCount) - { - info.fAverageCompletionTime = info.fTotalCompletionTime / info.nTotalStreamingRequestCount; - } - else - { - info.fAverageCompletionTime = 0; - } - info.nSessionReadBandwidth = (uint32)(info.nTotalReadBytes / fSecSinceLastReset); - info.nCurrentReadBandwidth = (uint32)(info.nTmpReadBytes / timeSinceLastUpdate.GetSeconds()); - - info.fAverageRequestCount = info.nTotalStreamingRequestCount / fSecSinceLastReset; - - totals.Merge(info); - - info.nTmpReadBytes = 0; - } - - if (totals.nTotalStreamingRequestCount > 0) - { - m_Statistics.fAverageCompletionTime = totals.fTotalCompletionTime / totals.nTotalStreamingRequestCount; - } - - m_Statistics.nTotalSessionReadBandwidth = (uint32)(totals.nTotalReadBytes / fSecSinceLastReset); - m_Statistics.nTotalCurrentReadBandwidth = (uint32)(totals.nTmpReadBytes / timeSinceLastUpdate.GetSeconds()); - m_Statistics.fAverageRequestCount = totals.nTotalStreamingRequestCount / fSecSinceLastReset; - - m_Statistics.nTotalRequestCount = totals.nTotalRequestCount; - m_Statistics.nTotalStreamingRequestCount = totals.nTotalStreamingRequestCount; - m_Statistics.nTotalBytesRead = totals.nTotalReadBytes; - - // update this flag only once a second to be sure it's visible in display info - m_Statistics.bTempMemOutOfBudget = m_bTempMemOutOfBudget; - m_bTempMemOutOfBudget = false; - - m_TimeOfLastUpdate = currentTime; - } - - int nTmpAllocated = m_tempMem.m_nTempAllocatedMemoryFrameMax; - m_Statistics.nMaxTempMemory = max(m_Statistics.nMaxTempMemory, nTmpAllocated); - m_Statistics.nTempMemory = nTmpAllocated; - - m_tempMem.m_nTempAllocatedMemoryFrameMax = m_tempMem.m_nTempAllocatedMemory; - - if (m_Statistics.vecHeavyAssets.size() > MAX_HEAVY_ASSETS) - { - AZStd::sort(m_Statistics.vecHeavyAssets.begin(), m_Statistics.vecHeavyAssets.end()); - m_Statistics.vecHeavyAssets.resize(MAX_HEAVY_ASSETS); - } - - if (g_cvars.sys_streaming_debug) - { - DrawStatistics(); - - if (!m_bInputCallback) - { - AzFramework::InputChannelEventListener::Connect(); - m_bInputCallback = true; - } - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Only waits at most the specified amount of time for some IO to complete -void CStreamEngine::UpdateAndWait(bool bAbortAll) -{ - // for stream->Wait sync - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - if (bAbortAll) - { - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->AbortAll(bAbortAll); - } - } - } - - while (!m_finishedStreams.empty() || !m_streams.empty()) - { - Update(); - // In case we still have cancelled or aborted streams in the queue, - // we wake the io threads here to ensure they are removed correctly; - for (uint32 i = 0; i < (uint32)eIOThread_Last; ++i) - { - SignalToStartWork((EIOThread)i, true); - } - CrySleep(10); - } - - if (bAbortAll) - { - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->AbortAll(false); - } - } - } -} - -// In the Multi-Threaded model (with the IO Worker thread) -// removes the proxies from the IO Queue as needed, and the proxies may call their callbacks -void CStreamEngine::MainThread_FinalizeIOJobs(uint32 type) -{ - static bool bNoReentrant = false; - - if (!bNoReentrant) - { - bNoReentrant = true; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks(); -#endif - - int nCount = 0; - - CryMT::vector finishedStreams; - // Dispatch completed callbacks. - CReadStream_AutoPtr pStream(0); - while (m_finishedStreams.try_pop_front(pStream)) - { - if (pStream->m_Type & type) - { - pStream->MainThread_Finalize(); - -#ifdef STREAMENGINE_ENABLE_STATS - // update statistics - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); - UpdateStatistics(pStream); -#endif - - m_streams.erase(pStream); - - nCount++; - // perform time slicing if requested - if (g_cvars.sys_streaming_max_finalize_per_frame > 0 && - nCount > g_cvars.sys_streaming_max_finalize_per_frame) - { - break; - } - } - else - { - finishedStreams.push_back(pStream); - } - } - - bNoReentrant = false; - - while (finishedStreams.try_pop_front(pStream)) - { - m_finishedStreams.push_back(pStream); - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks() - m_Statistics.nMainStreamingThreadWait; -#endif - } -} - - -// In the Multi-Threaded model (with the IO Worker thread) -// removes the proxies from the IO Queue as needed, and the proxies may call their callbacks -void CStreamEngine::MainThread_FinalizeIOJobs() -{ - static bool bNoReentrant = false; - - if (!bNoReentrant) - { - bNoReentrant = true; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks(); -#endif - - int nCount = 0; - - //Optim: swap finished streams out into a non MT vector - //avoid expensive push / pop operations. - m_tempFinishedStreams.clear(); - m_finishedStreams.swap(m_tempFinishedStreams); - - int numFinishedStreams = m_tempFinishedStreams.size(); - - // Dispatch completed callbacks. - for (int i = 0; i < numFinishedStreams; i++) - { - CReadStream_AutoPtr pStream = m_tempFinishedStreams[i]; - - //Check for a certain type of error that we need to handle in a TRC compliant way - if (pStream->GetError() == ERROR_VERIFICATION_FAIL) - { -#if !defined(_RELEASE) - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_COMMENT, "Stream error detected."); -#endif //!_RELEASE - } - - pStream->MainThread_Finalize(); - -#ifdef STREAMENGINE_ENABLE_STATS - // update statistics - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); - UpdateStatistics(pStream); -#endif - - m_streams.erase(pStream); - - nCount++; - - // AM: Optim, no longer support this behavior - // perform time slicing if requested - if (g_cvars.sys_streaming_max_finalize_per_frame > 0 && - nCount > g_cvars.sys_streaming_max_finalize_per_frame) - { - CryLogAlways("sys_streaming_max_finalize_per_frame is now deprecated"); - //break; - } - } - - m_tempFinishedStreams.clear(); - - bNoReentrant = false; - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks() - m_Statistics.nMainStreamingThreadWait; -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::UpdateJobPriority(IReadStreamPtr pJobStream) -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->NeedSorting(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::StopThreads() -{ - for (int i = 0; i < eIOThread_Last; i++) - { - m_pThreadIO[i] = 0; - } - - m_asyncCallbackThreads.clear(); - m_tempMem.m_nWakeEvents = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::StartThreads() -{ - StopThreads(); - - m_tempMem.m_nWakeEvents = 0; - - m_pThreadIO[eIOThread_HDD] = new CStreamingIOThread(this, eStreamSourceTypeHDD, "Streaming File IO HDD");//, 160); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_HDD]->GetWakeEvent(); - - if (!(gEnv->IsDedicated())) - { - if (m_bUseOpticalDriveThread) - { - m_pThreadIO[eIOThread_Optical] = new CStreamingIOThread(this, eStreamSourceTypeDisc, "Streaming File IO Optical"); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_Optical]->GetWakeEvent(); - } - - m_pThreadIO[eIOThread_InMemory] = new CStreamingIOThread(this, eStreamSourceTypeMemory, "Streaming File IO InMemory"); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_InMemory]->GetWakeEvent(); - } - - // Initialise fallback thread matrix, needed for rescheduling - for (int i = 0; i < eIOThread_Last; ++i) - { - if (!m_pThreadIO[i]) - { - continue; - } - - for (int j = 0; j < eIOThread_Last; ++j) - { - if (i == j) - { - continue; - } - if (!m_pThreadIO[j]) - { - continue; - } - - m_pThreadIO[i]->RegisterFallbackIOThread(m_pThreadIO[j]->GetMediaType(), m_pThreadIO[j]); - } - } - - // More decompress threads can be added here. - m_asyncCallbackQueues.push_back(new SStreamRequestQueue); - m_asyncCallbackThreads.push_back(new CStreamingWorkerThread(this, "Streaming AsyncCallback", CStreamingWorkerThread::eWorkerAsyncCallback, m_asyncCallbackQueues.back())); - - //m_asyncCallbackThreads.push_back( new CStreamingWorkerThread(this,"Streaming AsyncCallback Pak 1",CStreamingWorkerThread::eWorkerAsyncCallback, m_asyncCallbackQueues[eStreamTaskTypePak]) ); -} - -//! Puts the memory statistics into the given sizer object -//! According to the specifications in interface ICrySizer -void CStreamEngine::GetMemoryStatistics(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "CRefStreamEngine"); - - size_t nSize = sizeof(*this); - - pSizer->AddObject(this, nSize); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::AbortJob(CReadStream* pStream) -{ - if (m_finishedStreams.try_remove((CReadStream*)pStream)) - { -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); -#endif - } - - { - CryAutoLock pausedLock(m_pausedLock); - if (!m_pausedStreams.empty()) - { - std::vector::iterator it = std::find(m_pausedStreams.begin(), m_pausedStreams.end(), pStream); - if (it != m_pausedStreams.end()) - { - m_pausedStreams.erase(it); - } - } - } - - m_streams.erase(pStream); -} - -#if defined(STREAMENGINE_ENABLE_STATS) -SStreamEngineStatistics& CStreamEngine::GetStreamingStatistics() -{ - return m_Statistics; -} -#endif - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::UpdateStatistics(CReadStream* pReadStream) -{ - uint32 nBytesRead = pReadStream->m_nBytesRead; - - SStreamEngineStatistics::SRequestTypeInfo& info = m_Statistics.typeInfo[pReadStream->m_Type]; - info.nTotalRequestCount++; - - // only add to stats if request was valid - const string& name = pReadStream->GetName(); - if (name.length() > 0) - { - info.nTotalReadBytes += nBytesRead; - info.nTmpReadBytes += nBytesRead; - info.nTotalRequestDataSize += pReadStream->m_Params.nSize; - - CTimeValue completionTime = gEnv->pTimer->GetAsyncTime() - pReadStream->GetRequestTime(); - float fCompletionTime = completionTime.GetMilliSeconds(); - info.fTotalCompletionTime += fCompletionTime; - - size_t splitter = name.find_last_of("."); - if (splitter != string::npos) - { - string extension = name.substr(splitter + 1); - TExtensionInfoMap::iterator findRes = m_PerExtensionInfo.find(extension); - if (findRes == m_PerExtensionInfo.end()) - { - m_PerExtensionInfo[extension] = SExtensionInfo(); - findRes = m_PerExtensionInfo.find(extension); - } - - SExtensionInfo& extensionInfo = findRes->second; - extensionInfo.m_fTotalReadTime += pReadStream->m_ReadTime.GetMilliSeconds(); - extensionInfo.m_nTotalRequests++; - extensionInfo.m_nTotalReadSize += nBytesRead; - extensionInfo.m_nTotalRequestSize += pReadStream->m_Params.nSize; - } - } - - if (nBytesRead > 64 * 1024) - { - m_Statistics.vecHeavyAssets.push_back(SStreamEngineStatistics::SAsset(pReadStream->m_strFileName, nBytesRead)); - } -} -#endif - -void CStreamEngine::Shutdown() -{ - m_bShutDown = true; - - // make sure we don't have queued paused streams during shutdown for the audio system - // or we can suffer from deadlocks - uint32 nPauseMask = GetPauseMask(); - uint32 nUnPauseMask = ~(nPauseMask & ~STREAM_TASK_TYPE_AUDIO_ALL); - PauseStreaming(false, nUnPauseMask); - PauseStreaming(true, nPauseMask); - - UpdateAndWait(true); - CancelAll(); - - StopThreads(); - - m_streams.clear(); - m_finishedStreams.clear(); - - // unregister system listener - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::CancelAll() -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->BeginReset(); - } - } - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->EndReset(); - } - } - - for (size_t i = 0; i < m_asyncCallbackThreads.size(); ++i) - { - m_asyncCallbackThreads[i]->BeginReset(); - } - for (size_t i = 0; i < m_asyncCallbackThreads.size(); ++i) - { - m_asyncCallbackThreads[i]->EndReset(); - } - - // make sure we don't check for canceled tasks when destroying the m_finishedStreams container - m_streams.clear(); - stl::free_container(m_finishedStreams); - stl::free_container(m_tempFinishedStreams); - { - CryAutoLock lock(m_pausedLock); - - std::vector paused; - paused.swap(m_pausedStreams); - - for (std::vector::iterator it = paused.begin(), itEnd = paused.end(); it != itEnd; ++it) - { - CReadStream* pStream = &**it; - pStream->AbortShutdown(); - } - } - - CReadStream::Flush(); - CAsyncIOFileRequest::Flush(); -} - - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::ReportAsyncFileRequestComplete(CAsyncIOFileRequest_AutoPtr pFileRequest) -{ - if (!pFileRequest->IsCancelled()) - { -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamBeginAsyncCallback(&*pFileRequest); - } -#endif - - if (pFileRequest->m_pCallback) - { - pFileRequest->m_pCallback->OnAsyncFinished(pFileRequest); - } - if (pFileRequest->m_pReadStream) - { - CReadStream_AutoPtr pStream = (CReadStream*)(IReadStream*)pFileRequest->m_pReadStream; - pStream->OnAsyncFileRequestComplete(); - m_finishedStreams.push_back(pStream); - -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedIncrement(&m_Statistics.nCurrentFinishedCount); -#endif - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamEndAsyncCallback(&*pFileRequest); - } -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug != 0) - { - if (g_cvars.sys_streaming_debug == 2 || g_cvars.sys_streaming_debug == 4) - { - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!pFileRequest->m_strFileName.empty() && !m_bStreamingStatsPaused) - { - if (!sFileFilter || !sFileFilter[0] || strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - CryAutoCriticalSection lock(m_csStats); - m_statsRequestList.insert(m_statsRequestList.begin(), pFileRequest); - } - } - } - } -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -const char* CStreamEngine::GetStreamTaskTypeName(EStreamTaskType type) -{ - switch (type) - { - case eStreamTaskTypeMusic: - return "Music"; - case eStreamTaskTypeAnimation: - return "Animation"; - case eStreamTaskTypeGeometry: - return "Geometry"; - case eStreamTaskTypeSound: - return "Sound"; - case eStreamTaskTypeTexture: - return "Texture"; - case eStreamTaskTypeShader: - return "Shader"; - case eStreamTaskTypeTerrain: - return "Terrain"; - case eStreamTaskTypeVideo: - return "Video"; - case eStreamTaskTypeFlash: - return "Flash"; - case eStreamTaskTypePak: - return "Pak"; - case eStreamTaskTypeGeomCache: - return "GeomCache"; - case eStreamTaskTypeMergedMesh: - return "MergedMesh"; - } - return ""; -} - -SStreamJobEngineState CStreamEngine::GetJobEngineState() -{ - m_tempMem.m_nTempMemoryBudget = g_cvars.sys_streaming_memory_budget * 1024; - - SStreamJobEngineState state; - state.pReportQueues = &m_asyncCallbackQueues; -#ifdef STREAMENGINE_ENABLE_STATS - state.pStats = &m_Statistics; - state.pDecompressStats = &m_decompressStats; -#endif - state.pHeap = g_pPakHeap; - state.pTempMem = &m_tempMem; - return state; -} - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::GetBandwidthStats(EStreamTaskType type, float* bandwidth) -{ - *bandwidth = m_Statistics.typeInfo[type].nCurrentReadBandwidth / 1024.0f; -} -#endif - -void CStreamEngine::GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut) -{ - openStatsOut = m_OpenStatistics; -} - -#ifdef STREAMENGINE_ENABLE_LISTENER -void CStreamEngine::SetListener(IStreamEngineListener* pListener) -{ - m_pListener = pListener; -} -#endif - -#ifdef STREAMENGINE_ENABLE_LISTENER -IStreamEngineListener* CStreamEngine::GetListener() -{ - return m_pListener; -} -#endif - -////////////////////////////////////////////////////////////////////////// -void* CStreamEngine::TempAlloc(size_t nSize, const char* szDbgSource, bool bFallBackToMalloc, bool bUrgent, uint32 align) -{ - return m_tempMem.TempAlloc(g_pPakHeap, nSize, szDbgSource, bFallBackToMalloc, bUrgent, align); -} - -void CStreamEngine::TempFree(void* p, size_t nSize) -{ - m_tempMem.TempFree(g_pPakHeap, p, nSize); -} - -namespace -{ -#ifdef STREAMENGINE_ENABLE_STATS - void DrawText(const float, const float, ColorF, const char*, ...) - { - // 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 - - void WriteToStreamingLog([[maybe_unused]] const char* str) - { -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug == 4) - { - // ignore invalid file access when logging steaming data - CDebugAllowFileAccess ignoreInvalidFileAccess; - - static string sFileName; - static bool bFirstTime = true; - if (bFirstTime) - { - char path[AZ::IO::IArchive::MaxPath]; - path[sizeof(path) - 1] = 0; - gEnv->pCryPak->AdjustFileName("@usercache@\\TestResults\\StreamingLog.txt", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING); - sFileName = path; - } - AZ::IO::HandleType fileHandle = fxopen(sFileName, (bFirstTime) ? "wt" : "at"); - bFirstTime = false; - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "%s\n", str); - gEnv->pFileIO->Close(fileHandle); - } - } -#endif - } -} - -#ifdef STREAMENGINE_ENABLE_STATS -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::DrawStatistics() -{ - std::vector tempRequests; - - if (g_cvars.sys_streaming_debug == 4) - { - float tx = 0; - float ty = 30; - float ystep = 12.0f; - ColorF clText(1, 0, 0, 1); - - DrawText(tx, ty += ystep, clText, "Recording streaming stats to file ..."); - - { - CryAutoCriticalSection lock(m_csStats); - tempRequests.swap(m_statsRequestList); - } - - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!tempRequests.empty()) - { - for (int i = (int)tempRequests.size() - 1; i >= 0; i--) - { - CAsyncIOFileRequest* pFileRequest = tempRequests[i]; - - if (g_cvars.sys_streaming_debug_filter > 0 && pFileRequest->m_eType != g_cvars.sys_streaming_debug_filter) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter == -1 && pFileRequest->m_eMediaType == eStreamSourceTypeMemory) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter_min_time && (pFileRequest->m_readTime.GetMilliSeconds() < (float)g_cvars.sys_streaming_debug_filter_min_time)) - { - continue; - } - if (sFileFilter && sFileFilter[0] && !strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - continue; - } - - const char* sFlags = (pFileRequest->m_eMediaType == eStreamSourceTypeHDD) ? "HDD" : ((pFileRequest->m_eMediaType == eStreamSourceTypeMemory) ? "mem" : "DVD"); - const char* sPriority = ""; - switch (pFileRequest->m_ePriority) - { - case estpUrgent: - sPriority = " Urgent"; - break; - case estpNormal: - sPriority = " Normal"; - break; - case estpIdle: - sPriority = " Idle"; - break; - case estpPreempted: - sPriority = " Preempted"; - break; - case estpBelowNormal: - sPriority = "BelowNormal"; - break; - case estpAboveNormal: - sPriority = "AboveNormal"; - break; - default: - sPriority = " Unknown"; - break; - } - - string str; - str.Format("[N%6d] [%+8d] [%8d] [%6.2f ms] (%5d|%5d) [%5.3fs] <%3d> <%s> <%s> <%s> %s:", - pFileRequest->m_nReadCounter, - pFileRequest->m_nReadHeadOffsetKB, - pFileRequest->m_nDiskOffset >> 10, - pFileRequest->m_readTime.GetMilliSeconds(), - pFileRequest->m_nSizeOnMedia / 1024, - ((pFileRequest->m_nRequestedSize) ? pFileRequest->m_nRequestedSize : pFileRequest->m_nFileSize) / 1024, - (pFileRequest->m_completionTime - pFileRequest->m_startTime).GetSeconds(), - pFileRequest->m_nTimeGroup, - sPriority, - sFlags, - pFileRequest->m_pakFile.c_str(), - pFileRequest->m_strFileName.c_str()); - - WriteToStreamingLog(str.c_str()); - } - } - - return; - } - - - { - CryAutoCriticalSection lock(m_csStats); - tempRequests = m_statsRequestList; - - size_t nMaxRequests = g_cvars.sys_streaming_debug_filter_min_time ? 1000 : 100; - if (m_statsRequestList.size() > nMaxRequests) - { - m_statsRequestList.resize(nMaxRequests); - } - } - - std::vector& requests = tempRequests; - - stack_string temp; - float tx = 0; - float ty = 30; - float ystep = 12.0f; - float xColumn = 80; - ColorF clText(0, 1, 1, 1); - - SStreamEngineStatistics& stats = m_Statistics; - SStreamEngineOpenStats openStats = m_OpenStatistics; - - const char* sMediaType = m_bStreamDataOnHDD ? "HDD" : "DVD"; - const char* sStatus = (m_bStreamingStatsPaused) ? "Paused" : ""; - DrawText(tx, ty += ystep, clText, "Streaming IO: %.2f|%.2fMB/s, ACT: %3dmsec, Unzip: %.2fMB/s, Verify: %.2fMB/s, Jobs:%5d (%4d) %s %s", - (float)stats.nTotalCurrentReadBandwidth / (1024 * 1024), (float)stats.nTotalSessionReadBandwidth / (1024 * 1024), - (uint32)stats.fAverageCompletionTime, (float)stats.nDecompressBandwidth / (1024 * 1024), (float)stats.nVerifyBandwidth / (1024 * 1024), - (uint32)stats.nTotalStreamingRequestCount, (uint32)(stats.nTotalRequestCount - stats.nTotalStreamingRequestCount), - sMediaType, sStatus); - - DrawText(tx, ty += ystep, clText, "\t Request: Active:%2d (%2.1fMB) Live:%2d Decompress:%2d Async:%2d Finished:%2d Temp Pool Max:%2.1fMB", openStats.nOpenRequestCount, - (float)stats.nPendingReadBytes / (1024 * 1024), CAsyncIOFileRequest::s_nLiveRequests, stats.nCurrentDecompressCount, stats.nCurrentAsyncCount, stats.nCurrentFinishedCount, - (float)stats.nMaxTempMemory / (1024 * 1024)); - - ty += ystep; - - // HDD stats - if (stats.hddInfo.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "HDD : Request: %3d|%5d (%4d MB|%3d KB) - BW: %1.2f|%1.2f Mb/s (Eff: %2.1f|%2.1f Mb/s) \n", - stats.hddInfo.nRequestCount, stats.hddInfo.nTotalRequestCount, (uint32)(stats.hddInfo.nTotalBytesRead / (1024 * 1024)), - (uint32)(stats.hddInfo.nTotalBytesRead / (1024 * stats.hddInfo.nTotalRequestCount)), - (float)stats.hddInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.hddInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nAverageActualReadBandwidth / (1024 * 1024)); - DrawText(tx, ty += ystep, clText, "\t Seek: %1.2f GB - Active: %2.1f%%(%2.1f%%)", - (float)stats.hddInfo.nAverageSeekOffset / (1024 * 1024), - stats.hddInfo.fActiveDuringLastSecond, stats.hddInfo.fAverageActiveTime); - } - // Optical stats - if (stats.discInfo.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "Disc: Request: %3d|%5d (%4d MB|%3d KB) - BW: %1.2f|%1.2f Mb/s (Eff: %2.1f|%2.1f Mb/s) \n", - stats.discInfo.nRequestCount, stats.discInfo.nTotalRequestCount, (uint32)(stats.discInfo.nTotalBytesRead / (1024 * 1024)), - (uint32)(stats.discInfo.nTotalBytesRead / (1024 * stats.discInfo.nTotalRequestCount)), - (float)stats.discInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.discInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.discInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.discInfo.nAverageActualReadBandwidth / (1024 * 1024)); - DrawText(tx, ty += ystep, clText, "\t Seek: %1.2f GB - Active: %2.1f%%(%2.1f%%)", - (float)stats.discInfo.nAverageSeekOffset / (1024 * 1024), - stats.discInfo.fActiveDuringLastSecond, stats.discInfo.fAverageActiveTime); - } - DrawText(tx, ty += ystep, clText, "Mem : Request: %3d|%5d (%4d MB)", - stats.memoryInfo.nRequestCount, stats.memoryInfo.nTotalRequestCount, (stats.memoryInfo.nTotalBytesRead / (1024 * 1024))); - - ty += ystep; - - for (int i = eStreamTaskTypeCount - 1; i >= 1; i--) - { - EStreamTaskType eTaskType = (EStreamTaskType)i; - SStreamEngineStatistics::SRequestTypeInfo info = stats.typeInfo[eTaskType]; - - if (g_cvars.sys_streaming_debug > 1 || info.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "%9s: BSize:%3dKb Read:%4dMb BW:%1.2f|%1.2f Mb/s ACT:%5dms %2d(%2.1fMB)|%5d", - gEnv->pSystem->GetStreamEngine()->GetStreamTaskTypeName(eTaskType), - (uint32)(info.nTotalReadBytes / max((uint32)1, info.nTotalStreamingRequestCount) / 1024), - (uint32)(info.nTotalReadBytes / (1024 * 1024)), (float)info.nCurrentReadBandwidth / (1024 * 1024), - (float)info.nSessionReadBandwidth / (1024 * 1024), (uint32)info.fAverageCompletionTime, - openStats.nOpenRequestCountByType[eTaskType], (float)info.nPendingReadBytes / (1024 * 1024), (uint32)info.nTotalStreamingRequestCount); - } - } - - if (g_cvars.sys_streaming_debug == 5) - { - ty += ystep; - ty += ystep; - - DrawText(tx, ty += ystep, clText, "Name | Time(s) | Size(Kb) | Read(Mb) | ReqS(Mb) | Count"); - - for (TExtensionInfoMap::iterator it = m_PerExtensionInfo.begin(); it != m_PerExtensionInfo.end(); ++it) - { - SExtensionInfo& extensionInfo = it->second; - DrawText(tx, ty += ystep, clText, "%4s | %7.3f | %8d | %8.3f | %8.3f | %5d", - it->first.c_str(), extensionInfo.m_fTotalReadTime / 1000, (uint32)(extensionInfo.m_nTotalReadSize / max((size_t)1, extensionInfo.m_nTotalRequests) / 1024), - extensionInfo.m_nTotalReadSize / (1024.0f * 1024.0f), extensionInfo.m_nTotalRequestSize / (1024.0f * 1024.0f), extensionInfo.m_nTotalRequests); - } - } - else if (g_cvars.sys_streaming_debug > 1) - { - ty += ystep; - - DrawText(tx, ty += ystep, clText, "[Offset KB]"); - DrawText(tx + xColumn, ty, clText, "[io ms]\t(read | size) [t sec] [Grp] < Priority> Filename"); - - ty += ystep; - - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - for (size_t i = 0, nRequests = requests.size(); i < nRequests; i++) - { - CAsyncIOFileRequest* pFileRequest = requests[i]; - - if (g_cvars.sys_streaming_debug_filter > 0 && pFileRequest->m_eType != g_cvars.sys_streaming_debug_filter) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter == -1 && pFileRequest->m_eMediaType == eStreamSourceTypeMemory) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter_min_time && (pFileRequest->m_readTime.GetMilliSeconds() < (float)g_cvars.sys_streaming_debug_filter_min_time)) - { - continue; - } - if (sFileFilter != 0 && sFileFilter[0] && !strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - continue; - } - - { - float fMillis = pFileRequest->m_readTime.GetMilliSeconds(); - const char* sFlags = ""; - switch (pFileRequest->m_eMediaType) - { - case eStreamSourceTypeHDD: - sFlags = "HDD"; - break; - case eStreamSourceTypeDisc: - sFlags = "DVD"; - break; - case eStreamSourceTypeMemory: - sFlags = "MEM"; - break; - } - const char* sPriority = ""; - switch (pFileRequest->m_ePriority) - { - case estpUrgent: - sPriority = " Urgent"; - break; - case estpNormal: - sPriority = " Normal"; - break; - case estpIdle: - sPriority = " Idle"; - break; - case estpPreempted: - sPriority = " Preempted"; - break; - case estpBelowNormal: - sPriority = "BelowNormal"; - break; - case estpAboveNormal: - sPriority = "AboveNormal"; - break; - default: - sPriority = " Unknown"; - break; - } - uint32 nRequestedSize = (pFileRequest->m_nRequestedSize != 0) ? pFileRequest->m_nRequestedSize : pFileRequest->m_nFileSize; - - ////////////////////////////////////////////////////////////////////////// - ColorF colOffset; - if (pFileRequest->m_nReadHeadOffsetKB >= 0) - { - colOffset = ColorF (0, 1, 0, 1); // Green - if (pFileRequest->m_nReadHeadOffsetKB > 32) - { - colOffset = ColorF (0.5f, 1.f, 0, 1.f); // Cyan - } - } - else - { - colOffset = ColorF (1, 0, 0, 1); // Red - } - if (pFileRequest->m_eMediaType != eStreamSourceTypeMemory) - { - DrawText(tx, ty, colOffset, "[%+d]", pFileRequest->m_nReadHeadOffsetKB); - } - ////////////////////////////////////////////////////////////////////////// - - DrawText(tx + xColumn, ty, clText, "[%6.2f]\t(%5d|%5d) [%5.2f] [%3d] <%s> <%s>\t%s", - fMillis, pFileRequest->m_nSizeOnMedia / 1024, nRequestedSize / 1024, (pFileRequest->m_completionTime - pFileRequest->m_startTime).GetSeconds(), - pFileRequest->m_nTimeGroup, sPriority, sFlags, pFileRequest->m_strFileName.c_str()); - - ty += ystep; - } - } - } -} -#endif //STREAMENGINE_ENABLE_STATS - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::ClearStatistics() -{ - m_TimeOfLastReset = gEnv->pTimer->GetAsyncTime(); - m_TimeOfLastUpdate = m_TimeOfLastReset; - - m_Statistics.hddInfo.ResetStats(); - m_Statistics.discInfo.ResetStats(); - - m_PerExtensionInfo.clear(); - - m_Statistics.nDecompressBandwidth = 0; - m_Statistics.nVerifyBandwidth = 0; - m_Statistics.nDecompressBandwidthAverage = 0; - m_Statistics.nVerifyBandwidthAverage = 0; - - m_Statistics.nTotalBytesRead = 0; - m_Statistics.nTotalRequestCount = 0; - m_Statistics.nTotalStreamingRequestCount = 0; - - m_Statistics.nMaxTempMemory = 0; - - m_Statistics.fAverageCompletionTime = 0; - - for (int i = 0; i < eStreamTaskTypeCount; i++) - { - m_Statistics.typeInfo[i].ResetStats(); - } - m_Statistics.vecHeavyAssets.clear(); - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->m_InMemoryStats.Reset(); - m_pThreadIO[i]->m_NotInMemoryStats.Reset(); - } - } -} -#endif - -////////////////////////////////////////////////////////////////////////// -bool CStreamEngine::OnInputChannelEventFiltered([[maybe_unused]] const AzFramework::InputChannel& inputChannel) -{ -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug) - { - if (inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::Function11) - { - m_bStreamingStatsPaused = true; - } - if (inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::Function12) - { - m_bStreamingStatsPaused = false; - } - } -#endif - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_GAME_POST_INIT_DONE: - { - // unpause the streaming engine, when init phase is done - PauseStreaming(false, -1); - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - - WriteToStreamingLog("*LEVEL_LOAD_PREPARE"); - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_START: - { - WriteToStreamingLog("*LEVEL_LOAD_START"); - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - WriteToStreamingLog("*LEVEL_LOAD_END"); - break; - } - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - { - WriteToStreamingLog("*LEVEL_LOAD_PRECACHE_START"); - break; - } - case ESYSTEM_EVENT_LEVEL_PRECACHE_END: - { - WriteToStreamingLog("*LEVEL_LOAD_PRECACHE_END"); - break; - } - case ESYSTEM_EVENT_LEVEL_UNLOAD: - { - UpdateAndWait(true); - CancelAll(); - -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - break; - } - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - UpdateAndWait(true); - CancelAll(); - -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - } - break; - case ESYSTEM_EVENT_FAST_SHUTDOWN: - { - Shutdown(); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::PauseStreaming(bool bPause, uint32 nPauseTypesBitmask) -{ - CryAutoLock pausedLock(m_pausedLock); - if (bPause) - { - m_nPausedDataTypesMask |= nPauseTypesBitmask; - } - else - { - m_nPausedDataTypesMask &= ~nPauseTypesBitmask; - ResumePausedStreams_PauseLocked(); - } -} -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::PauseIO(bool bPause) -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->Pause(bPause); - } - } -} -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h b/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h deleted file mode 100644 index 57d47b8674..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h +++ /dev/null @@ -1,239 +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 : Streaming Engine - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H -#pragma once - - -#include "IStreamEngine.h" -#include "ISystem.h" -#include "TimeValue.h" - -#include -#include "StreamIOThread.h" -#include "StreamReadStream.h" - -#include -#include -#include -#include - -enum EIOThread -{ - eIOThread_HDD = 0, - eIOThread_Optical = 1, - eIOThread_InMemory = 2, - eIOThread_Last = 3, -}; - -////////////////////////////////////////////////////////////////////////// -class CStreamEngine - : public IStreamEngine - , public ISystemEventListener - , public AzFramework::InputChannelEventListener -{ -public: - CStreamEngine(); - ~CStreamEngine(); - - void Shutdown(); - // This is called to cancel all pending requests, without sending callbacks. - void CancelAll(); - - - //Helper added to aid in migration from Cry's CStreamEngine to AZ::IO::Streamer - static AZ::IO::IStreamerTypes::Priority CryStreamPriorityToAZStreamPriority(EStreamTaskPriority cryPriority); - static AZStd::chrono::milliseconds AZDeadlineFromReadParams(const StreamReadParams& params); - - ////////////////////////////////////////////////////////////////////////// - // IStreamEngine interface - ////////////////////////////////////////////////////////////////////////// - IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback, const StreamReadParams* pParams = NULL); - size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback = nullptr); - void BeginReadGroup(); - void EndReadGroup(); - - bool IsStreamDataOnHDD() const { return m_bStreamDataOnHDD; } - void SetStreamDataOnHDD(bool bFlag) { m_bStreamDataOnHDD = bFlag; } - - void Update(); - void UpdateAndWait(bool bAbortAll = false); - void Update(uint32 nUpdateTypesBitmask); - - void GetMemoryStatistics(ICrySizer* pSizer); - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics& GetStreamingStatistics(); - void ClearStatistics(); - - void GetBandwidthStats(EStreamTaskType type, float* bandwidth); -#endif - - void GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut); - - const char* GetStreamTaskTypeName(EStreamTaskType type); - - SStreamJobEngineState GetJobEngineState(); - SStreamEngineTempMemStats& GetTempMemStats() { return m_tempMem; } - - // Will pause or unpause streaming of specified by mask data types - void PauseStreaming(bool bPause, uint32 nPauseTypesBitmask); - // Pause/resumes any IO active from the streaming engine - void PauseIO(bool bPause); - - uint32 GetPauseMask() const { return m_nPausedDataTypesMask; } - -#if defined(STREAMENGINE_ENABLE_LISTENER) - void SetListener(IStreamEngineListener* pListener); - IStreamEngineListener* GetListener(); -#endif - - ////////////////////////////////////////////////////////////////////////// - - // updates the job priority of an IO job into the IOQueue while maintaining order in the queue - void UpdateJobPriority(IReadStreamPtr pJobStream); - - void ReportAsyncFileRequestComplete(CAsyncIOFileRequest_AutoPtr pFileRequest); - void AbortJob(CReadStream* pStream); - - - // Dispatches synchrnous callbacks, free temporary memory hold for callbacks. - void MainThread_FinalizeIOJobs(); - void MainThread_FinalizeIOJobs(uint32 type); - - void* TempAlloc(size_t nSize, const char* szDbgSource, bool bFallBackToMalloc = true, bool bUrgent = false, uint32 align = 0); - void TempFree(void* p, size_t nSize); - - uint32 GetCurrentTempMemorySize() const { return m_tempMem.m_nTempAllocatedMemory; } - void FlagTempMemOutOfBudget() - { -#ifdef STREAMENGINE_ENABLE_STATS - m_bTempMemOutOfBudget = true; -#endif - } - - ////////////////////////////////////////////////////////////////////////// - // AzFramework::InputChannelEventListener - ////////////////////////////////////////////////////////////////////////// - bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; - ////////////////////////////////////////////////////////////////////////// - - bool StartFileRequest(CAsyncIOFileRequest* pFileRequest); - void SignalToStartWork(EIOThread e, bool bForce); - -private: - void StartThreads(); - void StopThreads(); - - void ResumePausedStreams_PauseLocked(); - -#if defined(STREAMENGINE_ENABLE_STATS) - // add job to current statistics - void UpdateStatistics(CReadStream* pReadStream); - void DrawStatistics(); -#endif - - void QueueRequestCompleteJob(class AZRequestReadStream* stream, AZ::IO::SizeType numBytesRead, void* buffer, - AZ::IO::IStreamerTypes::RequestStatus requestState); - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - -private: - - ////////////////////////////////////////////////////////////////////////// - CryMT::set m_streams; - CryMT::vector m_finishedStreams; - std::vector m_tempFinishedStreams; - - CryCriticalSection m_pendingRequestCompletionsLock; - AZStd::queue m_pendingRequestCompletions; - - // 2 IO threads. - _smart_ptr m_pThreadIO[eIOThread_Last]; - std::vector<_smart_ptr > m_asyncCallbackThreads; - std::vector m_asyncCallbackQueues; - - CryCriticalSection m_pausedLock; - std::vector m_pausedStreams; - volatile uint32 m_nPausedDataTypesMask; - - bool m_bStreamDataOnHDD; - bool m_bUseOpticalDriveThread; - - ////////////////////////////////////////////////////////////////////////// - // Streaming statistics. - ////////////////////////////////////////////////////////////////////////// - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* m_pListener; -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - SStreamEngineStatistics m_Statistics; - SStreamEngineDecompressStats m_decompressStats; - CTimeValue m_TimeOfLastReset; - CTimeValue m_TimeOfLastUpdate; - - CryCriticalSection m_csStats; - std::vector m_statsRequestList; - - struct SExtensionInfo - { - SExtensionInfo() - : m_fTotalReadTime(0.0f) - , m_nTotalRequests(0) - , m_nTotalReadSize(0) - , m_nTotalRequestSize(0) - { - } - float m_fTotalReadTime; - size_t m_nTotalRequests; - uint64 m_nTotalReadSize; - uint64 m_nTotalRequestSize; - }; - typedef std::map TExtensionInfoMap; - TExtensionInfoMap m_PerExtensionInfo; - - ////////////////////////////////////////////////////////////////////////// - // Used to calculate unzip/verify bandwidth for statistics. - uint32 m_nUnzipBandwidth; - uint32 m_nUnzipBandwidthAverage; - uint32 m_nVerifyBandwidth; - uint32 m_nVerifyBandwidthAverage; - CTimeValue m_nLastBandwidthUpdateTime; - - bool m_bStreamingStatsPaused; - bool m_bInputCallback; - bool m_bTempMemOutOfBudget; - ////////////////////////////////////////////////////////////////////////// -#endif - - SStreamEngineOpenStats m_OpenStatistics; - - bool m_bShutDown; - - volatile int m_nBatchMode; - - // Memory currently allocated by streaming engine for temporary storage. - SStreamEngineTempMemStats m_tempMem; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp deleted file mode 100644 index e3d184fc31..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp +++ /dev/null @@ -1,819 +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 : Streaming Thread for IO - - -#include "CrySystem_precompiled.h" -#include "StreamIOThread.h" -#include "StreamEngine.h" -#include "../System.h" - -extern SSystemCVars g_cvars; - -//#pragma("control %push O=0") // to disable optimization - -////////////////////////////////////////////////////////////////////////// -CStreamingIOThread::CStreamingIOThread(CStreamEngine* pStreamEngine, EStreamSourceMediaType mediaType, const char* name) -{ - m_pStreamEngine = pStreamEngine; - m_bCancelThreadRequest = false; - m_bNeedSorting = false; - m_bNeedReset = false; - m_bNewRequests = false; - m_name = name; - m_eMediaType = mediaType; - m_nFallbackMTs = 0; - - m_iUrgentRequests = 0; - - m_bPaused = false; - m_bAbortReads = false; - - m_nReadCounter = 0; - m_nStreamingCPU = -1; - - Start((unsigned)(1 << g_cvars.sys_streaming_cpu), name); -} - -CStreamingIOThread::~CStreamingIOThread() -{ - Cancel(); - Stop(); - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::AddRequest(CAsyncIOFileRequest* pRequest, bool bStartImmidietly) -{ - pRequest->AddRef(); // Acquire ownership on file request. - pRequest->m_status = CAsyncIOFileRequest::eStatusInFileQueue; - if (pRequest->m_eMediaType != eStreamSourceTypeMemory) - { - pRequest->m_eMediaType = m_eMediaType; - } - // does this ignore the tmp out of memory - if (pRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - m_newFileRequests.push_back(pRequest); - - if (bStartImmidietly) - { - READ_WRITE_BARRIER - m_bNewRequests = true; - m_awakeEvent.Set(); - } -} - - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::SignalStartWork(bool bForce) -{ - if (!m_newFileRequests.empty() || bForce) - { - READ_WRITE_BARRIER - m_bNewRequests = true; - - m_awakeEvent.Set(); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CStreamingIOThread::Pause(bool bPause) -{ - m_bPaused = bPause; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::Run() -{ - SetName(m_name); - - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); - - m_nLastReadDiskOffset = 0; - - // - // Main thread loop - while (!m_bCancelThreadRequest) - { - if (m_nStreamingCPU != g_cvars.sys_streaming_cpu) - { - m_nStreamingCPU = g_cvars.sys_streaming_cpu; - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define STREAMIOTHREAD_CPP_SECTION_1 1 -#define STREAMIOTHREAD_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION STREAMIOTHREAD_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(StreamEngine/StreamIOThread_cpp) -#endif - } - - if (m_bNewRequests || !m_newFileRequests.empty()) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - else - { -#if defined(_RELEASE) - m_awakeEvent.Wait(); -#elif defined(STREAMENGINE_ENABLE_STATS) - // compute max time to wait - revive thread every second at least once to update stats - bool bWaiting = true; - while (bWaiting) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - uint64 msec = deltaT.GetMilliSecondsAsInt64(); - if (msec < 1000) - { - bWaiting = !m_awakeEvent.Wait(1000 - (uint32)msec); - } - - if (bWaiting) - { - // update the delta time again - t1 = gEnv->pTimer->GetAsyncTime(); - deltaT = t1 - t0; - - m_InMemoryStats.Update(deltaT); - m_NotInMemoryStats.Update(deltaT); - - t0 = t1; - } - } -#endif - } - - if (m_bNeedReset) - { - ProcessReset(); - } - - bool bIsOOM = false; - - while (!m_bCancelThreadRequest && !m_fileRequestQueue.empty()) - { - CAsyncIOFileRequest_TransferPtr pFileRequest(m_fileRequestQueue.back()); - m_fileRequestQueue.pop_back(); - - assert (&*pFileRequest); - - if (pFileRequest->HasFailed()) - { - // check if request was high prio, then decr open count - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - - continue; - } - - ////////////////////////////////////////////////////////////////////////// - // When temporary memory goes out of budget we must loop here and wait until previous file requests are finished and free up memory. - // Only allow processing of requests which are flagged for processing when out of tmp memory - ////////////////////////////////////////////////////////////////////////// - if (bIsOOM && !m_bCancelThreadRequest) - { - m_pStreamEngine->FlagTempMemOutOfBudget(); - if (m_iUrgentRequests > 0) - { - if (m_bNewRequests || !m_newFileRequests.empty()) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - - // readd the current request - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - - // search for the first request which ignores the current out of mem state - // Search for next highest priority request - std::vector::reverse_iterator rit; - for (rit = m_fileRequestQueue.rbegin(); rit != m_fileRequestQueue.rend(); ++rit) - { - if ((*rit)->IgnoreOutofTmpMem()) - { - pFileRequest = *rit; - std::vector::iterator it(rit.base()); - --it; - m_fileRequestQueue.erase(it); - break; - } - } - } - else - { - // read the current request - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - } - } - - // Simply let the io thread sleep when paused before doing any actual IO - while (m_bPaused) - { - CrySleep(10); - } - - // If at this point, the filerequest is zero, the above prioritization of - // urgent requests couldn't find a new task to displace the current - // one. As the current one had been pushed back previously, we can safely - // assume that restarting the loop will grab it again (eventually). - if (!pFileRequest) - { - break; - } - - // check if request was high prio, then decr open count - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - - bIsOOM = false; - - uint32 nSizeOnMedia = pFileRequest->m_nSizeOnMedia; - uint32 nError = 0; - - // Handle file request. - if (m_bAbortReads) - { - nError = ERROR_ABORTED_ON_SHUTDOWN; - } - else if (pFileRequest->m_bReadBegun) - { - nError = pFileRequest->ReadFileResume(this); - } - else - { - nError = pFileRequest->ReadFile(this); - } - -#ifdef STREAMENGINE_ENABLE_STATS - pFileRequest->m_nReadCounter = m_nReadCounter++; -#endif - - if (nError == 0) - { - if (pFileRequest->m_eMediaType != eStreamSourceTypeMemory) - { - pFileRequest->m_nReadHeadOffsetKB = (int32)(((int64)pFileRequest->m_nDiskOffset - m_nLastReadDiskOffset) >> 10); // in KB - m_nLastReadDiskOffset = pFileRequest->m_nDiskOffset + nSizeOnMedia; - -#ifdef STREAMENGINE_ENABLE_STATS - m_NotInMemoryStats.m_nTempReadOffset += abs(pFileRequest->m_nReadHeadOffsetKB); - m_NotInMemoryStats.m_nTotalReadOffset += abs(pFileRequest->m_nReadHeadOffsetKB); - - m_NotInMemoryStats.m_nTempRequestCount++; - - // Calc IO bandwidth only for non memory files. - m_NotInMemoryStats.m_nTempBytesRead += nSizeOnMedia; - m_NotInMemoryStats.m_TempReadTime += pFileRequest->m_readTime; -#endif - } - else - { -#ifdef STREAMENGINE_ENABLE_STATS - m_InMemoryStats.m_nTempRequestCount++; - - // Calc IO bandwidth only for in memory files. - m_InMemoryStats.m_nTempBytesRead += nSizeOnMedia; - m_InMemoryStats.m_TempReadTime += pFileRequest->m_readTime; -#endif - } - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - } - else - { - switch (nError) - { - case ERROR_OUT_OF_MEMORY: - bIsOOM = true; - - pFileRequest->SetPriority(estpPreempted); - - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - m_bNewRequests = true; - break; - - case ERROR_PREEMPTED: - pFileRequest->SetPriority(estpPreempted); - - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - m_bNewRequests = true; - break; - - case ERROR_MISSCHEDULED: - // Request tried to read a file that has changed media type. Reset the sort key - // and reschedule. - pFileRequest->m_bSortKeyComputed = 0; - AddRequest(&*pFileRequest, false); - break; - - default: - pFileRequest->SyncWithDecompress(); - pFileRequest->Failed(nError); - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - break; - } - } - - ////////////////////////////////////////////////////////////////////////// - if (m_bNewRequests) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - if (m_bNeedReset) - { - ProcessReset(); - } - if (m_bNeedSorting) - { - SortRequests(); - } - - ////////////////////////////////////////////////////////////////////////// -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_max_bandwidth != 0) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - - // Sleep in case we are streaming too fast. - const float fTheoreticalReadTime = float(nSizeOnMedia) / g_cvars.sys_streaming_max_bandwidth * 0.00000095367431640625f; // / (1024*1024) - - if (fTheoreticalReadTime - deltaT.GetSeconds() > FLT_EPSILON) - { - uint32 nSleepTime = uint32(1000.f * (fTheoreticalReadTime - deltaT.GetSeconds())); - CrySleep(nSleepTime); - } - } - - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - - // update the stats every second - if (deltaT.GetMilliSecondsAsInt64() > 1000) - { - m_InMemoryStats.Update(deltaT); - m_NotInMemoryStats.Update(deltaT); - - t0 = t1; - } -#endif - } - } -} - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamingIOThread::SStats::Update(const CTimeValue& deltaT) -{ - m_nReadBytesInLastSecond = (uint32)m_nTempBytesRead; - m_nRequestCountInLastSecond = m_nTempRequestCount; - m_nTotalReadBytes += (uint32)m_nTempBytesRead; - m_nTotalRequestCount += m_nTempRequestCount; - m_TotalReadTime += m_TempReadTime; - - if (m_TempReadTime.GetValue() != 0) - { - m_nActualReadBandwith = (uint32)(m_nTempBytesRead / m_TempReadTime.GetSeconds()); - } - else - { - m_nActualReadBandwith = 0; - } - m_nCurrentReadBandwith = (uint32)(m_nTempBytesRead / deltaT.GetSeconds()); - m_fReadingDuringLastSecond = m_TempReadTime.GetSeconds() / deltaT.GetSeconds() * 100; - - if (m_nTempRequestCount > 0) - { - m_nReadOffsetInLastSecond = m_nTempReadOffset / m_nTempRequestCount; - } - else - { - m_nReadOffsetInLastSecond = 0; - } - - m_TempReadTime.SetValue(0); - m_nTempBytesRead = 0; - m_nTempReadOffset = 0; - m_nTempRequestCount = 0; -} -#endif - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::Cancel() -{ - m_bCancelThreadRequest = true; - m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -struct SCompareAsyncFileRequest -{ - bool operator()(CAsyncIOFileRequest* pFile1, CAsyncIOFileRequest* pFile2) const - { - return pFile1->m_nSortKey > pFile2->m_nSortKey; - } -}; - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::SortRequests() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - std::sort(m_fileRequestQueue.begin(), m_fileRequestQueue.end(), SCompareAsyncFileRequest()); - - /* - int nStartOfQueue = 0; - int64 nDiskOffsetLimit = m_nLastReadDiskOffset - 32*1024; // 32KB less only - - int nCount = (int)m_fileRequestQueue.size(); - for (int i = nCount-1; i >= 0; i--) - { - if (m_fileRequestQueue[i]->m_nDiskOffset > nDiskOffsetLimit) - { - nStartOfQueue = i+1; - break; - } - } - if (nStartOfQueue < nCount && nStartOfQueue > 0) - { - int nElements = nCount - nStartOfQueue; - // Move all elements up to nStartOfQueue, from begining of the request array to the end. - m_temporaryArray.resize(0); - // Copy to temp array elements up to nStartOfQueue - m_temporaryArray.insert( m_temporaryArray.end(),m_fileRequestQueue.begin()+nStartOfQueue,m_fileRequestQueue.end() ); - // Remove elements up to nStartOfQueue from request list - m_fileRequestQueue.erase( m_fileRequestQueue.begin()+nStartOfQueue,m_fileRequestQueue.end() ); - // Add elemenets at the end from temp array. - m_fileRequestQueue.insert( m_fileRequestQueue.begin(),m_temporaryArray.begin(),m_temporaryArray.end() ); - } - */ - m_bNeedSorting = false; -} - -void CStreamingIOThread::NeedSorting() -{ - m_bNeedSorting = true; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::ProcessNewRequests() -{ - m_bNewRequests = false; - - std::vector temporaryArray; - temporaryArray.reserve(m_newFileRequests.size()); - m_newFileRequests.swap(temporaryArray); - - std::vector& newFiles = temporaryArray; - - if (!newFiles.empty()) - { - uint64 nCurrentKeyInProgress = m_fileRequestQueue.size() ? m_fileRequestQueue.back()->m_nSortKey : 0; - - // Compute sorting key for new file entries. - int iWakeFallback(0); - const TFallbackIOVecConstIt itEnd = m_FallbackIOThreads.end(); - const size_t fallbackNum = m_FallbackIOThreads.size(); - PREFAST_SUPPRESS_WARNING(6255) - uint8 * pFallbackSignals = fallbackNum ? (uint8*)alloca(fallbackNum) : NULL; - for (uint32 fb = 0; fb < fallbackNum; ++fb) - { - pFallbackSignals[fb] = 0; - } - - for (size_t i = 0, num = newFiles.size(); i < num; i++) - { - CAsyncIOFileRequest* pFilepRequest = newFiles[i]; - - pFilepRequest->ComputeSortKey(nCurrentKeyInProgress); - static_cast(&*pFilepRequest->m_pReadStream)->ComputedMediaType(pFilepRequest->m_eMediaType); - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = m_pStreamEngine->GetListener(); - if (pListener) - { - pListener->OnStreamComputedSortKey(pFilepRequest, pFilepRequest->m_nSortKey); - } -#endif - - bool bFallback = false; - int idx = -1; - for (TFallbackIOVecConstIt it = m_FallbackIOThreads.begin(); it != itEnd && !bFallback; ++it) - { - ++idx; - if (it->second == pFilepRequest->GetMediaType()) - { - if (pFilepRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - (it->first)->AddRequest(pFilepRequest, true); - pFilepRequest->Release(); // Release local ownership of request (moved to fallback IO thread) - iWakeFallback++; - bFallback = true; - pFallbackSignals[idx] = 1; - } - } - if (!bFallback) - { - m_fileRequestQueue.push_back(pFilepRequest); - } - } - - for (uint32 fb = 0; fb < fallbackNum; ++fb) - { - if (pFallbackSignals[fb] != 0) - { - (m_FallbackIOThreads[fb].first)->SignalStartWork(false); - } - } - - SortRequests(); - /* - if (m_fileRequestQueue.back() != pRequest && pRequest != 0) - { - // Highest priority changed. - if (m_fileRequestQueue.back()->m_nDiskOffset < (m_nLastReadDiskOffset-32*1024)) - { - //CryLog( "Bad Offset in Queue" ); - } - } - */ - } -} - -void CStreamingIOThread::ProcessReset() -{ - if (!m_fileRequestQueue.empty()) - { - for (std::vector::iterator it = m_fileRequestQueue.begin(), itEnd = m_fileRequestQueue.end(); it != itEnd; ++it) - { - (*it)->Release(); - } - } - - stl::free_container(m_fileRequestQueue); - - if (!m_temporaryArray.empty()) - { - for (std::vector::iterator it = m_temporaryArray.begin(), itEnd = m_temporaryArray.end(); it != itEnd; ++it) - { - (*it)->Release(); - } - } - - stl::free_container(m_temporaryArray); - - m_bNeedReset = false; - m_resetDoneEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::CancelAll() -{ - { - CryMT::vector::AutoLock lock(m_newFileRequests.get_lock()); - - if (!m_newFileRequests.empty()) - { - CAsyncIOFileRequest* const* it = &m_newFileRequests.front(); - CAsyncIOFileRequest* const* itEnd = it + m_newFileRequests.size(); - for (; it != itEnd; ++it) - { - (*it)->Release(); - } - } - } - - m_newFileRequests.free_memory(); - m_iUrgentRequests = 0; -} - -void CStreamingIOThread::AbortAll(bool bAbort) -{ - m_bAbortReads = bAbort; -} - -void CStreamingIOThread::BeginReset() -{ - CancelAll(); - - m_resetDoneEvent.Reset(); - m_bNeedReset = true; - m_awakeEvent.Set(); -} - -void CStreamingIOThread::EndReset() -{ - m_resetDoneEvent.Wait(); -} -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::RegisterFallbackIOThread(EStreamSourceMediaType mediaType, CStreamingIOThread* pIOThread) -{ - //check if media has not yet been registered - if (!pIOThread) - { - return;//no need for NULL register anymore - } - const TFallbackIOVecConstIt itEnd = m_FallbackIOThreads.end(); - for (TFallbackIOVecConstIt it = m_FallbackIOThreads.begin(); it != itEnd; ++it) - { - if (it->second == mediaType) - { - return; - } - } - m_FallbackIOThreads.push_back(std::make_pair(pIOThread, mediaType)); - m_nFallbackMTs |= 1 << mediaType; -} - -bool CStreamingIOThread::HasUrgentRequests() -{ - bool ret = false; - - if (m_iUrgentRequests > 0) - { - //lock to prevent list modification whilst traversing - m_newFileRequests.get_lock().Lock(); - - int nRequests = m_newFileRequests.size(); - - if (nRequests) - { - for (int i = 0; i < nRequests; i++) - { - if (m_newFileRequests[i]->m_ePriority == estpUrgent) - { - //printf("Urgent task pending: %s\n", m_newFileRequests[i]->m_strFileName.c_str()); - ret = true; - break; - } - } - } - m_newFileRequests.get_lock().Unlock(); - } - return ret; -} - -bool CStreamingIOThread::IsMisscheduled(EStreamSourceMediaType mt) const -{ - if (mt == m_eMediaType) - { - return false; - } - - if (m_nFallbackMTs & (1 << mt)) - { - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -CStreamingWorkerThread::CStreamingWorkerThread(CStreamEngine* pStreamEngine, const char* name, EWorkerType type, SStreamRequestQueue* pQueue) -{ - m_type = type; - m_name = name; - m_pStreamEngine = pStreamEngine; - m_pQueue = pQueue; - m_bCancelThreadRequest = false; - m_bNeedsReset = false; - - Start((unsigned)1 << g_cvars.sys_streaming_cpu_worker, name); -} - -CStreamingWorkerThread::~CStreamingWorkerThread() -{ - Cancel(); - Stop(); - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::Run() -{ - SetName(m_name); - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION STREAMIOTHREAD_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(StreamEngine/StreamIOThread_cpp) -#endif - - // Main thread loop - while (!m_bCancelThreadRequest) - { - m_pQueue->m_awakeEvent.Wait(); - m_pQueue->m_awakeEvent.Reset(); - - CAsyncIOFileRequest_AutoPtr pFileRequest; - while (!m_bCancelThreadRequest && !m_bNeedsReset && m_pQueue->TryPopRequest(pFileRequest)) - { - switch (m_type) - { - case eWorkerAsyncCallback: - { -#ifndef _RELEASE - float fTime = gEnv->pTimer->GetAsyncCurTime(); -#endif - - m_pStreamEngine->ReportAsyncFileRequestComplete(pFileRequest); -#ifndef _RELEASE - float fTime1 = gEnv->pTimer->GetAsyncCurTime(); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedDecrement(&m_pStreamEngine->GetStreamingStatistics().nCurrentAsyncCount); -#endif - -#ifndef _RELEASE - if ((fTime1 - fTime) > 1.f && !pFileRequest->m_strFileName.empty()) - { - string str; - str.Format("[ACALL] %s time=%.5f\n", pFileRequest->m_strFileName.c_str(), (fTime1 - fTime)); - if (gEnv && gEnv->pSystem && gEnv->pLog) - { - gEnv->pLog->Log(str.c_str()); - } - } -#endif - } - break; - } - } - - if (m_bNeedsReset) - { - m_pQueue->Reset(); - m_bNeedsReset = false; - m_resetDoneEvent.Set(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::Cancel() -{ - m_bCancelThreadRequest = true; - m_pQueue->m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::CancelAll() -{ - m_pQueue->Reset(); -} - -void CStreamingWorkerThread::BeginReset() -{ - CancelAll(); - - m_resetDoneEvent.Reset(); - m_bNeedsReset = true; - m_pQueue->m_awakeEvent.Set(); -} - -void CStreamingWorkerThread::EndReset() -{ - m_resetDoneEvent.Wait(); -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h b/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h deleted file mode 100644 index 14bac3a372..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h +++ /dev/null @@ -1,193 +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 : Streaming Thread for IO - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H -#pragma once - -#include -#include "StreamAsyncFileRequest.h" - - -class CStreamEngine; - -////////////////////////////////////////////////////////////////////////// -// Thread that performs IO operations. -////////////////////////////////////////////////////////////////////////// -class CStreamingIOThread - : public CrySimpleThread - , public CMultiThreadRefCount -{ -public: - CStreamingIOThread(CStreamEngine* pStreamEngine, EStreamSourceMediaType mediaType, const char* name); - ~CStreamingIOThread(); - - void CancelAll(); - void AbortAll(bool bAbort); - - void BeginReset(); - void EndReset(); - - void AddRequest(CAsyncIOFileRequest* pRequest, bool bStartImmidietly); - int GetRequestCount() const { return m_fileRequestQueue.size(); }; - void SortRequests(); - void NeedSorting(); - void SignalStartWork(bool bForce); - bool HasUrgentRequests(); - EStreamSourceMediaType GetMediaType() const { return m_eMediaType; } - bool IsMisscheduled(EStreamSourceMediaType mt) const; - - void Pause(bool bPause); - - void RegisterFallbackIOThread(EStreamSourceMediaType mediaType, CStreamingIOThread* pIOThread); - - CStreamEngineWakeEvent& GetWakeEvent() { return m_awakeEvent; } - - ////////////////////////////////////////////////////////////////////////// - // CrySimpleThread - ////////////////////////////////////////////////////////////////////////// - virtual void Run(); - virtual void Cancel(); - ////////////////////////////////////////////////////////////////////////// - -protected: - - void ProcessNewRequests(); - void ProcessReset(); - -public: - -#ifdef STREAMENGINE_ENABLE_STATS - struct SStats - { - SStats() - : m_nTotalReadBytes(0) - , m_nCurrentReadBandwith(0) - , m_nReadBytesInLastSecond(0) - , m_fReadingDuringLastSecond(.0f) - , m_nTempBytesRead(0) - , m_nActualReadBandwith(0) - , m_nTempReadOffset(0) - , m_nTotalReadOffset(0) - , m_nReadOffsetInLastSecond(0) - , m_nTempRequestCount(0) - , m_nTotalRequestCount(0) - , m_nRequestCountInLastSecond(0) - {} - - void Update(const CTimeValue& deltaT); - - void Reset() - { - m_nTotalReadBytes = 0; - m_nTotalReadOffset = 0; - m_nTotalRequestCount = 0; - m_TotalReadTime.SetValue(0); - } - - float m_fReadingDuringLastSecond; - CTimeValue m_TotalReadTime; - uint64 m_nTotalReadBytes; - uint64 m_nTotalReadOffset; - uint32 m_nTotalRequestCount; - uint32 m_nCurrentReadBandwith; // Read bandwidth over one second - uint32 m_nActualReadBandwith; // Actual read bandwidth extrapolated over one second - uint32 m_nReadBytesInLastSecond; - uint32 m_nRequestCountInLastSecond; - uint64 m_nReadOffsetInLastSecond; - - uint32 m_nTempRequestCount; - uint64 m_nTempBytesRead; - uint64 m_nTempReadOffset; - CTimeValue m_TempReadTime; - }; - - SStats m_InMemoryStats; - SStats m_NotInMemoryStats; -#endif - - int64 m_nLastReadDiskOffset; - int m_nStreamingCPU; - -private: - CStreamEngine* m_pStreamEngine; - std::vector m_fileRequestQueue; - std::vector m_temporaryArray; - CryMT::vector m_newFileRequests; - - EStreamSourceMediaType m_eMediaType; - uint32 m_nFallbackMTs; - - typedef std::pair TFallbackIOPair; - typedef std::vector TFallbackIOVec; - typedef TFallbackIOVec::iterator TFallbackIOVecConstIt; - TFallbackIOVec m_FallbackIOThreads; - - volatile bool m_bCancelThreadRequest; - volatile bool m_bNeedSorting; - volatile bool m_bNewRequests; - volatile bool m_bPaused; - volatile bool m_bNeedReset; - volatile bool m_bAbortReads; - - volatile int m_iUrgentRequests; - - CStreamEngineWakeEvent m_awakeEvent; - CryEvent m_resetDoneEvent; - string m_name; - uint32 m_nReadCounter; -}; - -////////////////////////////////////////////////////////////////////////// -// Thread that performs IO operations. -////////////////////////////////////////////////////////////////////////// -class CStreamingWorkerThread - : public CrySimpleThread - , public CMultiThreadRefCount -{ -public: - enum EWorkerType - { - eWorkerAsyncCallback, - }; - CStreamingWorkerThread(CStreamEngine* pStreamEngine, const char* name, EWorkerType type, SStreamRequestQueue* pQueue); - ~CStreamingWorkerThread(); - - void BeginReset(); - void EndReset(); - - void CancelAll(); - - ////////////////////////////////////////////////////////////////////////// - // CrySimpleThread - ////////////////////////////////////////////////////////////////////////// - virtual void Run(); - virtual void Cancel(); - ////////////////////////////////////////////////////////////////////////// - -private: - EWorkerType m_type; - CStreamEngine* m_pStreamEngine; - SStreamRequestQueue* m_pQueue; - - volatile bool m_bCancelThreadRequest; - volatile bool m_bNeedsReset; - - CryEvent m_resetDoneEvent; - string m_name; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp deleted file mode 100644 index 729f268d78..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp +++ /dev/null @@ -1,516 +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 : Streaming Engine - - -#include "CrySystem_precompiled.h" -#include -#include - -#include "StreamReadStream.h" -#include "StreamEngine.h" -#include "MTSafeAllocator.h" - -extern CMTSafeHeap* g_pPakHeap; -SLockFreeSingleLinkedListHeader CReadStream::s_freeRequests; - -CReadStream* CReadStream::Allocate(CStreamEngine* pEngine, const EStreamTaskType tSource, const char* szFilename, IStreamCallback* pCallback, const StreamReadParams* pParams) -{ - char* pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests)); - - CReadStream* pReq; - IF_LIKELY (pFree) - { - AZ_PUSH_DISABLE_WARNING(,"-Winvalid-offsetof") - ptrdiff_t offs = offsetof(CReadStream, m_nextFree); - AZ_POP_DISABLE_WARNING - pReq = reinterpret_cast(pFree - offs); - } - else - { - pReq = new CReadStream; - } - - pReq->m_pEngine = pEngine; - pReq->m_Type = tSource; - pReq->m_strFileName = szFilename; - pReq->m_pCallback = pCallback; - if (pParams) - { - pReq->m_Params = *pParams; - } - pReq->m_pBuffer = pReq->m_Params.pBuffer; - -#ifdef STREAMENGINE_ENABLE_STATS - pReq->m_requestTime = gEnv->pTimer->GetAsyncTime(); -#endif - - return pReq; -} - -void CReadStream::Flush() -{ - AZ_PUSH_DISABLE_WARNING(, "-Winvalid-offsetof") - ptrdiff_t offs = offsetof(CReadStream, m_nextFree); - AZ_POP_DISABLE_WARNING - - for (char* pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests)); - pFree; - pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests))) - { - CReadStream* pReq = reinterpret_cast(pFree - offs); - delete pReq; - } -} - -////////////////////////////////////////////////////////////////////////// -CReadStream::CReadStream() -{ - Reset(); -} - -////////////////////////////////////////////////////////////////////////// -CReadStream::~CReadStream() -{ -} - -// returns true if the file read was completed (successfully or unsuccessfully) -// check IsError to check if the whole requested file (piece) was read -bool CReadStream::IsFinished() -{ - return m_bFinished; -} - -// returns the number of bytes read so far (the whole buffer size if IsFinished()) -unsigned int CReadStream::GetBytesRead ([[maybe_unused]] bool bWait) -{ - if (!m_bError) - { - return m_Params.nSize; - } - return 0; -} - - -// returns the buffer into which the data has been or will be read -// at least GetBytesRead() bytes in this buffer are guaranteed to be already read -const void* CReadStream::GetBuffer () -{ - return m_pBuffer; -} - -void CReadStream::AbortShutdown() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - - m_bError = true; - m_nIOError = ERROR_ABORTED_ON_SHUTDOWN; - m_bFileRequestComplete = true; - - if (m_pFileRequest) - { - __debugbreak(); - } - } - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - { - CryAutoCriticalSection lock(m_callbackLock); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - } -} - -// tries to stop reading the stream; this is advisory and may have no effect -// all the callbacks will be called after this. If you just destructing object, -// dereference this object and it will automatically abort and release all associated resources. -void CReadStream::Abort() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - - m_bError = true; - m_nIOError = ERROR_USER_ABORT; - m_bFileRequestComplete = true; - - if (m_pFileRequest) - { - m_pFileRequest->Cancel(); - m_pFileRequest = 0; - } - } - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - { - CryAutoCriticalSection lock(m_callbackLock); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - } - - m_pEngine->AbortJob(this); -} - -bool CReadStream::TryAbort() -{ - if (!m_callbackLock.TryLock()) - { - return false; - } - - if (m_pFileRequest && !m_pFileRequest->TryCancel()) - { - m_callbackLock.Unlock(); - return false; - } - - m_bError = true; - m_nIOError = ERROR_USER_ABORT; - m_bFileRequestComplete = true; - m_pFileRequest = 0; - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - - m_callbackLock.Unlock(); - - m_pEngine->AbortJob(this); - - return true; -} - -// tries to raise the priority of the read; this is advisory and may have no effect -void CReadStream::SetPriority (EStreamTaskPriority ePriority) -{ - if (m_Params.ePriority != ePriority) - { - m_Params.ePriority = ePriority; - if (m_pFileRequest && m_pFileRequest->m_status == CAsyncIOFileRequest::eStatusInFileQueue) - { - m_pEngine->UpdateJobPriority(this); - } - } -} - -// unconditionally waits until the callback is called -// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback -// is called before return from this function (unless no callback was specified) -void CReadStream::Wait(int nMaxWaitMillis) -{ - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - bool bNeedFinalize = (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) == 0; - - if (!m_bFinished && !m_bError && !m_pFileRequest) - { - assert(m_pFileRequest != NULL); // If we want to Wait for stream its file request must not be NULL. - // This will almost certainly cause Dead-Lock - CryFatalError("Waiting for stream when StreamingEngine is paused"); - } - - CTimeValue t0; - - if (nMaxWaitMillis > 0) - { - t0 = gEnv->pTimer->GetAsyncTime(); - } - - while (!m_bFinished && !m_bError) - { - if (bNeedFinalize) - { - m_pEngine->MainThread_FinalizeIOJobs(); - } - if (!m_bFileRequestComplete) - { - CrySleep(5); - } - - if (nMaxWaitMillis > 0) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - if (CTimeValue(t1 - t0).GetMilliSeconds() > nMaxWaitMillis) - { - // Break if we are waiting for too long. - break; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -uint64 CReadStream::GetPriority() const -{ - return 0; -} - -// this gets called upon the IO has been executed to call the callbacks -void CReadStream::MainThread_Finalize() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - // call asynchronous callback function if needed synchronously - { - CryAutoCriticalSection lock(m_callbackLock); - ExecuteSyncCallback_CBLocked(); - } - m_pFileRequest = 0; -} - -IStreamCallback* CReadStream::GetCallback() const -{ - return m_pCallback; -} - -unsigned CReadStream::GetError() const -{ - return m_nIOError; -} - -const char* CReadStream::GetErrorName() const -{ - switch (m_nIOError) - { - case ERROR_UNKNOWN_ERROR: - return "Unknown error"; - case ERROR_UNEXPECTED_DESTRUCTION: - return "Unexpected destruction"; - case ERROR_INVALID_CALL: - return "Invalid call"; - case ERROR_CANT_OPEN_FILE: - return "Cannot open the file"; - case ERROR_REFSTREAM_ERROR: - return "Refstream error"; - case ERROR_OFFSET_OUT_OF_RANGE: - return "Offset out of range"; - case ERROR_REGION_OUT_OF_RANGE: - return "Region out of range"; - case ERROR_SIZE_OUT_OF_RANGE: - return "Size out of range"; - case ERROR_CANT_START_READING: - return "Cannot start reading"; - case ERROR_OUT_OF_MEMORY: - return "Out of memory"; - case ERROR_ABORTED_ON_SHUTDOWN: - return "Aborted on shutdown"; - case ERROR_OUT_OF_MEMORY_QUOTA: - return "Out of memory quota"; - case ERROR_ZIP_CACHE_FAILURE: - return "ZIP cache failure"; - case ERROR_USER_ABORT: - return "User aborted"; - } - return "Unrecognized error"; -} - -int CReadStream::AddRef() -{ - return CryInterlockedIncrement(&m_nRefCount); -} - -int CReadStream::Release() -{ - int nRef = CryInterlockedDecrement(&m_nRefCount); - -#ifndef _RELEASE - if (nRef < 0) - { - __debugbreak(); - } -#endif - - if (nRef == 0) - { - Reset(); - CryInterlockedPushEntrySList(s_freeRequests, m_nextFree); - } - - return nRef; -} - -void CReadStream::Reset() -{ - m_strFileName.clear(); - m_pFileRequest = NULL; - m_Params = StreamReadParams(); - memset((void*)&m_nRefCount, 0, (char*)(this + 1) - (char*)(&m_nRefCount)); -} - -void CReadStream::SetUserData(DWORD_PTR dwUserData) -{ - m_Params.dwUserData = dwUserData; -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::ExecuteAsyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_bIsAsyncCallbackExecuted && m_pCallback) - { - m_bIsAsyncCallbackExecuted = true; - m_pCallback->StreamAsyncOnComplete(this, m_nIOError); - } -} - -void CReadStream::ExecuteSyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_bIsSyncCallbackExecuted && m_pCallback && (0 == (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK))) - { - m_bIsSyncCallbackExecuted = true; - - CReadStream_AutoPtr protectMe(this); // Stream can be freed inside the callback! - - m_pCallback->StreamOnComplete(this, m_nIOError); - - // We do not need FileRequest here anymore, and not its temporary memory. - m_pFileRequest = 0; - m_pBuffer = NULL; - m_bFinished = true; - } - else - { - m_pFileRequest = 0; - m_pBuffer = NULL; - m_bFinished = true; - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = m_pEngine->GetListener(); - if (pListener) - { - pListener->OnStreamDone(this); - } -#endif -} - -void* CReadStream::operator new (size_t sz) -{ - return CryModuleMemalign(sz, alignof(CReadStream)); -} - -void CReadStream::operator delete(void* p) -{ - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::FreeTemporaryMemory() -{ - // Free temporary block. - if (m_pFileRequest) - { - m_pFileRequest->SyncWithDecompress(); - m_pFileRequest->FreeBuffer(); - } - m_pBuffer = 0; -} - -////////////////////////////////////////////////////////////////////////// -bool CReadStream::IsReqReading() -{ - if (m_strFileName.empty()) - { - return false; - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest* CReadStream::CreateFileRequest() -{ - m_pFileRequest = CAsyncIOFileRequest::Allocate(m_Type); - m_pFileRequest->m_nRequestedSize = m_Params.nSize; - m_pFileRequest->m_nRequestedOffset = m_Params.nOffset; - m_pFileRequest->m_pExternalMemoryBuffer = m_pBuffer; - m_pFileRequest->m_bWriteOnlyExternal = (m_Params.nFlags & IStreamEngine::FLAGS_WRITE_ONLY_EXTERNAL_BUFFER) != 0; - m_pFileRequest->m_pReadStream = this; - m_pFileRequest->m_strFileName = m_strFileName; - m_pFileRequest->m_ePriority = m_Params.ePriority; - m_pFileRequest->m_eMediaType = m_Params.eMediaType; - - m_bFileRequestComplete = false; - return m_pFileRequest; -} - -void* CReadStream::OnNeedStorage(size_t size, bool& bAbortOnFailToAlloc) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (m_pCallback) - { - return m_pCallback->StreamOnNeedStorage(this, size, bAbortOnFailToAlloc); - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::OnAsyncFileRequestComplete() -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (!m_bFileRequestComplete) - { - if (m_pFileRequest) - { - m_Params.nSize = m_pFileRequest->m_nRequestedSize; - m_pBuffer = m_pFileRequest->m_pOutputMemoryBuffer; - m_nBytesRead = m_pFileRequest->m_nSizeOnMedia; - m_nIOError = m_pFileRequest->m_nError; - m_bError = m_nIOError != 0; - if (m_bError) - { - m_nBytesRead = 0; - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_ReadTime = m_pFileRequest->m_readTime; -#endif - } - - ExecuteAsyncCallback_CBLocked(); - - if (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) - { - // We do not need FileRequest here anymore, and not its temporary memory. - m_pFileRequest = 0; - m_bFinished = true; - } - - m_bFileRequestComplete = true; - } -} - - diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h b/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h deleted file mode 100644 index cf6ee25d97..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h +++ /dev/null @@ -1,178 +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 : Streaming Engine - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H -#pragma once - - -#include "IStreamEngine.h" -#include "StreamAsyncFileRequest.h" - -class CStreamEngine; - -class CReadStream - : public IReadStream -{ - friend class CStreamEngine; - -public: - static CReadStream* Allocate(CStreamEngine* pEngine, const EStreamTaskType tSource, const char* szFilename, IStreamCallback* pCallback, const StreamReadParams* pParams); - static void Flush(); - -public: - CReadStream(); - virtual ~CReadStream (); - - virtual int AddRef(); - virtual int Release(); - - virtual DWORD_PTR GetUserData() {return m_Params.dwUserData; } - - // set user defined data into stream's params - virtual void SetUserData(DWORD_PTR dwUserData); - - // returns true if the file read was not successful. - virtual bool IsError() { return m_bError; }; - - // returns true if the file read was completed (successfully or unsuccessfully) - // check IsError to check if the whole requested file (piece) was read - virtual bool IsFinished(); - - // returns the number of bytes read so far (the whole buffer size if IsFinished()) - virtual unsigned int GetBytesRead (bool bWait); - - // returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read - virtual const void* GetBuffer (); - - void AbortShutdown(); - - // tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - virtual void Abort(); - virtual bool TryAbort(); - - // tries to raise the priority of the read; this is advisory and may have no effect - virtual void SetPriority (EStreamTaskPriority EPriority); - - // unconditionally waits until the callback is called - // i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified) - virtual void Wait(int nMaxWaitMillis = -1); - - virtual uint64 GetPriority() const; - - virtual const StreamReadParams& GetParams() const {return m_Params; } - - virtual const EStreamTaskType GetCallerType() const { return m_Type; } - - virtual EStreamSourceMediaType GetMediaType() const { return m_MediaType; } - - // return pointer to callback routine(can be NULL) - virtual IStreamCallback* GetCallback() const; - - // return IO error # - virtual unsigned GetError() const; - - // Returns IO error name - virtual const char* GetErrorName() const; - - // return stream name - virtual const char* GetName() const { return m_strFileName.c_str(); }; - - virtual void FreeTemporaryMemory(); - - // this gets called upon the IO has been executed to call the callbacks - void MainThread_Finalize(); - - bool IsReqReading(); - -#ifdef STREAMENGINE_ENABLE_STATS - void SetRequestTime(CTimeValue& time) { m_requestTime = time; } - const CTimeValue& GetRequestTime() { return m_requestTime; } -#endif - - // decompression of zip-compressed files with default behavior - CAsyncIOFileRequest* CreateFileRequest(); - void ComputedMediaType(EStreamSourceMediaType eMT) { m_MediaType = eMT; } - void* OnNeedStorage(size_t size, bool& bAbortOnFailToAlloc); - void OnAsyncFileRequestComplete(); - CAsyncIOFileRequest* GetFileRequest() { return m_pFileRequest; } - -private: - void Reset(); - - // call the async callback - void ExecuteAsyncCallback_CBLocked(); - - // call the sync callback - void ExecuteSyncCallback_CBLocked(); - -private: - void* operator new (size_t sz); - void operator delete(void* p); - -private: - static SLockFreeSingleLinkedListHeader s_freeRequests; - -private: - STREAMENGINE_LL_ALIGN SLockFreeSingleLinkedListEntry m_nextFree; - - CryStringLocal m_strFileName; - CryCriticalSection m_callbackLock; - CAsyncIOFileRequest_AutoPtr m_pFileRequest; - - StreamReadParams m_Params; - - // Only POD types must exist below here. They will be memset! - - volatile int m_nRefCount; - CStreamEngine* m_pEngine; - - // the type of the task - EStreamTaskType m_Type; - EStreamSourceMediaType m_MediaType; - // the initial data from the user - // the callback; may be NULL - IStreamCallback* m_pCallback; - - // Bytes actually read from media. - uint32 m_nBytesRead; - - volatile bool m_bIsAsyncCallbackExecuted; - volatile bool m_bIsSyncCallbackExecuted; - volatile bool m_bFileRequestComplete; - - // the actual buffer to read to - void* m_pBuffer; - - volatile bool m_bError; - volatile bool m_bFinished; - unsigned int m_nIOError; - -#ifdef STREAMENGINE_ENABLE_STATS - // time when request was made - CTimeValue m_requestTime; - // Time for actual reading - CTimeValue m_ReadTime; -#endif -}; - -TYPEDEF_AUTOPTR(CReadStream); - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H diff --git a/Code/CryEngine/CrySystem/System.cpp b/Code/CryEngine/CrySystem/System.cpp index 9016ea99f1..b105ec2f27 100644 --- a/Code/CryEngine/CrySystem/System.cpp +++ b/Code/CryEngine/CrySystem/System.cpp @@ -135,14 +135,12 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "XML/xml.h" #include "XML/ReadWriteXMLSink.h" -#include "StreamEngine/StreamEngine.h" #include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" #include "SystemEventDispatcher.h" #include "ServerThrottle.h" -#include "ResourceManager.h" #include "HMDBus.h" #include "IZLibCompressor.h" @@ -157,7 +155,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "CryWaterMark.h" WATERMARKDATA(_m); -#include "ImageHandler.h" #include #include #include @@ -179,7 +176,6 @@ WATERMARKDATA(_m); #include -#include #include // profilers api. @@ -191,14 +187,6 @@ SSystemCVars g_cvars; #include "ITextModeConsole.h" -extern int CryMemoryGetAllocatedSize(); - -// these heaps are used by underlying System structures -// to allocate, accordingly, small (like elements of std::set<..*>) and big (like memory for reading files) objects -// hopefully someday we'll have standard MT-safe heap -//CMTSafeHeap g_pakHeap; -CMTSafeHeap* g_pPakHeap = 0;// = &g_pakHeap; - ////////////////////////////////////////////////////////////////////////// #include "Validator.h" @@ -266,7 +254,6 @@ namespace // System Implementation. ////////////////////////////////////////////////////////////////////////// CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) - : m_imageHandler(std::make_unique()) { CrySystemRequestBus::Handler::BusConnect(); @@ -307,8 +294,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_env.pSharedEnvironment = pSharedEnvironment; ////////////////////////////////////////////////////////////////////////// - m_pStreamEngine = NULL; - m_pIFont = NULL; m_pIFontUi = NULL; m_rWidth = NULL; @@ -322,7 +307,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_rStencilBits = NULL; m_rFullscreen = NULL; m_sysNoUpdate = NULL; - m_pMemoryManager = NULL; m_pProcess = NULL; m_pValidator = NULL; @@ -387,12 +371,8 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pXMLUtils = new CXmlUtils(this); - m_pMemoryManager = CryGetIMemoryManager(); - m_pResourceManager = new CResourceManager; m_pTextModeConsole = NULL; - g_pPakHeap = new CMTSafeHeap; - if (!AZ::AllocatorInstance::IsReady()) { m_initedOSAllocator = true; @@ -433,11 +413,8 @@ CSystem::~CSystem() CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere"); SAFE_DELETE(m_pXMLUtils); - SAFE_DELETE(m_pResourceManager); SAFE_DELETE(m_pSystemEventDispatcher); - SAFE_DELETE(g_pPakHeap); - AZCoreLogSink::Disconnect(); if (m_initedSysAllocator) { @@ -477,12 +454,6 @@ void CSystem::FreeLib(AZStd::unique_ptr& hLibModule) } } -////////////////////////////////////////////////////////////////////////// -IStreamEngine* CSystem::GetStreamEngine() -{ - return m_pStreamEngine; -} - ////////////////////////////////////////////////////////////////////////// IRemoteConsole* CSystem::GetIRemoteConsole() { @@ -582,9 +553,6 @@ void CSystem::ShutDown() // Shutdown any running VR devices. EBUS_EVENT(AZ::VR::HMDInitRequestBus, Shutdown); - // Shutdown resource manager. - m_pResourceManager->Shutdown(); - if (gEnv && gEnv->pLyShine) { gEnv->pLyShine->Release(); @@ -645,11 +613,6 @@ void CSystem::ShutDown() SAFE_DELETE(m_pLocalizationManager); - //DebugStats(false, false);//true); - //CryLogAlways(""); - //CryLogAlways("release mode memory manager stats:"); - //DumpMMStats(true); - SAFE_DELETE(m_pCpu); delete m_pCmdLine; @@ -659,8 +622,7 @@ void CSystem::ShutDown() // Shut down audio as late as possible but before the streaming system and console get released! Audio::Gem::AudioSystemGemRequestBus::Broadcast(&Audio::Gem::AudioSystemGemRequestBus::Events::Release); - // Shut down the streaming system and console as late as possible and after audio! - SAFE_DELETE(m_pStreamEngine); + // Shut down console as late as possible and after audio! SAFE_RELEASE(m_env.pConsole); // Log must be last thing released. @@ -904,12 +866,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } #endif //PROFILE_WITH_VTUNE - if (m_pStreamEngine) - { - FRAME_PROFILER("StreamEngine::Update()", this, PROFILE_SYSTEM); - m_pStreamEngine->Update(); - } - #ifndef EXCLUDE_UPDATE_ON_CONSOLE if (m_bIgnoreUpdates) { @@ -1024,14 +980,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } } - ////////////////////////////////////////////////////////////////////////// - // Update Resource Manager. - ////////////////////////////////////////////////////////////////////////// - { - FRAME_PROFILER("SysUpdate:ResourceManager", this, PROFILE_SYSTEM); - m_pResourceManager->Update(); - } - // Use UI timer for CryMovie, because it should not be affected by pausing game time const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI); @@ -1419,24 +1367,12 @@ void CSystem::Relaunch(bool bRelaunch) SaveConfiguration(); } -////////////////////////////////////////////////////////////////////////// -uint32 CSystem::GetUsedMemory() -{ - return CryMemoryGetAllocatedSize(); -} - ////////////////////////////////////////////////////////////////////////// ILocalizationManager* CSystem::GetLocalizationManager() { return m_pLocalizationManager; } -////////////////////////////////////////////////////////////////////////// -IResourceManager* CSystem::GetIResourceManager() -{ - return m_pResourceManager; -} - ////////////////////////////////////////////////////////////////////////// void CSystem::debug_GetCallStackRaw(void** callstack, uint32& callstackLength) { diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index e27dfe4866..2e272c2f9e 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -23,7 +23,6 @@ #include "CmdLine.h" #include "CryName.h" -#include "MTSafeAllocator.h" #include "CPUDetect.h" #include #include "RenderBus.h" @@ -276,33 +275,6 @@ extern SSystemCVars g_cvars; class CSystem; -struct SmallModuleInfo -{ - string name; - CryModuleMemoryInfo memInfo; -}; - -struct SCryEngineStatsModuleInfo -{ - string name; - CryModuleMemoryInfo memInfo; - uint32 moduleStaticSize; - uint32 usedInModule; - uint32 SizeOfCode; - uint32 SizeOfInitializedData; - uint32 SizeOfUninitializedData; -}; - -struct SCryEngineStatsGlobalMemInfo -{ - int totalUsedInModules; - int totalCodeAndStatic; - int countedMemoryModules; - uint64 totalAllocatedInModules; - int totalNumAllocsInModules; - std::vector modules; -}; - struct CProfilingSystem : public IProfilingSystem { @@ -338,17 +310,6 @@ class CSystem , public CrySystemRequestBus::Handler { public: - - inline void* operator new(std::size_t) - { - size_t allocated = 0; - return CryMalloc(sizeof(CSystem), allocated, 64); - } - inline void operator delete(void* p) - { - CryFree(p, 64); - } - CSystem(SharedEnvironmentInstance* pSharedEnvironment); ~CSystem(); @@ -390,8 +351,6 @@ public: ISystem* GetCrySystem() override; //////////////////////////////////////////////////////////////////////// - uint32 GetUsedMemory(); - virtual bool SteamInit(); void Relaunch(bool bRelaunch); @@ -412,17 +371,14 @@ public: IConsole* GetIConsole() { return m_env.pConsole; }; IRemoteConsole* GetIRemoteConsole(); IMovieSystem* GetIMovieSystem() { return m_env.pMovieSystem; }; - IMemoryManager* GetIMemoryManager(){ return m_pMemoryManager; } ICryFont* GetICryFont(){ return m_env.pCryFont; } ILog* GetILog(){ return m_env.pLog; } ICmdLine* GetICmdLine(){ return m_pCmdLine; } - IStreamEngine* GetStreamEngine(); IValidator* GetIValidator() { return m_pValidator; }; INameTable* GetINameTable() { return m_env.pNameTable; }; IViewSystem* GetIViewSystem(); ILevelSystem* GetILevelSystem(); ISystemEventDispatcher* GetISystemEventDispatcher() { return m_pSystemEventDispatcher; } - IResourceManager* GetIResourceManager(); ITextModeConsole* GetITextModeConsole(); IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; } IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; } @@ -509,11 +465,6 @@ public: virtual int ShowMessage(const char* text, const char* caption, unsigned int uType); bool CheckLogVerbosity(int verbosity); - virtual void DebugStats(bool checkpoint, bool leaks); - void DumpWinHeaps(); - - virtual int DumpMMStats(bool log); - //! Return pointer to user defined callback. ISystemUserCallback* GetUserCallback() const { return m_pUserCallback; }; @@ -541,8 +492,6 @@ public: void SetVersionInfo(const char* const szVersion); #endif - virtual const IImageHandler* GetImageHandler() const override { return m_imageHandler.get(); } - void ShutdownModuleLibraries(); #if defined(WIN32) @@ -570,7 +519,6 @@ private: bool InitConsole(); bool InitFileSystem(); bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams); - bool InitStreamEngine(); bool InitAudioSystem(const SSystemInitParams& initParams); bool InitShine(const SSystemInitParams& initParams); @@ -597,7 +545,6 @@ private: #endif // #ifndef _RELEASE bool ReLaunchMediaCenter(); - void LogSystemInfo(); void UpdateAudioSystems(); void AddCVarGroupDirectory(const string& sPath); @@ -690,14 +637,9 @@ private: // ------------------------------------------------------ std::map > m_moduleDLLHandles; - //! THe streaming engine - class CStreamEngine* m_pStreamEngine; - //! current active process IProcess* m_pProcess; - IMemoryManager* m_pMemoryManager; - CCamera m_PhysRendererCamera; ICVar* m_p_draw_helpers_str; int m_iJumpToPhysProfileEnt; @@ -914,7 +856,6 @@ public: protected: // ------------------------------------------------------------- CCmdLine* m_pCmdLine; - class CResourceManager* m_pResourceManager; ITextModeConsole* m_pTextModeConsole; string m_currentLanguageAudio; @@ -943,7 +884,6 @@ protected: // ------------------------------------------------------------- bool m_bIsSteamInitialized; - std::unique_ptr m_imageHandler; std::vector m_windowMessageHandlers; bool m_initedOSAllocator = false; bool m_initedSysAllocator = false; diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 7d3a13d1a2..239f670453 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -95,7 +95,6 @@ #include "XConsole.h" #include "Log.h" #include "XML/xml.h" -#include "StreamEngine/StreamEngine.h" #include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "SystemEventDispatcher.h" @@ -103,8 +102,6 @@ #include "ServerThrottle.h" #include "SystemCFG.h" #include "AutoDetectSpec.h" -#include "ResourceManager.h" -#include "MTSafeAllocator.h" #include "ZLibCompressor.h" #include "ZLibDecompressor.h" #include "ZStdDecompressor.h" @@ -245,8 +242,6 @@ CUNIXConsole* pUnixConsole; #define AZ_TRACE_SYSTEM_WINDOW AZ::Debug::Trace::GetDefaultSystemWindow() -extern CMTSafeHeap* g_pPakHeap; - #ifdef WIN32 extern HMODULE gDLLHandle; #endif @@ -274,7 +269,6 @@ struct SCVarsClientConfigSink ////////////////////////////////////////////////////////////////////////// static inline void InlineInitializationProcessing([[maybe_unused]] const char* sDescription) { - assert(CryMemory::IsHeapValid()); if (gEnv->pLog) { gEnv->pLog->UpdateLoadingScreen(0); @@ -1101,12 +1095,7 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) auto projectName = AZ::Utils::GetProjectName(); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Name: %s\n", projectName.empty() ? "None specified" : projectName.c_str()); - // simply open all paks if fast load pak can't be found - if (!m_pResourceManager->LoadFastLoadPaks(true)) - { - OpenBasicPaks(); - } - + OpenBasicPaks(); // Load game-specific folder. LoadConfiguration("game.cfg"); @@ -1120,21 +1109,6 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) return (true); } -////////////////////////////////////////////////////////////////////////// -bool CSystem::InitStreamEngine() -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress("Initializing Stream Engine..."); - } - - m_pStreamEngine = new CStreamEngine(); - - return true; -} - ////////////////////////////////////////////////////////////////////////// bool CSystem::InitAudioSystem(const SSystemInitParams& initParams) { @@ -1299,8 +1273,6 @@ void CSystem::OpenBasicPaks() ////////////////////////////////////////////////////////////////////////// const char* const assetsDir = "@assets@"; - const char* shaderCachePakDir = "@assets@/shadercache.pak"; - const char* shaderCacheStartupPakDir = "@assets@/shadercachestartup.pak"; // After game paks to have same search order as with files on disk m_env.pCryPak->OpenPack(assetsDir, "Engine.pak"); @@ -1310,11 +1282,6 @@ void CSystem::OpenBasicPaks() #include AZ_RESTRICTED_FILE(SystemInit_cpp) #endif - m_env.pCryPak->OpenPack(assetsDir, shaderCachePakDir); - m_env.pCryPak->OpenPack(assetsDir, shaderCacheStartupPakDir); - m_env.pCryPak->OpenPack(assetsDir, "Shaders.pak"); - m_env.pCryPak->OpenPack(assetsDir, "ShadersBin.pak"); - #ifdef AZ_PLATFORM_ANDROID // Load Android Obb files if available const char* obbStorage = AZ::Android::Utils::GetObbStoragePath(); @@ -1326,22 +1293,6 @@ void CSystem::OpenBasicPaks() InlineInitializationProcessing("CSystem::OpenBasicPaks OpenPacks( Engine... )"); - ////////////////////////////////////////////////////////////////////////// - // Open paks in MOD subfolders. - ////////////////////////////////////////////////////////////////////////// -#if !defined(_RELEASE) - if (const ICmdLineArg* pModArg = GetICmdLine()->FindArg(eCLAT_Pre, "MOD")) - { - if (IsMODValid(pModArg->GetValue())) - { - AZStd::string modFolder = "Mods\\"; - modFolder += pModArg->GetValue(); - modFolder += "\\*.pak"; - GetIPak()->OpenPacks(assetsDir, modFolder, AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK); - } - } -#endif // !defined(_RELEASE) - // Load paks required for game init to mem gEnv->pCryPak->LoadPakToMemory("Engine.pak", AZ::IO::IArchive::eInMemoryPakLocale_GPU); } @@ -1687,8 +1638,6 @@ bool CSystem::Init(const SSystemInitParams& startupParams) m_systemConfigName += ".cfg"; } - AZ_Assert(CryMemory::IsHeapValid(), "Memory heap must be valid before continuing SystemInit."); - #if defined(WIN32) || defined(WIN64) // check OS version - we only want to run on XP or higher - talk to Martin Mittring if you want to change this { @@ -1709,8 +1658,6 @@ AZ_POP_DISABLE_WARNING } #endif - m_pResourceManager->Init(); - // Get file version information. QueryVersionInfo(); DetectGameFolderAccessRights(); @@ -1983,11 +1930,6 @@ AZ_POP_DISABLE_WARNING return false; } - if (!startupParams.bSkipConsole) - { - LogSystemInfo(); - } - InlineInitializationProcessing("CSystem::Init Load Engine Folders"); ////////////////////////////////////////////////////////////////////////// @@ -2052,29 +1994,6 @@ AZ_POP_DISABLE_WARNING gEnv->bNoAssertDialog = true; } - ////////////////////////////////////////////////////////////////////////// - // Stream Engine - ////////////////////////////////////////////////////////////////////////// - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Stream Engine Initialization"); - InitStreamEngine(); - InlineInitializationProcessing("CSystem::Init StreamEngine"); - - - { - if (m_pCmdLine->FindArg(eCLAT_Pre, "NullRenderer")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "NULL"); - } - else if (m_pCmdLine->FindArg(eCLAT_Pre, "DX11")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "DX11"); - } - else if (m_pCmdLine->FindArg(eCLAT_Pre, "GL")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "GL"); - } - } - LogBuildInfo(); InlineInitializationProcessing("CSystem::Init LoadConfigurations"); diff --git a/Code/CryEngine/CrySystem/SystemRender.cpp b/Code/CryEngine/CrySystem/SystemRender.cpp index b608ef5335..2314f593b7 100644 --- a/Code/CryEngine/CrySystem/SystemRender.cpp +++ b/Code/CryEngine/CrySystem/SystemRender.cpp @@ -47,13 +47,10 @@ #define SYSTEMRENDERER_CPP_SECTION_2 2 #endif -extern CMTSafeHeap* g_pPakHeap; #if defined(AZ_PLATFORM_ANDROID) #include #endif -extern int CryMemoryGetAllocatedSize(); - ///////////////////////////////////////////////////////////////////////////////// bool CSystem::GetPrimaryPhysicalDisplayDimensions([[maybe_unused]] int& o_widthPixels, [[maybe_unused]] int& o_heightPixels) { diff --git a/Code/CryEngine/CrySystem/SystemWin32.cpp b/Code/CryEngine/CrySystem/SystemWin32.cpp index 72c43bceed..c40b0f7c7b 100644 --- a/Code/CryEngine/CrySystem/SystemWin32.cpp +++ b/Code/CryEngine/CrySystem/SystemWin32.cpp @@ -51,7 +51,6 @@ #endif #include "XConsole.h" -#include "StreamEngine/StreamEngine.h" #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" #include "AutoDetectSpec.h" @@ -121,19 +120,6 @@ struct PEHeader_DLL #pragma pack(pop) #endif -const SmallModuleInfo* FindModuleInfo(std::vector& vec, const char* name) -{ - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].name.compareNoCase(name)) - { - return &vec[i]; - } - } - - return 0; -} - ////////////////////////////////////////////////////////////////////////// const char* CSystem::GetUserName() { @@ -231,30 +217,6 @@ int CSystem::GetApplicationLogInstance([[maybe_unused]] const char* logFilePath) #endif } -// these 2 functions are duplicated in System.cpp in editor -////////////////////////////////////////////////////////////////////////// -#if !defined(LINUX) -extern int CryStats(char* buf); -#endif -int CSystem::DumpMMStats(bool log) -{ -#if defined(LINUX) - return 0; -#else - if (log) - { - char buf[1024]; - int n = CryStats(buf); - GetILog()->Log(buf); - return n; - } - else - { - return CryStats(NULL); - }; -#endif -}; - ////////////////////////////////////////////////////////////////////////// struct CryDbgModule { @@ -264,273 +226,7 @@ struct CryDbgModule DWORD dwSize; }; -////////////////////////////////////////////////////////////////////////// -void CSystem::DebugStats([[maybe_unused]] bool checkpoint, [[maybe_unused]] bool leaks) -{ #ifdef WIN32 - std::vector dbgmodules; - - ////////////////////////////////////////////////////////////////////////// - // Use windows Performance Monitoring API to enumerate all modules of current process. - ////////////////////////////////////////////////////////////////////////// - HANDLE hSnapshot; - hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); - if (hSnapshot != INVALID_HANDLE_VALUE) - { - MODULEENTRY32 me; - memset (&me, 0, sizeof(me)); - me.dwSize = sizeof(me); - - if (Module32First (hSnapshot, &me)) - { - // the sizes of each module group - do - { - CryDbgModule module; - module.handle = me.hModule; - module.name = me.szModule; - module.dwSize = me.modBaseSize; - dbgmodules.push_back(module); - } while (Module32Next(hSnapshot, &me)); - } - CloseHandle (hSnapshot); - } - ////////////////////////////////////////////////////////////////////////// - - int nolib = 0; - -#ifdef _DEBUG - ILog* log = GetILog(); - int totalal = 0; - int totalbl = 0; - int extrastats[10]; -#endif - - int totalUsedInModules = 0; - int countedMemoryModules = 0; - for (int i = 0; i < (int)(dbgmodules.size()); i++) - { - if (!dbgmodules[i].handle) - { - CryLogAlways("WARNING: CSystem::DebugStats: NULL handle for %s", dbgmodules[i].name.c_str()); - nolib++; - continue; - } - ; - - typedef int (* PFN_MODULEMEMORY)(); - PFN_MODULEMEMORY fpCryModuleGetAllocatedMemory = (PFN_MODULEMEMORY)::GetProcAddress((HMODULE)dbgmodules[i].handle, "CryModuleGetAllocatedMemory"); - if (fpCryModuleGetAllocatedMemory) - { - int allocatedMemory = fpCryModuleGetAllocatedMemory(); - totalUsedInModules += allocatedMemory; - countedMemoryModules++; - CryLogAlways("%8d K used in Module %s: ", allocatedMemory / 1024, dbgmodules[i].name.c_str()); - } - -#ifdef _DEBUG - typedef void (* PFNUSAGESUMMARY)(ILog* log, const char*, int*); - typedef void (* PFNCHECKPOINT)(); - PFNUSAGESUMMARY fpu = (PFNUSAGESUMMARY)::GetProcAddress((HMODULE)dbgmodules[i].handle, "UsageSummary"); - PFNCHECKPOINT fpc = (PFNCHECKPOINT)::GetProcAddress((HMODULE)dbgmodules[i].handle, "CheckPoint"); - if (fpu && fpc) - { - if (checkpoint) - { - fpc(); - } - else - { - extrastats[2] = (int)leaks; - fpu(log, dbgmodules[i].name.c_str(), extrastats); - totalal += extrastats[0]; - totalbl += extrastats[1]; - }; - } - else - { - CryLogAlways("WARNING: CSystem::DebugStats: could not retrieve function from DLL %s", dbgmodules[i].name.c_str()); - nolib++; - }; -#endif - - typedef HANDLE(* PFNGETDLLHEAP)(); - PFNGETDLLHEAP fpg = (PFNGETDLLHEAP)::GetProcAddress((HMODULE)dbgmodules[i].handle, "GetDLLHeap"); - if (fpg) - { - dbgmodules[i].heap = fpg(); - } - ; - } - ; - - CryLogAlways("-------------------------------------------------------"); - CryLogAlways("%8d K Total Memory Allocated in %d Modules", totalUsedInModules / 1024, countedMemoryModules); -#ifdef _DEBUG - CryLogAlways("$8GRAND TOTAL: %d k, %d blocks (%d dlls not included)", totalal / 1024, totalbl, nolib); - CryLogAlways("estimated debugalloc overhead: between %d k and %d k", totalbl * 36 / 1024, totalbl * 72 / 1024); -#endif - - ////////////////////////////////////////////////////////////////////////// - // Get HeapQueryInformation pointer if on windows XP. - ////////////////////////////////////////////////////////////////////////// - typedef BOOL (WINAPI * FUNC_HeapQueryInformation)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T); - FUNC_HeapQueryInformation pFnHeapQueryInformation = NULL; - HMODULE hKernelInstance = CryLoadLibrary("Kernel32.dll"); - if (hKernelInstance) - { - pFnHeapQueryInformation = (FUNC_HeapQueryInformation)(::GetProcAddress(hKernelInstance, "HeapQueryInformation")); - } - ////////////////////////////////////////////////////////////////////////// - - const int MAXHANDLES = 100; - HANDLE handles[MAXHANDLES]; - int realnumh = GetProcessHeaps(MAXHANDLES, handles); - char hinfo[1024]; - PROCESS_HEAP_ENTRY phe; - CryLogAlways("$6--------------------- dump of windows heaps ---------------------"); - int nTotalC = 0, nTotalCP = 0, nTotalUC = 0, nTotalUCP = 0, totalo = 0; - for (int i = 0; i < realnumh; i++) - { - HANDLE hHeap = handles[i]; - HeapCompact(hHeap, 0); - hinfo[0] = 0; - if (pFnHeapQueryInformation) - { - pFnHeapQueryInformation(hHeap, HeapCompatibilityInformation, hinfo, 1024, NULL); - } - else - { - for (int m = 0; m < (int)(dbgmodules.size()); m++) - { - if (dbgmodules[m].heap == handles[i]) - { - azstrcpy(hinfo, AZ_ARRAY_SIZE(hinfo), dbgmodules[m].name.c_str()); - } - } - } - phe.lpData = NULL; - int nCommitted = 0, nUncommitted = 0, nOverhead = 0; - int nCommittedPieces = 0, nUncommittedPieces = 0; -#if !defined(NDEBUG) - int nPrevRegionIndex = -1; -#endif - while (HeapWalk(hHeap, &phe)) - { - if (phe.wFlags & PROCESS_HEAP_REGION) - { - assert (++nPrevRegionIndex == phe.iRegionIndex); - nCommitted += phe.Region.dwCommittedSize; - nUncommitted += phe.Region.dwUnCommittedSize; - assert (phe.cbData == 0 || (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY)); - } - else - if (phe.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) - { - nUncommittedPieces += phe.cbData; - } - else - { - //if (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) - nCommittedPieces += phe.cbData; - } - - - { - /* - MEMORY_BASIC_INFORMATION mbi; - if (VirtualQuery(phe.lpData, &mbi,sizeof(mbi)) == sizeof(mbi)) - { - if (mbi.State == MEM_COMMIT) - nCommittedPieces += phe.cbData;//mbi.RegionSize; - //else - // nUncommitted += mbi.RegionSize; - } - else - nCommittedPieces += phe.cbData; - */ - } - - nOverhead += phe.cbOverhead; - } - - CryLogAlways("* heap %8x: %6d (or ~%6d) K in use, %6d..%6d K uncommitted, %6d K overhead (%s)\n", - handles[i], nCommittedPieces / 1024, nCommitted / 1024, nUncommittedPieces / 1024, nUncommitted / 1024, nOverhead / 1024, hinfo); - - nTotalC += nCommitted; - nTotalCP += nCommittedPieces; - nTotalUC += nUncommitted; - nTotalUCP += nUncommittedPieces; - totalo += nOverhead; - } - ; - CryLogAlways("$6----------------- total in heaps: %d megs committed (win stats shows ~%d) (%d..%d uncommitted, %d k overhead) ---------------------", nTotalCP / 1024 / 1024, nTotalC / 1024 / 1024, nTotalUCP / 1024 / 1024, nTotalUC / 1024 / 1024, totalo / 1024); - -#endif //WIN32 -}; - -#ifdef WIN32 -struct DumpHeap32Stats -{ - DumpHeap32Stats() - : dwFree(0) - , dwMoveable(0) - , dwFixed(0) - , dwUnknown(0) - { - } - void operator += (const DumpHeap32Stats& right) - { - dwFree += right.dwFree; - dwMoveable += right.dwMoveable; - dwFixed += right.dwFixed; - dwUnknown += right.dwUnknown; - } - DWORD dwFree; - DWORD dwMoveable; - DWORD dwFixed; - DWORD dwUnknown; -}; -static void DumpHeap32 (const HEAPLIST32& hl, DumpHeap32Stats& stats) -{ - HEAPENTRY32 he; - memset (&he, 0, sizeof(he)); - he.dwSize = sizeof(he); - - if (Heap32First (&he, hl.th32ProcessID, hl.th32HeapID)) - { - DumpHeap32Stats heap; - do - { - if (he.dwFlags & LF32_FREE) - { - heap.dwFree += he.dwBlockSize; - } - else - if (he.dwFlags & LF32_MOVEABLE) - { - heap.dwMoveable += he.dwBlockSize; - } - else - if (he.dwFlags & LF32_FIXED) - { - heap.dwFixed += he.dwBlockSize; - } - else - { - heap.dwUnknown += he.dwBlockSize; - } - } while (Heap32Next (&he)); - - CryLogAlways ("%08X %6d %6d %6d (%d)", hl.th32HeapID, heap.dwFixed / 0x400, heap.dwFree / 0x400, heap.dwMoveable / 0x400, heap.dwUnknown / 0x400); - stats += heap; - } - else - { - CryLogAlways ("%08X empty or invalid"); - } -} - ////////////////////////////////////////////////////////////////////////// class CStringOrder { @@ -566,94 +262,6 @@ const char* GetModuleGroup (const char* szString) #endif -////////////////////////////////////////////////////////////////////////// -void CSystem::DumpWinHeaps() -{ -#ifdef WIN32 - // - // Retrieve modules and log them; remember the process id - - 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; - DWORD dwTotalModuleSize = 0; - CryLogAlways ("base size module"); - do - { - dwProcessID = me.th32ProcessID; - const char* szGroup = GetModuleGroup (me.szModule); - CryLogAlways ("%08X %8X %25s - %s", me.modBaseAddr, me.modBaseSize, me.szModule, azstricmp(szGroup, "Other") ? szGroup : ""); - dwTotalModuleSize += me.modBaseSize; - AddSize (mapGroupSize, szGroup, me.modBaseSize); - } while (Module32Next(hSnapshot, &me)); - - CryLogAlways ("------------------------------------"); - for (StringToSizeMap::iterator it = mapGroupSize.begin(); it != mapGroupSize.end(); ++it) - { - CryLogAlways (" %6.3f Mbytes - %s", double(it->second) / 0x100000, it->first); - } - CryLogAlways ("------------------------------------"); - CryLogAlways (" %6.3f Mbytes - TOTAL", double(dwTotalModuleSize) / 0x100000); - CryLogAlways ("------------------------------------"); - } - else - { - CryLogAlways ("No modules to dump"); - } - - CloseHandle (hSnapshot); - - // - // Retrieve the heaps and dump each of them with a special function - - hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - CryLogAlways ("Cannot get the heap LIST snapshot, error code %d", GetLastError()); - return; - } - - HEAPLIST32 hl; - memset (&hl, 0, sizeof(hl)); - hl.dwSize = sizeof(hl); - - CryLogAlways ("__Heap__ fixed free move (unknown)"); - if (Heap32ListFirst (hSnapshot, &hl)) - { - DumpHeap32Stats stats; - do - { - DumpHeap32 (hl, stats); - } while (Heap32ListNext (hSnapshot, &hl)); - - CryLogAlways ("-------------------------------------------------"); - CryLogAlways ("$6 %6.3f %6.3f %6.3f (%.3f) Mbytes", double(stats.dwFixed) / 0x100000, double(stats.dwFree) / 0x100000, double(stats.dwMoveable) / 0x100000, double(stats.dwUnknown) / 0x100000); - CryLogAlways ("-------------------------------------------------"); - } - else - { - CryLogAlways ("No heaps to dump"); - } - - CloseHandle(hSnapshot); -#endif -} - // Make system error message string ////////////////////////////////////////////////////////////////////////// //! \return pointer to the null terminated error string or 0 @@ -739,8 +347,6 @@ void CSystem::FatalError(const char* format, ...) assert(szBuffer[0] >= ' '); // strcpy(szBuffer,szBuffer+1); // remove verbosity tag since it is not supported by ::MessageBox - LogSystemInfo(); - OutputDebugString(szBuffer); #ifdef WIN32 OnFatalError(szBuffer); @@ -879,146 +485,6 @@ bool CSystem::ReLaunchMediaCenter() } #endif //defined(WIN32) -////////////////////////////////////////////////////////////////////////// -#if defined(WIN32) -void CSystem::LogSystemInfo() -{ - ////////////////////////////////////////////////////////////////////// - // Write the system informations to the log - ////////////////////////////////////////////////////////////////////// - - char szBuffer[1024]; - char szProfileBuffer[128]; - char szLanguageBuffer[64]; - //char szCPUModel[64]; - - MEMORYSTATUSEX MemoryStatus; - MemoryStatus.dwLength = sizeof(MemoryStatus); - - DEVMODE DisplayConfig; - OSVERSIONINFO OSVerInfo; - OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - // log system language - GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, szLanguageBuffer, sizeof(szLanguageBuffer)); - azsprintf(szBuffer, "System language: %s", szLanguageBuffer); - CryLogAlways(szBuffer); - - // log Windows directory - GetWindowsDirectory(szBuffer, sizeof(szBuffer)); - string str = "Windows Directory: \""; - str += szBuffer; - str += "\""; - CryLogAlways(str); - - ////////////////////////////////////////////////////////////////////// - // Send system time & date - ////////////////////////////////////////////////////////////////////// - - str = "Local time is "; - azstrtime(szBuffer); - str += szBuffer; - str += " "; - _strdate_s(szBuffer); - str += szBuffer; - azsprintf(szBuffer, ", system running for %lu minutes", GetTickCount() / 60000); - str += szBuffer; - CryLogAlways(str); - - ////////////////////////////////////////////////////////////////////// - // Send system memory status - ////////////////////////////////////////////////////////////////////// - - GlobalMemoryStatusEx(&MemoryStatus); - azsprintf(szBuffer, "%I64dMB physical memory installed, %I64dMB available, %I64dMB virtual memory installed, %ld percent of memory in use", - MemoryStatus.ullTotalPhys / 1048576 + 1, - MemoryStatus.ullAvailPhys / 1048576, - MemoryStatus.ullTotalVirtual / 1048576, - MemoryStatus.dwMemoryLoad); - CryLogAlways(szBuffer); - - if (GetISystem()->GetIMemoryManager()) - { - IMemoryManager::SProcessMemInfo memCounters; - GetISystem()->GetIMemoryManager()->GetProcessMemInfo(memCounters); - - uint64 PagefileUsage = memCounters.PagefileUsage; - uint64 PeakPagefileUsage = memCounters.PeakPagefileUsage; - uint64 WorkingSetSize = memCounters.WorkingSetSize; - azsprintf(szBuffer, "PageFile usage: %I64dMB, Working Set: %I64dMB, Peak PageFile usage: %I64dMB,", - (uint64)PagefileUsage / (1024 * 1024), - (uint64)WorkingSetSize / (1024 * 1024), - (uint64)PeakPagefileUsage / (1024 * 1024)); - CryLogAlways(szBuffer); - } - - ////////////////////////////////////////////////////////////////////// - // Send display settings - ////////////////////////////////////////////////////////////////////// - - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig); - GetPrivateProfileString("boot.description", "display.drv", - "(Unknown graphics card)", szProfileBuffer, sizeof(szProfileBuffer), - "system.ini"); - azsprintf(szBuffer, "Current display mode is %lux%lux%lu, %s", - DisplayConfig.dmPelsWidth, DisplayConfig.dmPelsHeight, - DisplayConfig.dmBitsPerPel, szProfileBuffer); - CryLogAlways(szBuffer); - - ////////////////////////////////////////////////////////////////////// - // Send input device configuration - ////////////////////////////////////////////////////////////////////// - - str = ""; - // Detect the keyboard type - switch (GetKeyboardType(0)) - { - case 1: - str = "IBM PC/XT (83-key)"; - break; - case 2: - str = "ICO (102-key)"; - break; - case 3: - str = "IBM PC/AT (84-key)"; - break; - case 4: - str = "IBM enhanced (101/102-key)"; - break; - case 5: - str = "Nokia 1050"; - break; - case 6: - str = "Nokia 9140"; - break; - case 7: - str = "Japanese"; - break; - default: - str = "Unknown"; - break; - } - - // Any mouse attached ? - if (!GetSystemMetrics(SM_MOUSEPRESENT)) - { - CryLogAlways(str + " keyboard and no mouse installed"); - } - else - { - azsprintf(szBuffer, " keyboard and %i+ button mouse installed", - GetSystemMetrics(SM_CMOUSEBUTTONS)); - CryLogAlways(str + szBuffer); - } - - CryLogAlways("--------------------------------------------------------------------------------"); -} -#else -void CSystem::LogSystemInfo() -{ -} -#endif - #if (defined(WIN32) || defined(WIN64)) ////////////////////////////////////////////////////////////////////////// bool CSystem::GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize) diff --git a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp b/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp index 637682065f..e384893e10 100644 --- a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp +++ b/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp @@ -15,7 +15,6 @@ #include #include #include -#include namespace UnitTests { @@ -25,10 +24,6 @@ namespace UnitTests public: void SetUp() override { - IMemoryManager* cryMemoryManager = nullptr; - CryGetIMemoryManagerInterface((void**)&cryMemoryManager); - AZ_Assert(cryMemoryManager, "Unable to resolve CryMemoryManager"); - m_cryMemoryManager = AZ::Environment::CreateVariable("CryIMemoryManagerInterface", cryMemoryManager); SSystemInitParams startupParams; AZ::AllocatorInstance::Create(); AZ::AllocatorInstance::Create(); @@ -44,8 +39,6 @@ namespace UnitTests CSystem* m_system = nullptr; - AZ::EnvironmentVariable m_cryMemoryManager; - }; TEST_F(CSystemUnitTests, ApplicationLogInstanceUnitTests) diff --git a/Code/CryEngine/CrySystem/XML/XmlUtils.cpp b/Code/CryEngine/CrySystem/XML/XmlUtils.cpp index de5a14ecd7..d4feec04f2 100644 --- a/Code/CryEngine/CrySystem/XML/XmlUtils.cpp +++ b/Code/CryEngine/CrySystem/XML/XmlUtils.cpp @@ -272,7 +272,6 @@ void CXmlUtils::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wpar case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: case ESYSTEM_EVENT_LEVEL_LOAD_END: g_pCXmlNode_PoolAlloc->FreeMemoryIfEmpty(); - STLALLOCATOR_CLEANUP; break; } } diff --git a/Code/CryEngine/CrySystem/crysystem_files.cmake b/Code/CryEngine/CrySystem/crysystem_files.cmake index 50cbdc24e4..6eff1ee8e2 100644 --- a/Code/CryEngine/CrySystem/crysystem_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_files.cmake @@ -19,13 +19,10 @@ set(FILES ConsoleBatchFile.cpp ConsoleHelpGen.cpp CryAsyncMemcpy.cpp - GeneralMemoryHeap.cpp HandlerBase.cpp - AsyncPakManager.cpp Log.cpp SystemRender.cpp PhysRenderer.cpp - ResourceManager.cpp ServerHandler.cpp ServerThrottle.cpp SyncLock.cpp @@ -42,9 +39,7 @@ set(FILES AutoDetectSpec.h ClientHandler.h HandlerBase.h - AsyncPakManager.h PhysRenderer.h - ResourceManager.h ServerHandler.h ServerThrottle.h SyncLock.h @@ -58,7 +53,6 @@ set(FILES ConsoleBatchFile.h ConsoleHelpGen.h CryWaterMark.h - GeneralMemoryHeap.h Log.h resource.h SimpleStringPool.h @@ -71,18 +65,6 @@ set(FILES WindowsConsole.h XConsole.h XConsoleVariable.h - crash_face.bmp - ImageHandler.h - ImageHandler.cpp - MemoryAddressRange.cpp - PageMappingHeap.cpp - CustomMemoryHeap.cpp - MemoryManager.cpp - MTSafeAllocator.cpp - MemoryAddressRange.h - PageMappingHeap.h - MemoryManager.h - MTSafeAllocator.h XML/SerializeXMLReader.cpp XML/SerializeXMLWriter.cpp XML/xml.cpp @@ -126,18 +108,6 @@ set(FILES ViewSystem/ViewSystem.h ZStdDecompressor.h ZStdDecompressor.cpp - StreamEngine/StreamAsyncFileRequest.cpp - StreamEngine/StreamAsyncFileRequest_Jobs.cpp - StreamEngine/StreamEngine.cpp - StreamEngine/StreamIOThread.cpp - StreamEngine/StreamReadStream.cpp - StreamEngine/AZRequestReadStream.cpp - StreamEngine/StreamAsyncFileRequest.h - StreamEngine/StreamEngine.h - StreamEngine/StreamIOThread.h - StreamEngine/StreamReadStream.h - StreamEngine/AZRequestReadStream.h - CrashHandler.rc CrySystem_precompiled.cpp CPUDetect.cpp CPUDetect.h diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index b2fe4417d3..c93f825a2c 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -916,27 +916,49 @@ namespace AZ SetSettingsRegistrySpecializations(specializations); AZStd::vector scratchBuffer; - // Retrieves the list gem module build targets that the active project depends on - SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, - AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) // In development builds apply the o3de registry and the command line to allow early overrides. This will // allow developers to override things like default paths or Asset Processor connection settings. Any additional // values will be replaced by later loads, so this step will happen again at the end of loading. SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + // Project User Registry is merged after the command line here to allow make sure the any command line override of the project path + // is used for merging the project's user registry SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); #endif + //! Retrieves the list gem targets that the project has load dependencies on + //! This populates the /Amazon/Gems//SourcePaths array entries which is required + //! by the MergeSettingsToRegistry_GemRegistry() function below to locate the gem's root folder + //! and merge in the gem's registry files. + //! But when running from a pre-built app from the O3DE SDK(Editor/AssetProcessor), the projects binary + //! directory is needed in order to located the load dependency registry files + //! That project binary folder is generated with the /user/Registry when CMake is configured + //! for the project + //! Therefore the order of merging must be as follows + //! 1. MergeSettingsToRegistry_ProjectUserRegistry - Populates the /Amazon/Project/Settings/Build/project_build_path + //! which contains the path to the project binary directory + //! 2. MergeSettingsToRegistry_TargetBuildDependencyRegistry - Loads the cmake_dependencies...setreg + //! file from the locations in order of + //! 1. /Registry + //! 2. /Registry + //! 3. /bin/$/Registry + //! 3. MergeSettingsToRegistry_GemRegistries - Merges the settings registry files from each gem's /Registry directory + + SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, + AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_EngineRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); #endif // Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); } void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations) diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 56dfbdcb71..bd73162498 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -599,6 +599,34 @@ namespace AZ::SettingsRegistryMergeUtils ? devWriteStorage.value() : projectUserPath.Native()); + // Set the project in-memory build path if the ProjectBuildPath key has been supplied + if (AZ::IO::FixedMaxPath projectBuildPath; registry.Get(projectBuildPath.Native(), ProjectBuildPath)) + { + registry.Remove(FilePathKey_ProjectBuildPath); + registry.Remove(FilePathKey_ProjectConfigurationBinPath); + AZ::IO::FixedMaxPath buildConfigurationPath = normalizedProjectPath / projectBuildPath; + if (IO::SystemFile::Exists(buildConfigurationPath.c_str())) + { + registry.Set(FilePathKey_ProjectBuildPath, buildConfigurationPath.LexicallyNormal().Native()); + } + + // Add the specific build configuration paths to the Settings Registry + // First try /bin/$ and if that path doesn't exist + // try /bin/$/$ + buildConfigurationPath /= "bin"; + if (IO::SystemFile::Exists((buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).c_str())) + { + registry.Set(FilePathKey_ProjectConfigurationBinPath, + (buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native()); + } + else if (IO::SystemFile::Exists((buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).c_str())) + { + registry.Set(FilePathKey_ProjectConfigurationBinPath, + (buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native()); + } + + } + // Project name - if it was set via merging project.json use that value, otherwise use the project path's folder name. auto projectNameKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) @@ -689,6 +717,14 @@ namespace AZ::SettingsRegistryMergeUtils mergePath /= SettingsRegistryInterface::RegistryFolder; registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer); } + + AZ::IO::FixedMaxPath projectBinPath; + if (registry.Get(projectBinPath.Native(), FilePathKey_ProjectConfigurationBinPath)) + { + // Append the project build path path to the project root + projectBinPath /= SettingsRegistryInterface::RegistryFolder; + registry.MergeSettingsFolder(projectBinPath.Native(), specializations, platform, "", scratchBuffer); + } } void MergeSettingsToRegistry_EngineRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform, @@ -934,7 +970,8 @@ namespace AZ::SettingsRegistryMergeUtils "project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}, OptionKeyToRegsetKey{ "project-cache-path", - AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}}; + AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}, + OptionKeyToRegsetKey{"project-build-path", ProjectBuildPath} }; AZStd::fixed_vector overrideArgs; diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h index 4e00c0e6ec..576066c29f 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h @@ -52,6 +52,14 @@ namespace AZ::SettingsRegistryMergeUtils //! project settings can be stored inline static constexpr char FilePathKey_ProjectUserPath[] = "/Amazon/AzCore/Runtime/FilePaths/SourceProjectUserPath"; + //! User facing key which represents the root of a project cmake build tree. i.e the ${CMAKE_BINARY_DIR} + //! A relative path is taking relative to the *project* root, NOT *engine* root. + inline constexpr AZStd::string_view ProjectBuildPath = "/Amazon/Project/Settings/Build/project_build_path"; + //! In-Memory only key which stores an absolute path to the project build directory + inline constexpr AZStd::string_view FilePathKey_ProjectBuildPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectBuildPath"; + //! In-Memory only key which stores the configuration directory containing the built binaries + inline constexpr AZStd::string_view FilePathKey_ProjectConfigurationBinPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectConfigurationBinPath"; + //! Development write storage path may be considered temporary or cache storage on some platforms inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage"; @@ -128,7 +136,7 @@ namespace AZ::SettingsRegistryMergeUtils //! Callback function that is after a has been filtered through the CommentPrefixFunc //! to determine if the text matches a section header //! returns a view of the section name if the line contains a section - //! Otherwise an empty view is returend + //! Otherwise an empty view is returned using SectionHeaderFunc = AZStd::function; //! Root JSON pointer path to place all key=values pairs of configuration data within diff --git a/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp b/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp index 169a4db6ff..30ec08538a 100644 --- a/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp +++ b/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp @@ -17,8 +17,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { + return {}; } void* OpenModule(const AZ::OSString& fileName, bool&) @@ -26,10 +27,9 @@ namespace AZ // Android 19 does not have RTLD_NOLOAD but it should be OK since only the Editor expects to reopen modules return dlopen(fileName.c_str(), RTLD_NOW); } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp index 8457ff14a6..7dd889e94d 100644 --- a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp +++ b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - path = exePath; - path.push_back('/'); - } + return AZ::Utils::GetExecutableDirectory(); } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,9 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp index 1c16f50203..8e2b40aaca 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp @@ -11,9 +11,11 @@ */ #include -#include // for AZ_MAX_PATH_LEN +#include +#include #include +#include #include #include @@ -21,9 +23,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path); + AZ::IO::FixedMaxPath GetModulePath(); void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen); - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath); + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath); } class DynamicModuleHandleUnixLike @@ -36,40 +38,55 @@ namespace AZ : DynamicModuleHandle(fullFileName) , m_handle(nullptr) { - AZ::OSString path; - AZ::OSString fileName; - AZ::OSString fullPath = ""; - AZ::OSString::size_type finalSlash = m_fileName.find_last_of("/"); - if (finalSlash != AZ::OSString::npos) + AZ::IO::FixedMaxPath fullFilePath(AZStd::string_view{m_fileName}); + if (fullFilePath.HasFilename()) { - // Path up to and including final slash - path = m_fileName.substr(0, finalSlash + 1); - // Everything after the final slash - // If m_fileName ends in /, the end result is path/lib.dylib, which just fails to load. - fileName = m_fileName.substr(finalSlash + 1); - } - else - { - // If no slash found, assume empty path, only file name - path = ""; - Platform::GetModulePath(path); - fileName = m_fileName; + AZ::IO::FixedMaxPathString fileNamePath{fullFilePath.Filename().Native()}; + if (!fileNamePath.starts_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX)) + { + fileNamePath = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileNamePath; + } + + if (!fileNamePath.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)) + { + fileNamePath += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + } + + fullFilePath.ReplaceFilename(AZStd::string_view(fileNamePath)); } - if (fileName.substr(0, 3) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX) + Platform::ConstructModuleFullFileName(fullFilePath); + + // Check if the module exist at the given path within the current working directory + // If it doesn't attempt to append the path to the executable path + if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str())) { - fileName = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileName; + auto candidatePath = Platform::GetModulePath() / fullFilePath; + if (AZ::IO::SystemFile::Exists(candidatePath.c_str())) + { + fullFilePath = candidatePath; + } } - size_t extensionLen = strlen(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION); - if (fileName.substr(fileName.length() - extensionLen, extensionLen) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION) + // If the path still doesn't exist at this point, check the SettingsRegistryMergeUtils + // FilePathKey_ProjectBuildPath key to see if a project-build-path argument has been supplied + if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str())) { - fileName = fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if(AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + projectModulePath /= fullFilePath; + if (AZ::IO::SystemFile::Exists(projectModulePath.c_str())) + { + fullFilePath = projectModulePath; + } + } + } } - - Platform::ConstructModuleFullFileName(path, fileName, fullPath); - m_fileName = fullPath; + m_fileName = AZStd::string_view{fullFilePath.Native()}; } ~DynamicModuleHandleUnixLike() override @@ -81,9 +98,9 @@ namespace AZ { AZ::Debug::Trace::Printf("Module", "Attempting to load module:%s\n", m_fileName.c_str()); bool alreadyOpen = false; - + m_handle = Platform::OpenModule(m_fileName, alreadyOpen); - + if(m_handle) { if (alreadyOpen) diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp index 49d5360faa..9daabfb86b 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace AZ @@ -31,13 +32,13 @@ namespace AZ { // Ensure filename ends in ".dll" // Otherwise filenames like "gem.1.0.0" fail to load (.0 is assumed to be the extension). - if (m_fileName.substr(m_fileName.length() - 4) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION) + if (!m_fileName.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)) { - m_fileName = m_fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + m_fileName += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; } AZ::IO::PathView modulePathView{ m_fileName }; - // If the module path doesn't have a directory within it, prepend it to the path + // If the module path doesn't have a directory within it, prepend the executable directory to the path // and check if the new path exist if (modulePathView.HasFilename() && !modulePathView.HasParentPath()) { @@ -54,6 +55,27 @@ namespace AZ } } } + + // If the module file path does not exist, attempt to search for the module within + // the project's build directory + if (!AZ::IO::SystemFile::Exists(m_fileName.c_str())) + { + // The Settings Registry may not exist in early startup if modules are loaded + // before the ComponentApplication is crated(such as in the Editor main.cpp) + // Therefore an existence check is needed + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if(AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + projectModulePath /= AZStd::string_view(m_fileName); + if (AZ::IO::SystemFile::Exists(projectModulePath.c_str())) + { + m_fileName.assign(projectModulePath.c_str(), projectModulePath.Native().size()); + } + } + } + } } ~DynamicModuleHandleWindows() override diff --git a/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp b/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp index 8457ff14a6..7dd889e94d 100644 --- a/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp +++ b/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - path = exePath; - path.push_back('/'); - } + return AZ::Utils::GetExecutableDirectory(); } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,9 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp b/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp index 8a082a01a6..569aae6f53 100644 --- a/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp +++ b/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - AZ::OSString frameworks = "/Frameworks/"; - path = exePath + frameworks; - } + return AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "Frameworks"; } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,15 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath) { - fullPath = path + fileName + ".framework/" + fileName; + // Append .framework to the name of full path + // Afterwards use the AZ::IO::Path Append function append the filename as a child + // of the framework directory + AZ::IO::FixedMaxPathString fileName = fullPath.Filename().Native(); + fullPath.ReplaceFilename(fileName + ".framework"); + fullPath /= fileName; } } } diff --git a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h index 4e89e0a45c..f5f1428ed6 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h +++ b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h @@ -24,7 +24,7 @@ namespace AZ::IO ePakPriorityPakOnly = 2 }; - // variables that control behavior of Archive/StreamEngine subsystems + // variables that control behavior of the Archive subsystem struct ArchiveVars { #if defined(_RELEASE) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 3c05887a89..9083cb7d0d 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -881,7 +881,7 @@ namespace AzFramework serializeContext->ClassDeprecate("NetBindable", "{80206665-D429-4703-B42E-94434F82F381}"); serializeContext->Class() - ->Version(4, &TransformComponentVersionConverter) + ->Version(5, &TransformComponentVersionConverter) ->Field("Parent", &TransformComponent::m_parentId) ->Field("Transform", &TransformComponent::m_worldTM) ->Field("LocalTransform", &TransformComponent::m_localTM) diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp index 30343b1322..cdfad7f116 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp @@ -979,7 +979,7 @@ namespace AzFramework }; serializeContext->Class() - ->Version(3, converter) + ->Version(4, converter) ->Field("ContextID", &ScriptComponent::m_contextId) ->Field("Properties", &ScriptComponent::m_properties) ->Field("Script", &ScriptComponent::m_script) diff --git a/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp b/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp index edd4af293d..1fb440e6e5 100644 --- a/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp +++ b/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp @@ -57,13 +57,16 @@ namespace AzGameFramework AZStd::vector scratchBuffer; - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); #endif + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + // Used the lowercase the platform name since the bootstrap.game...setreg is being loaded // from the asset cache root where all the files are in lowercased from regardless of the filesystem case-sensitivity static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE "." AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER ".setreg"; @@ -77,6 +80,7 @@ namespace AzGameFramework #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); #endif diff --git a/Code/Framework/AzTest/AzTest/AzTest.h b/Code/Framework/AzTest/AzTest/AzTest.h index a3d43bd521..c82598cb0c 100644 --- a/Code/Framework/AzTest/AzTest/AzTest.h +++ b/Code/Framework/AzTest/AzTest/AzTest.h @@ -17,7 +17,7 @@ #include AZ_PUSH_DISABLE_WARNING(4389 4800, "-Wunknown-warning-option"); // 'int' : forcing value to bool 'true' or 'false' (performance warning). -#undef strdup // platform.h in CryCommon changes this define which is required by googletest +#undef strdup // This define is required by googletest #include #include AZ_POP_DISABLE_WARNING; @@ -477,8 +477,7 @@ int main(int argc, char** argv) } \ } while (0); // safe multi-line macro - creates a single statement -// Avoid accidentally being managed by CryMemory, or problems with new/delete when -// AZ allocators are not ready or properly un/initialized. +// Avoid problems with new/delete when AZ allocators are not ready or properly un/initialized. #define AZ_TEST_CLASS_ALLOCATOR(Class_) \ void* operator new (size_t size) \ { \ diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 9649818ed9..5ecff637a1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -636,11 +636,18 @@ namespace AzToolsFramework if (!EntitiesBelongToSameInstance(entityIds)) { - return AZ::Failure(AZStd::string("DeleteEntitiesAndAllDescendantsInInstance - Deletion Error. Cannot delete multiple " - "entities belonging to different instances with one operation.")); + return AZ::Failure(AZStd::string("Cannot delete multiple entities belonging to different instances with one operation.")); } - InstanceOptionalReference instance = GetOwnerInstanceByEntityId(entityIds[0]); + AZ::EntityId firstEntityIdToDelete = entityIds[0]; + InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDelete); + + // If the first entity id is a container entity id, then we need to mark its parent as the common owning instance because you + // cannot delete an instance from itself. + if (commonOwningInstance->get().GetContainerEntityId() == firstEntityIdToDelete) + { + commonOwningInstance = commonOwningInstance->get().GetParentInstance(); + } // Retrieve entityList from entityIds EntityList inputEntityList = EntityIdListToEntityList(entityIds); @@ -680,14 +687,14 @@ namespace AzToolsFramework AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "Internal::DeleteEntities:UndoCaptureAndPurgeEntities"); Prefab::PrefabDom instanceDomBefore; - m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBefore, instance->get()); + m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBefore, commonOwningInstance->get()); if (deleteDescendants) { AZStd::vector entities; AZStd::vector> instances; - bool success = RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, instance->get(), entities, instances); + bool success = RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonOwningInstance->get(), entities, instances); if (!success) { @@ -701,6 +708,7 @@ namespace AzToolsFramework for (auto& nestedInstance : instances) { + RemoveLink(nestedInstance, commonOwningInstance->get().GetTemplateId(), currentUndoBatch); nestedInstance.reset(); } } @@ -712,22 +720,22 @@ namespace AzToolsFramework // If this is the container entity, it actually represents the instance so get its owner if (owningInstance->get().GetContainerEntityId() == entityId) { - auto instancePtr = instance->get().DetachNestedInstance(owningInstance->get().GetInstanceAlias()); - instancePtr.reset(); + auto instancePtr = commonOwningInstance->get().DetachNestedInstance(owningInstance->get().GetInstanceAlias()); + RemoveLink(instancePtr, commonOwningInstance->get().GetTemplateId(), currentUndoBatch); } else { - instance->get().DetachEntity(entityId); + commonOwningInstance->get().DetachEntity(entityId); AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationRequests::DeleteEntity, entityId); } } } Prefab::PrefabDom instanceDomAfter; - m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, instance->get()); + m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, commonOwningInstance->get()); PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance deletion"); - command->Capture(instanceDomBefore, instanceDomAfter, instance->get().GetTemplateId()); + command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId()); command->SetParent(selCommand); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index 7f28080e9e..bc7afbf085 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -403,9 +403,12 @@ namespace AzToolsFramework AzToolsFramework::EntityIdList selectedEntityIds; AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult( selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities); - - AzToolsFramework::ToolsApplicationRequestBus::Broadcast( - &AzToolsFramework::ToolsApplicationRequests::DeleteEntitiesAndAllDescendants, selectedEntityIds); + PrefabOperationResult deleteSelectedResult = + s_prefabPublicInterface->DeleteEntitiesAndAllDescendantsInInstance(selectedEntityIds); + if (!deleteSelectedResult.IsSuccess()) + { + WarnUserOfError("Delete selected entities error", deleteSelectedResult.GetError()); + } } void PrefabIntegrationManager::GenerateSuggestedFilenameFromEntities(const EntityIdList& entityIds, AZStd::string& outName) diff --git a/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp b/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp index b7f04a7e10..8f8d310475 100644 --- a/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp +++ b/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp @@ -50,7 +50,6 @@ int APIENTRY WinMain([[maybe_unused]] HINSTANCE hInstance, [[maybe_unused]] HINS { // HACK HACK HACK - is this still needed?!?! // CrySystem module can get loaded multiple times (even from within CrySystem itself) - // and currently there is no way to track them (\ref _CryMemoryManagerPoolHelper::Init() in CryMemoryManager_impl.h) // so we will release it as many times as it takes until it actually unloads. void* hModule = CryLoadLibraryDefName("CrySystem"); if (hModule) diff --git a/Code/Sandbox/Editor/GotoPositionDlg.cpp b/Code/Sandbox/Editor/GotoPositionDlg.cpp index dc0f024bcb..a09f594b7b 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.cpp +++ b/Code/Sandbox/Editor/GotoPositionDlg.cpp @@ -106,8 +106,7 @@ void CGotoPositionDlg::OnChangeEdit() { const int lengthInSw = 8; const int strNum = 6; - TArray< float > pos(strNum); - pos.Set(0); + AZStd::vector pos(strNum); m_sPos = m_ui->m_posEdit->text(); const QStringList parts = m_sPos.split(QRegularExpression("[\\s,;\\t]"), Qt::SkipEmptyParts); diff --git a/Code/Sandbox/Editor/IEditorImpl.cpp b/Code/Sandbox/Editor/IEditorImpl.cpp index 380fc80e66..4b3c494413 100644 --- a/Code/Sandbox/Editor/IEditorImpl.cpp +++ b/Code/Sandbox/Editor/IEditorImpl.cpp @@ -92,7 +92,6 @@ AZ_POP_DISABLE_WARNING #ifdef _RELEASE #undef _RELEASE #endif -#include #include "Core/QtEditorApplication.h" // for Editor::EditorQtApplication diff --git a/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp b/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp index 407c124f5e..98123a016b 100644 --- a/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp +++ b/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp @@ -2734,9 +2734,6 @@ void CTrackViewDopeSheetBase::DrawKeys(CTrackViewTrack* pTrack, QPainter* painte const int kDefaultWidthForDescription = 200; const int kSmallMargin = 10; - FixedDynArray drawnKeyTimes; - drawnKeyTimes.set(ArrayT((float*)alloca(numKeys * sizeof(float)), numKeys)); - AZStd::vector sortedKeys; sortedKeys.reserve(numKeys); for (int i = 0; i < numKeys; ++i) @@ -2751,11 +2748,6 @@ void CTrackViewDopeSheetBase::DrawKeys(CTrackViewTrack* pTrack, QPainter* painte CTrackViewKeyHandle keyHandle = sortedKeys[i]; const float time = keyHandle.GetTime(); - if (!stl::push_back_unique(drawnKeyTimes, time)) - { - continue; - } - int x = TimeToClient(time); if (x - kSmallMargin > rect.right()) { diff --git a/Code/Sandbox/Editor/Util/ImageTIF.cpp b/Code/Sandbox/Editor/Util/ImageTIF.cpp index 0182d9654b..f69acc4161 100644 --- a/Code/Sandbox/Editor/Util/ImageTIF.cpp +++ b/Code/Sandbox/Editor/Util/ImageTIF.cpp @@ -440,7 +440,6 @@ bool CImageTIF::SaveRAW(const QString& fileName, const void* pData, int width, i { size_t offset = h * pitch; int err = TIFFWriteScanline(tif, raster + offset, h, 0); - assert(CryMemory::IsHeapValid()); if (err < 0) { bRet = false; diff --git a/Code/Sandbox/Editor/Util/IndexedFiles.h b/Code/Sandbox/Editor/Util/IndexedFiles.h index 641aff0333..0ae26b5adf 100644 --- a/Code/Sandbox/Editor/Util/IndexedFiles.h +++ b/Code/Sandbox/Editor/Util/IndexedFiles.h @@ -22,7 +22,6 @@ #include "FileUtil.h" -#include "STLPoolAllocator.h" #include class CIndexedFiles @@ -117,15 +116,8 @@ private: std::vector > m_updateCallbacks; IFileUtil::FileArray m_files; std::map m_pathToIndex; -#if defined(_DEBUG) || defined(AZ_COMPILER_CLANG) - // In debug, the validation phase of the pool allocator when destructed takes so much time, - // and using the STLPoolAllocator causes a strange issue when compiling with clang typedef std::set > int_set; typedef std::map > TagTable; -#else - typedef std::set, stl::STLPoolAllocator > int_set; - typedef std::map, stl::STLPoolAllocator > > TagTable; -#endif TagTable m_tags; QString m_rootPath; diff --git a/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp b/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp index 37c8d0adee..523e39d622 100644 --- a/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp +++ b/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp @@ -297,20 +297,28 @@ namespace AssetProcessor AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, platform, specialization, &scratchBuffer); // Merge the Project User and User home settings registry only in non-release builds + constexpr bool executeRegDumpCommands = false; + AZ::CommandLine* commandLine{}; + AZ::ComponentApplicationBus::Broadcast([®istry, &commandLine](AZ::ComponentApplicationRequests* appRequests) + { + commandLine = appRequests->GetAzCommandLine(); + }); + if (!specialization.Contains("release")) { AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, platform, specialization, &scratchBuffer); + if (commandLine) + { + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands); + } AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, platform, specialization, &scratchBuffer); } - AZ::ComponentApplicationBus::Broadcast([®istry](AZ::ComponentApplicationRequests* appRequests) + if (commandLine) { - if (AZ::CommandLine* commandLine = appRequests->GetAzCommandLine(); commandLine != nullptr) - { - constexpr bool executeRegDumpCommands = false; - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands); - } - }); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands); + } + if (registry.Visit(exporter, "")) { diff --git a/Code/Tools/SerializeContextTools/Converter.cpp b/Code/Tools/SerializeContextTools/Converter.cpp index b15bb4fa8e..0b19d4e981 100644 --- a/Code/Tools/SerializeContextTools/Converter.cpp +++ b/Code/Tools/SerializeContextTools/Converter.cpp @@ -117,7 +117,7 @@ namespace AZ } return true; }; - if (!Utilities::InspectSerializedFile(filePath, convertSettings.m_serializeContext, callback)) + if (!Utilities::InspectSerializedFile(filePath.c_str(), convertSettings.m_serializeContext, callback)) { AZ_Warning("Convert", false, "Failed to load '%s'. File may not contain an object stream.", filePath.c_str()); result = false; @@ -287,7 +287,7 @@ namespace AZ } return true; }; - if (!Utilities::InspectSerializedFile(filePath, convertSettings.m_serializeContext, callback)) + if (!Utilities::InspectSerializedFile(filePath.c_str(), convertSettings.m_serializeContext, callback)) { AZ_Warning("Convert", false, "Failed to load '%s'. File may not contain an object stream.", filePath.c_str()); result = false; diff --git a/Code/Tools/SerializeContextTools/Converter.h b/Code/Tools/SerializeContextTools/Converter.h index 18f30cc562..c6338b8d29 100644 --- a/Code/Tools/SerializeContextTools/Converter.h +++ b/Code/Tools/SerializeContextTools/Converter.h @@ -42,7 +42,7 @@ namespace AZ //! Can be used to convert *.ini and *.cfg files static bool ConvertConfigFile(Application& application); - private: + protected: using PathDocumentPair = AZStd::pair; using PathDocumentContainer = AZStd::vector; diff --git a/Code/Tools/SerializeContextTools/Dumper.cpp b/Code/Tools/SerializeContextTools/Dumper.cpp index 55c9581602..590ee65571 100644 --- a/Code/Tools/SerializeContextTools/Dumper.cpp +++ b/Code/Tools/SerializeContextTools/Dumper.cpp @@ -85,7 +85,7 @@ namespace AZ::SerializeContextTools result = false; } }; - if (!Utilities::InspectSerializedFile(filePath, sc, callback)) + if (!Utilities::InspectSerializedFile(filePath.c_str(), sc, callback)) { result = false; continue; diff --git a/Code/Tools/SerializeContextTools/SliceConverter.cpp b/Code/Tools/SerializeContextTools/SliceConverter.cpp new file mode 100644 index 0000000000..2df3888607 --- /dev/null +++ b/Code/Tools/SerializeContextTools/SliceConverter.cpp @@ -0,0 +1,263 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// SliceConverter reads in a slice file (saved in an ObjectStream format), instantiates it, creates a prefab out of the data, +// and saves the prefab in a JSON format. This can be used for one-time migrations of slices or slice-based levels to prefabs. +// This converter is still in an early state. It can convert trivial slices, but it cannot handle nested slices yet. +// +// If the slice contains legacy data, it will print out warnings / errors about the data that couldn't be serialized. +// The prefab will be generated without that data. + +namespace AZ +{ + namespace SerializeContextTools + { + bool SliceConverter::ConvertSliceFiles(Application& application) + { + using namespace AZ::JsonSerializationResult; + + const AZ::CommandLine* commandLine = application.GetAzCommandLine(); + if (!commandLine) + { + AZ_Error("SerializeContextTools", false, "Command line not available."); + return false; + } + + JsonSerializerSettings convertSettings; + convertSettings.m_keepDefaults = commandLine->HasSwitch("keepdefaults"); + convertSettings.m_registrationContext = application.GetJsonRegistrationContext(); + convertSettings.m_serializeContext = application.GetSerializeContext(); + if (!convertSettings.m_serializeContext) + { + AZ_Error("Convert-Slice", false, "No serialize context found."); + return false; + } + if (!convertSettings.m_registrationContext) + { + AZ_Error("Convert-Slice", false, "No json registration context found."); + return false; + } + AZStd::string logggingScratchBuffer; + SetupLogging(logggingScratchBuffer, convertSettings.m_reporting, *commandLine); + + bool isDryRun = commandLine->HasSwitch("dryrun"); + + JsonDeserializerSettings verifySettings; + verifySettings.m_registrationContext = application.GetJsonRegistrationContext(); + verifySettings.m_serializeContext = application.GetSerializeContext(); + SetupLogging(logggingScratchBuffer, verifySettings.m_reporting, *commandLine); + + auto archiveInterface = AZ::Interface::Get(); + + // Find the Prefab System Component for use in creating and saving the prefab + AZ::Entity* systemEntity = application.FindEntity(AZ::SystemEntityId); + AZ_Assert(systemEntity != nullptr, "System entity doesn't exist."); + auto prefabSystemComponent = systemEntity->FindComponent(); + AZ_Assert(prefabSystemComponent != nullptr, "Prefab System component doesn't exist"); + + bool result = true; + rapidjson::StringBuffer scratchBuffer; + + AZStd::vector fileList = Utilities::ReadFileListFromCommandLine(application, "files"); + for (AZStd::string& filePath : fileList) + { + bool packOpened = false; + + AZ::IO::Path outputPath = filePath; + outputPath.ReplaceExtension("prefab"); + + AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + AZ_Printf("Convert-Slice", "Converting '%s' to '%s'\n", filePath.c_str(), outputPath.c_str()); + + AZ::IO::Path inputPath = filePath; + auto fileExtension = inputPath.Extension(); + if (fileExtension == ".ly") + { + // Special case: for level files, we need to open the .ly zip file and convert the levelentities.editor_xml file + // inside of it. All the other files can be ignored as they are deprecated legacy system files that are no longer + // loaded with prefab-based levels. + packOpened = archiveInterface->OpenPack(filePath); + inputPath.ReplaceFilename("levelentities.editor_xml"); + AZ_Warning("Convert-Slice", packOpened, " '%s' could not be opened as a pack file.\n", filePath.c_str()); + } + else + { + AZ_Warning( + "Convert-Slice", (fileExtension == ".slice"), + " Warning: Only .ly and .slice files are supported, conversion of '%.*s' may not work.\n", + AZ_STRING_ARG(fileExtension.Native())); + } + + auto callback = [prefabSystemComponent, &outputPath, isDryRun] + (void* classPtr, const Uuid& classId, [[maybe_unused]] SerializeContext* context) + { + if (classId != azrtti_typeid()) + { + AZ_Printf("Convert-Slice", " File not converted: Slice root is not an entity.\n"); + return false; + } + + AZ::Entity* rootEntity = reinterpret_cast(classPtr); + return ConvertSliceFile(prefabSystemComponent, outputPath, isDryRun, rootEntity); + }; + + if (!Utilities::InspectSerializedFile(inputPath.c_str(), convertSettings.m_serializeContext, callback)) + { + AZ_Warning("Convert-Slice", false, "Failed to load '%s'. File may not contain an object stream.", inputPath.c_str()); + result = false; + } + + if (packOpened) + { + [[maybe_unused]] bool closeResult = archiveInterface->ClosePack(filePath); + AZ_Warning("Convert-Slice", !closeResult, "Failed to close '%s'.", filePath.c_str()); + } + + AZ_Printf("Convert-Slice", "Finished converting '%s' to '%s'\n", filePath.c_str(), outputPath.c_str()); + AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + } + + return result; + } + + bool SliceConverter::ConvertSliceFile( + AzToolsFramework::Prefab::PrefabSystemComponent* prefabSystemComponent, AZ::IO::PathView outputPath, bool isDryRun, + AZ::Entity* rootEntity) + { + // Find the slice from the root entity. + SliceComponent* sliceComponent = AZ::EntityUtils::FindFirstDerivedComponent(rootEntity); + if (sliceComponent == nullptr) + { + AZ_Printf("Convert-Slice", " File not converted: Root entity did not contain a slice component.\n"); + return false; + } + + // Get all of the entities from the slice. + SliceComponent::EntityList sliceEntities; + bool getEntitiesResult = sliceComponent->GetEntities(sliceEntities); + if ((!getEntitiesResult) || (sliceEntities.empty())) + { + AZ_Printf("Convert-Slice", " File not converted: Slice entities could not be retrieved.\n"); + return false; + } + + // Create the Prefab with the entities from the slice + AZStd::unique_ptr sourceInstance( + prefabSystemComponent->CreatePrefab(sliceEntities, {}, outputPath)); + + // Dispatch events here, because prefab creation might trigger asset loads in rare circumstances. + AZ::Data::AssetManager::Instance().DispatchEvents(); + + // Set up the Prefab container entity to be a proper Editor entity. (This logic is normally triggered + // via an EditorRequests EBus in CreatePrefab, but the subsystem that listens for it isn't present in this tool.) + AzToolsFramework::Prefab::EntityOptionalReference container = sourceInstance->GetContainerEntity(); + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequestBus::Events::AddRequiredComponents, container->get()); + container->get().AddComponent(aznew AzToolsFramework::Prefab::EditorPrefabComponent()); + + // Reparent any root-level slice entities to the container entity. + for (auto entity : sliceEntities) + { + AzToolsFramework::Components::TransformComponent* transformComponent = + entity->FindComponent(); + if (transformComponent) + { + if (!transformComponent->GetParentId().IsValid()) + { + transformComponent->SetParent(container->get().GetId()); + } + } + } + + auto templateId = sourceInstance->GetTemplateId(); + + if (templateId == AzToolsFramework::Prefab::InvalidTemplateId) + { + AZ_Printf("Convert-Slice", " Path error. Path could be invalid, or the prefab may not be loaded in this level.\n"); + return false; + } + + // Update the prefab template with the fixed-up data in our prefab instance. + AzToolsFramework::Prefab::PrefabDom prefabDom; + bool storeResult = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*sourceInstance, prefabDom); + if (storeResult == false) + { + AZ_Printf("Convert-Slice", " Failed to convert prefab instance data to a PrefabDom.\n"); + return false; + } + prefabSystemComponent->UpdatePrefabTemplate(templateId, prefabDom); + + // Dispatch events here, because prefab serialization might trigger asset loads in rare circumstances. + AZ::Data::AssetManager::Instance().DispatchEvents(); + + if (isDryRun) + { + PrintPrefab(prefabDom, sourceInstance->GetTemplateSourcePath()); + return true; + } + else + { + return SavePrefab(templateId); + } + } + + void SliceConverter::PrintPrefab(const AzToolsFramework::Prefab::PrefabDom& prefabDom, const AZ::IO::Path& templatePath) + { + rapidjson::StringBuffer prefabBuffer; + rapidjson::PrettyWriter writer(prefabBuffer); + prefabDom.Accept(writer); + AZ_Printf("Convert-Slice", "JSON for %s:\n", templatePath.c_str()); + + // We use Output() to print out the JSON because AZ_Printf has a 4096-character limit. + AZ::Debug::Trace::Instance().Output("", prefabBuffer.GetString()); + AZ::Debug::Trace::Instance().Output("", "\n"); + } + + bool SliceConverter::SavePrefab(AzToolsFramework::Prefab::TemplateId templateId) + { + auto prefabLoaderInterface = AZ::Interface::Get(); + + if (!prefabLoaderInterface->SaveTemplate(templateId)) + { + AZ_Printf("Convert-Slice", " Could not save prefab - internal error (Json write operation failure).\n"); + return false; + } + + return true; + } + + } // namespace SerializeContextTools +} // namespace AZ diff --git a/Code/Tools/SerializeContextTools/SliceConverter.h b/Code/Tools/SerializeContextTools/SliceConverter.h new file mode 100644 index 0000000000..90dfa0d50a --- /dev/null +++ b/Code/Tools/SerializeContextTools/SliceConverter.h @@ -0,0 +1,53 @@ +/* +* 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. +* +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace AZ +{ + class CommandLine; + class Entity; + class ModuleEntity; + class SerializeContext; + struct Uuid; + + namespace SerializeContextTools + { + class Application; + + class SliceConverter : public Converter + { + public: + static bool ConvertSliceFiles(Application& application); + + private: + + static bool ConvertSliceFile(AzToolsFramework::Prefab::PrefabSystemComponent* prefabSystemComponent, + AZ::IO::PathView outputPath, bool isDryRun, AZ::Entity* rootEntity); + + static void PrintPrefab(const AzToolsFramework::Prefab::PrefabDom& prefabDom, const AZ::IO::Path& templatePath); + static bool SavePrefab(AzToolsFramework::Prefab::TemplateId templateId); + }; + } // namespace SerializeContextTools +} // namespace AZ diff --git a/Code/Tools/SerializeContextTools/Utilities.cpp b/Code/Tools/SerializeContextTools/Utilities.cpp index 1c50466443..cfd75a44e7 100644 --- a/Code/Tools/SerializeContextTools/Utilities.cpp +++ b/Code/Tools/SerializeContextTools/Utilities.cpp @@ -209,30 +209,42 @@ namespace AZ::SerializeContextTools return result; } - bool Utilities::InspectSerializedFile(const AZStd::string& filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback) + bool Utilities::InspectSerializedFile(const char* filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback) { - if (!AZ::IO::SystemFile::Exists(filePath.c_str())) + if (!AZ::IO::FileIOBase::GetInstance()->Exists(filePath)) { - AZ_Error("Verify", false, "Unable to open file '%s' as it doesn't exist.", filePath.c_str()); + AZ_Error("Verify", false, "Unable to open file '%s' as it doesn't exist.", filePath); return false; } - u64 fileLength = AZ::IO::SystemFile::Length(filePath.c_str()); - if (fileLength == 0) + AZ::IO::HandleType fileHandle; + auto openResult = AZ::IO::FileIOBase::GetInstance()->Open(filePath, AZ::IO::OpenMode::ModeRead, fileHandle); + if (!openResult) { - AZ_Error("Verify", false, "File '%s' doesn't have content.", filePath.c_str()); + AZ_Error("Verify", false, "File '%s' could not be opened.", filePath); + return false; + } + + u64 fileLength = 0; + auto sizeResult = AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileLength); + if (!sizeResult || (fileLength == 0)) + { + AZ_Error("Verify", false, "File '%s' doesn't have content.", filePath); return false; } AZStd::vector data; data.resize_no_construct(fileLength); - u64 bytesRead = AZ::IO::SystemFile::Read(filePath.c_str(), data.data()); - if (bytesRead != fileLength) + u64 bytesRead = 0; + auto readResult = AZ::IO::FileIOBase::GetInstance()->Read(fileHandle, data.data(), fileLength, true, &bytesRead); + if (!readResult || (bytesRead != fileLength)) { - AZ_Error("Verify", false, "Unable to read file '%s'.", filePath.c_str()); + AZ_Error("Verify", false, "Unable to read file '%s'.", filePath); return false; } + AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); + AZ::IO::MemoryStream stream(data.data(), fileLength); ObjectStream::FilterDescriptor filter; @@ -241,7 +253,7 @@ namespace AZ::SerializeContextTools filter.m_assetCB = AZ::Data::AssetFilterNoAssetLoading; if (!ObjectStream::LoadBlocking(&stream, *sc, classCallback, filter)) { - AZ_Printf("Verify", "Failed to deserialize '%s'\n", filePath.c_str()); + AZ_Printf("Verify", "Failed to deserialize '%s'\n", filePath); return false; } return true; diff --git a/Code/Tools/SerializeContextTools/Utilities.h b/Code/Tools/SerializeContextTools/Utilities.h index d04f67a304..f08bfc2f64 100644 --- a/Code/Tools/SerializeContextTools/Utilities.h +++ b/Code/Tools/SerializeContextTools/Utilities.h @@ -39,7 +39,7 @@ namespace AZ static AZStd::vector GetSystemComponents(const Application& application); - static bool InspectSerializedFile(const AZStd::string& filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback); + static bool InspectSerializedFile(const char* filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback); private: Utilities() = delete; diff --git a/Code/Tools/SerializeContextTools/main.cpp b/Code/Tools/SerializeContextTools/main.cpp index fb2dc442ed..d9f2cfbcc2 100644 --- a/Code/Tools/SerializeContextTools/main.cpp +++ b/Code/Tools/SerializeContextTools/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include void PrintHelp() @@ -74,6 +75,14 @@ void PrintHelp() AZ_Printf("Help", R"( On Windows the should be in quotes, as \"/\" is treated as command option prefix)" "\n"); AZ_Printf("Help", R"( [opt] -verbose: Report additional details during the conversion process.)" "\n"); AZ_Printf("Help", R"( example: 'convert-ini --files=AssetProcessorPlatformConfig.ini;bootstrap.cfg --ext=setreg)" "\n"); + AZ_Printf("Help", " 'convert-slice': Converts ObjectStream-based slice files or legacy levels to a JSON-based prefab.\n"); + AZ_Printf("Help", " [arg] -files=: -separated list of files to convert. Supports wildcards.\n"); + AZ_Printf("Help", " [opt] -dryrun: Processes as normal, but doesn't write files.\n"); + AZ_Printf("Help", " [opt] -keepdefaults: Fields are written if a default value was found.\n"); + AZ_Printf("Help", " [opt] -verbose: Report additional details during the conversion process.\n"); + AZ_Printf("Help", " example: 'convert-slice -files=*.slice -specializations=editor\n"); + AZ_Printf("Help", " example: 'convert-slice -files=Levels/TestLevel/TestLevel.ly -specializations=editor\n"); + AZ_Printf("Help", "\n"); } int main(int argc, char** argv) @@ -114,6 +123,10 @@ int main(int argc, char** argv) { result = Converter::ConvertConfigFile(application); } + else if (AZ::StringFunc::Equal("convert-slice", action.c_str())) + { + result = SliceConverter::ConvertSliceFiles(application); + } else { PrintHelp(); diff --git a/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake b/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake index db584ff385..814c55ea08 100644 --- a/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake +++ b/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake @@ -17,6 +17,8 @@ set(FILES Dumper.h Dumper.cpp main.cpp + SliceConverter.h + SliceConverter.cpp Utilities.h Utilities.cpp ) diff --git a/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h b/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h index 951877ab28..a35e39ff6b 100644 --- a/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h +++ b/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h @@ -12,6 +12,7 @@ #pragma once #include +#include namespace AssetMemoryAnalyzer { diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp index ccba00f15f..59c799a601 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp @@ -79,7 +79,7 @@ namespace ImageProcessingAtom builderDescriptor.m_busId = azrtti_typeid(); builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_version = 22; // [ATOM-14765] + builderDescriptor.m_version = 23; // [ATOM-14022] builderDescriptor.m_analysisFingerprint = ImageProcessingAtom::BuilderSettingManager::Instance()->GetAnalysisFingerprint(); m_imageBuilder.BusConnect(builderDescriptor.m_busId); AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); diff --git a/Code/CryEngine/CryCommon/AzDXGIFormat.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/AzDXGIFormat.h similarity index 97% rename from Code/CryEngine/CryCommon/AzDXGIFormat.h rename to Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/AzDXGIFormat.h index 6315dd3955..74a7f469fb 100644 --- a/Code/CryEngine/CryCommon/AzDXGIFormat.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/AzDXGIFormat.h @@ -17,11 +17,11 @@ #include -#if defined(AZ_PLATFORM_WINDOWS) && !defined(OPENGL) -#include +#if __has_include() +# include // For non-windows platforms need to define the formats so that the ImageExtension // class used by the editor can have access to these -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(OPENGL) || defined(AZ_PLATFORM_LINUX) || defined(AZ_PLATFORM_ANDROID) +#else #define DXGI_FORMAT_DEFINED 1 diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h index f280d4df48..25ee79c414 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h @@ -15,9 +15,6 @@ #include #include -//! The following defines and constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with ImageExtensionHelper.h - #define IMAGE_BUIDER_MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((AZ::u32)(AZ::u8)(ch0) | ((AZ::u32)(AZ::u8)(ch1) << 8) | \ ((AZ::u32)(AZ::u8)(ch2) << 16) | ((AZ::u32)(AZ::u8)(ch3) << 24)) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp index 9c02894b7c..2448f501af 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -238,14 +239,9 @@ namespace ImageProcessingAtom uint8_t* mipBuffer; uint32_t pitch; m_imageObject->GetImagePointer(mip, mipBuffer, pitch); - uint32_t mipBufferSize = m_imageObject->GetMipBufSize(mip); - - RHI::ImageSubresourceLayout layout; - layout.m_bytesPerImage = mipBufferSize / arraySize; - layout.m_rowCount = layout.m_bytesPerImage / pitch; - layout.m_size = RHI::Size(m_imageObject->GetWidth(mip), m_imageObject->GetHeight(mip) / arraySize, 1); - layout.m_bytesPerRow = pitch; - + RHI::Format format = Utils::PixelFormatToRHIFormat(m_imageObject->GetPixelFormat(), m_imageObject->HasImageFlags(EIF_SRGBRead)); + + RHI::ImageSubresourceLayout layout = RHI::GetImageSubresourceLayout(RHI::Size(m_imageObject->GetWidth(mip), m_imageObject->GetHeight(mip) / arraySize, 1), format); builder.BeginMip(layout); for (uint32_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h index f8942d0b61..6cf0a0e6dc 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h @@ -12,9 +12,6 @@ #pragma once -//! The following constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with the same constants defined in ImageExtensionHelper.h - namespace ImageProcessingAtom { // flags to propagate from the RC to the engine through GetImageFlags() diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h index 7dd81fb195..8a4f8df1b2 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h @@ -164,7 +164,7 @@ namespace ImageProcessingAtom AZ::Color m_colMinARGB; // ARGB will be added the properties of the DDS file AZ::Color m_colMaxARGB; // ARGB will be added the properties of the DDS file float m_averageBrightness; // will be added to the properties of the DDS file - AZ::u32 m_imageFlags; // combined from CImageExtensionHelper::EIF_Cubemap,... + AZ::u32 m_imageFlags; // AZ::u32 m_numPersistentMips; // number of mipmaps won't be splitted public: diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h index 7d8c6f9284..6b099468ea 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h @@ -12,7 +12,7 @@ #pragma once -#include // DX10+ formats. DXGI_FORMAT +#include // DX10+ formats. DXGI_FORMAT #include diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake b/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake index dfcfdfc319..69c678877d 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake @@ -41,6 +41,7 @@ set(FILES Source/BuilderSettings/PresetSettings.h Source/BuilderSettings/TextureSettings.cpp Source/BuilderSettings/TextureSettings.h + Source/Processing/AzDXGIFormat.h Source/Processing/DDSHeader.h Source/Processing/ImageAssetProducer.cpp Source/Processing/ImageAssetProducer.h diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h index b536ed5524..e75ee4d4bf 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h @@ -100,7 +100,9 @@ namespace AZ Size size, uint32_t rowCount, uint32_t bytesPerRow, - uint32_t bytesPerImage); + uint32_t bytesPerImage, + uint32_t numBlocksWidth, + uint32_t numBlocksHeight); /// The size of the image subresource in pixels. Certain formats have alignment requirements. /// Block compressed formats are 4 pixel aligned. Other non-standard formats may be 2 pixel aligned. @@ -114,6 +116,13 @@ namespace AZ /// The number of bytes in a single image slice. 3D textures are comprised of m_size.m_depth image slices. uint32_t m_bytesPerImage = 0; + + /// The number of blocks in width based on the texture fomat + uint32_t m_blockElementWidth = 1; + + /// The number of blocks in height based on the texture fomat + uint32_t m_blockElementHeight = 1; + }; struct ImageSubresourceLayoutPlaced : ImageSubresourceLayout diff --git a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp index 4e34fe2b32..c76af7d5bb 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp @@ -102,11 +102,13 @@ namespace AZ if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(0) + ->Version(1) ->Field("m_size", &ImageSubresourceLayout::m_size) ->Field("m_rowCount", &ImageSubresourceLayout::m_rowCount) ->Field("m_bytesPerRow", &ImageSubresourceLayout::m_bytesPerRow) ->Field("m_bytesPerImage", &ImageSubresourceLayout::m_bytesPerImage) + ->Field("m_blockElementWidth", &ImageSubresourceLayout::m_blockElementWidth) + ->Field("m_blockElementHeight", &ImageSubresourceLayout::m_blockElementHeight) ; } } @@ -115,11 +117,15 @@ namespace AZ Size size, uint32_t rowCount, uint32_t bytesPerRow, - uint32_t bytesPerImage) + uint32_t bytesPerImage, + uint32_t blockElementWidth, + uint32_t blockElementHeight) : m_size{size} , m_rowCount{rowCount} , m_bytesPerRow{bytesPerRow} , m_bytesPerImage{bytesPerImage} + , m_blockElementWidth{blockElementWidth} + , m_blockElementHeight{blockElementHeight} {} ImageSubresourceLayoutPlaced::ImageSubresourceLayoutPlaced(const ImageSubresourceLayout& subresourceLayout, size_t offset) @@ -296,8 +302,22 @@ namespace AZ numBlocks = 4; break; + case RHI::Format::EAC_R11_UNORM: + case RHI::Format::EAC_R11_SNORM: + isBlockCompressed = true; + bytesPerElement = 8; + numBlocks = 4; + break; + + case RHI::Format::EAC_RG11_UNORM: + case RHI::Format::EAC_RG11_SNORM: + isBlockCompressed = true; + bytesPerElement = 16; + numBlocks = 4; + break; + default: - AZ_Assert(false, "Unimplemented esoteric format."); + AZ_Assert(false, "Unimplemented esoteric format %i.", static_cast(imageFormat)); } if (isBlockCompressed) @@ -316,6 +336,8 @@ namespace AZ subresourceLayout.m_rowCount = numBlocksHigh; subresourceLayout.m_size.m_width = imageSize.m_width; subresourceLayout.m_size.m_height = imageSize.m_height; + subresourceLayout.m_blockElementWidth = numBlocks; + subresourceLayout.m_blockElementHeight = numBlocks; } else if (isPacked) { diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp index 22849f7236..951a405d40 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp @@ -271,7 +271,7 @@ namespace AZ // Staging sizes uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, DX12_TEXTURE_DATA_PITCH_ALIGNMENT); uint32_t stagingSlicePitch = RHI::AlignUp(subresourceLayout.m_rowCount*stagingRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); - const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount; + const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_blockElementHeight; // ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression. // Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images. @@ -386,7 +386,7 @@ namespace AZ const uint32_t numRowsToCopy = endRow - startRow; // Calculate the blocksize for BC formatted images; the copy command works in texels. - const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; + uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; // Copy subresource data to staging memory { @@ -402,6 +402,14 @@ namespace AZ } } + //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over + //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight + if(destHeight+heightToCopy > subresourceLayout.m_size.m_height) + { + uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height; + heightToCopy -= HeightDiff; + } + // Add copy command to copy image subresource from staging memory to image gpu resource // Source location diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.h b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.h index c7a2a5dd64..a6fe57f6d8 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.h +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.h @@ -415,7 +415,7 @@ namespace AZ // this assert typically happens when a shader needs a particular Srg (e.g., the ViewSrg) but the code did not bind it, // check the pass code in this callstack to determine why it was not bound - AZ_Assert(false, "ShaderResourceGroup in slot '%d' is null at DrawItem submit time. This is not valid and means the shader is expecting an Srg that is not currently bound in the pipeline. Current bindings: %s", + AZ_Assert(false, "ShaderResourceGroup in slot '%d' is null at DrawItem submit time. This is not valid and means the shader is expecting an Srg that isF not currently bound in the pipeline. Current bindings: %s", srgSlot, slotSrgString.c_str()); diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp index 891f9ea2f3..594a4931b9 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp @@ -190,8 +190,8 @@ namespace AZ const uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, bufferOffsetAlign); const uint32_t stagingSlicePitch = RHI::AlignUp(subresourceLayout.m_rowCount * stagingRowPitch, bufferOffsetAlign); const uint32_t rowsPerSplit = static_cast(m_descriptor.m_stagingSizeInBytes) / stagingRowPitch; - const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount; - + const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_blockElementHeight; + // ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression. // Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images. if (subresourceLayout.m_size.m_height < subresourceLayout.m_rowCount) @@ -281,7 +281,7 @@ namespace AZ const uint32_t endRow = AZStd::min(startRow + rowsPerSplit, subresourceLayout.m_rowCount); // Calculate the blocksize for BC formatted images; the copy command works in texels. - const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; + uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; // Copy subresource data to staging memory. uint8_t* stagingDataStart = framePacket->m_stagingResourceData + framePacket->m_dataOffset; @@ -293,6 +293,14 @@ namespace AZ const uint32_t bytesCopied = (endRow - startRow) * stagingRowPitch; Platform::SynchronizeBufferOnCPU(framePacket->m_stagingResource, framePacket->m_dataOffset, bytesCopied); + //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over + //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight + if(destHeight+heightToCopy > subresourceLayout.m_size.m_height) + { + uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height; + heightToCopy -= HeightDiff; + } + const RHI::Size sourceSize = RHI::Size(subresourceLayout.m_size.m_width, heightToCopy, 1); const RHI::Origin sourceOrigin = RHI::Origin(0, destHeight, depth); CopyBufferToImage(framePacket, image, stagingRowPitch, bytesCopied, diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp index a6e7ff082f..ed578f18c5 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp @@ -214,7 +214,7 @@ namespace AZ const uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, bufferOffsetAlign); const uint32_t stagingSlicePitch = subresourceLayout.m_rowCount * stagingRowPitch; const uint32_t rowsPerSplit = static_cast(m_descriptor.m_stagingSizeInBytes) / stagingRowPitch; - const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount; + const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_blockElementHeight; // ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression. // Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images. @@ -333,7 +333,7 @@ namespace AZ const uint32_t endRow = AZStd::min(startRow + rowsPerSplit, subresourceLayout.m_rowCount); // Calculate the blocksize for BC formatted images; the copy command works in texels. - const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; + uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; // Copy subresource data to staging memory. { @@ -348,6 +348,14 @@ namespace AZ framePacket->m_stagingBuffer->GetBufferMemoryView()->Unmap(RHI::HostMemoryAccess::Write); } + //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over + //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight + if(destHeight+heightToCopy > subresourceLayout.m_size.m_height) + { + uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height; + heightToCopy -= HeightDiff; + } + // Add copy command to copy image subresource from staging memory to image GPU resource. copyDescriptor.m_destinationOrigin.m_top = destHeight; copyDescriptor.m_sourceSize.m_height = heightToCopy; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp index 25ba5aa837..f550a6f2ca 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -40,15 +41,12 @@ namespace AZ Data::AssetId ShaderVariantTreeAsset::GetShaderVariantTreeAssetIdFromShaderAssetId(const Data::AssetId& shaderAssetId) { //From the shaderAssetId We can deduce the path of the shader asset, and from the path of the shader asset we can deduce the path of the ShaderVariantTreeAsset. - AZStd::string shaderAssetPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderAssetPath - , &AZ::Data::AssetCatalogRequests::GetAssetPathById - , shaderAssetId); - - AZStd::string shaderAssetPathRoot; - AZStd::string shaderAssetPathName; - AzFramework::StringFunc::Path::Split(shaderAssetPath.c_str(), nullptr /*drive*/, &shaderAssetPathRoot, &shaderAssetPathName, nullptr /*extension*/); - + AZ::IO::FixedMaxPath shaderAssetPath; + AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderAssetPath.Native(), &AZ::Data::AssetCatalogRequests::GetAssetPathById + , shaderAssetId); + AZ::IO::FixedMaxPath shaderAssetPathRoot = shaderAssetPath.ParentPath(); + AZ::IO::FixedMaxPath shaderAssetPathName = shaderAssetPath.Stem(); + AZStd::string shaderVariantTreeAssetDir; AzFramework::StringFunc::Path::Join(ShaderVariantTreeAsset::CommonSubFolderLowerCase, shaderAssetPathRoot.c_str(), shaderVariantTreeAssetDir); AZStd::string shaderVariantTreeAssetFilename = AZStd::string::format("%s.%s", shaderAssetPathName.c_str(), ShaderVariantTreeAsset::Extension); @@ -63,8 +61,7 @@ namespace AZ { // If the game project did not customize the shadervariantlist, let's see if the original author of the .shader file // provided a shadervariantlist. - shaderVariantTreeAssetDir = shaderAssetPathRoot; - AzFramework::StringFunc::Path::Join(shaderVariantTreeAssetDir.c_str(), shaderVariantTreeAssetFilename.c_str(), shaderVariantTreeAssetPath); + AzFramework::StringFunc::Path::Join(shaderAssetPathRoot.c_str(), shaderVariantTreeAssetFilename.c_str(), shaderVariantTreeAssetPath); AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderVariantTreeAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath , shaderVariantTreeAssetPath.c_str(), AZ::Data::s_invalidAssetType, false); } diff --git a/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h b/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h index eaecb67e94..954ab9365f 100644 --- a/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h +++ b/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 256 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "256" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 72 << 10 /* 72 MiB (re-evaluate this size!) */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "2048 (2 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h b/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h index 951eec5d54..472afd51e5 100644 --- a/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h +++ b/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 512 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "512" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 384 << 10 /* 384 MiB */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "393216 (384 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h b/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h index 951eec5d54..472afd51e5 100644 --- a/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h +++ b/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 512 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "512" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 384 << 10 /* 384 MiB */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "393216 (384 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h b/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h index 11fb0ee66d..fa37cf1e89 100644 --- a/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h +++ b/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 1024 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "1024" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 384 << 10 /* 384 MiB */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "393216 (384 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h b/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h index 3ffcf4a345..7a008237e2 100644 --- a/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h +++ b/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 128 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "128" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 2 << 10 /* 2 MiB (re-evaluate this size!) */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "2048 (2 MiB)" diff --git a/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h b/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h index fa72a78db9..c6624a125b 100644 --- a/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h +++ b/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h @@ -29,9 +29,6 @@ #include #include -#include - - namespace Audio { @@ -393,7 +390,7 @@ namespace Audio , m_memoryBlockAlignment(AUDIO_MEMORY_ALIGNMENT) , m_flags(eAFF_NOTFOUND) , m_dataScope(eADS_ALL) - , m_memoryBlock(nullptr) + // , m_memoryBlock(nullptr) // ToDo: Update to use non-legacy memory: LYN-3792 , m_implData(implData) { } @@ -406,7 +403,7 @@ namespace Audio size_t m_memoryBlockAlignment; Flags m_flags; EATLDataScope m_dataScope; - AZStd::unique_ptr m_memoryBlock; + // AZStd::unique_ptr m_memoryBlock; // ToDo: Update to use non-legacy memory: LYN-3792 AZ::IO::FileRequestPtr m_asyncStreamRequest; diff --git a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp index 7be14244d0..0e84679261 100644 --- a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp +++ b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp @@ -25,7 +25,6 @@ #include #include -#include #include namespace Audio @@ -76,12 +75,13 @@ namespace Audio { if (size > 0) { - m_memoryHeap.reset(static_cast(gEnv->pSystem->GetIMemoryManager()->CreateCustomMemoryHeapInstance(AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY))); + // ToDo: Update to use non-legacy memory: LYN-3792 + /*m_memoryHeap.reset(???); if (m_memoryHeap.get()) { m_maxByteTotal = size << 10; - } + }*/ } } @@ -541,7 +541,7 @@ namespace Audio CATLAudioFileEntry* audioFileEntry = fileEntryIter->second; AZ_Assert(audioFileEntry, "FileCacheManager - Audio file entry is null!"); - AZ_Assert(buffer == audioFileEntry->m_memoryBlock->GetData(), "FileCacheManager - The memory buffer doesn't match the file entry memory block!"); + // AZ_Assert(buffer == audioFileEntry->m_memoryBlock->GetData(), "FileCacheManager - The memory buffer doesn't match the file entry memory block!"); // ToDo: Update to use non-legacy memory: LYN-3792 FinishCachingFileInternal(audioFileEntry, numBytesRead, streamer->GetRequestStatus(request)); } } @@ -574,7 +574,7 @@ namespace Audio SATLAudioFileEntryInfo fileEntryInfo; fileEntryInfo.nMemoryBlockAlignment = audioFileEntry->m_memoryBlockAlignment; - fileEntryInfo.pFileData = audioFileEntry->m_memoryBlock->GetData(); + // fileEntryInfo.pFileData = audioFileEntry->m_memoryBlock->GetData(); // ToDo: Update to use non-legacy memory: LYN-3792 fileEntryInfo.nSize = audioFileEntry->m_fileSize; fileEntryInfo.pImplData = audioFileEntry->m_implData; fileEntryInfo.sFileName = PathUtil::GetFile(audioFileEntry->m_filePath.c_str()); @@ -649,9 +649,12 @@ namespace Audio } /////////////////////////////////////////////////////////////////////////////////////////////// - bool CFileCacheManager::AllocateMemoryBlockInternal(CATLAudioFileEntry* const audioFileEntry) + bool CFileCacheManager::AllocateMemoryBlockInternal([[maybe_unused]]CATLAudioFileEntry* const audioFileEntry) { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Audio); + // ToDo: Update to use non-legacy memory: LYN-3792 + return false; + + /*AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Audio); // Must not have valid memory yet. AZ_Assert(!audioFileEntry->m_memoryBlock, "FileCacheManager AllocateMemoryBlockInternal - Memory appears to be set already!"); @@ -673,7 +676,7 @@ namespace Audio } } - return (audioFileEntry->m_memoryBlock != nullptr); + return (audioFileEntry->m_memoryBlock != nullptr);*/ } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -700,7 +703,8 @@ namespace Audio audioFileEntry->m_asyncStreamRequest.reset(); } - if (audioFileEntry->m_memoryBlock && audioFileEntry->m_memoryBlock->GetData()) + // ToDo: Update to use non-legacy memory heap: LYN-3792 + /*if (audioFileEntry->m_memoryBlock && audioFileEntry->m_memoryBlock->GetData()) { SATLAudioFileEntryInfo fileEntryInfo; fileEntryInfo.nMemoryBlockAlignment = audioFileEntry->m_memoryBlockAlignment; @@ -713,7 +717,7 @@ namespace Audio g_audioLogger.Log(eALT_COMMENT, "FileCacheManager - File Uncached: '%s'\n", fileEntryInfo.sFileName); } - audioFileEntry->m_memoryBlock.reset(); + audioFileEntry->m_memoryBlock.reset();*/ audioFileEntry->m_flags.ClearFlags(eAFF_CACHED | eAFF_REMOVABLE); AZ_Warning("FileCacheManager", audioFileEntry->m_useCount == 0, "Use-count of file '%s' is non-zero while uncaching it! Use Count: %d", audioFileEntry->m_filePath.c_str(), audioFileEntry->m_useCount); audioFileEntry->m_useCount = 0; @@ -765,7 +769,7 @@ namespace Audio bool CFileCacheManager::TryCacheFileCacheEntryInternal( CATLAudioFileEntry* const audioFileEntry, [[maybe_unused]] const TAudioFileEntryID fileEntryId, - const bool loadSynchronously, + [[maybe_unused]] const bool loadSynchronously, const bool overrideUseCount /* = false */, const size_t useCount /* = 0 */) { @@ -775,7 +779,8 @@ namespace Audio if (!audioFileEntry->m_filePath.empty() && !audioFileEntry->m_flags.AreAnyFlagsActive(eAFF_CACHED | eAFF_LOADING)) { - if (DoesRequestFitInternal(audioFileEntry->m_fileSize) && AllocateMemoryBlockInternal(audioFileEntry)) + // ToDo: Update to use non-legacy memory heap: LYN-3792 + /*if (DoesRequestFitInternal(audioFileEntry->m_fileSize) && AllocateMemoryBlockInternal(audioFileEntry)) { auto streamer = AZ::Interface::Get(); AZ_Assert(streamer, "FileCacheManager - Streamer should be ready!"); @@ -849,7 +854,7 @@ namespace Audio // The user should be made aware of it. g_audioLogger.Log(eALT_ERROR, "FileCacheManager: Could not cache '%s' - out of memory or fragmented memory!", audioFileEntry->m_filePath.c_str()); - } + }*/ } else if (audioFileEntry->m_flags.AreAnyFlagsActive(eAFF_CACHED | eAFF_LOADING)) { diff --git a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h index 0e780bd467..b06a810e49 100644 --- a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h +++ b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h @@ -23,7 +23,6 @@ #include // Forward declarations -class CCustomMemoryHeap; struct IRenderAuxGeom; namespace Audio @@ -103,7 +102,7 @@ namespace Audio TATLPreloadRequestLookup& m_preloadRequests; TAudioFileEntries m_audioFileEntries; - AZStd::unique_ptr m_memoryHeap; + // AZStd::unique_ptr m_memoryHeap; // ToDo: Update to use non-legacy memory: LYN-3792 size_t m_currentByteTotal; size_t m_maxByteTotal; }; diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp index bb15996223..57c52671df 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp @@ -2308,20 +2308,12 @@ void CUiAnimViewDopeSheetBase::DrawKeys(CUiAnimViewTrack* pTrack, QPainter* pain const int kDefaultWidthForDescription = 200; const int kSmallMargin = 10; - FixedDynArray drawnKeyTimes; - drawnKeyTimes.set(ArrayT((float*)alloca(numKeys * sizeof(float)), numKeys)); - // Draw keys. for (int i = 0; i < numKeys; ++i) { CUiAnimViewKeyHandle keyHandle = pTrack->GetKey(i); const float time = keyHandle.GetTime(); - if (!stl::push_back_unique(drawnKeyTimes, time)) - { - continue; - } - int x = TimeToClient(time); if (x - kSmallMargin > rect.right()) { diff --git a/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp b/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp index 24b8841059..29e63f62c3 100644 --- a/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp +++ b/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp @@ -21,34 +21,6 @@ ////////////////////////////////////////////////////////////////////////// void HeapCheck::Check([[maybe_unused]] const char* file, [[maybe_unused]] int line) { -#ifdef _DEBUG - AZ_Assert(CryMemory::IsHeapValid(), "Invalid heap"); -#endif - - /* - int heapstatus = _heapchk(); - switch( heapstatus ) - { - case _HEAPOK: - break; - case _HEAPEMPTY: - break; - case _HEAPBADBEGIN: - { - CString str; - str.Format( "Bad Start of Heap, at file %s line:%d",file,line ); - MessageBox( NULL,str,"Heap Check",MB_OK ); - } - break; - case _HEAPBADNODE: - { - CString str; - str.Format( "Bad Node in Heap, at file %s line:%d",file,line ); - MessageBox( NULL,str,"Heap Check",MB_OK ); - } - break; - } - */ } #include diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp index 8e8079e18e..f55c8c5957 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp @@ -56,26 +56,6 @@ #include "UiDynamicScrollBoxComponent.h" #include "UiNavigationSettings.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -struct CSystemEventListener_UI - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - break; - } - } - } -}; -static CSystemEventListener_UI g_system_event_listener_ui; - - namespace LyShine { const AZStd::list* LyShineSystemComponent::m_componentDescriptors = nullptr; @@ -228,9 +208,6 @@ namespace LyShine //////////////////////////////////////////////////////////////////////////////////////////////////// void LyShineSystemComponent::InitializeSystem() { - // Not sure if this is still required - gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_ui); - m_pLyShine = new CLyShine(gEnv->pSystem); gEnv->pLyShine = m_pLyShine; BroadcastCursorImagePathname(); diff --git a/Gems/LyShine/Code/Source/UiInteractableComponent.cpp b/Gems/LyShine/Code/Source/UiInteractableComponent.cpp index b665bbe1dc..e4ba507340 100644 --- a/Gems/LyShine/Code/Source/UiInteractableComponent.cpp +++ b/Gems/LyShine/Code/Source/UiInteractableComponent.cpp @@ -546,6 +546,7 @@ void UiInteractableComponent::Reflect(AZ::ReflectContext* context) ->Handler(); } + UiInteractableStateAction::Reflect(context); UiInteractableStateColor::Reflect(context); UiInteractableStateAlpha::Reflect(context); UiInteractableStateSprite::Reflect(context); diff --git a/Gems/LyShine/Code/Source/UiInteractableState.cpp b/Gems/LyShine/Code/Source/UiInteractableState.cpp index f5d703d87a..965899a958 100644 --- a/Gems/LyShine/Code/Source/UiInteractableState.cpp +++ b/Gems/LyShine/Code/Source/UiInteractableState.cpp @@ -41,6 +41,16 @@ void UiInteractableStateAction::SetInteractableEntity(AZ::EntityId interactableE m_interactableEntity = interactableEntityId; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UiInteractableStateAction::Reflect(AZ::ReflectContext* context) +{ + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class(); + } +} + + //////////////////////////////////////////////////////////////////////////////////////////////////// void UiInteractableStateAction::Init(AZ::EntityId interactableEntityId) { @@ -128,8 +138,8 @@ void UiInteractableStateColor::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(2, &VersionConverter) + serializeContext->Class() + ->Version(3, &VersionConverter) ->Field("TargetEntity", &UiInteractableStateColor::m_targetEntity) ->Field("Color", &UiInteractableStateColor::m_color); @@ -223,8 +233,8 @@ void UiInteractableStateAlpha::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(1) + serializeContext->Class() + ->Version(2) ->Field("TargetEntity", &UiInteractableStateAlpha::m_targetEntity) ->Field("Alpha", &UiInteractableStateAlpha::m_alpha); @@ -379,8 +389,8 @@ void UiInteractableStateSprite::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(3) + serializeContext->Class() + ->Version(4) ->Field("TargetEntity", &UiInteractableStateSprite::m_targetEntity) ->Field("Sprite", &UiInteractableStateSprite::m_spritePathname) ->Field("Index", &UiInteractableStateSprite::m_spriteSheetCellIndex); @@ -633,8 +643,8 @@ void UiInteractableStateFont::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(1) + serializeContext->Class() + ->Version(2) ->Field("TargetEntity", &UiInteractableStateFont::m_targetEntity) ->Field("FontFileName", &UiInteractableStateFont::m_fontFilename) ->Field("EffectIndex", &UiInteractableStateFont::m_fontEffectIndex); diff --git a/Gems/LyShine/Code/Source/UiInteractableState.h b/Gems/LyShine/Code/Source/UiInteractableState.h index 966c24f202..81e9ac48e1 100644 --- a/Gems/LyShine/Code/Source/UiInteractableState.h +++ b/Gems/LyShine/Code/Source/UiInteractableState.h @@ -42,6 +42,8 @@ public: // member functions virtual ~UiInteractableStateAction() {} + static void Reflect(AZ::ReflectContext* context); + //! Called from the Init of the UiInteractableComponent virtual void Init(AZ::EntityId); diff --git a/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas b/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas index 2e3ab0121f..3bcd4f3db3 100644 --- a/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas +++ b/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas @@ -56,7 +56,7 @@ - + diff --git a/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp b/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp index cd0dfb02b3..1ee2ddc1c8 100644 --- a/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp +++ b/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp @@ -105,34 +105,11 @@ namespace Maestro MaestroAllocatorScope::DeactivateAllocators(); } - ////////////////////////////////////////////////////////////////////////// - void CSystemEventListener_Movie::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - CLightAnimWrapper::ReconstructCache(); - break; - } - } - } - /////////////////////////////////////////////////////////////////////////////////////////////// void MaestroSystemComponent::OnCrySystemInitialized(ISystem& system, const SSystemInitParams& startupParams) { if (!startupParams.bSkipMovie) { - // OnCrySystemInitialized should only ever be called once, and we should be the only one initializing gEnv->pMovieSystem - AZ_Assert(!m_movieSystemEventListener && gEnv && !gEnv->pMovieSystem, "MaestroSystemComponent::OnCrySystemInitialized - movie system was alread initialized."); - - if (!m_movieSystemEventListener) - { - m_movieSystemEventListener.reset(new CSystemEventListener_Movie); - } - system.GetISystemEventDispatcher()->RegisterListener(m_movieSystemEventListener.get()); - // Create the movie System m_movieSystem.reset(new CMovieSystem(&system)); gEnv->pMovieSystem = m_movieSystem.get(); @@ -142,17 +119,6 @@ namespace Maestro /////////////////////////////////////////////////////////////////////////////////////////////// void MaestroSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system) { - // Remove the system movie listener and clean up allocations - if (m_movieSystemEventListener) - { - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetISystemEventDispatcher()) - { - gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(m_movieSystemEventListener.get()); - } - // delete m_movieSystemEventListener - m_movieSystemEventListener.reset(); - } - if (gEnv && gEnv->pMovieSystem) { gEnv->pMovieSystem = nullptr; diff --git a/Gems/Maestro/Code/Source/MaestroSystemComponent.h b/Gems/Maestro/Code/Source/MaestroSystemComponent.h index ca8ae35d06..39a087eaa7 100644 --- a/Gems/Maestro/Code/Source/MaestroSystemComponent.h +++ b/Gems/Maestro/Code/Source/MaestroSystemComponent.h @@ -42,13 +42,6 @@ namespace Maestro void Deactivate() override; }; - ////////////////////////////////////////////////////////////////////////// - struct CSystemEventListener_Movie - : public ISystemEventListener - { - void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) override; - }; - ////////////////////////////////////////////////////////////////////////// class MaestroSystemComponent : public AZ::Component @@ -91,6 +84,5 @@ namespace Maestro private: // singletons representing the movie system AZStd::unique_ptr m_movieSystem; - AZStd::unique_ptr m_movieSystemEventListener; }; } diff --git a/Gems/NvCloth/Code/CMakeLists.txt b/Gems/NvCloth/Code/CMakeLists.txt index d83190a05c..0f019a985f 100644 --- a/Gems/NvCloth/Code/CMakeLists.txt +++ b/Gems/NvCloth/Code/CMakeLists.txt @@ -30,11 +30,7 @@ ly_add_target( BUILD_DEPENDENCIES PUBLIC 3rdParty::NvCloth - # CryCommon required for 'gEnv->IsDedicated()'. - # Because of this the module will need CrySystemEventBus to initialize gEnv - # and tests targets will need to fake gEnv. To be removed when there is - # an AZ replacement for asking if the game is running on a server or not. - Legacy::CryCommon + AZ::AzFramework Gem::AtomLyIntegration_CommonFeatures.Public PRIVATE Gem::EMotionFXStaticLib diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp index 912255c798..0170fd65bd 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp @@ -10,9 +10,8 @@ * */ -#include - #include +#include #include @@ -55,10 +54,14 @@ namespace NvCloth void ClothComponent::Activate() { // Cloth components do not run on dedicated servers. - AZ_Assert(gEnv, "Environment not ready"); - if (gEnv->IsDedicated()) + if (auto* console = AZ::Interface::Get()) { - return; + bool isDedicated = false; + if (const auto result = console->GetCvarValue("sv_isDedicated", isDedicated); + result == AZ::GetValueResult::Success && isDedicated) + { + return; + } } AZ::Render::MeshComponentNotificationBus::Handler::BusConnect(GetEntityId()); diff --git a/Gems/NvCloth/Code/Source/Module.cpp b/Gems/NvCloth/Code/Source/Module.cpp index 08d673fd07..66390dda86 100644 --- a/Gems/NvCloth/Code/Source/Module.cpp +++ b/Gems/NvCloth/Code/Source/Module.cpp @@ -10,9 +10,6 @@ * */ -#include -#include - #include #include @@ -31,7 +28,6 @@ namespace NvCloth { class Module : public AZ::Module - , protected CrySystemEventBus::Handler { public: AZ_RTTI(Module, "{34C529D4-688F-4B51-BF60-75425754A7E6}", AZ::Module); @@ -47,8 +43,6 @@ namespace NvCloth m_fabricCooker = AZStd::make_unique(); m_tangentSpaceHelper = AZStd::make_unique(); - CrySystemEventBus::Handler::BusConnect(); - // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. m_descriptors.insert(m_descriptors.end(), { SystemComponent::CreateDescriptor(), @@ -64,8 +58,6 @@ namespace NvCloth ~Module() { - CrySystemEventBus::Handler::BusDisconnect(); - m_tangentSpaceHelper.reset(); m_fabricCooker.reset(); @@ -85,33 +77,10 @@ namespace NvCloth }; } - protected: - // CrySystemEventBus ... - void OnCrySystemPreInitialize(ISystem& system, const SSystemInitParams& systemInitParams) override; - void OnCrySystemPostShutdown() override; - private: AZStd::unique_ptr m_fabricCooker; AZStd::unique_ptr m_tangentSpaceHelper; }; - - void Module::OnCrySystemPreInitialize( - [[maybe_unused]] ISystem& system, - [[maybe_unused]] const SSystemInitParams& systemInitParams) - { -#if !defined(AZ_MONOLITHIC_BUILD) - // When module is linked dynamically, we must set our gEnv pointer. - // When module is linked statically, we'll share the application's gEnv pointer. - gEnv = system.GetGlobalEnvironment(); -#endif - } - - void Module::OnCrySystemPostShutdown() - { -#if !defined(AZ_MONOLITHIC_BUILD) - gEnv = nullptr; -#endif - } } // namespace NvCloth // DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM diff --git a/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp b/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp index 379cf6988d..ad37c8f079 100644 --- a/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp +++ b/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp @@ -12,8 +12,6 @@ #include -#include - #include #include #include @@ -25,48 +23,14 @@ namespace UnitTest { - //! Sets up a mock global environment to - //! change between server and client. class NvClothComponent : public ::testing::Test { - public: - static void SetUpTestCase(); - static void TearDownTestCase(); - protected: AZStd::unique_ptr CreateClothActorEntity(const NvCloth::ClothConfiguration& clothConfiguration); bool IsConnectedToMeshComponentNotificationBus(NvCloth::ClothComponent* clothComponent) const; - - private: - static AZStd::unique_ptr s_mockGEnv; - static SSystemGlobalEnvironment* s_previousGEnv; }; - AZStd::unique_ptr NvClothComponent::s_mockGEnv; - SSystemGlobalEnvironment* NvClothComponent::s_previousGEnv = nullptr; - - void NvClothComponent::SetUpTestCase() - { - // override global environment - s_previousGEnv = gEnv; - s_mockGEnv = AZStd::make_unique(); - gEnv = s_mockGEnv.get(); - -#if !defined(CONSOLE) - // Set environment to not be a server by default. - gEnv->SetIsDedicated(false); -#endif - } - - void NvClothComponent::TearDownTestCase() - { - // restore global environment - gEnv = s_previousGEnv; - s_mockGEnv.reset(); - s_previousGEnv = nullptr; - } - AZStd::unique_ptr NvClothComponent::CreateClothActorEntity(const NvCloth::ClothConfiguration& clothConfiguration) { AZStd::unique_ptr entity = AZStd::make_unique(); @@ -101,10 +65,35 @@ namespace UnitTest EXPECT_TRUE(sortOutcome.IsSuccess()); } -#if !defined(CONSOLE) - TEST_F(NvClothComponent, ClothComponent_OnServer_DoesNotConnectToMeshComponentNotificationBusOnActivation) + TEST_F(NvClothComponent, ClothComponent_WithoutMultiplayerGem_ConnectsToMeshComponentNotificationBusOnActivation) { - gEnv->SetIsDedicated(true); + AZStd::unique_ptr entity = CreateClothActorEntity({}); + entity->Activate(); + + auto* clothComponent = entity->FindComponent(); + + EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent)); + } + + TEST_F(NvClothComponent, ClothComponent_WithMultiplayerGem_Game_ConnectsToMeshComponentNotificationBusOnActivation) + { + // Fake that multiplayer gem is enabled by creating a local sv_isDedicated AZ_CVAR + AZ::ConsoleDataWrapper> sv_isDedicated(false, + nullptr, "sv_isDedicated", "", AZ::ConsoleFunctorFlags::DontReplicate); + + AZStd::unique_ptr entity = CreateClothActorEntity({}); + entity->Activate(); + + auto* clothComponent = entity->FindComponent(); + + EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent)); + } + + TEST_F(NvClothComponent, ClothComponent_WithMultiplayerGem_Server_DoesNotConnectToMeshComponentNotificationBusOnActivation) + { + // Fake that multiplayer gem is enabled by creating a local sv_isDedicated AZ_CVAR + AZ::ConsoleDataWrapper> sv_isDedicated(true, + nullptr, "sv_isDedicated", "", AZ::ConsoleFunctorFlags::DontReplicate); AZStd::unique_ptr entity = CreateClothActorEntity({}); entity->Activate(); @@ -112,10 +101,7 @@ namespace UnitTest auto* clothComponent = entity->FindComponent(); EXPECT_FALSE(IsConnectedToMeshComponentNotificationBus(clothComponent)); - - gEnv->SetIsDedicated(false); } -#endif TEST_F(NvClothComponent, ClothComponent_OneEntityWithTwoClothComponents_BothConnectToMeshComponentNotificationBusOnActivation) { diff --git a/Registry/application_options.setreg b/Registry/application_options.setreg index 06ccdc9b41..8dbb6fe418 100644 --- a/Registry/application_options.setreg +++ b/Registry/application_options.setreg @@ -6,6 +6,7 @@ "project-path", "engine-path", "project-cache-path", + "project-build-path", "regset", "regremove", "regdump", diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py index 36746b510f..1b0afb3efe 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py @@ -108,15 +108,7 @@ class Launcher(object): # Wait for the AssetProcessor to be open. if launch_ap: - timeout = 10 - self.workspace.asset_processor.start() - ly_test_tools.environment.waiter.wait_for( - lambda: ly_test_tools.environment.process_utils.process_exists( - name="AssetProcessor", ignore_extensions=True), - exc=ly_test_tools.launchers.exceptions.SetupError( - f'AssetProcessor never opened after {timeout} seconds'), - timeout=timeout - ) + self.workspace.asset_processor.start(connect_to_ap=True, connection_timeout=10) # verify connection self.workspace.asset_processor.wait_for_idle() log.debug('AssetProcessor started from calling Launcher.setup()') diff --git a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py index 11cd1fc4ce..0983d2c45f 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py @@ -20,7 +20,7 @@ import time import tempfile import shutil import stat -from typing import List +from typing import List, Tuple import psutil import ly_test_tools @@ -45,6 +45,7 @@ ASSET_PROCESSOR_PLATFORM_MAP = { ASSET_PROCESSOR_SETTINGS_ROOT_KEY = '/Amazon/AssetProcessor/Settings' + class AssetProcessorError(Exception): """ Indicates that the AssetProcessor raised an error """ @@ -88,11 +89,16 @@ class AssetProcessor(object): def wait_for_idle(self, timeout=DEFAULT_TIMEOUT_SECONDS): """ Communicate with asset processor to request a response if either AP is currently idle, - or whenever it becomes idle + or that it becomes idle within the timeout """ + if not self.process_exists(): + logger.warning("Not currently managing a running Asset Processor, cannot request idle") + return False + self.send_message("waitforidle") result = self.read_message(read_timeout=timeout) - assert result == "idle" or not self.process_exists(), f"Couldn't get idle state from AP, message {result}" + assert self.process_exists(), "Asset Processor appears unexpectedly shut down, or has crashed" + assert result == "idle", f"Did not get idle state from AP, message was instead: {result}" return True def next_idle(self): @@ -103,9 +109,14 @@ class AssetProcessor(object): which will be picked up by the scanner but may take a couple seconds to begin, and you only want to hear back after it's done. """ + if not self.process_exists(): + logger.warning("Not currently managing a running Asset Processor, cannot request idle") + return + self.send_message("signalidle") result = self.read_message() - assert result == "idle" or not self.process_exists(), f"Couldn't get idle state from AP, message {result}" + assert self.process_exists(), "Asset Processor appears unexpectedly shut down, or has crashed" + assert result == "idle", f"Did not get idle state from AP, message was instead: {result}" def send_quit(self): """ @@ -160,8 +171,6 @@ class AssetProcessor(object): logger.warning(f"Failed to read message from with error {e}") return f"error_{e}" - - def read_control_port(self): return self.read_port_from_log("Control Port") @@ -185,7 +194,7 @@ class AssetProcessor(object): if port: logger.info(f"Read port type {port_type} : {port}") return port - except: + except Exception: # intentionally broad pass time.sleep(1) logger.warning(f"Failed to read port type {port_type}") @@ -203,7 +212,7 @@ class AssetProcessor(object): control_timeout = 60 try: return self.connect_socket("Control Connection", self.read_control_port, - set_port_method=self.set_control_connection, timeout=control_timeout) + set_port_method=self.set_control_connection, timeout=control_timeout) except AssetProcessorError as e: # We dont want a failure of our test socket connection to fail the entire test automatically. logger.error(f"Failed to connect control socket with error {e}") @@ -237,7 +246,7 @@ class AssetProcessor(object): if set_port_method is not None: set_port_method(connection_socket) return True, None - except Exception as e: # Purposefully broad + except Exception: # Purposefully broad # Short delay to prevent immediate failure due to slower starting applications such as debug builds time.sleep(0.01) if not connect_port or not self.using_temp_workspace(): @@ -261,7 +270,7 @@ class AssetProcessor(object): :return: None """ if not self._ap_proc: - logger.info("Attempting to quit AP but none running") + logger.warning("Attempting to quit AP but none running") return if not self._control_connection: @@ -319,7 +328,7 @@ class AssetProcessor(object): pass _, remaining = psutil.wait_procs(process_list, timeout=10, callback=term_success) for process in remaining: - logger.info(f"Killing: {this_process.name()} pid: {this_process.pid}") + logger.info(f"Killing: {process.name()} pid: {process.pid}") process.kill() logger.info("Finished terminating asset processor") self._ap_proc = None @@ -500,22 +509,17 @@ class AssetProcessor(object): def build_ap_command(self, ap_path, fastscan=True, platforms=None, extra_params=None, add_gem_scan_folders=None, add_config_scan_folders=None, scan_folder_pattern=None): - # type: (float, bool) -> bool """ Launch asset processor batch and wait for it to complete or until the timeout expires. Returns true on success and False if an error is reported. :param fastscan: Enable "zero analysis mode" - :param capture_output = Capture output which will be returned in the second of the return pair :param platforms: Different set of platforms to run against :param add_gem_scan_folders: Should gem scan folders be added to the processing - by default this is off if scan folder overrides are set, on if not :param add_config_scan_folders: Should config scan folders be added to the processing - by default this is off if scan folder overrides are set, on if not - :param decode: decode byte strings from captured output to utf-8 - :return: Pair: Success, output: True if all assets were processed successfully, False if the process times out - or returns errors. output is raw output from process - + :return: Command list ready to pass to subprocess """ logger.info(f"Starting {ap_path}") command = [ap_path] @@ -784,7 +788,7 @@ class AssetProcessor(object): def prepare_test_environment(self, assets_path: str, function_name: str, use_current_root=False, relative_asset_root=None, add_scan_folder=True, cache_platform=None, - existing_function_name=None) -> str: + existing_function_name=None) -> Tuple[str, str]: """ Creates a temporary test workspace, copies the specified test assets and sets the folder as a scan folder for processing. @@ -844,7 +848,7 @@ class AssetProcessor(object): """ return self._test_assets_source_folder - def compare_assets_with_cache(self) -> str: + def compare_assets_with_cache(self) -> Tuple[List[str], List[str]]: """ Helper to compare output assets from a test run using prepare_test_environment @@ -982,14 +986,10 @@ def _build_ap_batch_call_params(ap_path, project, platforms, extra_params=None): project_str.rstrip(' ') param_list = [ap_path, project_str] - if self._disable_all_platforms: - command.append(f'--regremove="f{ASSET_PROCESSOR_SETTINGS_ROOT_KEY}/Platforms"') if platforms: if isinstance(platforms, list): platforms = ','.join(platforms) param_list.append(f'--platforms={platforms}') - for key, value in self._enabled_platform_overrides: - param_list.append(f'--regset="f{ASSET_PROCESSOR_SETTINGS_ROOT_KEY}/Platforms/{key}={value}"') if extra_params: if isinstance(extra_params, list): @@ -1053,4 +1053,3 @@ def get_num_failed_processed_assets(output): def has_invalid_server_address(output): return parse_output_value(output, 'Invalid server address') is not None - diff --git a/cmake/Projects.cmake b/cmake/Projects.cmake index 139c2a24d1..781fee3711 100644 --- a/cmake/Projects.cmake +++ b/cmake/Projects.cmake @@ -105,9 +105,54 @@ function(ly_add_project_dependencies) ) endfunction() +#template for generating the project build_path setreg +set(project_build_path_template [[ +{ + "Amazon": { + "Project": { + "Settings": { + "Build": { + "project_build_path": "@project_bin_path@" + } + } + } + } +}]] +) + + +#! ly_generate_project_build_path_setreg: Generates a .setreg file that contains an absolute path to the ${CMAKE_BINARY_DIR} +# This allows locate the directory where the project it's binaries are built to be located within the engine. +# Which are the shared libraries and launcher executables +# When an a pre-built engine application runs from a directory other than the project build directory, it needs +# to be able to locate the project build directory to determine the list of gems that the project depends on to load +# as well the location of those gems. +# For example if the project uses an external gem not associated with the engine, that gem's dlls/so/dylib files +# would be located within the project build directory and the engine SDK binary directory would need that info + +# NOTE: This only needed for non-monolithic host platforms. +# This is because there are no dynamic gems to load on monolithic builds +# Furthermore the pre-built SDK engine applications such as the Editor and AssetProcessor +# can only run on the host platform +# \arg:project_real_path Full path to the o3de project directory +function(ly_generate_project_build_path_setreg project_real_path) + # The build path isn't needed on non-monolithic platforms + # Nor on any non-host platforms + if (LY_MONOLITHIC_GAME OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) + return() + endif() + + # Set the project_bin_path to the ${CMAKE_BINARY_DIR} to provide the configure template + # with the project build directory + set(project_bin_path ${CMAKE_BINARY_DIR}) + string(CONFIGURE ${project_build_path_template} project_build_path_setreg_content @ONLY) + set(project_user_build_path_setreg_file ${project_real_path}/user/Registry/Platform/${PAL_PLATFORM_NAME}/build_path.setreg) + file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content}) +endfunction() + # Add the projects here so the above function is found foreach(project ${LY_PROJECTS}) - get_filename_component(full_directory_path ${project} REALPATH ${CMAKE_SOURCE_DIR}) + file(REAL_PATH ${project} full_directory_path BASE_DIRECTORY ${CMAKE_SOURCE_DIR}) string(SHA256 full_directory_hash ${full_directory_path}) # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit @@ -117,5 +162,6 @@ foreach(project ${LY_PROJECTS}) get_filename_component(project_folder_name ${project} NAME) list(APPEND LY_PROJECTS_FOLDER_NAME ${project_folder_name}) add_subdirectory(${project} "${project_folder_name}-${full_directory_hash}") + ly_generate_project_build_path_setreg(${full_directory_path}) endforeach() ly_set(LY_PROJECTS_FOLDER_NAME ${LY_PROJECTS_FOLDER_NAME})