diff options
Diffstat (limited to 'retrace')
-rw-r--r-- | retrace/daemon/gldispatch/glframe_glhelper.cpp | 9 | ||||
-rw-r--r-- | retrace/daemon/gldispatch/glframe_glhelper.hpp | 1 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace.cpp | 10 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace.hpp | 3 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_context.cpp | 25 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_context.hpp | 3 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_interface.hpp | 15 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.cpp | 169 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.hpp | 24 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_skeleton.cpp | 11 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_stub.cpp | 35 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_stub.hpp | 3 | ||||
-rw-r--r-- | retrace/daemon/playback.proto | 8 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_retrace_model.cpp | 2 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_state_model.cpp | 28 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_state_model.hpp | 2 | ||||
-rw-r--r-- | retrace/daemon/ui/qml/StateControl.qml | 10 |
17 files changed, 320 insertions, 38 deletions
diff --git a/retrace/daemon/gldispatch/glframe_glhelper.cpp b/retrace/daemon/gldispatch/glframe_glhelper.cpp index 74b728b8..aa2a4357 100644 --- a/retrace/daemon/gldispatch/glframe_glhelper.cpp +++ b/retrace/daemon/gldispatch/glframe_glhelper.cpp @@ -120,6 +120,7 @@ static void *pUniformMatrix4fv = NULL; static void *pUniformMatrix4x2fv = NULL; static void *pUniformMatrix4x3fv = NULL; static void *pFinish = NULL; +static void *pCullFace = NULL; } // namespace @@ -330,6 +331,8 @@ GlFunctions::Init(void *lookup_fn) { assert(pUniformMatrix4x3fv); pFinish = _GetProcAddress("glFinish"); assert(pFinish); + pCullFace = _GetProcAddress("glCullFace"); + assert(pCullFace); } GLuint @@ -950,3 +953,9 @@ GlFunctions::Finish() { typedef void (*FINISH)(); return ((FINISH)pFinish)(); } + +void +GlFunctions::CullFace(GLenum mode) { + typedef void (*CULLFACE)(GLenum mode); + return ((CULLFACE)pCullFace)(mode); +} diff --git a/retrace/daemon/gldispatch/glframe_glhelper.hpp b/retrace/daemon/gldispatch/glframe_glhelper.hpp index ec441266..6398881a 100644 --- a/retrace/daemon/gldispatch/glframe_glhelper.hpp +++ b/retrace/daemon/gldispatch/glframe_glhelper.hpp @@ -175,6 +175,7 @@ class GlFunctions { static void UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); static void Finish(); + static void CullFace(GLenum mode); private: GlFunctions(); diff --git a/retrace/daemon/glframe_retrace.cpp b/retrace/daemon/glframe_retrace.cpp index 73b00fdd..23a71adc 100644 --- a/retrace/daemon/glframe_retrace.cpp +++ b/retrace/daemon/glframe_retrace.cpp @@ -395,3 +395,13 @@ FrameRetrace::retraceState(const RenderSelection &selection, for (auto i : m_contexts) i->retraceState(selection, experimentCount, m_tracker, callback); } + +void +FrameRetrace::setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value) { + // reset to beginning of frame + parser->setBookmark(frame_start.start); + for (auto i : m_contexts) + i->setState(selection, item, value); +} diff --git a/retrace/daemon/glframe_retrace.hpp b/retrace/daemon/glframe_retrace.hpp index 336360a2..fc1e9d68 100644 --- a/retrace/daemon/glframe_retrace.hpp +++ b/retrace/daemon/glframe_retrace.hpp @@ -116,6 +116,9 @@ class FrameRetrace : public IFrameRetrace { void retraceState(const RenderSelection &selection, ExperimentId experimentCount, OnFrameRetrace *callback); + void setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value); private: // these are global diff --git a/retrace/daemon/glframe_retrace_context.cpp b/retrace/daemon/glframe_retrace_context.cpp index 6160858c..bcfbf03b 100644 --- a/retrace/daemon/glframe_retrace_context.cpp +++ b/retrace/daemon/glframe_retrace_context.cpp @@ -466,9 +466,9 @@ RetraceContext::retraceUniform(const RenderSelection &selection, for (auto r : m_renders) { if (isSelected(r.first, selection)) { // pass down the context that is needed to make the uniform callback - const RetraceRender::UniformCallbackContext c(selection.id, - experimentCount, - r.first, callback); + const RetraceRender::CallbackContext c(selection.id, + experimentCount, + r.first, callback); r.second->retrace(tracker, &c); } else { r.second->retrace(tracker); @@ -491,8 +491,23 @@ RetraceContext::retraceState(const RenderSelection &selection, const StateTrack &tracker, OnFrameRetrace *callback) { for (auto r : m_renders) { - r.second->retrace(tracker); + if (isSelected(r.first, selection)) { + const RetraceRender::CallbackContext c(selection.id, + experimentCount, + r.first, callback); + r.second->retrace(tracker, NULL, &c); + } else { + r.second->retrace(tracker); + } + } +} + +void +RetraceContext::setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value) { + for (auto r : m_renders) { if (isSelected(r.first, selection)) - r.second->onState(selection.id, experimentCount, r.first, callback); + r.second->setState(item, value); } } diff --git a/retrace/daemon/glframe_retrace_context.hpp b/retrace/daemon/glframe_retrace_context.hpp index bbbe7c89..e991677e 100644 --- a/retrace/daemon/glframe_retrace_context.hpp +++ b/retrace/daemon/glframe_retrace_context.hpp @@ -110,6 +110,9 @@ class RetraceContext { ExperimentId experimentCount, const StateTrack &tracker, OnFrameRetrace *callback); + void setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value); private: trace::AbstractParser *m_parser; diff --git a/retrace/daemon/glframe_retrace_interface.hpp b/retrace/daemon/glframe_retrace_interface.hpp index 59773d0e..8badec99 100644 --- a/retrace/daemon/glframe_retrace_interface.hpp +++ b/retrace/daemon/glframe_retrace_interface.hpp @@ -93,6 +93,7 @@ class RenderId { bool operator>=(const RenderId &o) const { return value >= o.value; } bool operator<=(const RenderId &o) const { return value <= o.value; } bool operator==(const RenderId &o) const { return value == o.value; } + bool operator!=(const RenderId &o) const { return value != o.value; } static const uint32_t INVALID_RENDER = (-1 & ~ID_PREFIX_MASK); private: @@ -192,6 +193,7 @@ struct MetricSeries { struct RenderSequence { RenderSequence(RenderId b, RenderId e) : begin(b), end(e) {} + RenderSequence(const RenderSequence &o) : begin(o.begin), end(o.end) {} RenderSequence() {} RenderId begin; RenderId end; @@ -202,6 +204,9 @@ typedef std::vector<RenderSequence> RenderSeries; struct RenderSelection { SelectionId id; RenderSeries series; + RenderSelection() {} + RenderSelection(const RenderSelection &o) + : id(o.id), series(o.series) {} void clear() { series.clear(); } void push_back(int begin, int end) { series.push_back(RenderSequence(RenderId(begin), RenderId(end))); @@ -268,6 +273,13 @@ struct StateKey { StateKey() : name(INVALID_NAME), index(0) {} StateKey(StateItem n, int i) : name(n), index(i) {} + bool operator<(const StateKey &o) const { + if (name < o.name) + return true; + if (name > o.name) + return false; + return index < o.index; + } }; class OnFrameRetrace { @@ -376,6 +388,9 @@ class IFrameRetrace { virtual void retraceState(const RenderSelection &selection, ExperimentId experimentCount, OnFrameRetrace *callback) = 0; + virtual void setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value) = 0; }; class FrameState { diff --git a/retrace/daemon/glframe_retrace_render.cpp b/retrace/daemon/glframe_retrace_render.cpp index 4251d568..c39069d4 100644 --- a/retrace/daemon/glframe_retrace_render.cpp +++ b/retrace/daemon/glframe_retrace_render.cpp @@ -50,6 +50,9 @@ using glretrace::StateTrack; using glretrace::RenderTargetType; using glretrace::RenderId; using glretrace::OnFrameRetrace; +using glretrace::CULL_FACE; +using glretrace::CULL_FACE_MODE; +using glretrace::state_name_to_enum; static const std::string simple_fs = "void main(void) {\n" @@ -147,17 +150,130 @@ class RetraceRender::UniformOverride { std::map<UniformKey, std::string> m_uniform_overrides; }; +uint32_t +glretrace::state_name_to_enum(const std::string &value) { + static const std::map<std::string, uint32_t> names { + {"CULL_FACE", CULL_FACE}, + {"CULL_FACE_MODE", CULL_FACE_MODE} + }; + return names.find(value)->second; +} + +uint32_t value_to_int(const std::string &value) { + static const std::map<std::string, uint32_t> lookup = { + {"GL_FRONT", GL_FRONT}, + {"GL_BACK", GL_BACK}, + {"GL_FRONT_AND_BACK", GL_FRONT_AND_BACK}, + {"true", 1}, + {"false", 0} + }; + return lookup.find(value)->second; +} + +class RetraceRender::StateOverride { + public: + StateOverride() {} + void setState(const StateKey &item, + const std::string &value) { + m_overrides[item] = value_to_int(value); + } + void saveState(); + void overrideState() const; + void restoreState() const; + + private: + struct Key { + uint32_t item; + uint32_t offset; + Key(uint32_t i, uint32_t o) : item(i), offset(o) {} + bool operator<(const Key &o) const { + if (item < o.item) + return true; + if (item > o.item) + return false; + return offset < o.offset; + } + }; + typedef std::map<StateKey, uint32_t> KeyMap; + void enact_state(const KeyMap &m) const; + KeyMap m_overrides; + KeyMap m_saved_state; +}; + +void +RetraceRender::StateOverride::saveState() { + for (auto i : m_overrides) { + if (m_saved_state.find(i.first) != m_saved_state.end()) + continue; + switch (i.first.name) { + case CULL_FACE: + assert(GL::GetError() == GL_NO_ERROR); + m_saved_state[i.first] = GlFunctions::IsEnabled(GL_CULL_FACE); + assert(GL::GetError() == GL_NO_ERROR); + break; + case CULL_FACE_MODE: { + assert(GL::GetError() == GL_NO_ERROR); + GLint cull; + GlFunctions::GetIntegerv(GL_CULL_FACE_MODE, &cull); + assert(GL::GetError() == GL_NO_ERROR); + m_saved_state[i.first] = cull; + break; + } + case INVALID_NAME: + assert(false); + break; + } + } +} + +void +RetraceRender::StateOverride::overrideState() const { + enact_state(m_overrides); +} + +void +RetraceRender::StateOverride::restoreState() const { + enact_state(m_saved_state); +} + +void +RetraceRender::StateOverride::enact_state(const KeyMap &m) const { + for (auto i : m) { + switch (i.first.name) { + case CULL_FACE: + assert(GL::GetError() == GL_NO_ERROR); + if (i.second) + GlFunctions::Enable(GL_CULL_FACE); + else + GlFunctions::Disable(GL_CULL_FACE); + assert(GL::GetError() == GL_NO_ERROR); + break; + case CULL_FACE_MODE: { + assert(GL::GetError() == GL_NO_ERROR); + GlFunctions::CullFace(i.second); + assert(GL::GetError() == GL_NO_ERROR); + break; + } + case INVALID_NAME: + assert(false); + break; + } + } +} + RetraceRender::RetraceRender(trace::AbstractParser *parser, retrace::Retracer *retracer, - StateTrack *tracker) : m_parser(parser), - m_retracer(retracer), - m_rt_program(-1), - m_retrace_program(-1), - m_end_of_frame(false), - m_highlight_rt(false), - m_changes_context(false), - m_disabled(false), - m_simple_shader(false) { + StateTrack *tracker) + : m_parser(parser), + m_retracer(retracer), + m_rt_program(-1), + m_retrace_program(-1), + m_end_of_frame(false), + m_highlight_rt(false), + m_changes_context(false), + m_disabled(false), + m_simple_shader(false), + m_state_override(new StateOverride()) { m_parser->getBookmark(m_bookmark.start); trace::Call *call = NULL; std::stringstream call_stream; @@ -220,6 +336,7 @@ RetraceRender::RetraceRender(trace::AbstractParser *parser, RetraceRender::~RetraceRender() { delete m_uniform_override; + delete m_state_override; } void @@ -258,6 +375,8 @@ RetraceRender::retraceRenderTarget(const StateTrack &tracker, } m_uniform_override->overrideUniforms(); + m_state_override->saveState(); + m_state_override->overrideState(); // retrace the final render trace::Call *call = m_parser->parse_call(); @@ -267,6 +386,7 @@ RetraceRender::retraceRenderTarget(const StateTrack &tracker, delete(call); m_uniform_override->restoreUniforms(); + m_state_override->restoreState(); if (blend_enabled) GlFunctions::Enable(GL_BLEND); @@ -320,7 +440,8 @@ RetraceRender::retrace(StateTrack *tracker) const { void RetraceRender::retrace(const StateTrack &tracker, - const UniformCallbackContext *callback) const { + const CallbackContext *uniform_context, + const CallbackContext *state_context) const { // check that the parser is in correct state trace::ParseBookmark bm; m_parser->getBookmark(bm); @@ -348,6 +469,8 @@ RetraceRender::retrace(const StateTrack &tracker, } m_uniform_override->overrideUniforms(); + m_state_override->saveState(); + m_state_override->overrideState(); // retrace the final render trace::Call *call = m_parser->parse_call(); @@ -356,12 +479,18 @@ RetraceRender::retrace(const StateTrack &tracker, m_retracer->retrace(*call); delete(call); - if (callback) { + if (uniform_context) { Uniforms u; - u.onUniform(callback->selection, callback->experiment, - callback->render, callback->callback); + u.onUniform(uniform_context->selection, uniform_context->experiment, + uniform_context->render, uniform_context->callback); } + if (state_context) { + onState(state_context->selection, state_context->experiment, + state_context->render, state_context->callback); + } + + m_state_override->restoreState(); m_uniform_override->restoreUniforms(); StateTrack::useProgramGL(m_original_program); @@ -426,8 +555,8 @@ RetraceRender::setUniform(const std::string &name, int index, m_uniform_override->setUniform(name, index, data); } -std::string cull_to_string(GLint cull) { - switch (cull) { +std::string value_to_string(GLint value) { + switch (value) { case GL_FRONT: return std::string("GL_FRONT"); case GL_BACK: @@ -443,7 +572,7 @@ void RetraceRender::onState(SelectionId selId, ExperimentId experimentCount, RenderId renderId, - OnFrameRetrace *callback) { + OnFrameRetrace *callback) const { { GL::GetError(); GLboolean cull_enabled = GlFunctions::IsEnabled(GL_CULL_FACE); @@ -460,7 +589,7 @@ RetraceRender::onState(SelectionId selId, GlFunctions::GetIntegerv(GL_CULL_FACE_MODE, &cull); GLenum e = GL::GetError(); if (e == GL_NO_ERROR) { - const std::string cull_str = cull_to_string(cull); + const std::string cull_str = value_to_string(cull); if (cull_str.size() > 0) { callback->onState(selId, experimentCount, renderId, StateKey(CULL_FACE_MODE, 0), cull_str); @@ -468,3 +597,9 @@ RetraceRender::onState(SelectionId selId, } } } + +void +RetraceRender::setState(const StateKey &item, + const std::string &value) { + m_state_override->setState(item, value); +} diff --git a/retrace/daemon/glframe_retrace_render.hpp b/retrace/daemon/glframe_retrace_render.hpp index 7fd2066a..0b7318ff 100644 --- a/retrace/daemon/glframe_retrace_render.hpp +++ b/retrace/daemon/glframe_retrace_render.hpp @@ -49,6 +49,8 @@ class ExperimentId; class MetricId; class PerfMetrics; +uint32_t state_name_to_enum(const std::string &value); + class RetraceRender { public: RetraceRender(trace::AbstractParser *parser, @@ -56,9 +58,9 @@ class RetraceRender { StateTrack *tracker); ~RetraceRender(); - struct UniformCallbackContext { - UniformCallbackContext(SelectionId s, ExperimentId e, - RenderId r, OnFrameRetrace *c) + struct CallbackContext { + CallbackContext(SelectionId s, ExperimentId e, + RenderId r, OnFrameRetrace *c) : selection(s), experiment(e), render(r), callback(c) {} SelectionId selection; ExperimentId experiment; @@ -70,7 +72,8 @@ class RetraceRender { RenderTargetType type) const; void retrace(StateTrack *tracker) const; void retrace(const StateTrack &tracker, - const UniformCallbackContext *c = NULL) const; + const CallbackContext *uniform_context = NULL, + const CallbackContext *state_context = NULL) const; bool endsFrame() const { return m_end_of_frame; } bool replaceShaders(StateTrack *tracker, const std::string &vs, @@ -88,10 +91,9 @@ class RetraceRender { OnFrameRetrace *callback); void setUniform(const std::string &name, int index, const std::string &data); - void onState(SelectionId selId, - ExperimentId experimentCount, - RenderId renderId, - OnFrameRetrace *callback); + void setState(const StateKey &item, + const std::string &value); + static bool isRender(const trace::Call &c); static bool changesContext(const trace::Call &c); static bool endsFrame(const trace::Call &c); @@ -99,6 +101,10 @@ class RetraceRender { private: void overrideUniforms() const; + void onState(SelectionId selId, + ExperimentId experimentCount, + RenderId renderId, + OnFrameRetrace *callback) const; trace::AbstractParser *m_parser; retrace::Retracer *m_retracer; @@ -116,6 +122,8 @@ class RetraceRender { bool m_disabled, m_simple_shader; class UniformOverride; UniformOverride *m_uniform_override; + class StateOverride; + StateOverride *m_state_override; }; } // namespace glretrace diff --git a/retrace/daemon/glframe_retrace_skeleton.cpp b/retrace/daemon/glframe_retrace_skeleton.cpp index 46334f49..a66f9e20 100644 --- a/retrace/daemon/glframe_retrace_skeleton.cpp +++ b/retrace/daemon/glframe_retrace_skeleton.cpp @@ -407,6 +407,17 @@ FrameRetraceSkeleton::Run() { writeResponse(m_socket, proto_response, &m_buf); break; } + case ApiTrace::SET_STATE_REQUEST: + { + assert(request.has_set_state()); + auto state = request.set_state(); + RenderSelection selection; + makeRenderSelection(state.selection(), &selection); + glretrace::StateKey k((glretrace::StateItem)state.item().name(), + state.item().index()); + m_frame->setState(selection, k, state.value()); + break; + } } } } diff --git a/retrace/daemon/glframe_retrace_stub.cpp b/retrace/daemon/glframe_retrace_stub.cpp index 7c39f7da..8199f999 100644 --- a/retrace/daemon/glframe_retrace_stub.cpp +++ b/retrace/daemon/glframe_retrace_stub.cpp @@ -63,6 +63,7 @@ using glretrace::Semaphore; using glretrace::Severity; using glretrace::ShaderAssembly; using glretrace::Socket; +using glretrace::StateKey; using glretrace::Thread; using glretrace::WARN; using google::protobuf::io::ArrayInputStream; @@ -70,6 +71,7 @@ using google::protobuf::io::ArrayOutputStream; using google::protobuf::io::CodedInputStream; using google::protobuf::io::CodedOutputStream; using glretrace::UniformType; + namespace { class RetraceSocket { @@ -1013,6 +1015,32 @@ class StateRequest : public IRetraceRequest { OnFrameRetrace *m_callback; }; +class SetStateRequest : public IRetraceRequest { + public: + SetStateRequest(const RenderSelection &selection, + StateKey item, + const std::string &value) + : m_selection(selection), + m_item(item), + m_value(value) {} + void retrace(RetraceSocket *sock) { + RetraceRequest msg; + msg.set_requesttype(ApiTrace::SET_STATE_REQUEST); + auto req = msg.mutable_set_state(); + auto item = req->mutable_item(); + item->set_name(static_cast<ApiTrace::StateItem>(m_item.name)); + item->set_index(m_item.index); + auto selection = req->mutable_selection(); + makeRenderSelection(m_selection, selection); + req->set_value(m_value); + sock->request(msg); + } + private: + const RenderSelection m_selection; + const StateKey m_item; + const std::string m_value; +}; + class NullRequest : public IRetraceRequest { public: // to pump the thread, and force it to stop @@ -1289,3 +1317,10 @@ FrameRetraceStub::retraceState(const RenderSelection &selection, &m_mutex, selection, callback)); } + +void +FrameRetraceStub::setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value) { + m_thread->push(new SetStateRequest(selection, item, value)); +} diff --git a/retrace/daemon/glframe_retrace_stub.hpp b/retrace/daemon/glframe_retrace_stub.hpp index ac34f771..1c7b9c26 100644 --- a/retrace/daemon/glframe_retrace_stub.hpp +++ b/retrace/daemon/glframe_retrace_stub.hpp @@ -96,6 +96,9 @@ class FrameRetraceStub : public IFrameRetrace { virtual void retraceState(const RenderSelection &selection, ExperimentId experimentCount, OnFrameRetrace *callback); + virtual void setState(const RenderSelection &selection, + const StateKey &item, + const std::string &value); private: mutable std::mutex m_mutex; diff --git a/retrace/daemon/playback.proto b/retrace/daemon/playback.proto index a0369af0..b21d76b8 100644 --- a/retrace/daemon/playback.proto +++ b/retrace/daemon/playback.proto @@ -20,6 +20,7 @@ enum RequestType { UNIFORM_REQUEST = 11; SET_UNIFORM_REQUEST = 12; STATE_REQUEST = 13; + SET_STATE_REQUEST = 14; }; message OpenFileRequest { @@ -249,6 +250,12 @@ message StateResponse { required string value = 5; } +message SetStateRequest { + required RenderSelection selection = 1; + required StateKey item = 2; + required string value = 3; +} + message RetraceRequest { required RequestType requestType = 1; optional RenderTargetRequest renderTarget = 2; @@ -264,6 +271,7 @@ message RetraceRequest { optional UniformRequest uniform = 12; optional SetUniformRequest set_uniform = 13; optional StateRequest state = 14; + optional SetStateRequest set_state = 15; } message RetraceResponse { diff --git a/retrace/daemon/ui/glframe_retrace_model.cpp b/retrace/daemon/ui/glframe_retrace_model.cpp index 1f00c148..70288111 100644 --- a/retrace/daemon/ui/glframe_retrace_model.cpp +++ b/retrace/daemon/ui/glframe_retrace_model.cpp @@ -422,6 +422,8 @@ FrameRetraceModel::setSelection(QSelection *s) { &m_shaders, &QRenderShadersList::onExperiment); connect(m_uniforms, &QUniformsModel::uniformExperiment, s, &QSelection::experiment); + connect(m_stateModel, &QStateModel::stateExperiment, + s, &QSelection::experiment); } void diff --git a/retrace/daemon/ui/glframe_state_model.cpp b/retrace/daemon/ui/glframe_state_model.cpp index 6eb943e8..53f99b2b 100644 --- a/retrace/daemon/ui/glframe_state_model.cpp +++ b/retrace/daemon/ui/glframe_state_model.cpp @@ -31,10 +31,12 @@ #include <vector> #include "glframe_os.hpp" +#include "glframe_retrace_render.hpp" using glretrace::QStateModel; using glretrace::QStateValue; using glretrace::StateItem; +using glretrace::state_name_to_enum; QStateValue::QStateValue(const std::string &_name, const std::vector<std::string> &_choices) @@ -48,10 +50,9 @@ QStateValue::insert(int index, const std::string &value) { int value_index = 0; QVariant qvalue(value.c_str()); for (auto c : m_choices) { - if (qvalue == c) { + if (qvalue == c) break; ++value_index; - } } // value must be found assert(value_index < m_choices.size()); @@ -66,7 +67,7 @@ QStateValue::insert(int index, const std::string &value) { QStateModel::QStateModel() {} -QStateModel::QStateModel(IFrameRetrace *retrace) {} +QStateModel::QStateModel(IFrameRetrace *retrace) : m_retrace(retrace) {} QStateModel::~QStateModel() {} @@ -119,6 +120,7 @@ QStateModel::clear() { for (auto i : m_state_by_name) delete i.second; m_state_by_name.clear(); + m_renders.clear(); } } @@ -151,6 +153,8 @@ void QStateModel::onState(SelectionId selectionCount, assert(selectionCount == m_sel_count); assert(experimentCount == m_experiment_count); } + if (m_renders.empty() || renderId != m_renders.back()) + m_renders.push_back(renderId); const auto name = state_name_to_string(item.name); auto state_value = m_state_by_name.find(name); if (state_value == m_state_by_name.end()) { @@ -166,6 +170,22 @@ void QStateModel::setState(const QString &name, const int index, const QString &value) { - assert(false); + RenderSelection sel; + sel.id = m_sel_count; + auto r = m_renders.begin(); + sel.series.push_back(RenderSequence(*r, RenderId(r->index() + 1))); + ++r; + while (r != m_renders.end()) { + if (*r == sel.series.back().end) + ++sel.series.back().end; + else + sel.series.push_back(RenderSequence(*r, RenderId(r->index() + 1))); + ++r; + } + + StateItem i = static_cast<StateItem>(state_name_to_enum(name.toStdString())); + StateKey key(i, index); + m_retrace->setState(sel, key, value.toStdString()); + emit stateExperiment(); } diff --git a/retrace/daemon/ui/glframe_state_model.hpp b/retrace/daemon/ui/glframe_state_model.hpp index 7dd3b6ef..0532e017 100644 --- a/retrace/daemon/ui/glframe_state_model.hpp +++ b/retrace/daemon/ui/glframe_state_model.hpp @@ -87,7 +87,6 @@ class QStateModel : public QObject, const QString &value); signals: - // after index is selected, uniform data is available void stateExperiment(); void stateChanged(); @@ -99,6 +98,7 @@ class QStateModel : public QObject, std::map<std::string, QStateValue*> m_state_by_name; QList<QStateValue*> m_states; std::vector<QStateValue*> m_for_deletion; + std::vector<RenderId> m_renders; mutable std::mutex m_protect; }; diff --git a/retrace/daemon/ui/qml/StateControl.qml b/retrace/daemon/ui/qml/StateControl.qml index b31089d0..c54f8b40 100644 --- a/retrace/daemon/ui/qml/StateControl.qml +++ b/retrace/daemon/ui/qml/StateControl.qml @@ -51,15 +51,19 @@ Item { id: stateGrid anchors.left: parent.left anchors.right: parent.right - // property var choice_width: getWidth(modelData.choices) Repeater { model: modelData.values property var choices: modelData.choices + property var name: modelData.name ComboBoxFitContents { model: choices + property int stateIndex : index currentIndex: modelData - // currentText: modelData - // border.width: 1 + onActivated: { + stateModel.setState(name, + stateIndex, + choices[currentIndex]); + } } } } |