mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-25 23:40:51 +08:00
[ui] fixed slider freeze after load new file in "Zoom" mode;
[core] #157 added new build flag EASY_OPTION_TRUNCATE_RUNTIME_NAMES which will prevent from crash for very big block names, but will reduce performance. Disabled by default because of very rare use case; [core] #157 added new build flag EASY_OPTION_CHECK_MAX_VALUE_SIZE for EASY_VALUE arrays and strings - same as the flag above for block names. Also disabled by default;
This commit is contained in:
parent
0dc5a71aad
commit
272c0ceab1
@ -3,6 +3,8 @@ message(STATUS "EASY_PROFILER.Core version = ${EASY_PRODUCT_VERSION_STRING}")
|
||||
message(STATUS "")
|
||||
|
||||
|
||||
set(EASY_MAX_SIZE_VALUE 2816)
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Checking c++11 thread_local support
|
||||
@ -39,6 +41,8 @@ set(EASY_DEFAULT_PORT 28077 CACHE STRING "Default listening po
|
||||
set(EASY_OPTION_LISTEN OFF CACHE BOOL "Enable automatic startListen on startup")
|
||||
set(EASY_OPTION_PROFILE_SELF OFF CACHE BOOL "Enable self profiling (measure time for internal storage expand)")
|
||||
set(EASY_OPTION_PROFILE_SELF_BLOCKS_ON OFF CACHE BOOL "Storage expand default status (profiler::ON or profiler::OFF)")
|
||||
set(EASY_OPTION_TRUNCATE_RUNTIME_NAMES OFF CACHE BOOL "Enable truncation of block dynamic names (set at run-time, not compile-time). Reduces performance. Turn ON only if you want to use dynamic block names of length >${EASY_MAX_SIZE_VALUE} symbols at runtime. It is better to use EASY_VALUE instead of such long names.")
|
||||
set(EASY_OPTION_CHECK_MAX_VALUE_SIZE OFF CACHE BOOL "Enable checking EASY_VALUE maximum data size. Slightly reduces performance. Turn ON only if you want to pass big EASY_ARRAY, EASY_STRING, EASY_TEXT of length >${EASY_MAX_SIZE_VALUE} bytes. It is better to split such arrays into the smaller ones.")
|
||||
set(EASY_OPTION_LOG OFF CACHE BOOL "Print errors to stderr")
|
||||
set(EASY_OPTION_PRETTY_PRINT OFF CACHE BOOL "Use pretty-printed function names with signature and argument types")
|
||||
set(EASY_OPTION_PREDEFINED_COLORS ON CACHE BOOL "Use predefined set of colors (see profiler_colors.h). If you want to use your own colors palette you can turn this option OFF")
|
||||
@ -81,6 +85,19 @@ message(STATUS " Default listening port = ${EASY_DEFAULT_PORT}")
|
||||
message(STATUS " Auto-start listening = ${EASY_OPTION_LISTEN}")
|
||||
message(STATUS " Profile self = ${EASY_OPTION_PROFILE_SELF}")
|
||||
message(STATUS " Profile self blocks initial status = ${EASY_OPTION_PROFILE_SELF_BLOCKS_ON}")
|
||||
|
||||
if (EASY_OPTION_TRUNCATE_RUNTIME_NAMES)
|
||||
message(STATUS " Truncate block dynamic names = ${EASY_OPTION_TRUNCATE_RUNTIME_NAMES} (reduces performance)")
|
||||
else()
|
||||
message(STATUS " Truncate block dynamic names = ${EASY_OPTION_TRUNCATE_RUNTIME_NAMES} (may cause crash if using dynamic block names of length >${EASY_MAX_SIZE_VALUE} symbols)")
|
||||
endif()
|
||||
|
||||
if (EASY_OPTION_CHECK_MAX_VALUE_SIZE)
|
||||
message(STATUS " Check maximum EASY_VALUE data size = ${EASY_OPTION_CHECK_MAX_VALUE_SIZE} (slightly reduces performance)")
|
||||
else()
|
||||
message(STATUS " Check maximum EASY_VALUE data size = ${EASY_OPTION_CHECK_MAX_VALUE_SIZE} (may cause crash if using EASY_VALUE arrays of total data size >${EASY_MAX_SIZE_VALUE} bytes)")
|
||||
endif()
|
||||
|
||||
message(STATUS " Implicit thread registration = ${EASY_OPTION_IMPLICIT_THREAD_REGISTRATION}")
|
||||
if (WIN32)
|
||||
message(STATUS " Event tracing = ${EASY_OPTION_EVENT_TRACING}")
|
||||
@ -201,6 +218,8 @@ easy_define_target_option(easy_profiler BUILD_WITH_CHRONO_HIGH_RESOLUTION_CLOCK
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_LISTEN EASY_OPTION_START_LISTEN_ON_STARTUP)
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_PROFILE_SELF EASY_OPTION_MEASURE_STORAGE_EXPAND)
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_PROFILE_SELF_BLOCKS_ON EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON)
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_TRUNCATE_RUNTIME_NAMES EASY_OPTION_TRUNCATE_LONG_RUNTIME_NAMES)
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_CHECK_MAX_VALUE_SIZE EASY_OPTION_CHECK_MAX_VALUE_DATA_SIZE)
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_IMPLICIT_THREAD_REGISTRATION EASY_OPTION_IMPLICIT_THREAD_REGISTRATION)
|
||||
if (WIN32)
|
||||
easy_define_target_option(easy_profiler EASY_OPTION_EVENT_TRACING EASY_OPTION_EVENT_TRACING_ENABLED)
|
||||
|
@ -376,4 +376,37 @@ public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <const uint16_t N, bool, bool>
|
||||
struct aligned_size;
|
||||
|
||||
template <const uint16_t N, bool dummy>
|
||||
struct aligned_size<N, true, dummy> {
|
||||
EASY_STATIC_CONSTEXPR uint16_t Size = N;
|
||||
};
|
||||
|
||||
template <const uint16_t N>
|
||||
struct aligned_size<N, false, true> {
|
||||
EASY_STATIC_CONSTEXPR uint16_t Size = static_cast<uint16_t>(N - (N % EASY_ALIGNMENT_SIZE));
|
||||
};
|
||||
|
||||
template <const uint16_t N>
|
||||
struct aligned_size<N, false, false> {
|
||||
EASY_STATIC_CONSTEXPR uint16_t Size = static_cast<uint16_t>(N + EASY_ALIGNMENT_SIZE - (N % EASY_ALIGNMENT_SIZE));
|
||||
};
|
||||
|
||||
template <const size_t N>
|
||||
struct get_aligned_size {
|
||||
EASY_STATIC_CONSTEXPR uint16_t Size =
|
||||
aligned_size<static_cast<uint16_t>(N), (N % EASY_ALIGNMENT_SIZE) == 0, (N > (65536 - EASY_ALIGNMENT_SIZE))>::Size;
|
||||
};
|
||||
|
||||
static_assert(get_aligned_size<EASY_ALIGNMENT_SIZE - 3>::Size == EASY_ALIGNMENT_SIZE, "wrong get_aligned_size");
|
||||
static_assert(get_aligned_size<2 * EASY_ALIGNMENT_SIZE - 3>::Size == 2 * EASY_ALIGNMENT_SIZE, "wrong get_aligned_size");
|
||||
static_assert(get_aligned_size<65530>::Size == 65536 - EASY_ALIGNMENT_SIZE, "wrong get_aligned_size");
|
||||
static_assert(get_aligned_size<65526>::Size == 65536 - EASY_ALIGNMENT_SIZE, "wrong get_aligned_size");
|
||||
static_assert(get_aligned_size<65536 - EASY_ALIGNMENT_SIZE>::Size == 65536 - EASY_ALIGNMENT_SIZE, "wrong get_aligned_size");
|
||||
static_assert(get_aligned_size<65536 + 3 - EASY_ALIGNMENT_SIZE * 2>::Size == 65536 - EASY_ALIGNMENT_SIZE, "wrong get_aligned_size");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // EASY_PROFILER_CHUNK_ALLOCATOR_H
|
||||
|
@ -158,9 +158,9 @@ void foo(const A& a) {
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
\warning Max array size is 4096. Passing bigger size has undefined behavior.
|
||||
\warning Max data size (sizeof(value) * size) is MAX_BLOCK_DATA_SIZE. Passing bigger size has undefined behavior.
|
||||
|
||||
\sa EASY_VALUE, EASY_TEXT, EASY_STRING
|
||||
\sa EASY_VALUE, EASY_TEXT, EASY_STRING, MAX_BLOCK_DATA_SIZE
|
||||
|
||||
\ingroup profiler
|
||||
*/
|
||||
@ -178,9 +178,9 @@ Could be C-string or std::string.
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
\warning Max string length is 4096 (including trailing '\0'). Passing bigger size has undefined behavior.
|
||||
\warning Max string length is MAX_BLOCK_DATA_SIZE (including trailing '\0'). Passing bigger size has undefined behavior.
|
||||
|
||||
\sa EASY_VALUE, EASY_ARRAY, EASY_STRING
|
||||
\sa EASY_VALUE, EASY_ARRAY, EASY_STRING, MAX_BLOCK_DATA_SIZE
|
||||
|
||||
\ingroup profiler
|
||||
*/
|
||||
@ -201,9 +201,9 @@ Use this for C-strings of known length (compile-time or run-time).
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
\warning Max string length is 4096 (including trailing '\0'). Passing bigger size has undefined behavior.
|
||||
\warning Max string length is MAX_BLOCK_DATA_SIZE (including trailing '\0'). Passing bigger size has undefined behavior.
|
||||
|
||||
\sa EASY_VALUE, EASY_ARRAY, EASY_TEXT
|
||||
\sa EASY_VALUE, EASY_ARRAY, EASY_TEXT, MAX_BLOCK_DATA_SIZE
|
||||
|
||||
\ingroup profiler
|
||||
*/
|
||||
@ -216,8 +216,6 @@ Use this for C-strings of known length (compile-time or run-time).
|
||||
namespace profiler
|
||||
{
|
||||
|
||||
EASY_CONSTEXPR uint16_t MaxArbitraryValuesArraySize = 4096;
|
||||
|
||||
extern "C" PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data,
|
||||
uint16_t _size, bool _isArray, ValueId _vin);
|
||||
|
||||
@ -235,7 +233,7 @@ namespace profiler
|
||||
storeValue(_desc, StdToDataType<Type>::data_type, &_value, static_cast<uint16_t>(sizeof(Type)), false, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _arraySize > 4096 may cause undefined behavior!
|
||||
///< WARNING: Passing _arraySize > (MAX_BLOCK_DATA_SIZE / sizeof(T)) may cause undefined behavior!
|
||||
template <class T>
|
||||
inline void setValue(const BaseBlockDescriptor* _desc, const T* _valueArray, ValueId _vin, uint16_t _arraySize)
|
||||
{
|
||||
@ -251,24 +249,24 @@ namespace profiler
|
||||
static_assert(StdToDataType<T>::data_type != DataType::TypesCount,
|
||||
"You should use standard builtin scalar types as profiler::Value type!");
|
||||
|
||||
static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 4096.");
|
||||
static_assert(sizeof(_value) <= MAX_BLOCK_DATA_SIZE, "Maximum arbitrary values data size exceeded.");
|
||||
|
||||
storeValue(_desc, StdToDataType<T>::data_type, _value, static_cast<uint16_t>(sizeof(_value)), true, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _textLength > 4096 may cause undefined behavior!
|
||||
///< WARNING: Passing _textLength > MAX_BLOCK_DATA_SIZE may cause undefined behavior!
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin, uint16_t _textLength)
|
||||
{
|
||||
storeValue(_desc, DataType::String, _text, _textLength, true, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _text with length > 4096 may cause undefined behavior!
|
||||
///< WARNING: Passing _text with length > MAX_BLOCK_DATA_SIZE may cause undefined behavior!
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin)
|
||||
{
|
||||
storeValue(_desc, DataType::String, _text, static_cast<uint16_t>(strlen(_text) + 1), true, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _text with length > 4096 may cause undefined behavior!
|
||||
///< WARNING: Passing _text with length > MAX_BLOCK_DATA_SIZE may cause undefined behavior!
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const ::std::string& _text, ValueId _vin)
|
||||
{
|
||||
storeValue(_desc, DataType::String, _text.c_str(), static_cast<uint16_t>(_text.size() + 1), true, _vin);
|
||||
@ -277,7 +275,7 @@ namespace profiler
|
||||
template <size_t N>
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char (&_text)[N], ValueId _vin)
|
||||
{
|
||||
static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 4096.");
|
||||
static_assert(N <= MAX_BLOCK_DATA_SIZE, "Maximum arbitrary values data size exceeded.");
|
||||
storeValue(_desc, DataType::String, &_text[0], static_cast<uint16_t>(N), true, _vin);
|
||||
}
|
||||
|
||||
|
@ -198,6 +198,8 @@ namespace profiler {
|
||||
|
||||
}; // END of class ThreadGuard.
|
||||
|
||||
EASY_CONSTEXPR uint16_t MAX_BLOCK_DATA_SIZE = 2048 + 512 + 256; ///< Estimated maximum size of block dynamic name or EASY_VALUE data size
|
||||
|
||||
} // END of namespace profiler.
|
||||
|
||||
#endif // EASY_PROFILER_PUBLIC_TYPES_H
|
||||
|
@ -45,6 +45,8 @@ The Apache License, Version 2.0 (the "License");
|
||||
|
||||
#include <easy/details/profiler_public_types.h>
|
||||
|
||||
#define MAX_DYNAMIC_BLOCK_NAME_SIZE_ESTIMATED MAX_BLOCK_DATA_SIZE
|
||||
|
||||
#if defined ( __clang__ )
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
|
@ -43,10 +43,11 @@ The Apache License, Version 2.0 (the "License");
|
||||
#ifndef EASY_PROFILER_STACK_BUFFER_H
|
||||
#define EASY_PROFILER_STACK_BUFFER_H
|
||||
|
||||
#include "nonscoped_block.h"
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
|
||||
#include "nonscoped_block.h"
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
|
@ -40,11 +40,32 @@ The Apache License, Version 2.0 (the "License");
|
||||
|
||||
**/
|
||||
|
||||
#include <algorithm>
|
||||
#include "thread_storage.h"
|
||||
#include "current_thread.h"
|
||||
#include "current_time.h"
|
||||
|
||||
static profiler::vin_t ptr2vin(const void* ptr)
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
EASY_CONSTEXPR uint16_t BASE_SIZE = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + 1U);
|
||||
|
||||
#if EASY_OPTION_TRUNCATE_LONG_RUNTIME_NAMES != 0
|
||||
EASY_CONSTEXPR uint16_t MAX_BLOCK_NAME_LENGTH = BLOCK_CHUNK_SIZE - BASE_SIZE;
|
||||
#endif
|
||||
|
||||
#if EASY_OPTION_CHECK_MAX_VALUE_DATA_SIZE != 0
|
||||
EASY_CONSTEXPR uint16_t MAX_VALUE_DATA_SIZE = BLOCK_CHUNK_SIZE - static_cast<uint16_t>(sizeof(profiler::ArbitraryValue));
|
||||
#endif
|
||||
|
||||
profiler::vin_t ptr2vin(const void* ptr)
|
||||
{
|
||||
static_assert(sizeof(uintptr_t) == sizeof(void*),
|
||||
"Can not cast void* to uintptr_t. Different sizes.");
|
||||
@ -55,6 +76,8 @@ static profiler::vin_t ptr2vin(const void* ptr)
|
||||
return static_cast<profiler::vin_t>(reinterpret_cast<uintptr_t>(ptr));
|
||||
}
|
||||
|
||||
} // end of namespace <noname>.
|
||||
|
||||
ThreadStorage::ThreadStorage()
|
||||
: nonscopedBlocks(16)
|
||||
, frameStartTime(0)
|
||||
@ -68,9 +91,23 @@ ThreadStorage::ThreadStorage()
|
||||
expired = ATOMIC_VAR_INIT(0);
|
||||
}
|
||||
|
||||
void ThreadStorage::storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, uint16_t _size, bool _isArray, profiler::ValueId _vin)
|
||||
{
|
||||
void ThreadStorage::storeValue(
|
||||
profiler::timestamp_t _timestamp,
|
||||
profiler::block_id_t _id,
|
||||
profiler::DataType _type,
|
||||
const void* _data,
|
||||
uint16_t _size,
|
||||
bool _isArray,
|
||||
profiler::ValueId _vin
|
||||
) {
|
||||
#if EASY_OPTION_CHECK_MAX_VALUE_DATA_SIZE != 0
|
||||
if (_size > MAX_VALUE_DATA_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const uint16_t serializedDataSize = _size + static_cast<uint16_t>(sizeof(profiler::ArbitraryValue));
|
||||
|
||||
void* data = blocks.closedList.allocate(serializedDataSize);
|
||||
|
||||
::new (data) profiler::ArbitraryValue(_timestamp, ptr2vin(_vin.m_id), _id, _size, _type, _isArray);
|
||||
@ -94,11 +131,16 @@ void ThreadStorage::storeBlock(const profiler::Block& block)
|
||||
EASY_THREAD_LOCAL static profiler::timestamp_t endTime = 0ULL;
|
||||
#endif
|
||||
|
||||
#if EASY_OPTION_TRUNCATE_LONG_RUNTIME_NAMES != 0
|
||||
const uint16_t nameLength = std::min(static_cast<uint16_t>(strlen(block.name())), MAX_BLOCK_NAME_LENGTH);
|
||||
#else
|
||||
const uint16_t nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
#endif
|
||||
|
||||
#if EASY_OPTION_MEASURE_STORAGE_EXPAND == 0
|
||||
const
|
||||
#endif
|
||||
uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + nameLength + 1);
|
||||
auto serializedDataSize = static_cast<uint16_t>(BASE_SIZE + nameLength);
|
||||
|
||||
#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0
|
||||
const bool expanded = (desc->m_status & profiler::ON) && blocks.closedList.need_expand(serializedDataSize);
|
||||
@ -130,8 +172,8 @@ void ThreadStorage::storeBlock(const profiler::Block& block)
|
||||
|
||||
void ThreadStorage::storeBlockForce(const profiler::Block& block)
|
||||
{
|
||||
const uint16_t nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
const uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + nameLength + 1);
|
||||
const auto nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
const auto serializedDataSize = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + nameLength + 1);
|
||||
|
||||
void* data = blocks.closedList.marked_allocate(serializedDataSize);
|
||||
::new (data) profiler::SerializedBlock(block, nameLength);
|
||||
@ -140,8 +182,8 @@ void ThreadStorage::storeBlockForce(const profiler::Block& block)
|
||||
|
||||
void ThreadStorage::storeCSwitch(const CSwitchBlock& block)
|
||||
{
|
||||
const uint16_t nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
const uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::CSwitchEvent) + nameLength + 1);
|
||||
const auto nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
const auto serializedDataSize = static_cast<uint16_t>(sizeof(profiler::CSwitchEvent) + nameLength + 1);
|
||||
|
||||
void* data = sync.closedList.allocate(serializedDataSize);
|
||||
::new (data) profiler::SerializedCSwitch(block, nameLength);
|
||||
|
@ -43,21 +43,26 @@ The Apache License, Version 2.0 (the "License");
|
||||
#ifndef EASY_PROFILER_THREAD_STORAGE_H
|
||||
#define EASY_PROFILER_THREAD_STORAGE_H
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <easy/details/profiler_public_types.h>
|
||||
#include <easy/details/arbitrary_value_public_types.h>
|
||||
#include <easy/serialized_block.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include "stack_buffer.h"
|
||||
|
||||
#include "chunk_allocator.h"
|
||||
#include "stack_buffer.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T, const uint16_t N>
|
||||
struct BlocksList
|
||||
{
|
||||
BlocksList(const BlocksList&) = delete;
|
||||
BlocksList(BlocksList&&) = delete;
|
||||
|
||||
BlocksList() = default;
|
||||
|
||||
std::vector<T> openedList;
|
||||
@ -65,17 +70,13 @@ struct BlocksList
|
||||
uint64_t usedMemorySize = 0;
|
||||
uint64_t frameMemorySize = 0;
|
||||
|
||||
void clearClosed() {
|
||||
void clearClosed()
|
||||
{
|
||||
//closedList.clear();
|
||||
usedMemorySize = 0;
|
||||
frameMemorySize = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
BlocksList(const BlocksList&) = delete;
|
||||
BlocksList(BlocksList&&) = delete;
|
||||
|
||||
}; // END of struct BlocksList.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -92,17 +93,29 @@ public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EASY_CONSTEXPR uint16_t SIZEOF_BLOCK = sizeof(profiler::BaseBlockData) + 1 + sizeof(uint16_t); // SerializedBlock stores BaseBlockData + at least 1 character for name ('\0') + 2 bytes for size of serialized data
|
||||
EASY_CONSTEXPR uint16_t SIZEOF_CSWITCH = sizeof(profiler::CSwitchEvent) + 1 + sizeof(uint16_t); // SerializedCSwitch also stores additional 4 bytes to be able to save 64-bit thread_id
|
||||
EASY_CONSTEXPR uint16_t BLOCKS_IN_CHUNK = 128U;
|
||||
EASY_CONSTEXPR uint16_t SIZEOF_BLOCK = sizeof(profiler::BaseBlockData) + 1U + sizeof(uint16_t); // SerializedBlock stores BaseBlockData + at least 1 character for name ('\0') + 2 bytes for size of serialized data
|
||||
EASY_CONSTEXPR uint16_t SIZEOF_CSWITCH = sizeof(profiler::CSwitchEvent) + 1U + sizeof(uint16_t); // SerializedCSwitch also stores additional 4 bytes to be able to save 64-bit thread_id
|
||||
|
||||
static_assert((int)SIZEOF_BLOCK * 128 < 65536, "Chunk size for profiler::Block must be less than 65536");
|
||||
static_assert((int)SIZEOF_CSWITCH * 128 < 65536, "Chunk size for CSwitchBlock must be less than 65536");
|
||||
static_assert(((int)SIZEOF_BLOCK * (int)BLOCKS_IN_CHUNK) < 65536, "Chunk size for profiler::Block must be less than 65536");
|
||||
static_assert(((int)SIZEOF_CSWITCH * (int)BLOCKS_IN_CHUNK) < 65536, "Chunk size for CSwitchBlock must be less than 65536");
|
||||
|
||||
EASY_CONSTEXPR uint16_t BLOCK_CHUNK_SIZE = get_aligned_size<SIZEOF_BLOCK * BLOCKS_IN_CHUNK>::Size;
|
||||
EASY_CONSTEXPR uint16_t CSWITCH_CHUNK_SIZE = get_aligned_size<SIZEOF_BLOCK * BLOCKS_IN_CHUNK>::Size;
|
||||
|
||||
static_assert((BLOCK_CHUNK_SIZE % EASY_ALIGNMENT_SIZE) == 0, "BLOCK_CHUNK_SIZE not aligned");
|
||||
static_assert((CSWITCH_CHUNK_SIZE % EASY_ALIGNMENT_SIZE) == 0, "CSWITCH_CHUNK_SIZE not aligned");
|
||||
static_assert(BLOCK_CHUNK_SIZE > 2048, "wrong BLOCK_CHUNK_SIZE");
|
||||
static_assert(CSWITCH_CHUNK_SIZE > 2048, "wrong CSWITCH_CHUNK_SIZE");
|
||||
|
||||
struct ThreadStorage EASY_FINAL
|
||||
{
|
||||
StackBuffer<NonscopedBlock> nonscopedBlocks;
|
||||
BlocksList<std::reference_wrapper<profiler::Block>, SIZEOF_BLOCK * (uint16_t)128U> blocks;
|
||||
BlocksList<CSwitchBlock, SIZEOF_CSWITCH * (uint16_t)128U> sync;
|
||||
using BlocksStorage = BlocksList<std::reference_wrapper<profiler::Block>, BLOCK_CHUNK_SIZE>;
|
||||
using ContextSwitchStorage = BlocksList<CSwitchBlock, CSWITCH_CHUNK_SIZE>;
|
||||
|
||||
StackBuffer<NonscopedBlock> nonscopedBlocks;
|
||||
BlocksStorage blocks;
|
||||
ContextSwitchStorage sync;
|
||||
|
||||
std::string name; ///< Thread name
|
||||
profiler::timestamp_t frameStartTime; ///< Current frame start time. Used to calculate FPS.
|
||||
|
@ -709,9 +709,23 @@ void ArbitraryValuesChartItem::paint(QPainter* _painter, const QStyleOptionGraph
|
||||
drawImage();
|
||||
}
|
||||
|
||||
QRectF rect(0, m_boundingRect.top() - widget->margin(), width - 3, m_boundingRect.height() + widget->margins());
|
||||
_painter->setPen(profiler_gui::TEXT_COLOR);
|
||||
_painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, bindMode ? " Mode: Zoom" : " Mode: Overview");
|
||||
// MODE
|
||||
{
|
||||
QRectF rect(3, m_boundingRect.top() - widget->margin(), width - 3, m_boundingRect.height() + widget->margins());
|
||||
QRectF textBounds;
|
||||
|
||||
_painter->setPen(Qt::blue);
|
||||
_painter->drawText(
|
||||
rect,
|
||||
Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip | Qt::TextIncludeTrailingSpaces,
|
||||
QStringLiteral("MODE: "),
|
||||
&textBounds
|
||||
);
|
||||
rect.adjust(textBounds.width(), 0, 0, 0);
|
||||
|
||||
_painter->setPen(profiler_gui::TEXT_COLOR);
|
||||
_painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, bindMode ? "Zoom" : "Overview");
|
||||
}
|
||||
|
||||
_painter->setPen(Qt::darkGray);
|
||||
_painter->drawLine(QLineF(0, bottom, width, bottom));
|
||||
@ -1705,10 +1719,10 @@ int GraphicsChart::filterWindowSize() const
|
||||
return m_chartItem->filterWindowSize();
|
||||
}
|
||||
|
||||
//bool GraphicsChart::canShowSlider() const
|
||||
//{
|
||||
// return chartType() != ChartType::Complexity && !m_bBindMode;
|
||||
//}
|
||||
bool GraphicsChart::canShowSlider() const
|
||||
{
|
||||
return chartType() != ChartType::Complexity && !bindMode();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -280,7 +280,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
//bool canShowSlider() const override;
|
||||
bool canShowSlider() const override;
|
||||
|
||||
private slots:
|
||||
|
||||
|
@ -383,7 +383,11 @@ bool GraphicsSliderArea::setValue(qreal _value)
|
||||
}
|
||||
|
||||
if (m_imageItem->isVisible())
|
||||
{
|
||||
m_imageItem->onValueChanged();
|
||||
if (!m_slider->isVisible())
|
||||
scene()->update();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -415,10 +419,14 @@ void GraphicsSliderArea::setRange(qreal _minValue, qreal _maxValue)
|
||||
void GraphicsSliderArea::setSliderWidth(qreal _width)
|
||||
{
|
||||
m_slider->setWidth(_width);
|
||||
if (!setValue(m_value))
|
||||
if (setValue(m_value))
|
||||
return;
|
||||
|
||||
if (m_imageItem->isVisible())
|
||||
{
|
||||
if (m_imageItem->isVisible())
|
||||
m_imageItem->onValueChanged();
|
||||
m_imageItem->onValueChanged();
|
||||
if (!m_slider->isVisible())
|
||||
scene()->update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,8 +488,10 @@ void GraphicsSliderArea::mousePressEvent(QMouseEvent* _event)
|
||||
if (!_event->modifiers())
|
||||
{
|
||||
m_bBindMode = !m_bBindMode;
|
||||
m_slider->setVisible(canShowSlider());
|
||||
if (m_imageItem->isVisible())
|
||||
m_imageItem->onModeChanged();
|
||||
scene()->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user