예제 #1
0
size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, EasyTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows)
{
    size_t total_items = 0;
    for (auto child_index : _children)
    {
        if (_safelocker.interrupted())
            break;

        auto& gui_block = easyBlock(child_index);
        const auto& child = gui_block.tree;
        const auto startTime = child.node->begin();
        const auto endTime = child.node->end();
        const auto duration = endTime - startTime;
        _duration += duration;

        if (startTime > _right || endTime < _left)
        {
            continue;
        }

        auto item = new EasyTreeWidgetItem(child_index, _parent);

        auto name = *child.node->name() != 0 ? child.node->name() : easyDescriptor(child.node->id()).name();
        item->setText(COL_NAME, ::profiler_gui::toUnicode(name));
        item->setTimeSmart(COL_DURATION, duration);
        item->setTimeMs(COL_BEGIN, startTime - _beginTime);
        item->setTimeMs(COL_END, endTime - _beginTime);
        item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);

        if (child.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also
        {
            const auto& per_thread_stats = child.per_thread_stats;
            const auto& per_parent_stats = child.per_parent_stats;
            const auto& per_frame_stats = child.per_frame_stats;

            auto percentage = duration == 0 ? 0 : ::profiler_gui::percent(duration, _parent->duration());
            auto percentage_sum = ::profiler_gui::percent(per_parent_stats->total_duration, _parent->duration());
            item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage);
            item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage));
            item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, percentage_sum);
            item->setText(COL_PERCENT_SUM_PER_PARENT, QString::number(percentage_sum));

            if (_frame != nullptr)
            {
                if (_parent != _frame)
                {
                    percentage = duration == 0 ? 0 : ::profiler_gui::percent(duration, _frame->duration());
                    percentage_sum = ::profiler_gui::percent(per_frame_stats->total_duration, _frame->duration());
                }

                item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, percentage);
                item->setText(COL_PERCENT_PER_FRAME, QString::number(percentage));
                item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, percentage_sum);
                item->setText(COL_PERCENT_SUM_PER_FRAME, QString::number(percentage_sum));
            }
            else
            {
                item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
                item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, 0);

                if (_thread)
                {
                    auto percentage_per_thread = ::profiler_gui::percent(duration, _thread->selfDuration());
                    item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread);
                    item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread));
                }
                else
                {
                    item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
                }
            }


            if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
            {
                item->setTimeSmart(COL_MIN_PER_THREAD, per_thread_stats->min_duration, "min ");
                item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max ");
                item->setTimeSmart(COL_AVERAGE_PER_THREAD, per_thread_stats->average_duration());
                item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, per_thread_stats->total_duration);
            }

            item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number);
            item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number));

            if (_thread)
            {
                auto percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, _thread->selfDuration());
                item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread);
                item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));
            }


            if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
            {
                item->setTimeSmart(COL_MIN_PER_PARENT, per_parent_stats->min_duration, "min ");
                item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max ");
                item->setTimeSmart(COL_AVERAGE_PER_PARENT, per_parent_stats->average_duration());
                item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, per_parent_stats->total_duration);
            }

            item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, per_parent_stats->calls_number);
            item->setText(COL_NCALLS_PER_PARENT, QString::number(per_parent_stats->calls_number));


            if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
            {
                item->setTimeSmart(COL_MIN_PER_FRAME, per_frame_stats->min_duration, "min ");
                item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max ");
                item->setTimeSmart(COL_AVERAGE_PER_FRAME, per_frame_stats->average_duration());
                item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, per_frame_stats->total_duration);
            }

            item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number);
            item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number));
        }
        else
        {
            if (_frame == nullptr && _thread != nullptr)
            {
                auto percentage_per_thread = ::profiler_gui::percent(duration, _thread->selfDuration());
                item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread);
                item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread));
            }
            else
            {
                item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
            }

            item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, 0);
            item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);
        }

        const auto color = easyDescriptor(child.node->id()).color();
        //const auto bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
        const auto fgColor = ::profiler_gui::textColorForRgb(color);// 0x00ffffff - bgColor;
        item->setBackgroundColor(color);
        item->setTextColor(fgColor);

        auto item_index = static_cast<uint32_t>(_items.size());
        _items.push_back(item);

        size_t children_items_number = 0;
        ::profiler::timestamp_t children_duration = 0;
        if (!child.children.empty())
        {
            children_items_number = FillTreeClass<T>::setTreeInternal(_safelocker, _items, _beginTime, child.children, item, _frame ? _frame : item, _thread, _left, _right, _strict, children_duration, _colorizeRows);
            if (_safelocker.interrupted())
                break;
        }

        int percentage = 100;
        auto self_duration = duration - children_duration;
        if (children_duration > 0 && duration > 0)
        {
            percentage = ::profiler_gui::percent(self_duration, duration);
        }

        item->setTimeSmart(COL_SELF_DURATION, self_duration);
        item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage);
        item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage));

        if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right))
        {
            total_items += children_items_number + 1;
            gui_block.tree_item = item_index;

            if (_colorizeRows)
                item->colorize(_colorizeRows);

            if (gui_block.expanded)
                item->setExpanded(true);
        }
        else
        {
            _items.pop_back();
            delete item;
        }
    }

    return total_items;
}
예제 #2
0
void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows)
{
    //size_t blocksNumber = 0;
    //for (const auto& block : _blocks)
    //    blocksNumber += calculateTotalChildrenNumber(*block.tree);
    //    //blocksNumber += block.tree->total_children_number;
    //m_items.reserve(blocksNumber + _blocks.size()); // blocksNumber does not include root blocks

    RootsMap threadsMap;

    const auto u_thread = ::profiler_gui::toUnicode("thread");
    int i = 0, total = static_cast<int>(_blocks.size());
    //const QSignalBlocker b(this);
    for (const auto& block : _blocks)
    {
        if (_safelocker.interrupted())
            break;

        auto& gui_block = easyBlock(block.tree);
        const auto startTime = gui_block.tree.node->begin();
        const auto endTime = gui_block.tree.node->end();
        if (startTime > _right || endTime < _left)
        {
            _safelocker.setProgress((90 * ++i) / total);
            continue;
        }

        ::profiler::timestamp_t duration = 0;
        EasyTreeWidgetItem* thread_item = nullptr;
        auto thread_item_it = threadsMap.find(block.root->thread_id);
        if (thread_item_it != threadsMap.end())
        {
            thread_item = thread_item_it->second;
        }
        else
        {
            thread_item = new EasyTreeWidgetItem();

            QString threadName;
            if (block.root->got_name())
            {
                QString rootname(::profiler_gui::toUnicode(block.root->name()));
                if (rootname.contains(u_thread, Qt::CaseInsensitive))
                    threadName = ::std::move(QString("%1 %2").arg(rootname).arg(block.root->thread_id));
                else
                    threadName = ::std::move(QString("%1 Thread %2").arg(rootname).arg(block.root->thread_id));
            }
            else
            {
                threadName = ::std::move(QString("Thread %1").arg(block.root->thread_id));
            }

            thread_item->setText(COL_NAME, threadName);

            if (!block.root->children.empty())
                duration = blocksTree(block.root->children.back()).node->end() - blocksTree(block.root->children.front()).node->begin();

            thread_item->setTimeSmart(COL_DURATION, duration);
            thread_item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
            thread_item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND);

            // Sum of all children durations:
            thread_item->setTimeSmart(COL_SELF_DURATION, block.root->active_time);

            threadsMap.insert(::std::make_pair(block.root->thread_id, thread_item));
        }

        auto item = new EasyTreeWidgetItem(block.tree, thread_item);
        duration = endTime - startTime;

        auto name = *gui_block.tree.node->name() != 0 ? gui_block.tree.node->name() : easyDescriptor(gui_block.tree.node->id()).name();
        item->setText(COL_NAME, ::profiler_gui::toUnicode(name));
        item->setTimeSmart(COL_DURATION, duration);
        item->setTimeMs(COL_BEGIN, startTime - _beginTime);
        item->setTimeMs(COL_END, endTime - _beginTime);

        item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);

        auto percentage_per_thread = ::profiler_gui::percent(duration, block.root->active_time);
        item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread);
        item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread));

        if (gui_block.tree.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also
        {
            const auto& per_thread_stats = gui_block.tree.per_thread_stats;
            const auto& per_parent_stats = gui_block.tree.per_parent_stats;
            const auto& per_frame_stats = gui_block.tree.per_frame_stats;


            if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
            {
                item->setTimeSmart(COL_MIN_PER_THREAD, per_thread_stats->min_duration, "min ");
                item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max ");
                item->setTimeSmart(COL_AVERAGE_PER_THREAD, per_thread_stats->average_duration());
                item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, per_thread_stats->total_duration);
            }

            item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number);
            item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number));

            percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, block.root->active_time);
            item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread);
            item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));


            if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
            {
                item->setTimeSmart(COL_MIN_PER_PARENT, per_parent_stats->min_duration, "min ");
                item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max ");
                item->setTimeSmart(COL_AVERAGE_PER_PARENT, per_parent_stats->average_duration());
                item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, per_parent_stats->total_duration);
            }

            item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, per_parent_stats->calls_number);
            item->setText(COL_NCALLS_PER_PARENT, QString::number(per_parent_stats->calls_number));


            if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
            {
                item->setTimeSmart(COL_MIN_PER_FRAME, per_frame_stats->min_duration, "min ");
                item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max ");
                item->setTimeSmart(COL_AVERAGE_PER_FRAME, per_frame_stats->average_duration());
                item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, per_frame_stats->total_duration);
            }

            item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number);
            item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number));
        }
        else
        {
            item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);
            item->setText(COL_PERCENT_SUM_PER_THREAD, "");
        }

        const auto color = easyDescriptor(gui_block.tree.node->id()).color();
        //const auto bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
        const auto fgColor = ::profiler_gui::textColorForRgb(color);//0x00ffffff - bgColor;
        item->setBackgroundColor(color);
        item->setTextColor(fgColor);

        auto item_index = static_cast<unsigned int>(_items.size());
        _items.push_back(item);

        size_t children_items_number = 0;
        ::profiler::timestamp_t children_duration = 0;
        if (!gui_block.tree.children.empty())
        {
            children_items_number = FillTreeClass<T>::setTreeInternal(_safelocker, _items, _beginTime, gui_block.tree.children, item, item, thread_item, _left, _right, _strict, children_duration, _colorizeRows);
            if (_safelocker.interrupted())
                break;
        }

        int percentage = 100;
        auto self_duration = duration - children_duration;
        if (children_duration > 0 && duration > 0)
        {
            percentage = static_cast<int>(0.5 + 100. * static_cast<double>(self_duration) / static_cast<double>(duration));
        }

        item->setTimeSmart(COL_SELF_DURATION, self_duration);
        item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage);
        item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage));

        if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right))
        {
            //total_items += children_items_number + 1;
            gui_block.tree_item = item_index;

            if (_colorizeRows)
                item->colorize(_colorizeRows);

            if (gui_block.expanded)
                item->setExpanded(true);

        }
        else
        {
            _items.pop_back();
            delete item;
        }

        _safelocker.setProgress((90 * ++i) / total);
    }

    i = 0;
    total = static_cast<int>(threadsMap.size());
    for (auto& it : threadsMap)
    {
        auto item = it.second;

        if (item->childCount() > 0)
        {
            //addTopLevelItem(item);
            //m_roots[it.first] = item;

            //_items.push_back(item);
            _topLevelItems.emplace_back(it.first, item);

            //++total_items;
        }
        else
        {
            delete item;
        }

        _safelocker.setProgress(90 + (10 * ++i) / total);
    }

    _safelocker.setDone();
    //return total_items;
}