]> git.cworth.org Git - apitrace/blobdiff - common/trace_model.hpp
Rename trim::CallSet to trace::FastCallSet
[apitrace] / common / trace_model.hpp
index a74508efc5e0a0fc2411f9fe19b3e1aea070beda..93363219cdb271930104e35dfbecd3629da89251 100644 (file)
 
 
 #include <assert.h>
+#include <stdlib.h>
 
 #include <map>
 #include <vector>
-#include <iostream>
 
 
-namespace Trace {
+namespace trace {
+
+
+// Should match Call::no
+typedef unsigned CallNo;
 
 
 typedef unsigned Id;
@@ -60,13 +64,19 @@ struct StructSig {
 };
 
 
-struct EnumSig {
-    Id id;
+struct EnumValue {
     const char *name;
     signed long long value;
 };
 
 
+struct EnumSig {
+    Id id;
+    unsigned num_values;
+    const EnumValue *values;
+};
+
+
 struct BitmaskFlag {
     const char *name;
     unsigned long long value;
@@ -101,8 +111,6 @@ public:
     virtual const char *toString(void) const;
 
     const Value & operator[](size_t index) const;
-
-    void dump(std::ostream &os, bool color=true);
 };
 
 
@@ -173,7 +181,23 @@ public:
 class Float : public Value
 {
 public:
-    Float(double _value) : value(_value) {}
+    Float(float _value) : value(_value) {}
+
+    bool toBool(void) const;
+    signed long long toSInt(void) const;
+    unsigned long long toUInt(void) const;
+    virtual float toFloat(void) const;
+    virtual double toDouble(void) const;
+    void visit(Visitor &visitor);
+
+    float value;
+};
+
+
+class Double : public Value
+{
+public:
+    Double(double _value) : value(_value) {}
 
     bool toBool(void) const;
     signed long long toSInt(void) const;
@@ -200,19 +224,25 @@ public:
 };
 
 
-class Enum : public Value
+class Enum : public SInt
 {
 public:
-    Enum(const EnumSig *_sig) : sig(_sig) {}
+    Enum(const EnumSig *_sig, signed long long _value) : SInt(_value), sig(_sig) {}
 
-    bool toBool(void) const;
-    signed long long toSInt(void) const;
-    unsigned long long toUInt(void) const;
-    virtual float toFloat(void) const;
-    virtual double toDouble(void) const;
     void visit(Visitor &visitor);
 
     const EnumSig *sig;
+
+    const EnumValue *
+    lookup() {
+        // TODO: use a std::map
+        for (const EnumValue *it = sig->values; it != sig->values + sig->num_values; ++it) {
+            if (it->value == value) {
+                return it;
+            }
+        }
+        return NULL;
+    }
 };
 
 
@@ -251,6 +281,11 @@ public:
     void visit(Visitor &visitor);
 
     std::vector<Value *> values;
+
+    inline size_t
+    size(void) const {
+        return values.size();
+    }
 };
 
 
@@ -289,6 +324,35 @@ public:
 };
 
 
+class Repr : public Value
+{
+public:
+    Repr(Value *human, Value *machine) :
+        humanValue(human),
+        machineValue(machine)
+    {}
+
+    /** Human-readible value */
+    Value *humanValue;
+
+    /** Machine-readible value */
+    Value *machineValue;
+    
+    virtual bool toBool(void) const;
+    virtual signed long long toSInt(void) const;
+    virtual unsigned long long toUInt(void) const;
+    virtual float toFloat(void) const;
+    virtual double toDouble(void) const;
+
+    virtual void *toPointer(void) const;
+    virtual void *toPointer(bool bind);
+    virtual unsigned long long toUIntPtr(void) const;
+    virtual const char *toString(void) const;
+
+    void visit(Visitor &visitor);
+};
+
+
 class Visitor
 {
 public:
@@ -297,6 +361,7 @@ public:
     virtual void visit(SInt *);
     virtual void visit(UInt *);
     virtual void visit(Float *);
+    virtual void visit(Double *);
     virtual void visit(String *);
     virtual void visit(Enum *);
     virtual void visit(Bitmask *);
@@ -304,6 +369,7 @@ public:
     virtual void visit(Array *);
     virtual void visit(Blob *);
     virtual void visit(Pointer *);
+    virtual void visit(Repr *);
 
 protected:
     inline void _visit(Value *value) {
@@ -314,23 +380,107 @@ protected:
 };
 
 
-inline std::ostream & operator <<(std::ostream &os, Value *value) {
-    if (value) {
-        value->dump(os);
-    }
-    return os;
-}
+typedef unsigned CallFlags;
+
+/**
+ * Call flags.
+ *
+ * TODO: It might be better to to record some of these (but not all) into the
+ * trace file.
+ */
+enum {
+
+    /**
+     * Whether a call was really done by the application or not.
+     *
+     * This flag is set for fake calls -- calls not truly done by the application
+     * but emitted and recorded for completeness, to provide contextual information
+     * necessary for retracing, that would not be available through other ways.
+     *
+     * XXX: This one definetely needs to go into the trace file.
+     */
+    CALL_FLAG_FAKE                      = (1 << 0),
+
+    /**
+     * Whether this call should be retraced or ignored.
+     *
+     * This flag is set for calls which can't be safely replayed (due to incomplete
+     * information) or that have no sideffects.
+     *
+     * Some incomplete calls are unreproduceable, but not all.
+     */
+    CALL_FLAG_NON_REPRODUCIBLE         = (1 << 1),
+    
+    /**
+     * Whether this call has no side-effects, therefore don't need to be
+     * retraced.
+     *
+     * This flag is set for calls that merely query information which is not
+     * needed for posterior calls.
+     */
+    CALL_FLAG_NO_SIDE_EFFECTS            = (1 << 2),
+
+    /**
+     * Whether this call renders into the bound rendertargets.
+     */
+    CALL_FLAG_RENDER                    = (1 << 3),
+
+    /**
+     * Whether this call causes render target to be swapped.
+     *
+     * This does not mark frame termination by itself -- that's solely the
+     * responsibility of `endOfFrame` bit. 
+     *
+     * This mean that snapshots should be take prior to the call, and not
+     * after.
+     */
+    CALL_FLAG_SWAP_RENDERTARGET         = (1 << 4),
+        
+    /**
+     * Whether this call terminates a frame.
+     *
+     * XXX: This can't always be determined by the function name, so it should also
+     * go into the trace file eventually.
+     */
+    CALL_FLAG_END_FRAME                 = (1 << 5),
+
+    /**
+     * Whether this call is incomplete, i.e., it never returned.
+     */
+    CALL_FLAG_INCOMPLETE                = (1 << 6),
+
+    /**
+     * Whether this call is verbose (i.e., not usually interesting).
+     */
+    CALL_FLAG_VERBOSE                  = (1 << 7),
+};
+
+
+struct Arg
+{
+    Value *value;
+};
 
 
 class Call
 {
 public:
+    unsigned thread_id;
     unsigned no;
     const FunctionSig *sig;
-    std::vector<Value *> args;
+    std::vector<Arg> args;
     Value *ret;
 
-    Call(FunctionSig *_sig) : sig(_sig), args(_sig->num_args), ret(0) { }
+    CallFlags flags;
+
+    Call(const FunctionSig *_sig, const CallFlags &_flags, unsigned _thread_id) :
+        thread_id(_thread_id), 
+        sig(_sig), 
+        args(_sig->num_args), 
+        ret(0),
+        flags(_flags) {
+    }
+
     ~Call();
 
     inline const char * name(void) const {
@@ -339,19 +489,11 @@ public:
 
     inline Value & arg(unsigned index) {
         assert(index < args.size());
-        return *(args[index]);
+        return *(args[index].value);
     }
-
-    void dump(std::ostream &os, bool color=true);
 };
 
 
-inline std::ostream & operator <<(std::ostream &os, Call &call) {
-    call.dump(os);
-    return os;
-}
-
-
-} /* namespace Trace */
+} /* namespace trace */
 
 #endif /* _TRACE_MODEL_HPP_ */