Skip to content

Commit

Permalink
[wip] player: integrate a profiler.
Browse files Browse the repository at this point in the history
Currently only into the terminal.

TODO:d cos
  • Loading branch information
mosra committed May 4, 2020
1 parent a93c8c9 commit 551cbc0
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/player/AbstractPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <Corrade/PluginManager/PluginManager.h>
#include <Corrade/Utility/Utility.h>
#include <Magnum/DebugTools/FrameProfiler.h>
#ifdef CORRADE_TARGET_EMSCRIPTEN
#include <Magnum/Platform/EmscriptenApplication.h>
#else
Expand Down Expand Up @@ -63,7 +64,7 @@ class AbstractPlayer: public AbstractUiScreen {
};

/* Extreme PIMPL. */
Containers::Pointer<AbstractPlayer> createScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom);
Containers::Pointer<AbstractPlayer> createScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom, const DebugTools::GLFrameProfiler::Values profilerValues);
Containers::Pointer<AbstractPlayer> createImagePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom);

}}
Expand Down
18 changes: 14 additions & 4 deletions src/player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
#include <Corrade/Utility/Configuration.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Directory.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/Resource.h>
#include <Corrade/Utility/String.h>
#include <Magnum/DebugTools/FrameProfiler.h>
#include <Magnum/GL/Context.h>
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/GL/Extensions.h>
Expand Down Expand Up @@ -198,6 +200,7 @@ class Player: public Platform::ScreenedApplication, public Interconnect::Receive
#endif
;

DebugTools::GLFrameProfiler::Values _profilerValues;
#ifdef CORRADE_IS_DEBUG_BUILD
Utility::Tweakable _tweakable;
#endif
Expand Down Expand Up @@ -347,6 +350,7 @@ Player::Player(const Arguments& arguments): Platform::ScreenedApplication{argume
#endif
args.addBooleanOption("no-merge-animations").setHelp("no-merge-animations", "don't merge glTF animations into a single clip")
.addOption("msaa").setHelp("msaa", "MSAA level to use (if not set, defaults to 8x or 2x for HiDPI)", "N")
.addOption("profile", "FrameTime CpuDuration GpuDuration").setHelp("profile", "Profile rendering", "VALUES")
#ifdef CORRADE_IS_DEBUG_BUILD
.addBooleanOption("tweakable").setHelp("tweakable", "Enable live source tweakability")
#endif
Expand All @@ -356,7 +360,11 @@ Player::Player(const Arguments& arguments): Platform::ScreenedApplication{argume
The -i / --importer-options argument accepts a comma-separated list of
key/value pairs to set in the importer plugin configuration. If the = character
is omitted, it's equivalent to saying key=true; you can specify configuration
subgroups using a slash.)")
subgroups using a slash.
The --profile option accepts a space-separated list of measured values.
Available values are FrameTime, CpuDuration, GpuDuration, VertexFetchRatio and
PrimitiveClipRatio.)")
.parse(arguments.argc, arguments.argv);

/* Try 8x MSAA, fall back to zero samples if not possible. Enable only 2x
Expand All @@ -381,6 +389,8 @@ subgroups using a slash.)")
create(conf, glConf.setSampleCount(0));
}

_profilerValues = args.value<DebugTools::GLFrameProfiler::Values>("profile");

#ifdef CORRADE_IS_DEBUG_BUILD
if(args.isSet("tweakable")) _tweakable.enable();
#endif
Expand Down Expand Up @@ -531,7 +541,7 @@ subgroups using a slash.)")
if(args.value("importer") != "AnySceneImporter" && !importer->object3DCount() && !importer->meshCount() && importer->image2DCount() >= 1)
_player = createImagePlayer(*this, *_overlay->ui);
else
_player = createScenePlayer(*this, *_overlay->ui);
_player = createScenePlayer(*this, *_overlay->ui, _profilerValues);
_player->load(_file, *importer, _id);
_importer = args.value("importer");
} else if(args.value("importer") == "AnySceneImporter") {
Expand All @@ -552,7 +562,7 @@ subgroups using a slash.)")
_manager.loadAndInstantiate("TinyGltfImporter");
Utility::Resource rs{"data"};
importer->openData(rs.getRaw("artwork/default.glb"));
_player = createScenePlayer(*this, *_overlay->ui);
_player = createScenePlayer(*this, *_overlay->ui, _profilerValues);
_player->load({}, *importer, -1);
#endif

Expand Down Expand Up @@ -642,7 +652,7 @@ void Player::loadFile(std::size_t totalCount, const char* filename, Containers::
return;
}

_player = createScenePlayer(*this, *_overlay->ui);
_player = createScenePlayer(*this, *_overlay->ui, _profilerValues);
_player->load(*gltfFile, *importer, -1);

/* If there's just one non-glTF file, try to load it as an image instead */
Expand Down
58 changes: 51 additions & 7 deletions src/player/ScenePlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
#include <Magnum/PixelFormat.h>
#include <Magnum/Animation/Player.h>
#include <Magnum/DebugTools/ColorMap.h>
#include <Magnum/DebugTools/FrameProfiler.h>
#include <Magnum/GL/Context.h>
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/GL/Extensions.h>
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/PixelFormat.h>
Expand Down Expand Up @@ -274,7 +277,7 @@ enum class Visualization: UnsignedByte {

class ScenePlayer: public AbstractPlayer, public Interconnect::Receiver {
public:
explicit ScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom);
explicit ScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom, const DebugTools::GLFrameProfiler::Values profilerValues);

private:
void drawEvent() override;
Expand Down Expand Up @@ -350,6 +353,11 @@ class ScenePlayer: public AbstractPlayer, public Interconnect::Receiver {
GL::Mesh _fullscreenTriangle{NoCreate};
DepthReinterpretShader _reinterpretShader{NoCreate};
#endif

/* Profiling */
DebugTools::GLFrameProfiler _profiler;
Debug _profilerOut{Debug::Flag::NoNewlineAtTheEnd|
(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors)};
};

class FlatDrawable: public SceneGraph::Drawable3D {
Expand Down Expand Up @@ -405,7 +413,7 @@ class MeshVisualizerDrawable: public SceneGraph::Drawable3D {
const bool& _shadeless;
};

ScenePlayer::ScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom): AbstractPlayer{application, PropagatedEvent::Draw|PropagatedEvent::Input} {
ScenePlayer::ScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom, DebugTools::GLFrameProfiler::Values profilerValues): AbstractPlayer{application, PropagatedEvent::Draw|PropagatedEvent::Input} {
_colorMapTexture
.setMinificationFilter(SamplerFilter::Linear, SamplerMipmap::Linear)
.setMagnificationFilter(SamplerFilter::Linear)
Expand Down Expand Up @@ -461,6 +469,31 @@ ScenePlayer::ScenePlayer(Platform::ScreenedApplication& application, Ui::UserInt
_fullscreenTriangle = GL::Mesh{};
_fullscreenTriangle.setCount(3);
#endif

/* Set up the profiler, filter away unsupported values */
if(profilerValues & DebugTools::GLFrameProfiler::Value::GpuDuration && !GL::Context::current().isExtensionSupported<GL::Extensions::ARB::timer_query>()) {
Debug{} << "ARB_timer_query not supported, GPU time profiling will be unavailable";
profilerValues &= ~DebugTools::GLFrameProfiler::Value::GpuDuration;
}
#ifndef MAGNUM_TARGET_GLES
if(profilerValues & (DebugTools::GLFrameProfiler::Value::VertexFetchRatio|DebugTools::GLFrameProfiler::Value::PrimitiveClipRatio) &&
!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::pipeline_statistics_query>()
) {
Debug{} << "ARB_pipeline_statistics_query not supported, GPU pipeline profiling will be unavailable";
profilerValues &= ~(DebugTools::GLFrameProfiler::Value::VertexFetchRatio|DebugTools::GLFrameProfiler::Value::PrimitiveClipRatio);
}
#else
if(profilerValues & DebugTools::GLFrameProfiler::Value::GpuDuration &&
!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::disjoint_timer_query>()
) {
Debug{} << "EXT_disjoint_timer_query not supported, GPU time profiling will be unavailable";
profilerValues &= ~DebugTools::GLFrameProfiler::Value::GpuDuration;
}
#endif

/* Disable profiler by default */
_profiler = DebugTools::GLFrameProfiler{profilerValues, 50};
_profiler.disable();
}

Shaders::Flat3D& ScenePlayer::flatShader(Shaders::Flat3D::Flags flags) {
Expand Down Expand Up @@ -1170,6 +1203,8 @@ void MeshVisualizerDrawable::draw(const Matrix4& transformationMatrix, SceneGrap
}

void ScenePlayer::drawEvent() {
_profiler.beginFrame();

/* Another FB could be bound from a depth / object ID read (moreover with
color output disabled), set it back to the default framebuffer */
GL::defaultFramebuffer.bind(); /** @todo mapForDraw() should bind implicitly */
Expand Down Expand Up @@ -1220,6 +1255,10 @@ void ScenePlayer::drawEvent() {
}
}

/* Don't profile UI drawing */
_profiler.endFrame();
_profiler.printStatistics(_profilerOut, 10);

/* Draw the UI. Disable the depth buffer and enable premultiplied alpha
blending. */
{
Expand All @@ -1232,9 +1271,10 @@ void ScenePlayer::drawEvent() {
GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
}

/* Schedule a redraw only if the player is playing to avoid hogging the
CPU */
if(_data && _data->player.state() == Animation::State::Playing) redraw();
/* Schedule a redraw only if profiling is enabled or the player is playing
to avoid hogging the CPU */
if(_profiler.isEnabled() || (_data && _data->player.state() == Animation::State::Playing))
redraw();

#ifdef MAGNUM_TARGET_WEBGL
/* The rendered depth buffer might get lost later, so resolve it to our
Expand Down Expand Up @@ -1399,6 +1439,10 @@ void ScenePlayer::keyPressEvent(KeyEvent& event) {
0xccccff_rgbf*_brightness});
}

/* Toggle profiling */
} else if(event.key() == KeyEvent::Key::P) {
_profiler.isEnabled() ? _profiler.disable() : _profiler.enable();

} else return;

event.setAccepted();
Expand Down Expand Up @@ -1611,8 +1655,8 @@ void ScenePlayer::mouseScrollEvent(MouseScrollEvent& event) {

}

Containers::Pointer<AbstractPlayer> createScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom) {
return Containers::Pointer<ScenePlayer>{Containers::InPlaceInit, application, uiToStealFontFrom};
Containers::Pointer<AbstractPlayer> createScenePlayer(Platform::ScreenedApplication& application, Ui::UserInterface& uiToStealFontFrom, const DebugTools::GLFrameProfiler::Values profilerValues) {
return Containers::Pointer<ScenePlayer>{Containers::InPlaceInit, application, uiToStealFontFrom, profilerValues};
}

}}

0 comments on commit 551cbc0

Please sign in to comment.