mirror of
https://github.com/diasurgical/DevilutionX.git
synced 2026-10-11 22:29:54 +00:00
Poormans profiler
This commit is contained in:
@@ -167,6 +167,7 @@ set(libdevilutionx_SRCS
|
||||
utils/str_cat.cpp
|
||||
utils/str_case.cpp
|
||||
utils/surface_to_clx.cpp
|
||||
utils/profiler.cpp
|
||||
utils/timer.cpp
|
||||
utils/utf8.cpp)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <utils/profiler.h>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -697,6 +698,7 @@ bool HandleTextInput(std::string_view text)
|
||||
|
||||
void GameEventHandler(const SDL_Event &event, uint16_t modState)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
StaticVector<ControllerButtonEvent, 4> ctrlEvents = ToControllerButtonEvents(event);
|
||||
for (ControllerButtonEvent ctrlEvent : ctrlEvents) {
|
||||
GameAction action;
|
||||
@@ -825,6 +827,7 @@ void RunGameLoop(interface_mode uMsg)
|
||||
unsigned run_game_iteration = 0;
|
||||
#endif
|
||||
|
||||
FunctionProfiler profiler(__func__);
|
||||
while (gbRunGame) {
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -2454,6 +2457,12 @@ int DiabloMain(int argc, char **argv)
|
||||
|
||||
DiabloSplash();
|
||||
mainmenu_loop();
|
||||
|
||||
for (const auto &timing : FunctionProfiler::Dump()) {
|
||||
fmt::print("{}: {}ms ({} calls)\n", timing.name, timing.ms, timing.count);
|
||||
}
|
||||
fmt::print("\n");
|
||||
|
||||
DiabloDeinit();
|
||||
|
||||
return 0;
|
||||
@@ -3002,6 +3011,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
|
||||
|
||||
bool game_loop(bool bStartup)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
uint16_t wait = bStartup ? sgGameInitInfo.nTickRate * 3 : 3;
|
||||
|
||||
for (unsigned i = 0; i < wait; i++) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "engine/render/scrollrt.h"
|
||||
#include "utils/attributes.h"
|
||||
#include "utils/clx_decode.hpp"
|
||||
#include "utils/profiler.h"
|
||||
|
||||
#ifdef DEBUG_CLX
|
||||
#include <fmt/format.h>
|
||||
@@ -194,6 +195,7 @@ void DoRenderBackwards(
|
||||
const Surface &out, Point position, const uint8_t *src, size_t srcSize,
|
||||
unsigned srcWidth, unsigned srcHeight, BlitFn &&blitFn)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (position.y < 0 || position.y + 1 >= static_cast<int>(out.h() + srcHeight))
|
||||
return;
|
||||
const ClipX clipX = CalculateClipX(position.x, srcWidth, out);
|
||||
@@ -615,6 +617,7 @@ template <bool SkipColorIndexZero>
|
||||
void RenderClxOutline(const Surface &out, Point position, const uint8_t *src, std::size_t srcSize,
|
||||
std::size_t srcWidth, uint8_t color)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
RenderSrc srcForBackwards { src, src + srcSize, static_cast<uint_fast16_t>(srcWidth) };
|
||||
if (position.x > 0 && position.x + static_cast<int>(srcWidth) < static_cast<int>(out.w())) {
|
||||
RenderClxOutlineClippedY<SkipColorIndexZero>(out, position, srcForBackwards, color);
|
||||
@@ -625,6 +628,7 @@ void RenderClxOutline(const Surface &out, Point position, const uint8_t *src, st
|
||||
|
||||
void ClxApplyTrans(ClxSprite sprite, const uint8_t *trn)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
// A bit of a hack but this is the only place in the code where we need mutable sprites.
|
||||
auto *dst = const_cast<uint8_t *>(sprite.pixelData());
|
||||
uint16_t remaining = sprite.pixelDataSize();
|
||||
@@ -666,6 +670,7 @@ void ClxApplyTrans(ClxSpriteSheet sheet, const uint8_t *trn)
|
||||
|
||||
bool IsPointWithinClx(Point position, ClxSprite clx)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
const uint8_t *src = clx.pixelData();
|
||||
const uint8_t *end = src + clx.pixelDataSize();
|
||||
const uint16_t width = clx.width();
|
||||
@@ -719,6 +724,7 @@ bool IsPointWithinClx(Point position, ClxSprite clx)
|
||||
|
||||
std::pair<int, int> ClxMeasureSolidHorizontalBounds(ClxSprite clx)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
const uint8_t *src = clx.pixelData();
|
||||
const uint8_t *end = src + clx.pixelDataSize();
|
||||
const uint16_t width = clx.width();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
|
||||
#include "utils/profiler.h"
|
||||
#include "engine/render/blit_impl.hpp"
|
||||
#include "lighting.h"
|
||||
#include "options.h"
|
||||
@@ -922,6 +923,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileType(TileType tile, uint8_t *
|
||||
template <bool OpaquePrefix, int8_t PrefixIncrement>
|
||||
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareDispatch(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (tbl == LightTables[LightsMax].data()) {
|
||||
RenderTransparentSquare<LightType::FullyDark, OpaquePrefix, PrefixIncrement>(dst, dstPitch, src, tbl, clip);
|
||||
} else if (tbl == LightTables[0].data()) {
|
||||
@@ -964,6 +966,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidOrTransparentSquare
|
||||
template <bool OpaquePrefix, int8_t PrefixIncrement>
|
||||
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidOrTransparentSquareDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (tbl == LightTables[LightsMax].data()) {
|
||||
RenderLeftTrapezoidOrTransparentSquare<LightType::FullyDark, OpaquePrefix, PrefixIncrement>(tile, dst, dstPitch, src, tbl, clip);
|
||||
} else if (tbl == LightTables[0].data()) {
|
||||
@@ -976,6 +979,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidOrTransparentSquareD
|
||||
template <bool OpaquePrefix, int8_t PrefixIncrement>
|
||||
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidOrTransparentSquareDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (tbl == LightTables[LightsMax].data()) {
|
||||
RenderRightTrapezoidOrTransparentSquare<LightType::FullyDark, OpaquePrefix, PrefixIncrement>(tile, dst, dstPitch, src, tbl, clip);
|
||||
} else if (tbl == LightTables[0].data()) {
|
||||
@@ -988,6 +992,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidOrTransparentSquare
|
||||
template <bool Transparent>
|
||||
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (tbl == LightTables[LightsMax].data()) {
|
||||
RenderTileType<LightType::FullyDark, Transparent>(tile, dst, dstPitch, src, tbl, clip);
|
||||
} else if (tbl == LightTables[0].data()) {
|
||||
@@ -1126,6 +1131,7 @@ std::string_view MaskTypeToString(MaskType maskType)
|
||||
void RenderTile(const Surface &out, Point position,
|
||||
LevelCelBlock levelCelBlock, MaskType maskType, const uint8_t *tbl)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
const TileType tile = levelCelBlock.type();
|
||||
|
||||
#ifdef DEBUG_RENDER_OFFSET_X
|
||||
@@ -1180,6 +1186,7 @@ void RenderTile(const Surface &out, Point position,
|
||||
|
||||
void world_draw_black_tile(const Surface &out, int sx, int sy)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
#ifdef DEBUG_RENDER_OFFSET_X
|
||||
sx += DEBUG_RENDER_OFFSET_X;
|
||||
#endif
|
||||
|
||||
@@ -86,6 +86,7 @@ std::unordered_multimap<WorldTilePosition, Missile *> MissilesAtRenderingTile;
|
||||
*/
|
||||
bool CouldMissileCollide(Point tile, bool checkPlayerAndMonster)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (!InDungeonBounds(tile))
|
||||
return true;
|
||||
if (checkPlayerAndMonster) {
|
||||
@@ -100,6 +101,7 @@ bool CouldMissileCollide(Point tile, bool checkPlayerAndMonster)
|
||||
|
||||
void UpdateMissilePositionForRendering(Missile &m, int progress)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
DisplacementOf<int64_t> velocity = m.position.velocity;
|
||||
velocity *= progress;
|
||||
velocity /= AnimationInfo::baseValueFraction;
|
||||
@@ -113,6 +115,7 @@ void UpdateMissilePositionForRendering(Missile &m, int progress)
|
||||
|
||||
void UpdateMissileRendererData(Missile &m)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
m.position.tileForRendering = m.position.tile;
|
||||
m.position.offsetForRendering = m.position.offset;
|
||||
|
||||
@@ -155,6 +158,7 @@ void UpdateMissileRendererData(Missile &m)
|
||||
|
||||
void UpdateMissilesRendererData()
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
MissilesAtRenderingTile.clear();
|
||||
|
||||
for (auto &m : Missiles) {
|
||||
@@ -174,6 +178,7 @@ Rectangle PrevCursorRect;
|
||||
|
||||
void BlitCursor(uint8_t *dst, uint32_t dstPitch, uint8_t *src, uint32_t srcPitch, uint32_t srcWidth, uint32_t srcHeight)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
for (std::uint32_t i = 0; i < srcHeight; ++i, src += srcPitch, dst += dstPitch) {
|
||||
memcpy(dst, src, srcWidth);
|
||||
}
|
||||
@@ -184,6 +189,7 @@ void BlitCursor(uint8_t *dst, uint32_t dstPitch, uint8_t *src, uint32_t srcPitch
|
||||
*/
|
||||
void UndrawCursor(const Surface &out)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
DrawnCursor &cursor = GetDrawnCursor();
|
||||
BlitCursor(&out[cursor.rect.position], out.pitch(), cursor.behindBuffer, cursor.rect.size.width, cursor.rect.size.width, cursor.rect.size.height);
|
||||
PrevCursorRect = cursor.rect;
|
||||
@@ -191,6 +197,7 @@ void UndrawCursor(const Surface &out)
|
||||
|
||||
bool ShouldShowCursor()
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (ControlMode == ControlTypes::KeyboardAndMouse)
|
||||
return true;
|
||||
if (pcurs == CURSOR_TELEPORT)
|
||||
@@ -208,6 +215,7 @@ bool ShouldShowCursor()
|
||||
*/
|
||||
void DrawCursor(const Surface &out)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
DrawnCursor &cursor = GetDrawnCursor();
|
||||
if (IsHardwareCursor()) {
|
||||
SetHardwareCursorVisible(ShouldShowCursor());
|
||||
@@ -268,6 +276,7 @@ void DrawCursor(const Surface &out)
|
||||
*/
|
||||
void DrawMissilePrivate(const Surface &out, const Missile &missile, Point targetBufferPosition, bool pre)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (missile._miPreFlag != pre || !missile._miDrawFlag)
|
||||
return;
|
||||
|
||||
@@ -290,6 +299,7 @@ void DrawMissilePrivate(const Surface &out, const Missile &missile, Point target
|
||||
*/
|
||||
void DrawMissile(const Surface &out, WorldTilePosition tilePosition, Point targetBufferPosition, bool pre)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
const auto [begin, end] = MissilesAtRenderingTile.equal_range(tilePosition);
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
DrawMissilePrivate(out, *it->second, targetBufferPosition, pre);
|
||||
@@ -305,6 +315,7 @@ void DrawMissile(const Surface &out, WorldTilePosition tilePosition, Point targe
|
||||
*/
|
||||
void DrawMonster(const Surface &out, Point tilePosition, Point targetBufferPosition, const Monster &monster)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (!monster.animInfo.sprites) {
|
||||
Log("Draw Monster \"{}\": NULL Cel Buffer", monster.name());
|
||||
return;
|
||||
@@ -334,6 +345,7 @@ void DrawMonster(const Surface &out, Point tilePosition, Point targetBufferPosit
|
||||
*/
|
||||
void DrawPlayerIconHelper(const Surface &out, MissileGraphicID missileGraphicId, Point position, const Player &player, bool infraVision)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
bool lighting = &player != MyPlayer;
|
||||
|
||||
if (player.isWalking())
|
||||
@@ -365,6 +377,7 @@ void DrawPlayerIconHelper(const Surface &out, MissileGraphicID missileGraphicId,
|
||||
*/
|
||||
void DrawPlayerIcons(const Surface &out, const Player &player, Point position, bool infraVision)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (player.pManaShield)
|
||||
DrawPlayerIconHelper(out, MissileGraphicID::ManaShield, position, player, infraVision);
|
||||
if (player.wReflections > 0)
|
||||
@@ -380,6 +393,7 @@ void DrawPlayerIcons(const Surface &out, const Player &player, Point position, b
|
||||
*/
|
||||
void DrawPlayer(const Surface &out, const Player &player, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (!IsTileLit(tilePosition) && !MyPlayer->_pInfraFlag && !MyPlayer->isOnArenaLevel() && leveltype != DTYPE_TOWN) {
|
||||
return;
|
||||
}
|
||||
@@ -422,6 +436,7 @@ void DrawPlayer(const Surface &out, const Player &player, Point tilePosition, Po
|
||||
*/
|
||||
void DrawDeadPlayer(const Surface &out, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
dFlags[tilePosition.x][tilePosition.y] &= ~DungeonFlag::DeadPlayer;
|
||||
|
||||
for (Player &player : Players) {
|
||||
@@ -442,6 +457,7 @@ void DrawDeadPlayer(const Surface &out, Point tilePosition, Point targetBufferPo
|
||||
*/
|
||||
void DrawObject(const Surface &out, Point tilePosition, Point targetBufferPosition, bool pre)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (LightTableIndex >= LightsMax) {
|
||||
return;
|
||||
}
|
||||
@@ -480,6 +496,7 @@ static void DrawDungeon(const Surface & /*out*/, Point /*tilePosition*/, Point /
|
||||
*/
|
||||
void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
const uint16_t levelPieceId = dPiece[tilePosition.x][tilePosition.y];
|
||||
const MICROS *pMap = &DPieceMicros[levelPieceId];
|
||||
|
||||
@@ -593,6 +610,7 @@ void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition
|
||||
*/
|
||||
void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
LightTableIndex = dLight[tilePosition.x][tilePosition.y];
|
||||
|
||||
const uint8_t *tbl = LightTables[LightTableIndex].data();
|
||||
@@ -627,6 +645,7 @@ void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPositio
|
||||
*/
|
||||
void DrawItem(const Surface &out, Point tilePosition, Point targetBufferPosition, bool pre)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
int8_t bItem = dItem[tilePosition.x][tilePosition.y];
|
||||
|
||||
if (bItem <= 0)
|
||||
@@ -654,6 +673,7 @@ void DrawItem(const Surface &out, Point tilePosition, Point targetBufferPosition
|
||||
*/
|
||||
void DrawMonsterHelper(const Surface &out, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
int mi = dMonster[tilePosition.x][tilePosition.y];
|
||||
bool isNegativeMonster = mi < 0;
|
||||
mi = std::abs(mi) - 1;
|
||||
@@ -715,6 +735,7 @@ void DrawMonsterHelper(const Surface &out, Point tilePosition, Point targetBuffe
|
||||
*/
|
||||
void DrawPlayerHelper(const Surface &out, const Player &player, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
DrawPlayer(out, player, tilePosition, targetBufferPosition);
|
||||
}
|
||||
|
||||
@@ -726,6 +747,7 @@ void DrawPlayerHelper(const Surface &out, const Player &player, Point tilePositi
|
||||
*/
|
||||
void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
assert(InDungeonBounds(tilePosition));
|
||||
|
||||
if (dRendered.test(tilePosition.x, tilePosition.y))
|
||||
@@ -814,6 +836,7 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit
|
||||
*/
|
||||
void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPosition, int rows, int columns)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < columns; j++) {
|
||||
if (InDungeonBounds(tilePosition)) {
|
||||
@@ -845,6 +868,7 @@ void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPositio
|
||||
|
||||
bool IsWall(Point position)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
return TileHasAny(dPiece[position.x][position.y], TileProperties::Solid) || dSpecial[position.x][position.y] != 0;
|
||||
}
|
||||
|
||||
@@ -858,6 +882,7 @@ bool IsWall(Point position)
|
||||
*/
|
||||
void DrawTileContent(const Surface &out, Point tilePosition, Point targetBufferPosition, int rows, int columns)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
// Keep evaluating until MicroTiles can't affect screen
|
||||
rows += MicroTileLen;
|
||||
dRendered.reset();
|
||||
@@ -907,6 +932,7 @@ void DrawTileContent(const Surface &out, Point tilePosition, Point targetBufferP
|
||||
*/
|
||||
void Zoom(const Surface &out)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
int viewportWidth = out.w();
|
||||
int viewportOffsetX = 0;
|
||||
if (CanPanelsCoverView()) {
|
||||
@@ -964,6 +990,7 @@ int tileRows;
|
||||
|
||||
void CalcFirstTilePosition(Point &position, Displacement &offset)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
// Adjust by player offset and tile grid alignment
|
||||
Player &myPlayer = *MyPlayer;
|
||||
offset = tileOffset;
|
||||
@@ -1015,6 +1042,7 @@ void CalcFirstTilePosition(Point &position, Displacement &offset)
|
||||
*/
|
||||
void DrawGame(const Surface &fullOut, Point position, Displacement offset)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
// Limit rendering to the view area
|
||||
const Surface &out = !*sgOptions.Graphics.zoom
|
||||
? fullOut.subregionY(0, gnViewportHeight)
|
||||
@@ -1093,6 +1121,7 @@ void DrawGame(const Surface &fullOut, Point position, Displacement offset)
|
||||
*/
|
||||
void DrawView(const Surface &out, Point startPosition)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
#ifdef _DEBUG
|
||||
DebugCoordsMap.clear();
|
||||
#endif
|
||||
@@ -1263,6 +1292,7 @@ void DrawFPS(const Surface &out)
|
||||
*/
|
||||
void DoBlitScreen(int x, int y, int w, int h)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
#ifdef DEBUG_DO_BLIT_SCREEN
|
||||
const Surface &out = GlobalBackBuffer();
|
||||
const uint8_t debugColor = PAL8_RED;
|
||||
@@ -1291,6 +1321,7 @@ void DrawMain(const Surface &out, int dwHgt, bool drawDesc, bool drawHp, bool dr
|
||||
if (!gbActive || RenderDirectlyToOutputSurface) {
|
||||
return;
|
||||
}
|
||||
FunctionProfiler profiler(__func__);
|
||||
|
||||
assert(dwHgt >= 0 && dwHgt <= gnScreenHeight);
|
||||
|
||||
@@ -1339,6 +1370,7 @@ void DrawMain(const Surface &out, int dwHgt, bool drawDesc, bool drawHp, bool dr
|
||||
|
||||
Displacement GetOffsetForWalking(const AnimationInfo &animationInfo, const Direction dir, bool cameraMode /*= false*/)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
// clang-format off
|
||||
// South, SouthWest, West, NorthWest, North, NorthEast, East, SouthEast,
|
||||
constexpr Displacement StartOffset[8] = { { 0, -32 }, { 32, -16 }, { 64, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { -64, 0 }, { -32, -16 } };
|
||||
@@ -1372,6 +1404,7 @@ void ShiftGrid(int *x, int *y, int horizontal, int vertical)
|
||||
|
||||
int RowsCoveredByPanel()
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
auto &mainPanelSize = GetMainPanel().size;
|
||||
if (GetScreenWidth() <= mainPanelSize.width) {
|
||||
return 0;
|
||||
@@ -1387,6 +1420,7 @@ int RowsCoveredByPanel()
|
||||
|
||||
void CalcTileOffset(int *offsetX, int *offsetY)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
uint16_t screenWidth = GetScreenWidth();
|
||||
uint16_t viewportHeight = GetViewportHeight();
|
||||
|
||||
@@ -1412,6 +1446,7 @@ void CalcTileOffset(int *offsetX, int *offsetY)
|
||||
|
||||
void TilesInView(int *rcolumns, int *rrows)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
uint16_t screenWidth = GetScreenWidth();
|
||||
uint16_t viewportHeight = GetViewportHeight();
|
||||
|
||||
@@ -1489,6 +1524,7 @@ void CalcViewportGeometry()
|
||||
|
||||
Point GetScreenPosition(Point tile)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
Point firstTile = ViewPosition;
|
||||
Displacement offset = {};
|
||||
CalcFirstTilePosition(firstTile, offset);
|
||||
@@ -1507,6 +1543,7 @@ void ClearScreenBuffer()
|
||||
{
|
||||
if (HeadlessMode)
|
||||
return;
|
||||
FunctionProfiler profiler(__func__);
|
||||
|
||||
assert(PalSurface != nullptr);
|
||||
SDL_FillRect(PalSurface, nullptr, 0);
|
||||
@@ -1583,6 +1620,7 @@ void scrollrt_draw_game_screen()
|
||||
{
|
||||
if (HeadlessMode)
|
||||
return;
|
||||
FunctionProfiler profiler(__func__);
|
||||
|
||||
int hgt = 0;
|
||||
|
||||
@@ -1604,6 +1642,7 @@ void DrawAndBlit()
|
||||
if (!gbRunGame || HeadlessMode) {
|
||||
return;
|
||||
}
|
||||
FunctionProfiler profiler(__func__);
|
||||
|
||||
int hgt = 0;
|
||||
bool drawHealth = IsRedrawComponent(PanelDrawComponent::Health);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <utils/profiler.h>
|
||||
#include "engine.h"
|
||||
#include "engine/animationinfo.h"
|
||||
#include "engine/point.hpp"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include "utils/profiler.h"
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "DiabloUI/ui_item.h"
|
||||
#include "engine.h"
|
||||
@@ -469,6 +470,7 @@ void UnloadFonts()
|
||||
|
||||
int GetLineWidth(std::string_view text, GameFontTables size, int spacing, int *charactersInLine)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
int lineWidth = 0;
|
||||
CurrentFont currentFont;
|
||||
uint32_t codepoints = 0;
|
||||
@@ -502,6 +504,7 @@ int GetLineWidth(std::string_view text, GameFontTables size, int spacing, int *c
|
||||
|
||||
int GetLineWidth(std::string_view fmt, DrawStringFormatArg *args, std::size_t argsLen, size_t argsOffset, GameFontTables size, int spacing, int *charactersInLine)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
int lineWidth = 0;
|
||||
CurrentFont currentFont;
|
||||
|
||||
@@ -555,6 +558,7 @@ int GetLineWidth(std::string_view fmt, DrawStringFormatArg *args, std::size_t ar
|
||||
|
||||
int GetLineHeight(std::string_view text, GameFontTables fontIndex)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
if (fontIndex == GameFont12 && IsSmallFontTall() && ContainsSmallFontTallCodepoints(text)) {
|
||||
return SmallFontTallLineHeight;
|
||||
}
|
||||
@@ -574,6 +578,7 @@ int AdjustSpacingToFitHorizontally(int &lineWidth, int maxSpacing, int character
|
||||
|
||||
std::string WordWrapString(std::string_view text, unsigned width, GameFontTables size, int spacing)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
std::string output;
|
||||
if (text.empty() || text[0] == '\0')
|
||||
return output;
|
||||
@@ -660,6 +665,7 @@ std::string WordWrapString(std::string_view text, unsigned width, GameFontTables
|
||||
*/
|
||||
uint32_t DrawString(const Surface &out, std::string_view text, const Rectangle &rect, UiFlags flags, int spacing, int lineHeight)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
GameFontTables size = GetSizeFromFlags(flags);
|
||||
text_color color = GetColorFromFlags(flags);
|
||||
|
||||
@@ -710,6 +716,7 @@ uint32_t DrawString(const Surface &out, std::string_view text, const Rectangle &
|
||||
|
||||
void DrawStringWithColors(const Surface &out, std::string_view fmt, DrawStringFormatArg *args, std::size_t argsLen, const Rectangle &rect, UiFlags flags, int spacing, int lineHeight)
|
||||
{
|
||||
FunctionProfiler profiler(__func__);
|
||||
GameFontTables size = GetSizeFromFlags(flags);
|
||||
text_color color = GetColorFromFlags(flags);
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <utils/profiler.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <windows.h>
|
||||
#include <SDL.h>
|
||||
|
||||
std::unordered_map<std::string, TimingInfo> timings;
|
||||
|
||||
FunctionProfiler::FunctionProfiler(std::string name)
|
||||
: _name(name)
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
if (QueryPerformanceFrequency(&frequency)) {
|
||||
_frequency = frequency.QuadPart;
|
||||
} else {
|
||||
_frequency = 1000;
|
||||
}
|
||||
|
||||
LARGE_INTEGER ticks;
|
||||
if (QueryPerformanceCounter(&ticks)) {
|
||||
_start = ticks.QuadPart;
|
||||
} else {
|
||||
_start = SDL_GetTicks() * _frequency / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
FunctionProfiler::~FunctionProfiler()
|
||||
{
|
||||
LARGE_INTEGER ticks;
|
||||
uint64_t now;
|
||||
if (QueryPerformanceCounter(&ticks)) {
|
||||
now = ticks.QuadPart;
|
||||
} else {
|
||||
now = SDL_GetTicks() * _frequency / 1000;
|
||||
}
|
||||
double ms = (double)(now - _start) * 1000.0 / (double)_frequency;
|
||||
|
||||
TimingInfo &timing = timings[_name];
|
||||
timing.ms += ms;
|
||||
timing.count++;
|
||||
}
|
||||
|
||||
static bool CompareTiming(const TimingInfo &a, const TimingInfo &b)
|
||||
{
|
||||
return a.ms > b.ms;
|
||||
}
|
||||
|
||||
std::vector<TimingInfo> FunctionProfiler::Dump()
|
||||
{
|
||||
std::vector<TimingInfo> timingList;
|
||||
for (auto it = timings.begin(); it != timings.end(); ++it) {
|
||||
it->second.name = it->first;
|
||||
timingList.push_back(it->second);
|
||||
}
|
||||
std::sort(timingList.begin(), timingList.end(), CompareTiming);
|
||||
return timingList;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct TimingInfo {
|
||||
std::string name;
|
||||
double ms;
|
||||
int count;
|
||||
};
|
||||
|
||||
class FunctionProfiler {
|
||||
public:
|
||||
FunctionProfiler(std::string name);
|
||||
~FunctionProfiler();
|
||||
static std::vector<TimingInfo> Dump();
|
||||
private:
|
||||
std::string _name;
|
||||
uint64_t _frequency;
|
||||
uint64_t _start;
|
||||
};
|
||||
Reference in New Issue
Block a user