summaryrefslogtreecommitdiff
path: root/retrace
diff options
context:
space:
mode:
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]);
+ }
}
}
}