//! The root of the GUI\r
EGUIET_ROOT,\r
\r
- //! IGUIProfiler\r
- EGUIET_PROFILER,\r
-\r
//! Not an element, amount of elements in there\r
EGUIET_COUNT,\r
\r
+++ /dev/null
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-// Written by Michael Zeilfelder\r
-\r
-#ifndef __I_PROFILER_H_INCLUDED__\r
-#define __I_PROFILER_H_INCLUDED__\r
-\r
-#include "IrrCompileConfig.h"\r
-#include "irrString.h"\r
-#include "irrArray.h"\r
-#include "ITimer.h"\r
-#include <limits.h> // for INT_MAX (we should have a S32_MAX...)\r
-\r
-namespace irr\r
-{\r
-\r
-class ITimer;\r
-\r
-//! Used to store the profile data (and also used for profile group data).\r
-struct SProfileData\r
-{\r
- friend class IProfiler;\r
-\r
- SProfileData()\r
- {\r
- GroupIndex = 0;\r
- reset();\r
- }\r
-\r
- bool operator<(const SProfileData& pd) const\r
- {\r
- return Id < pd.Id;\r
- }\r
-\r
- bool operator==(const SProfileData& pd) const\r
- {\r
- return Id == pd.Id;\r
- }\r
-\r
- u32 getGroupIndex() const\r
- {\r
- return GroupIndex;\r
- }\r
-\r
- const core::stringw& getName() const\r
- {\r
- return Name;\r
- }\r
-\r
- //! Each time profiling for this data is stopped it increases the counter by 1.\r
- u32 getCallsCounter() const\r
- {\r
- return CountCalls;\r
- }\r
-\r
- //! Longest time a profile call for this id took from start until it was stopped again.\r
- u32 getLongestTime() const\r
- {\r
- return LongestTime;\r
- }\r
-\r
- //! Time spend between start/stop\r
- u32 getTimeSum() const\r
- {\r
- return TimeSum;\r
- }\r
-\r
-private:\r
-\r
- // just to be used for searching as it does no initialization besides id\r
- SProfileData(u32 id) : Id(id) {}\r
-\r
- void reset()\r
- {\r
- CountCalls = 0;\r
- LongestTime = 0;\r
- TimeSum = 0;\r
- LastTimeStarted = 0;\r
- StartStopCounter = 0;\r
- }\r
-\r
- s32 Id;\r
- u32 GroupIndex;\r
- core::stringw Name;\r
-\r
- s32 StartStopCounter; // 0 means stopped > 0 means it runs.\r
- u32 CountCalls;\r
- u32 LongestTime;\r
- u32 TimeSum;\r
-\r
- u32 LastTimeStarted;\r
-};\r
-\r
-//! Code-profiler. Please check the example in the Irrlicht examples folder about how to use it.\r
-// Implementer notes:\r
-// The design is all about allowing to use the central start/stop mechanism with minimal time overhead.\r
-// This is why the class works without a virtual functions interface contrary to the usual Irrlicht design.\r
-// And also why it works with id's instead of strings in the start/stop functions even if it makes using\r
-// the class slightly harder.\r
-// The class comes without reference-counting because the profiler instance is never released (TBD).\r
-class IProfiler\r
-{\r
-public:\r
- //! Constructor. You could use this to create a new profiler, but usually getProfiler() is used to access the global instance.\r
- IProfiler() : Timer(0), NextAutoId(INT_MAX)\r
- {}\r
-\r
- virtual ~IProfiler()\r
- {}\r
-\r
- //! Add an id with given name and group which can be used for profiling with start/stop\r
- /** After calling this once you can start/stop profiling for the given id.\r
- \param id: Should be >= 0 as negative id's are reserved for Irrlicht. Also very large numbers (near INT_MAX) might\r
- have been added automatically by the other add function.\r
- \param name: Name for displaying profile data.\r
- \param groupName: Each id belongs into a group - this helps on displaying profile data. */\r
- inline void add(s32 id, const core::stringw &name, const core::stringw &groupName);\r
-\r
- //! Add an automatically generated for the given name and group which can be used for profiling with start/stop.\r
- /** After calling this once you can start/stop profiling with the returned id.\r
- \param name: Name for displaying profile data.\r
- \param groupName: Each id belongs into a group - this helps on displaying profile data.\r
- \return Automatic id's start at INT_MAX and count down for each new id. If the name already has an id then that id will be returned. */\r
- inline s32 add(const core::stringw &name, const core::stringw &groupName);\r
-\r
- //! Return the number of profile data blocks. There is one for each id.\r
- u32 getProfileDataCount() const\r
- {\r
- return ProfileDatas.size();\r
- }\r
-\r
- //! Search for the index of the profile data by name\r
- /** \param result Receives the resulting data index when one was found.\r
- \param name String with name to search for\r
- \return true when found, false when not found */\r
- inline bool findDataIndex(u32 & result, const core::stringw &name) const;\r
-\r
- //! Get the profile data\r
- /** \param index A value between 0 and getProfileDataCount()-1. Indices can change when new id's are added.*/\r
- const SProfileData& getProfileDataByIndex(u32 index) const\r
- {\r
- return ProfileDatas[index];\r
- }\r
-\r
- //! Get the profile data\r
- /** \param id Same value as used in ::add\r
- \return Profile data for the given id or 0 when it does not exist. */\r
- inline const SProfileData* getProfileDataById(u32 id);\r
-\r
- //! Get the number of profile groups. Will be at least 1.\r
- /** NOTE: The first groups is always L"overview" which is an overview for all existing groups */\r
- inline u32 getGroupCount() const\r
- {\r
- return ProfileGroups.size();\r
- }\r
-\r
- //! Get profile data for a group.\r
- /** NOTE: The first groups is always L"overview" which is an overview for all existing groups */\r
- inline const SProfileData& getGroupData(u32 index) const\r
- {\r
- return ProfileGroups[index];\r
- }\r
-\r
- //! Find the group index by the group-name\r
- /** \param result Receives the resulting group index when one was found.\r
- \param name String with name to search for\r
- \return true when found, false when not found */\r
- inline bool findGroupIndex(u32 & result, const core::stringw &name) const;\r
-\r
-\r
- //! Start profile-timing for the given id\r
- /** This increases an internal run-counter for the given id. It will profile as long as that counter is > 0.\r
- NOTE: you have to add the id first with one of the ::add functions\r
- */\r
- inline void start(s32 id);\r
-\r
- //! Stop profile-timing for the given id\r
- /** This increases an internal run-counter for the given id. If it reaches 0 the time since start is recorded.\r
- You should have the same amount of start and stop calls. If stop is called more often than start\r
- then the additional stop calls will be ignored (counter never goes below 0)\r
- */\r
- inline void stop(s32 id);\r
-\r
- //! Reset profile data for the given id\r
- inline void resetDataById(s32 id);\r
-\r
- //! Reset profile data for the given index\r
- inline void resetDataByIndex(u32 index);\r
-\r
- //! Reset profile data for a whole group\r
- inline void resetGroup(u32 index);\r
-\r
- //! Reset all profile data\r
- /** NOTE: This is not deleting id's or groups, just resetting all timers to 0. */\r
- inline void resetAll();\r
-\r
- //! Write all profile-data into a string\r
- /** \param result Receives the result string.\r
- \param includeOverview When true a group-overview is attached first\r
- \param suppressUncalled When true elements which got never called are not printed */\r
- virtual void printAll(core::stringw &result, bool includeOverview=false,bool suppressUncalled=true) const = 0;\r
-\r
- //! Write the profile data of one group into a string\r
- /** \param result Receives the result string.\r
- \param groupIndex_ */\r
- virtual void printGroup(core::stringw &result, u32 groupIndex, bool suppressUncalled) const = 0;\r
-\r
-protected:\r
-\r
- inline u32 addGroup(const core::stringw &name);\r
-\r
- // I would prefer using os::Timer, but os.h is not in the public interface so far.\r
- // Timer must be initialized by the implementation.\r
- ITimer * Timer;\r
- core::array<SProfileData> ProfileDatas;\r
- core::array<SProfileData> ProfileGroups;\r
-\r
-private:\r
- s32 NextAutoId; // for giving out id's automatically\r
-};\r
-\r
-//! Access the Irrlicht profiler object.\r
-/** Profiler is always accessible, except in destruction of global objects.\r
-If you want to get internal profiling information about the engine itself\r
-you will have to re-compile the engine with _IRR_COMPILE_WITH_PROFILING_ enabled.\r
-But you can use the profiler for profiling your own projects without that. */\r
-IRRLICHT_API IProfiler& IRRCALLCONV getProfiler();\r
-\r
-//! Class where the objects profile their own life-time.\r
-/** This is a comfort wrapper around the IProfiler start/stop mechanism which is easier to use\r
-when you want to profile a scope. You only have to create an object and it will profile it's own lifetime\r
-for the given id. */\r
-class CProfileScope\r
-{\r
-public:\r
- //! Construct with an known id.\r
- /** This is the fastest scope constructor, but the id must have been added before.\r
- \param id Any id which you did add to the profiler before. */\r
- CProfileScope(s32 id)\r
- : Id(id), Profiler(getProfiler())\r
- {\r
- Profiler.start(Id);\r
- }\r
-\r
- //! Object will create the given name, groupName combination for the id if it doesn't exist already\r
- /** \param id: Should be >= 0 as negative id's are reserved for Irrlicht. Also very large numbers (near INT_MAX) might\r
- have been created already by the automatic add function of ::IProfiler.\r
- \param name: Name for displaying profile data.\r
- \param groupName: Each id belongs into a group - this helps on displaying profile data. */\r
- CProfileScope(s32 id, const core::stringw &name, const core::stringw &groupName)\r
- : Id(id), Profiler(getProfiler())\r
- {\r
- Profiler.add(Id, name, groupName);\r
- Profiler.start(Id);\r
- }\r
-\r
- //! Object will create an id for the given name, groupName combination if they don't exist already\r
- /** Slowest scope constructor, but usually still fine unless speed is very critical.\r
- \param name: Name for displaying profile data.\r
- \param groupName: Each id belongs into a group - this helps on displaying profile data. */\r
- CProfileScope(const core::stringw &name, const core::stringw &groupName)\r
- : Profiler(getProfiler())\r
- {\r
- Id = Profiler.add(name, groupName);\r
- Profiler.start(Id);\r
- }\r
-\r
- ~CProfileScope()\r
- {\r
- Profiler.stop(Id);\r
- }\r
-\r
-protected:\r
- s32 Id;\r
- IProfiler& Profiler;\r
-};\r
-\r
-\r
-// IMPLEMENTATION for in-line stuff\r
-\r
-void IProfiler::start(s32 id)\r
-{\r
- s32 idx = ProfileDatas.binary_search(SProfileData(id));\r
- if ( idx >= 0 && Timer )\r
- {\r
- ++ProfileDatas[idx].StartStopCounter;\r
- if (ProfileDatas[idx].StartStopCounter == 1 )\r
- ProfileDatas[idx].LastTimeStarted = Timer->getRealTime();\r
- }\r
-}\r
-\r
-void IProfiler::stop(s32 id)\r
-{\r
- if ( Timer )\r
- {\r
- u32 timeNow = Timer->getRealTime();\r
- s32 idx = ProfileDatas.binary_search(SProfileData(id));\r
- if ( idx >= 0 )\r
- {\r
- SProfileData &data = ProfileDatas[idx];\r
- --ProfileDatas[idx].StartStopCounter;\r
- if ( data.LastTimeStarted != 0 && ProfileDatas[idx].StartStopCounter == 0)\r
- {\r
- // update data for this id\r
- ++data.CountCalls;\r
- u32 diffTime = timeNow - data.LastTimeStarted;\r
- data.TimeSum += diffTime;\r
- if ( diffTime > data.LongestTime )\r
- data.LongestTime = diffTime;\r
- data.LastTimeStarted = 0;\r
-\r
- // update data of it's group\r
- SProfileData & group = ProfileGroups[data.GroupIndex];\r
- ++group.CountCalls;\r
- group.TimeSum += diffTime;\r
- if ( diffTime > group.LongestTime )\r
- group.LongestTime = diffTime;\r
- group.LastTimeStarted = 0;\r
- }\r
- else if ( ProfileDatas[idx].StartStopCounter < 0 )\r
- {\r
- // ignore additional stop calls\r
- ProfileDatas[idx].StartStopCounter = 0;\r
- }\r
- }\r
- }\r
-}\r
-\r
-s32 IProfiler::add(const core::stringw &name, const core::stringw &groupName)\r
-{\r
- u32 index;\r
- if ( findDataIndex(index, name) )\r
- {\r
- add( ProfileDatas[index].Id, name, groupName );\r
- return ProfileDatas[index].Id;\r
- }\r
- else\r
- {\r
- s32 id = NextAutoId;\r
- --NextAutoId;\r
- add( id, name, groupName );\r
- return id;\r
- }\r
-}\r
-\r
-void IProfiler::add(s32 id, const core::stringw &name, const core::stringw &groupName)\r
-{\r
- u32 groupIdx;\r
- if ( !findGroupIndex(groupIdx, groupName) )\r
- {\r
- groupIdx = addGroup(groupName);\r
- }\r
-\r
- SProfileData data(id);\r
- s32 idx = ProfileDatas.binary_search(data);\r
- if ( idx < 0 )\r
- {\r
- data.reset();\r
- data.GroupIndex = groupIdx;\r
- data.Name = name;\r
-\r
- ProfileDatas.push_back(data);\r
- ProfileDatas.sort();\r
- }\r
- else\r
- {\r
- // only reset on group changes, otherwise we want to keep the data or coding CProfileScope would become tricky.\r
- if ( groupIdx != ProfileDatas[idx].GroupIndex )\r
- {\r
- resetDataByIndex((u32)idx);\r
- ProfileDatas[idx].GroupIndex = groupIdx;\r
- }\r
- ProfileDatas[idx].Name = name;\r
- }\r
-}\r
-\r
-u32 IProfiler::addGroup(const core::stringw &name)\r
-{\r
- SProfileData group;\r
- group.Id = -1; // Id for groups doesn't matter so far\r
- group.Name = name;\r
- ProfileGroups.push_back(group);\r
- return ProfileGroups.size()-1;\r
-}\r
-\r
-bool IProfiler::findDataIndex(u32 & result, const core::stringw &name) const\r
-{\r
- for ( u32 i=0; i < ProfileDatas.size(); ++i )\r
- {\r
- if ( ProfileDatas[i].Name == name )\r
- {\r
- result = i;\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
-}\r
-\r
-const SProfileData* IProfiler::getProfileDataById(u32 id)\r
-{\r
- SProfileData data(id);\r
- s32 idx = ProfileDatas.binary_search(data);\r
- if ( idx >= 0 )\r
- return &ProfileDatas[idx];\r
- return NULL;\r
-}\r
-\r
-bool IProfiler::findGroupIndex(u32 & result, const core::stringw &name) const\r
-{\r
- for ( u32 i=0; i < ProfileGroups.size(); ++i )\r
- {\r
- if ( ProfileGroups[i].Name == name )\r
- {\r
- result = i;\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
-}\r
-\r
-void IProfiler::resetDataById(s32 id)\r
-{\r
- s32 idx = ProfileDatas.binary_search(SProfileData(id));\r
- if ( idx >= 0 )\r
- {\r
- resetDataByIndex((u32)idx);\r
- }\r
-}\r
-\r
-void IProfiler::resetDataByIndex(u32 index)\r
-{\r
- SProfileData &data = ProfileDatas[index];\r
-\r
- SProfileData & group = ProfileGroups[data.GroupIndex];\r
- group.CountCalls -= data.CountCalls;\r
- group.TimeSum -= data.TimeSum;\r
-\r
- data.reset();\r
-}\r
-\r
-//! Reset profile data for a whole group\r
-void IProfiler::resetGroup(u32 index)\r
-{\r
- for ( u32 i=0; i<ProfileDatas.size(); ++i )\r
- {\r
- if ( ProfileDatas[i].GroupIndex == index )\r
- ProfileDatas[i].reset();\r
- }\r
- if ( index < ProfileGroups.size() )\r
- ProfileGroups[index].reset();\r
-}\r
-\r
-void IProfiler::resetAll()\r
-{\r
- for ( u32 i=0; i<ProfileDatas.size(); ++i )\r
- {\r
- ProfileDatas[i].reset();\r
- }\r
-\r
- for ( u32 i=0; i<ProfileGroups.size(); ++i )\r
- {\r
- ProfileGroups[i].reset();\r
- }\r
-}\r
-\r
-//! For internal engine use:\r
-//! Code inside IRR_PROFILE is only executed when _IRR_COMPILE_WITH_PROFILING_ is set\r
-//! This allows disabling all profiler code completely by changing that define.\r
-//! It's generally useful to wrap profiler-calls in application code with a similar macro.\r
-#ifdef _IRR_COMPILE_WITH_PROFILING_\r
- #define IRR_PROFILE(X) X\r
-#else\r
- #define IRR_PROFILE(X)\r
-#endif // IRR_PROFILE\r
-\r
-} // namespace irr\r
-\r
-#endif // __I_PROFILER_H_INCLUDED__\r
#include "CMeshBuffer.h"\r
#include "coreutil.h"\r
#include "CVertexBuffer.h"\r
-#include "IProfiler.h"\r
#include "dimension2d.h"\r
#include "ECullingTypes.h"\r
#include "EDebugSceneTypes.h"\r
COSOperator.cpp
Irrlicht.cpp
os.cpp
- CProfiler.cpp
)
if(ANDROID)
#include "EVertexAttributes.h"\r
#include "CImage.h"\r
#include "os.h"\r
-#include "EProfileIDs.h"\r
-#include "IProfiler.h"\r
\r
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_\r
#include "android_native_app_glue.h"\r
setDebugName("COGLES2Driver");\r
#endif\r
\r
- IRR_PROFILE(\r
- static bool initProfile = false;\r
- if (!initProfile )\r
- {\r
- initProfile = true;\r
- getProfiler().add(EPID_ES2_END_SCENE, L"endScene", L"ES2");\r
- getProfiler().add(EPID_ES2_BEGIN_SCENE, L"beginScene", L"ES2");\r
- getProfiler().add(EPID_ES2_UPDATE_VERTEX_HW_BUF, L"upVertBuf", L"ES2");\r
- getProfiler().add(EPID_ES2_UPDATE_INDEX_HW_BUF, L"upIdxBuf", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_PRIMITIVES, L"drawPrim", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_2DIMAGE, L"draw2dImg", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_2DIMAGE_BATCH, L"draw2dImgB", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_2DRECTANGLE, L"draw2dRect", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_2DLINE, L"draw2dLine", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_3DLINE, L"draw3dLine", L"ES2");\r
- getProfiler().add(EPID_ES2_SET_RENDERSTATE_2D, L"rstate2d", L"ES2");\r
- getProfiler().add(EPID_ES2_SET_RENDERSTATE_3D, L"rstate3d", L"ES2");\r
- getProfiler().add(EPID_ES2_SET_RENDERSTATE_BASIC, L"rstateBasic", L"ES2");\r
- getProfiler().add(EPID_ES2_SET_RENDERSTATE_TEXTURE, L"rstateTex", L"ES2");\r
- getProfiler().add(EPID_ES2_DRAW_SHADOW, L"shadows", L"ES2");\r
- }\r
- )\r
if (!ContextManager)\r
return;\r
\r
\r
bool COGLES2Driver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_BEGIN_SCENE);)\r
-\r
CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\r
\r
if (ContextManager)\r
\r
bool COGLES2Driver::endScene()\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_END_SCENE);)\r
-\r
CNullDriver::endScene();\r
\r
glFlush();\r
if (!HWBuffer)\r
return false;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_UPDATE_VERTEX_HW_BUF);)\r
-\r
const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;\r
const void* vertices = mb->getVertices();\r
const u32 vertexCount = mb->getVertexCount();\r
if (!HWBuffer)\r
return false;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_UPDATE_INDEX_HW_BUF);)\r
-\r
const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;\r
\r
const void* indices = mb->getIndices();\r
if (!checkPrimitiveCount(primitiveCount))\r
return;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_PRIMITIVES);)\r
-\r
CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);\r
\r
setRenderStates3DMode();\r
if (!sourceRect.isValid())\r
return;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DIMAGE);)\r
-\r
core::position2d<s32> targetPos(destPos);\r
core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner);\r
core::dimension2d<s32> sourceSize(sourceRect.getSize());\r
if (!texture)\r
return;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DIMAGE);)\r
-\r
// texcoords need to be flipped horizontally for RTTs\r
const bool isRTT = texture->isRenderTarget();\r
const core::dimension2du& ss = texture->getOriginalSize();\r
if (!texture)\r
return;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DIMAGE_BATCH);)\r
-\r
const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());\r
\r
core::array<S3DVertex> vtx(drawCount * 4);\r
if (!texture)\r
return;\r
\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DIMAGE_BATCH);)\r
-\r
chooseMaterial2D();\r
if (!setMaterialTexture(0, texture))\r
return;\r
const core::rect<s32>& position,\r
const core::rect<s32>* clip)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DRECTANGLE);)\r
-\r
chooseMaterial2D();\r
setMaterialTexture(0, 0);\r
\r
SColor colorLeftDown, SColor colorRightDown,\r
const core::rect<s32>* clip)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DRECTANGLE);)\r
-\r
core::rect<s32> pos = position;\r
\r
if (clip)\r
void COGLES2Driver::draw2DLine(const core::position2d<s32>& start,\r
const core::position2d<s32>& end, SColor color)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_2DLINE);)\r
-\r
if (start==end)\r
drawPixel(start.X, start.Y, color);\r
else\r
\r
void COGLES2Driver::setRenderStates3DMode()\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_SET_RENDERSTATE_3D);)\r
-\r
if ( LockRenderStateMode )\r
return;\r
\r
//! Can be called by an IMaterialRenderer to make its work easier.\r
void COGLES2Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, bool resetAllRenderStates)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_SET_RENDERSTATE_BASIC);)\r
-\r
// ZBuffer\r
switch (material.ZBuffer)\r
{\r
//! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.\r
void COGLES2Driver::setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_SET_RENDERSTATE_TEXTURE);)\r
-\r
// Set textures to TU/TIU and apply filters to them\r
\r
for (s32 i = Feature.MaxTextureUnits - 1; i >= 0; --i)\r
//! sets the needed renderstates\r
void COGLES2Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_SET_RENDERSTATE_2D);)\r
-\r
if ( LockRenderStateMode )\r
return;\r
\r
//! Draws a shadow volume into the stencil buffer.\r
void COGLES2Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_SHADOW);)\r
-\r
const u32 count=triangles.size();\r
if (!StencilBuffer || !count)\r
return;\r
video::SColor leftUpEdge, video::SColor rightUpEdge,\r
video::SColor leftDownEdge, video::SColor rightDownEdge)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_SHADOW);)\r
-\r
if (!StencilBuffer)\r
return;\r
\r
void COGLES2Driver::draw3DLine(const core::vector3df& start,\r
const core::vector3df& end, SColor color)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_DRAW_3DLINE);)\r
-\r
setRenderStates3DMode();\r
\r
u16 indices[] = {0, 1};\r
#include "EVertexAttributes.h"\r
#include "CImage.h"\r
#include "os.h"\r
-#include "EProfileIDs.h"\r
-#include "IProfiler.h"\r
\r
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_\r
#include "android_native_app_glue.h"\r
\r
bool COGLES1Driver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_BEGIN_SCENE);)\r
-\r
CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\r
\r
if (ContextManager)\r
\r
bool COGLES1Driver::endScene()\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_ES2_END_SCENE);)\r
-\r
CNullDriver::endScene();\r
\r
glFlush();\r
+++ /dev/null
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-// Written by Michael Zeilfelder\r
-\r
-#include "CProfiler.h"\r
-#include "CTimer.h"\r
-\r
-namespace irr\r
-{\r
-IRRLICHT_API IProfiler& IRRCALLCONV getProfiler()\r
-{\r
- static CProfiler profiler;\r
- return profiler;\r
-}\r
-\r
-CProfiler::CProfiler()\r
-{\r
- Timer = new CTimer(true);\r
-\r
- addGroup(L"overview");\r
-}\r
-\r
-CProfiler::~CProfiler()\r
-{\r
- if ( Timer )\r
- Timer->drop();\r
-}\r
-\r
-void CProfiler::printAll(core::stringw &ostream, bool includeOverview, bool suppressUncalled) const\r
-{\r
- ostream += makeTitleString();\r
- ostream += L"\n";\r
- for ( u32 i=includeOverview ?0:1; i<ProfileGroups.size(); ++i )\r
- {\r
- printGroup( ostream, i, suppressUncalled );\r
- }\r
-}\r
-\r
-void CProfiler::printGroup(core::stringw &ostream, u32 idxGroup, bool suppressUncalled) const\r
-{\r
- ostream += getAsString(ProfileGroups[idxGroup]);\r
- ostream += L"\n";\r
-\r
- // print overview for groups\r
- if ( idxGroup == 0 )\r
- {\r
- for ( u32 i=0; i<ProfileGroups.size(); ++i )\r
- {\r
- if ( !suppressUncalled || ProfileGroups[i].getCallsCounter() > 0)\r
- {\r
- ostream += getAsString(ProfileGroups[i]);\r
- ostream += L"\n";\r
- }\r
- }\r
- }\r
- // print all data in a group\r
- else\r
- {\r
- for ( u32 i=0; i<ProfileDatas.size(); ++i )\r
- {\r
- if ( (!suppressUncalled || ProfileDatas[i].getCallsCounter() > 0)\r
- && ProfileDatas[i].getGroupIndex() == idxGroup )\r
- {\r
- ostream += getAsString(ProfileDatas[i]);\r
- ostream += L"\n";\r
- }\r
- }\r
- }\r
-}\r
-\r
-//! Convert the whole data into a string\r
-core::stringw CProfiler::getAsString(const SProfileData& data) const\r
-{\r
- if ( data.getCallsCounter() > 0 )\r
- {\r
- wchar_t dummy[512];\r
- swprintf_irr(dummy, 512, L"%-15.15s%-12u%-12u%-12u%-12u",\r
- data.getName().c_str(), data.getCallsCounter(), data.getTimeSum(),\r
- data.getTimeSum() / data.getCallsCounter(), data.getLongestTime());\r
-\r
- return core::stringw(dummy);\r
- }\r
- else\r
- {\r
- return data.getName();\r
- }\r
-}\r
-\r
-//! Return a string which describes the columns returned by getAsString\r
-core::stringw CProfiler::makeTitleString() const\r
-{\r
- return core::stringw("name calls time(sum) time(avg) time(max)");\r
-}\r
-\r
-} // namespace irr\r
+++ /dev/null
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-// Written by Michael Zeilfelder\r
-\r
-#ifndef __C_PROFILER_H_INCLUDED__\r
-#define __C_PROFILER_H_INCLUDED__\r
-\r
-#include "IrrCompileConfig.h"\r
-#include "IProfiler.h"\r
-\r
-namespace irr\r
-{\r
-class CProfiler : public IProfiler\r
-{\r
-public:\r
-\r
- CProfiler();\r
- virtual ~CProfiler();\r
-\r
- //! Write all profile-data into a string\r
- void printAll(core::stringw &result, bool includeOverview,bool suppressUncalled) const override;\r
-\r
- //! Write the profile data of one group into a string\r
- void printGroup(core::stringw &result, u32 groupIndex, bool suppressUncalled) const override;\r
-\r
-protected:\r
- core::stringw makeTitleString() const;\r
- core::stringw getAsString(const SProfileData& data) const;\r
-};\r
-} // namespace irr\r
-\r
-#endif // __C_PROFILER_H_INCLUDED__\r
#include "IMaterialRenderer.h"\r
#include "IReadFile.h"\r
#include "IWriteFile.h"\r
-#include "EProfileIDs.h"\r
-#include "IProfiler.h"\r
\r
#include "os.h"\r
\r
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_\r
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));\r
#endif\r
-\r
- IRR_PROFILE(\r
- static bool initProfile = false;\r
- if (!initProfile )\r
- {\r
- initProfile = true;\r
- getProfiler().add(EPID_SM_DRAW_ALL, L"drawAll", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_ANIMATE, L"animate", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_CAMERAS, L"cameras", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_LIGHTS, L"lights", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_SKYBOXES, L"skyboxes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_DEFAULT, L"defaultnodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_SHADOWS, L"shadows", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_TRANSPARENT, L"transp.nodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_EFFECT, L"effectnodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_GUI_NODES, L"guinodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_REGISTER, L"reg.render.node", L"Irrlicht scene");\r
- }\r
- )\r
}\r
\r
\r
//! registers a node for rendering it at a specific time.\r
u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS pass)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_SM_REGISTER);)\r
u32 taken = 0;\r
\r
switch(pass)\r
//! draws all scene nodes\r
void CSceneManager::drawAll()\r
{\r
- IRR_PROFILE(CProfileScope psAll(EPID_SM_DRAW_ALL);)\r
-\r
if (!Driver)\r
return;\r
\r
Driver->setAllowZWriteOnTransparent(Parameters->getAttributeAsBool(ALLOW_ZWRITE_ON_TRANSPARENT));\r
\r
// do animations and other stuff.\r
- IRR_PROFILE(getProfiler().start(EPID_SM_ANIMATE));\r
OnAnimate(os::Timer::getTime());\r
- IRR_PROFILE(getProfiler().stop(EPID_SM_ANIMATE));\r
\r
/*!\r
First Scene Node for prerendering should be the active camera\r
consistent Camera is needed for culling\r
*/\r
- IRR_PROFILE(getProfiler().start(EPID_SM_RENDER_CAMERAS));\r
camWorldPos.set(0,0,0);\r
if (ActiveCamera)\r
{\r
ActiveCamera->render();\r
camWorldPos = ActiveCamera->getAbsolutePosition();\r
}\r
- IRR_PROFILE(getProfiler().stop(EPID_SM_RENDER_CAMERAS));\r
\r
// let all nodes register themselves\r
OnRegisterSceneNode();\r
\r
//render camera scenes\r
{\r
- IRR_PROFILE(CProfileScope psCam(EPID_SM_RENDER_CAMERAS);)\r
CurrentRenderPass = ESNRP_CAMERA;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
// render skyboxes\r
{\r
- IRR_PROFILE(CProfileScope psSkyBox(EPID_SM_RENDER_SKYBOXES);)\r
CurrentRenderPass = ESNRP_SKY_BOX;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
// render default objects\r
{\r
- IRR_PROFILE(CProfileScope psDefault(EPID_SM_RENDER_DEFAULT);)\r
CurrentRenderPass = ESNRP_SOLID;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
// render transparent objects.\r
{\r
- IRR_PROFILE(CProfileScope psTrans(EPID_SM_RENDER_TRANSPARENT);)\r
CurrentRenderPass = ESNRP_TRANSPARENT;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
// render transparent effect objects.\r
{\r
- IRR_PROFILE(CProfileScope psEffect(EPID_SM_RENDER_EFFECT);)\r
CurrentRenderPass = ESNRP_TRANSPARENT_EFFECT;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
// render custom gui nodes\r
{\r
- IRR_PROFILE(CProfileScope psEffect(EPID_SM_RENDER_GUI_NODES);)\r
CurrentRenderPass = ESNRP_GUI;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
+++ /dev/null
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-\r
-#ifndef E_PROFILE_IDS_H_INCLUDED__\r
-#define E_PROFILE_IDS_H_INCLUDED__\r
-\r
-#include "IrrCompileConfig.h"\r
-#include "limits.h"\r
-\r
-namespace irr\r
-{\r
-#ifdef _IRR_COMPILE_WITH_PROFILING_\r
- enum EPROFILE_ID\r
- {\r
- // We use negative ID's to avoid clashing with user application id's.\r
- EPID_FIRST = -INT_MAX, // not used\r
-\r
- //! scenemanager.\r
- EPID_SM_DRAW_ALL,\r
- EPID_SM_ANIMATE,\r
- EPID_SM_RENDER_CAMERAS,\r
- EPID_SM_RENDER_LIGHTS,\r
- EPID_SM_RENDER_SKYBOXES,\r
- EPID_SM_RENDER_DEFAULT,\r
- EPID_SM_RENDER_SHADOWS,\r
- EPID_SM_RENDER_TRANSPARENT,\r
- EPID_SM_RENDER_EFFECT,\r
- EPID_SM_RENDER_GUI_NODES,\r
- EPID_SM_REGISTER,\r
-\r
- //! octrees\r
- EPID_OC_RENDER,\r
- EPID_OC_CALCPOLYS,\r
-\r
- //! es2 driver\r
- EPID_ES2_END_SCENE,\r
- EPID_ES2_BEGIN_SCENE,\r
- EPID_ES2_UPDATE_VERTEX_HW_BUF,\r
- EPID_ES2_UPDATE_INDEX_HW_BUF,\r
- EPID_ES2_DRAW_PRIMITIVES,\r
- EPID_ES2_DRAW_2DIMAGE,\r
- EPID_ES2_DRAW_2DIMAGE_BATCH,\r
- EPID_ES2_DRAW_2DRECTANGLE,\r
- EPID_ES2_DRAW_2DLINE,\r
- EPID_ES2_DRAW_3DLINE,\r
- EPID_ES2_SET_RENDERSTATE_2D,\r
- EPID_ES2_SET_RENDERSTATE_3D,\r
- EPID_ES2_SET_RENDERSTATE_BASIC,\r
- EPID_ES2_SET_RENDERSTATE_TEXTURE,\r
- EPID_ES2_DRAW_SHADOW\r
- };\r
-#endif\r
-} // end namespace irr\r
-\r
-#endif // E_PROFILE_IDS_H_INCLUDED__\r