summaryrefslogtreecommitdiff
path: root/retrace
diff options
context:
space:
mode:
authorMark Janes <mark.a.janes@intel.com>2017-10-04 11:51:10 -0700
committerMark Janes <mark.a.janes@intel.com>2017-11-26 19:14:25 -0800
commit31e1c6032069d0bf0ffad01b091810cb769c75f9 (patch)
tree5616c7ac0fe580e00b549701c0e3156545c3f046 /retrace
parent4df6b1014db3eaf87c3589a88cc73d43d0fb02e9 (diff)
State: Allow the user to override state
Initial implementation provides editable values in the UI, which send commands to change state during rendering. The existing state values need to be recorded at the time they are overridden, so they can be restored for subsequent renders.
Diffstat (limited to 'retrace')
-rw-r--r--retrace/daemon/gldispatch/glframe_glhelper.cpp9
-rw-r--r--retrace/daemon/gldispatch/glframe_glhelper.hpp1
-rw-r--r--retrace/daemon/glframe_retrace.cpp10
-rw-r--r--retrace/daemon/glframe_retrace.hpp3
-rw-r--r--retrace/daemon/glframe_retrace_context.cpp25
-rw-r--r--retrace/daemon/glframe_retrace_context.hpp3
-rw-r--r--retrace/daemon/glframe_retrace_interface.hpp15
-rw-r--r--retrace/daemon/glframe_retrace_render.cpp169
-rw-r--r--retrace/daemon/glframe_retrace_render.hpp24
-rw-r--r--retrace/daemon/glframe_retrace_skeleton.cpp11
-rw-r--r--retrace/daemon/glframe_retrace_stub.cpp35
-rw-r--r--retrace/daemon/glframe_retrace_stub.hpp3
-rw-r--r--retrace/daemon/playback.proto8
-rw-r--r--retrace/daemon/ui/glframe_retrace_model.cpp2
-rw-r--r--retrace/daemon/ui/glframe_state_model.cpp28
-rw-r--r--retrace/daemon/ui/glframe_state_model.hpp2
-rw-r--r--retrace/daemon/ui/qml/StateControl.qml10
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]);
+ }
}
}
}