add_definitions (${PNG_DEFINITIONS})
link_libraries (${PNG_LIBRARIES})
+if (MSVC)
+ add_subdirectory (thirdparty/getopt EXCLUDE_FROM_ALL)
+ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/getopt)
+ set (GETOPT_LIBRARIES getopt_bundled)
+endif ()
+
# The Qt website provides binaries for Windows and MacOSX, and they are
# automatically found by cmake without any manual intervention. The situation
# for QJSON is substantially different: there are no binaries for QJSON
endif ()
add_library (common STATIC
+ common/trace_callset.cpp
common/trace_dump.cpp
common/trace_file.cpp
common/trace_file_read.cpp
===========================
+Call sets
+---------
+
+Several tools take `CALLSET` arguments, e.g:
+
+ apitrace dump --calls CALLSET foo.trace
+ glretrace -S CALLSET foo.trace
+
+The call syntax is very flexible. Here are a few examples:
+
+ * `4` one call
+
+ * `1,2,4,5` set of calls
+
+ * `"1 2 4 5"` set of calls (commas are optional and can be replaced with whitespace)
+
+ * `1-100/2` calls 1, 3, 5, ..., 99
+
+ * `1-1000/draw` all draw calls between 1 and 1000
+
+ * `1-1000/fbo` all fbo changes between calls 1 and 1000
+
+ * `frame` all calls at end of frames
+
+ * `@foo.txt` read call numbers from `foo.txt`, using the same syntax as above
+
+
+
Tracing manually
----------------
cli_diff_images.cpp
cli_dump.cpp
cli_pager.cpp
+ cli_pickle.cpp
cli_repack.cpp
cli_trace.cpp
+ cli_trim.cpp
+)
+
+target_link_libraries (apitrace
+ ${GETOPT_LIBRARIES}
)
install (TARGETS apitrace RUNTIME DESTINATION bin)
extern const Command diff_state_command;
extern const Command diff_images_command;
extern const Command dump_command;
+extern const Command pickle_command;
extern const Command repack_command;
extern const Command trace_command;
+extern const Command trim_command;
#endif /* _APITRACE_CLI_HPP_ */
{
int i;
- for (i = 0; i < argc; ++i) {
+ for (i = 1; i < argc; ++i) {
const char *arg = argv[i];
if (arg[0] != '-') {
return 1;
}
- char **args = new char* [argc + 2];
+ char **args = new char* [argc + 1];
args[0] = (char *) command.str();
- for (i = 0; i < argc; i++) {
- args[i + 1] = argv[i];
+ for (i = 1; i < argc; i++) {
+ args[i] = argv[i];
}
- args[i + 1] = NULL;
+ args[argc] = NULL;
ret = os::execute(args);
{
int i;
- for (i = 0; i < argc; ++i) {
+ for (i = 1; i < argc; ++i) {
const char *arg = argv[i];
if (arg[0] != '-') {
#include <string.h>
+#include <limits.h> // for CHAR_MAX
+#include <getopt.h>
#include "cli.hpp"
#include "cli_pager.hpp"
#include "trace_parser.hpp"
#include "trace_dump.hpp"
+#include "trace_callset.hpp"
enum ColorOption {
static bool verbose = false;
+static trace::CallSet calls(trace::FREQUENCY_ALL);
+
static const char *synopsis = "Dump given trace(s) to standard output.";
static void
usage(void)
{
std::cout
- << "usage: apitrace dump [OPTIONS] <trace-file>...\n"
+ << "usage: apitrace dump [OPTIONS] TRACE_FILE...\n"
<< synopsis << "\n"
"\n"
- " -v, --verbose verbose output\n"
- " --color=<WHEN>\n"
- " --colour=<WHEN> Colored syntax highlighting\n"
- " WHEN is 'auto', 'always', or 'never'\n"
- " --no-arg-names Don't dump argument names\n"
- " --thread-ids Dump thread ids\n"
+ " -h, --help show this help message and exit\n"
+ " -v, --verbose verbose output\n"
+ " --calls=CALLSET only dump specified calls\n"
+ " --color[=WHEN]\n"
+ " --colour[=WHEN] colored syntax highlighting\n"
+ " WHEN is 'auto', 'always', or 'never'\n"
+ " --arg-names[=BOOL] dump argument names [default: yes]\n"
+ " --thread-ids=[=BOOL] dump thread ids [default: no]\n"
+ "\n"
;
}
+enum {
+ CALLS_OPT = CHAR_MAX + 1,
+ COLOR_OPT,
+ ARG_NAMES_OPT,
+ THREAD_IDS_OPT,
+};
+
+const static char *
+shortOptions = "hv";
+
+const static struct option
+longOptions[] = {
+ {"help", no_argument, 0, 'h'},
+ {"verbose", no_argument, 0, 'v'},
+ {"calls", required_argument, 0, CALLS_OPT},
+ {"colour", optional_argument, 0, COLOR_OPT},
+ {"color", optional_argument, 0, COLOR_OPT},
+ {"arg-names", optional_argument, 0, ARG_NAMES_OPT},
+ {"thread-ids", optional_argument, 0, THREAD_IDS_OPT},
+ {0, 0, 0, 0}
+};
+
+static bool
+boolOption(const char *option, bool default_ = true) {
+ if (!option) {
+ return default_;
+ }
+ if (strcmp(option, "0") == 0 ||
+ strcmp(option, "no") == 0 ||
+ strcmp(option, "false") == 0) {
+ return false;
+ }
+ if (strcmp(option, "0") == 0 ||
+ strcmp(option, "yes") == 0 ||
+ strcmp(option, "true") == 0) {
+ return true;
+ }
+ std::cerr << "error: unexpected bool " << option << "\n";
+ return default_;
+}
+
static int
command(int argc, char *argv[])
{
trace::DumpFlags dumpFlags = 0;
bool dumpThreadIds = false;
-
- int i;
-
- for (i = 0; i < argc; ++i) {
- const char *arg = argv[i];
-
- if (arg[0] != '-') {
- break;
- }
-
- if (!strcmp(arg, "--")) {
- break;
- } else if (!strcmp(arg, "--help")) {
+
+ int opt;
+ while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
+ switch (opt) {
+ case 'h':
usage();
return 0;
- } else if (strcmp(arg, "-v") == 0 ||
- strcmp(arg, "--verbose") == 0) {
+ case 'v':
verbose = true;
- } else if (!strcmp(arg, "--color=auto") ||
- !strcmp(arg, "--colour=auto")) {
- color = COLOR_OPTION_AUTO;
- } else if (!strcmp(arg, "--color") ||
- !strcmp(arg, "--colour") ||
- !strcmp(arg, "--color=always") ||
- !strcmp(arg, "--colour=always")) {
- color = COLOR_OPTION_ALWAYS;
- } else if (!strcmp(arg, "--color=never") ||
- !strcmp(arg, "--colour=never") ||
- !strcmp(arg, "--no-color") ||
- !strcmp(arg, "--no-colour")) {
- color = COLOR_OPTION_NEVER;
- } else if (!strcmp(arg, "--no-arg-names")) {
- dumpFlags |= trace::DUMP_FLAG_NO_ARG_NAMES;
- } else if (!strcmp(arg, "--thread-ids")) {
- dumpThreadIds = true;
- } else {
- std::cerr << "error: unknown option " << arg << "\n";
+ break;
+ case CALLS_OPT:
+ calls = trace::CallSet(optarg);
+ break;
+ case COLOR_OPT:
+ if (!optarg ||
+ !strcmp(optarg, "always")) {
+ color = COLOR_OPTION_ALWAYS;
+ } else if (!strcmp(optarg, "auto")) {
+ color = COLOR_OPTION_AUTO;
+ } else if (!strcmp(optarg, "never")) {
+ color = COLOR_OPTION_NEVER;
+ } else {
+ std::cerr << "error: unknown color argument " << optarg << "\n";
+ return 1;
+ }
+ break;
+ case ARG_NAMES_OPT:
+ if (boolOption(optarg)) {
+ dumpFlags &= ~trace::DUMP_FLAG_NO_ARG_NAMES;
+ } else {
+ dumpFlags |= trace::DUMP_FLAG_NO_ARG_NAMES;
+ }
+ break;
+ case THREAD_IDS_OPT:
+ dumpThreadIds = boolOption(optarg);
+ break;
+ default:
+ std::cerr << "error: unexpected option `" << opt << "`\n";
usage();
return 1;
}
dumpFlags |= trace::DUMP_FLAG_NO_COLOR;
}
- for (; i < argc; ++i) {
+ for (int i = optind; i < argc; ++i) {
trace::Parser p;
if (!p.open(argv[i])) {
trace::Call *call;
while ((call = p.parse_call())) {
- if (verbose ||
- !(call->flags & trace::CALL_FLAG_VERBOSE)) {
- if (dumpThreadIds) {
- std::cout << std::hex << call->thread_id << std::dec << " ";
+ if (calls.contains(*call)) {
+ if (verbose ||
+ !(call->flags & trace::CALL_FLAG_VERBOSE)) {
+ if (dumpThreadIds) {
+ std::cout << std::hex << call->thread_id << std::dec << " ";
+ }
+ trace::dump(*call, std::cout, dumpFlags);
}
- trace::dump(*call, std::cout, dumpFlags);
}
delete call;
}
&diff_state_command,
&diff_images_command,
&dump_command,
+ &pickle_command,
&repack_command,
&trace_command,
+ &trim_command,
&help_command
};
const Command *command;
int i;
- if (argc != 1) {
+ if (argc != 2) {
help_usage();
return 0;
}
- char *command_name = argv[0];
+ char *command_name = argv[1];
for (i = 0; i < ARRAY_SIZE(commands); i++) {
command = commands[i];
return 1;
}
- command_name = argv[i++];
+ command_name = argv[i];
argc -= i;
argv = &argv[i];
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <string.h>
+
+#ifdef _WIN32
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#include "pickle.hpp"
+
+#include "cli.hpp"
+#include "cli_pager.hpp"
+
+#include "trace_parser.hpp"
+#include "trace_model.hpp"
+#include "trace_callset.hpp"
+
+
+using namespace trace;
+
+
+class PickleVisitor : public trace::Visitor
+{
+protected:
+ PickleWriter &writer;
+
+public:
+ PickleVisitor(PickleWriter &_writer) :
+ writer(_writer) {
+ }
+
+ void visit(Null *node) {
+ writer.writeInt(0);
+ }
+
+ void visit(Bool *node) {
+ writer.writeBool(node->value);
+ }
+
+ void visit(SInt *node) {
+ writer.writeInt(node->value);
+ }
+
+ void visit(UInt *node) {
+ writer.writeInt(node->value);
+ }
+
+ void visit(Float *node) {
+ writer.writeFloat(node->value);
+ }
+
+ void visit(Double *node) {
+ writer.writeFloat(node->value);
+ }
+
+ void visit(String *node) {
+ writer.writeString(node->value);
+ }
+
+ void visit(Enum *node) {
+ // TODO: keep symbolic name
+ writer.writeInt(node->value);
+ }
+
+ void visit(Bitmask *node) {
+ // TODO: keep symbolic name
+ writer.writeInt(node->value);
+ }
+
+ void visit(Struct *node) {
+ writer.beginDict();
+ for (unsigned i = 0; i < node->sig->num_members; ++i) {
+ writer.beginItem(node->sig->member_names[i]);
+ _visit(node->members[i]);
+ writer.endItem();
+ }
+ writer.endDict();
+ }
+
+ void visit(Array *node) {
+ writer.beginList();
+ for (std::vector<Value *>::iterator it = node->values.begin(); it != node->values.end(); ++it) {
+ _visit(*it);
+ }
+ writer.endList();
+ }
+
+ void visit(Blob *node) {
+ writer.writeString((const char *)node->buf, node->size);
+ }
+
+ void visit(Pointer *node) {
+ writer.writeInt(node->value);
+ }
+
+ void visit(Call *call) {
+ writer.beginTuple();
+
+ writer.writeInt(call->no);
+
+ writer.writeString(call->name());
+
+ writer.beginList();
+ for (unsigned i = 0; i < call->args.size(); ++i) {
+ if (call->args[i].value) {
+ _visit(call->args[i].value);
+ } else {
+ writer.writeNone();
+ }
+ }
+ writer.endList();
+
+ if (call->ret) {
+ _visit(call->ret);
+ } else {
+ writer.writeNone();
+ }
+
+ writer.endTuple();
+ }
+};
+
+
+static trace::CallSet calls(trace::FREQUENCY_ALL);
+
+static const char *synopsis = "Pickle given trace(s) to standard output.";
+
+static void
+usage(void)
+{
+ std::cout
+ << "usage: apitrace pickle [OPTIONS] <trace-file>...\n"
+ << synopsis << "\n"
+ "\n"
+ " --calls <CALLSET> Only pickle specified calls\n"
+ ;
+}
+
+static int
+command(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc;) {
+ const char *arg = argv[i];
+
+ if (arg[0] != '-') {
+ break;
+ }
+
+ ++i;
+
+ if (!strcmp(arg, "--")) {
+ break;
+ } else if (!strcmp(arg, "--help")) {
+ usage();
+ return 0;
+ } else if (!strcmp(arg, "--calls")) {
+ calls = trace::CallSet(argv[i++]);
+ } else {
+ std::cerr << "error: unknown option " << arg << "\n";
+ usage();
+ return 1;
+ }
+ }
+
+#ifdef _WIN32
+ // Set stdout in binary mode
+ fflush(stdout);
+ int mode = _setmode(_fileno(stdout), _O_BINARY);
+ if (mode == -1) {
+ std::cerr << "warning: failed to set stdout in binary mode\n";
+ }
+#endif
+
+ for (; i < argc; ++i) {
+ trace::Parser parser;
+
+ if (!parser.open(argv[i])) {
+ std::cerr << "error: failed to open " << argv[i] << "\n";
+ return 1;
+ }
+
+ trace::Call *call;
+ while ((call = parser.parse_call())) {
+ if (calls.contains(*call)) {
+ PickleWriter writer(std::cout);
+ PickleVisitor visitor(writer);
+
+ visitor.visit(call);
+ }
+ delete call;
+ }
+ }
+
+#ifdef _WIN32
+ std::cout.flush();
+ fflush(stdout);
+ if (mode != -1) {
+ _setmode(_fileno(stdout), mode);
+ }
+#endif
+
+ return 0;
+}
+
+const Command pickle_command = {
+ "pickle",
+ synopsis,
+ usage,
+ command
+};
{
int i;
- for (i = 0; i < argc; ++i) {
+ for (i = 1; i < argc; ++i) {
const char *arg = argv[i];
if (arg[0] != '-') {
const char *output = NULL;
int i;
- for (i = 0; i < argc; ) {
+ for (i = 1; i < argc; ) {
const char *arg = argv[i];
if (arg[0] != '-') {
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * Copyright 2011 Intel corporation
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <string.h>
+
+#include "cli.hpp"
+
+#include "os_string.hpp"
+
+#include "trace_callset.hpp"
+#include "trace_parser.hpp"
+#include "trace_writer.hpp"
+
+static const char *synopsis = "Create a new trace by trimming an existing trace.";
+
+static void
+usage(void)
+{
+ std::cout
+ << "usage: apitrace trim [OPTIONS] <trace-file>...\n"
+ << synopsis << "\n"
+ "\n"
+ " --calls <CALLSET> Only trim specified calls\n"
+ " -o --output <TRACEFILE> Output trace file\n"
+ "\n"
+ ;
+}
+
+static int
+command(int argc, char *argv[])
+{
+ std::string output;
+ trace::CallSet calls(trace::FREQUENCY_ALL);
+ int i;
+
+ for (i = 1; i < argc;) {
+ const char *arg = argv[i];
+
+ if (arg[0] != '-') {
+ break;
+ }
+
+ ++i;
+
+ if (!strcmp(arg, "--")) {
+ break;
+ } else if (!strcmp(arg, "--help")) {
+ usage();
+ return 0;
+ } else if (!strcmp(arg, "--calls")) {
+ calls = trace::CallSet(argv[i++]);
+ } else if (!strcmp(arg, "-o") ||
+ !strcmp(arg, "--output")) {
+ output = argv[i++];
+ } else {
+ std::cerr << "error: unknown option " << arg << "\n";
+ usage();
+ return 1;
+ }
+ }
+
+ if (i >= argc) {
+ std::cerr << "Error: apitrace trim requires a trace file as an argument.\n";
+ usage();
+ return 1;
+ }
+
+ for ( ; i < argc; ++i) {
+ trace::Parser p;
+ if (!p.open(argv[i])) {
+ std::cerr << "error: failed to open " << argv[i] << "\n";
+ return 1;
+ }
+
+ if (output.empty()) {
+ os::String base(argv[i]);
+ base.trimExtension();
+
+ output = std::string(base.str()) + std::string("-trim.trace");
+ }
+
+ trace::Writer writer;
+ if (!writer.open(output.c_str())) {
+ std::cerr << "error: failed to create " << argv[i] << "\n";
+ return 1;
+ }
+
+ trace::Call *call;
+ while ((call = p.parse_call())) {
+ if (calls.contains(*call)) {
+ writer.writeCall(call);
+ }
+ delete call;
+ }
+
+ std::cout << "Trimmed trace is available as " << output << "\n";
+ }
+
+ return 0;
+}
+
+const Command trim_command = {
+ "trim",
+ synopsis,
+ usage,
+ command
+};
return EXCEPTION_CONTINUE_SEARCH;
}
+ /*
+ * Ignore thread naming exception.
+ *
+ * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+ */
+ if (pExceptionRecord->ExceptionCode == 0x406d1388) {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
// Clear direction flag
#ifdef _MSC_VER
#ifndef _WIN64
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/*
+ * Python pickle writer
+ */
+
+#ifndef _PICKLE_HPP_
+#define _PICKLE_HPP_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <ostream>
+#include <string>
+
+
+class PickleWriter
+{
+private:
+ std::ostream &os;
+
+ /*
+ * Python pickle opcodes. See pickle.py and pickletools.py from Python
+ * standard library for details.
+ */
+ enum Opcode {
+ MARK = '(',
+ STOP = '.',
+ POP = '0',
+ POP_MARK = '1',
+ DUP = '2',
+ FLOAT = 'F',
+ INT = 'I',
+ BININT = 'J',
+ BININT1 = 'K',
+ LONG = 'L',
+ BININT2 = 'M',
+ NONE = 'N',
+ PERSID = 'P',
+ BINPERSID = 'Q',
+ REDUCE = 'R',
+ STRING = 'S',
+ BINSTRING = 'T',
+ SHORT_BINSTRING = 'U',
+ UNICODE = 'V',
+ BINUNICODE = 'X',
+ APPEND = 'a',
+ BUILD = 'b',
+ GLOBAL = 'c',
+ DICT = 'd',
+ EMPTY_DICT = '}',
+ APPENDS = 'e',
+ GET = 'g',
+ BINGET = 'h',
+ INST = 'i',
+ LONG_BINGET = 'j',
+ LIST = 'l',
+ EMPTY_LIST = ']',
+ OBJ = 'o',
+ PUT = 'p',
+ BINPUT = 'q',
+ LONG_BINPUT = 'r',
+ SETITEM = 's',
+ TUPLE = 't',
+ EMPTY_TUPLE = ')',
+ SETITEMS = 'u',
+ BINFLOAT = 'G',
+
+ PROTO = '\x80',
+ NEWOBJ = '\x81',
+ EXT1 = '\x82',
+ EXT2 = '\x83',
+ EXT4 = '\x84',
+ TUPLE1 = '\x85',
+ TUPLE2 = '\x86',
+ TUPLE3 = '\x87',
+ NEWTRUE = '\x88',
+ NEWFALSE = '\x89',
+ LONG1 = '\x8a',
+ LONG4 = '\x8b',
+ };
+
+public:
+ PickleWriter(std::ostream &_os) :
+ os(_os)
+ {
+ os.put(PROTO);
+ os.put(2);
+ }
+
+ ~PickleWriter() {
+ os.put(STOP);
+ }
+
+ inline void beginDict() {
+ os.put(EMPTY_DICT);
+ os.put(BINPUT);
+ os.put(1);
+ }
+
+ inline void endDict() {
+ }
+
+ inline void beginItem() {
+ }
+
+ inline void beginItem(const char * name) {
+ writeString(name);
+ }
+
+ inline void beginItem(const std::string &name) {
+ beginItem(name.c_str());
+ }
+
+ inline void endItem(void) {
+ os.put(SETITEM);
+ }
+
+ inline void beginList() {
+ os.put(EMPTY_LIST);
+ os.put(BINPUT);
+ os.put(1);
+ os.put(MARK);
+ }
+
+ inline void endList(void) {
+ os.put(APPENDS);
+ }
+
+ inline void beginTuple() {
+ os.put(MARK);
+ }
+
+ inline void endTuple(void) {
+ os.put(TUPLE);
+ }
+
+ inline void writeString(const char *s, size_t length) {
+ if (!s) {
+ writeNone();
+ return;
+ }
+
+ if (length < 256) {
+ os.put(SHORT_BINSTRING);
+ os.put(length);
+ } else {
+ os.put(BINSTRING);
+ putInt32(length);
+ }
+ os.write(s, length);
+
+ os.put(BINPUT);
+ os.put(1);
+ }
+
+ inline void writeString(const char *s) {
+ if (!s) {
+ writeNone();
+ return;
+ }
+
+ writeString(s, strlen(s));
+ }
+
+ inline void writeString(const std::string &s) {
+ writeString(s.c_str(), s.size());
+ }
+
+ inline void writeNone(void) {
+ os.put(NONE);
+ }
+
+ inline void writeBool(bool b) {
+ os.put(b ? NEWTRUE : NEWFALSE);
+ }
+
+ inline void writeInt(uint8_t i) {
+ os.put(BININT1);
+ os.put(i);
+ }
+
+ inline void writeInt(uint16_t i) {
+ if (i < 0x100) {
+ writeInt((uint8_t)i);
+ } else {
+ os.put(BININT2);
+ putInt16(i);
+ }
+ }
+
+ inline void writeInt(int32_t i) {
+ if (0 <= i && i < 0x10000) {
+ writeInt((uint16_t)i);
+ } else {
+ os.put(BININT);
+ putInt32(i);
+ }
+ }
+
+ inline void writeInt(uint32_t i) {
+ if (i < 0x8000000) {
+ writeInt((int32_t)i);
+ } else {
+ writeLong(i);
+ }
+ }
+
+ inline void writeInt(long long i) {
+ if (-0x8000000 <= i && i < 0x8000000) {
+ writeInt((int32_t)i);
+ } else {
+ writeLong(i);
+ }
+ }
+
+ inline void writeInt(unsigned long long i) {
+ if (i < 0x8000000) {
+ writeInt((int32_t)i);
+ } else {
+ writeLong(i);
+ }
+ }
+
+ inline void writeFloat(double f) {
+ union {
+ double f;
+ char c[8];
+ } u;
+
+ assert(sizeof u.f == sizeof u.c);
+ u.f = f;
+
+ os.put(BINFLOAT);
+ os.put(u.c[7]);
+ os.put(u.c[6]);
+ os.put(u.c[5]);
+ os.put(u.c[4]);
+ os.put(u.c[3]);
+ os.put(u.c[2]);
+ os.put(u.c[1]);
+ os.put(u.c[0]);
+ }
+
+protected:
+ inline void putInt16(uint16_t i) {
+ os.put( i & 0xff);
+ os.put( i >> 8 );
+ }
+
+ inline void putInt32(uint32_t i) {
+ os.put( i & 0xff);
+ os.put((i >> 8) & 0xff);
+ os.put((i >> 16) & 0xff);
+ os.put( i >> 24 );
+ }
+
+ template< class T >
+ inline void writeLong(T l) {
+ os.put(LONG1);
+
+ if (l == 0) {
+ os.put(0);
+ return;
+ }
+
+ unsigned c = 1;
+ // Same as l >> (8 * sizeof l), but without the warnings
+ T sign = l < 0 ? ~0 : 0;
+ while ((l >> (8 * c)) != sign) {
+ ++c;
+ }
+ // Add an extra byte if sign bit doesn't match
+ if (((l >> (8 * c - 1)) & 1) != ((l >> (8 * sizeof l - 1)) & 1)) {
+ ++c;
+ }
+ os.put(c);
+
+ for (unsigned i = 0; i < c; ++ i) {
+ os.put(l & 0xff);
+ l >>= 8;
+ }
+ }
+};
+
+#endif /* _Pickle_HPP_ */
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <limits>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include <trace_callset.hpp>
+
+
+using namespace trace;
+
+
+// Parser class for call sets
+class CallSetParser
+{
+ CallSet &set;
+
+protected:
+ char lookahead;
+
+ CallSetParser(CallSet &_set) :
+ set(_set),
+ lookahead(0)
+ {}
+
+public:
+ void parse() {
+ skipWhiteSpace();
+ while (lookahead) {
+ assert(!isSpace());
+ parseRange();
+ // skip any comma
+ isOperator(',');
+ }
+ }
+
+private:
+ void parseRange() {
+ CallNo start = std::numeric_limits<CallNo>::min();
+ CallNo stop = std::numeric_limits<CallNo>::max();
+ CallNo step = 1;
+ CallFlags freq = FREQUENCY_ALL;
+ if (isAlpha()) {
+ freq = parseFrequency();
+ } else {
+ if (isOperator('*')) {
+ // no-change
+ } else {
+ start = parseCallNo();
+ if (isOperator('-')) {
+ if (isDigit()) {
+ stop = parseCallNo();
+ } else {
+ // no-change
+ }
+ } else {
+ stop = start;
+ }
+ }
+ if (isOperator('/')) {
+ if (isDigit()) {
+ step = parseCallNo();
+ } else {
+ freq = parseFrequency();
+ }
+ }
+ }
+ set.addRange(CallRange(start, stop, step, freq));
+ }
+
+ // match and consume an operator
+ bool isOperator(char c) {
+ if (lookahead == c) {
+ consume();
+ skipWhiteSpace();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ CallNo parseCallNo() {
+ CallNo number = 0;
+ if (isDigit()) {
+ do {
+ CallNo digit = consume() - '0';
+ number = number * 10 + digit;
+ } while (isDigit());
+ } else {
+ std::cerr << "error: expected digit, found '" << lookahead << "'\n";
+ exit(0);
+ }
+ skipWhiteSpace();
+ return number;
+ }
+
+ CallFlags parseFrequency() {
+ std::string freq;
+ if (isAlpha()) {
+ do {
+ freq.push_back(consume());
+ } while (isAlpha());
+ } else {
+ std::cerr << "error: expected frequency, found '" << lookahead << "'\n";
+ exit(0);
+ }
+ skipWhiteSpace();
+ if (freq == "frame") {
+ return FREQUENCY_FRAME;
+ } else if (freq == "rendertarget" || freq == "fbo") {
+ return FREQUENCY_RENDERTARGET;
+ } else if (freq == "render" || freq == "draw") {
+ return FREQUENCY_RENDER;
+ } else {
+ std::cerr << "error: expected frequency, found '" << freq << "'\n";
+ exit(0);
+ return FREQUENCY_NONE;
+ }
+ }
+
+ // match lookahead with a digit (does not consume)
+ bool isDigit() const {
+ return lookahead >= '0' && lookahead <= '9';
+ }
+
+ bool isAlpha() const {
+ return lookahead >= 'a' && lookahead <= 'z';
+ }
+
+ void skipWhiteSpace() {
+ while (isSpace()) {
+ consume();
+ }
+ }
+
+ bool isSpace() const {
+ return lookahead == ' ' ||
+ lookahead == '\t' ||
+ lookahead == '\r' ||
+ lookahead == '\n';
+ }
+
+ virtual char consume() = 0;
+};
+
+
+class StringCallSetParser : public CallSetParser
+{
+ const char *buf;
+
+public:
+ StringCallSetParser(CallSet &_set, const char *_buf) :
+ CallSetParser(_set),
+ buf(_buf)
+ {
+ lookahead = *buf;
+ }
+
+ char consume() {
+ char c = lookahead;
+ if (lookahead) {
+ ++buf;
+ lookahead = *buf;
+ }
+ return c;
+ }
+};
+
+
+class FileCallSetParser : public CallSetParser
+{
+ std::ifstream stream;
+
+public:
+ FileCallSetParser(CallSet &_set, const char *filename) :
+ CallSetParser(_set)
+ {
+ stream.open(filename);
+ if (!stream.is_open()) {
+ std::cerr << "error: failed to open \"" << filename << "\"\n";
+ exit(1);
+ }
+
+ stream.get(lookahead);
+ }
+
+ char consume() {
+ char c = lookahead;
+ if (stream.eof()) {
+ lookahead = 0;
+ } else {
+ stream.get(lookahead);
+ }
+ return c;
+ }
+};
+
+
+CallSet::CallSet(const char *string)
+{
+ if (*string == '@') {
+ FileCallSetParser parser(*this, &string[1]);
+ parser.parse();
+ } else {
+ StringCallSetParser parser(*this, string);
+ parser.parse();
+ }
+}
+
+
+CallSet::CallSet(CallFlags freq) {
+ if (freq != FREQUENCY_NONE) {
+ CallNo start = std::numeric_limits<CallNo>::min();
+ CallNo stop = std::numeric_limits<CallNo>::max();
+ CallNo step = 1;
+ addRange(CallRange(start, stop, step, freq));
+ assert(!empty());
+ }
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/*
+ * Representation of call sets.
+ *
+ * Grammar:
+ *
+ * set = '@' filename
+ * | range ( ',' ? range ) *
+ *
+ * range = interval ( '/' frequency )
+ *
+ * interval = '*'
+ * | number
+ * | start_number '-' end_number
+ *
+ * frequency = divisor
+ * | "frame"
+ * | "rendertarget" | "fbo"
+ * | "render | "draw"
+ *
+ */
+
+#ifndef _TRACE_CALLSET_HPP_
+#define _TRACE_CALLSET_HPP_
+
+
+#include <list>
+
+#include "trace_model.hpp"
+
+
+namespace trace {
+
+
+ // Should match Call::no
+ typedef unsigned CallNo;
+
+
+ // Aliases for call flags
+ enum {
+ FREQUENCY_NONE = 0,
+ FREQUENCY_FRAME = CALL_FLAG_END_FRAME,
+ FREQUENCY_RENDERTARGET = CALL_FLAG_END_FRAME | CALL_FLAG_SWAP_RENDERTARGET,
+ FREQUENCY_RENDER = CALL_FLAG_RENDER,
+ FREQUENCY_ALL = 0xffffffff
+ };
+
+ // A linear range of calls
+ class CallRange
+ {
+ public:
+ CallNo start;
+ CallNo stop;
+ CallNo step;
+ CallFlags freq;
+
+ CallRange(CallNo callNo) :
+ start(callNo),
+ stop(callNo),
+ step(1),
+ freq(FREQUENCY_ALL)
+ {}
+
+ CallRange(CallNo _start, CallNo _stop, CallNo _step = 1, CallFlags _freq = FREQUENCY_ALL) :
+ start(_start),
+ stop(_stop),
+ step(_step),
+ freq(_freq)
+ {}
+
+ bool
+ contains(CallNo callNo, CallFlags callFlags) const {
+ return callNo >= start &&
+ callNo <= stop &&
+ ((callNo - start) % step) == 0 &&
+ ((callFlags & freq) ||
+ freq == FREQUENCY_ALL);
+ }
+ };
+
+
+ // A collection of call ranges
+ class CallSet
+ {
+ public:
+ // TODO: use binary tree to speed up lookups
+ typedef std::list< CallRange > RangeList;
+ RangeList ranges;
+
+ CallSet() {}
+
+ CallSet(CallFlags freq);
+
+ CallSet(const char *str);
+
+ // Not empty set
+ inline bool
+ empty() const {
+ return ranges.empty();
+ }
+
+ void
+ addRange(const CallRange & range) {
+ if (range.start <= range.stop &&
+ range.freq != FREQUENCY_NONE) {
+
+ RangeList::iterator it = ranges.begin();
+ while (it != ranges.end() && it->start < range.start) {
+ ++it;
+ }
+
+ ranges.insert(it, range);
+ }
+ }
+
+ inline bool
+ contains(CallNo callNo, CallFlags callFlags = FREQUENCY_ALL) const {
+ if (empty()) {
+ return false;
+ }
+ RangeList::const_iterator it;
+ for (it = ranges.begin(); it != ranges.end() && it->start <= callNo; ++it) {
+ if (it->contains(callNo, callFlags)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool
+ contains(const trace::Call &call) {
+ return contains(call.no, call.flags);
+ }
+ };
+
+
+ CallSet parse(const char *string);
+
+
+} /* namespace trace */
+
+
+#endif /* _TRACE_CALLSET_HPP_ */
void visit(Call *call) {
CallFlags callFlags = call->flags;
+
+ if (!(dumpFlags & DUMP_FLAG_NO_CALL_NO)) {
+ os << call->no << " ";
+ }
if (callFlags & CALL_FLAG_NON_REPRODUCIBLE) {
os << strike;
if (!(dumpFlags & DUMP_FLAG_NO_ARG_NAMES)) {
os << italic << call->sig->arg_names[i] << normal << " = ";
}
- if (call->args[i]) {
- _visit(call->args[i]);
+ if (call->args[i].value) {
+ _visit(call->args[i].value);
} else {
os << "?";
}
void dump(Call &call, std::ostream &os, DumpFlags flags) {
Dumper d(os, flags);
- os << call.no << " ";
d.visit(&call);
}
enum {
DUMP_FLAG_NO_COLOR = (1 << 0),
DUMP_FLAG_NO_ARG_NAMES = (1 << 1),
+ DUMP_FLAG_NO_CALL_NO = (1 << 2),
};
Call::~Call() {
for (unsigned i = 0; i < args.size(); ++i) {
- delete args[i];
+ delete args[i].value;
}
if (ret) {
};
+struct Arg
+{
+ Value *value;
+};
+
class Call
{
unsigned thread_id;
unsigned no;
const FunctionSig *sig;
- std::vector<Value *> args;
+ std::vector<Arg> args;
Value *ret;
CallFlags flags;
inline Value & arg(unsigned index) {
assert(index < args.size());
- return *(args[index]);
+ return *(args[index].value);
}
};
if (index >= call->args.size()) {
call->args.resize(index + 1);
}
- call->args[index] = value;
+ call->args[index].value = value;
}
}
void visit(Call *call) {
unsigned call_no = writer.beginEnter(call->sig, call->thread_id);
for (unsigned i = 0; i < call->args.size(); ++i) {
- if (call->args[i]) {
+ if (call->args[i].value) {
writer.beginArg(i);
- _visit(call->args[i]);
+ _visit(call->args[i].value);
writer.endArg();
}
}
#define __inline static __inline__
#define __deref_out /**/
#define __deref_out_opt /**/
-#define __deref_out_bcount(x)
-#define __maybenull
-#define __in_z
-#define __in_z_opt
-#define __out_z
-#define __out_ecount_z(x)
-#define __nullterminated
-#define __notnull
-#define __field_ecount_opt(x)
-#define __range(x,y)
-#define __out_ecount_part_opt(x,y)
+#define __deref_out_bcount(x) /**/
+#define __maybenull /**/
+#define __in_z /**/
+#define __in_z_opt /**/
+#define __out_z /**/
+#define __out_ecount_z(x) /**/
+#define __nullterminated /**/
+#define __notnull /**/
+#define __field_ecount_opt(x) /**/
+#define __range(x,y) /**/
+#define __out_ecount_part_opt(x,y) /**/
#ifndef DECLSPEC_DEPRECATED
#define DECLSPEC_DEPRECATED /**/
#endif
#ifndef DECLSPEC_NOVTABLE
-#define DECLSPEC_NOVTABLE
+#define DECLSPEC_NOVTABLE /**/
#endif
#ifndef __MINGW64_VERSION_MAJOR
if __name__ == '__main__':
+ print '#define INITGUID'
+ print
print '#include "trace_writer_local.hpp"'
print '#include "os.hpp"'
print
DllTracer.declareWrapperInterfaceVariables(self, interface)
if interface.name == 'IDirect3DVertexBuffer9':
- print ' UINT m_OffsetToLock;'
print ' UINT m_SizeToLock;'
print ' VOID *m_pbData;'
def implementWrapperInterfaceMethodBody(self, interface, base, method):
if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Unlock':
print ' if (m_pbData) {'
- print ' if (!m_SizeToLock) {'
- print ' D3DVERTEXBUFFER_DESC Desc;'
- print ' m_pInstance->GetDesc(&Desc);'
- print ' m_SizeToLock = Desc.Size;'
- print ' }'
- self.emit_memcpy('(LPBYTE)m_pbData + m_OffsetToLock', '(LPBYTE)m_pbData + m_OffsetToLock', 'm_SizeToLock')
+ self.emit_memcpy('(LPBYTE)m_pbData', '(LPBYTE)m_pbData', 'm_SizeToLock')
print ' }'
DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method)
if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Lock':
+ # FIXME: handle recursive locks
print ' if (__result == D3D_OK && !(Flags & D3DLOCK_READONLY)) {'
- print ' m_OffsetToLock = OffsetToLock;'
- print ' m_SizeToLock = SizeToLock;'
+ print ' if (SizeToLock) {'
+ print ' m_SizeToLock = SizeToLock;'
+ print ' } else {'
+ print ' D3DVERTEXBUFFER_DESC Desc;'
+ print ' m_pInstance->GetDesc(&Desc);'
+ print ' m_SizeToLock = Desc.Size;'
+ print ' }'
print ' m_pbData = *ppbData;'
print ' } else {'
print ' m_pbData = NULL;'
extern long long startTime;
extern bool wait;
-enum frequency {
- FREQUENCY_NEVER = 0,
- FREQUENCY_FRAME,
- FREQUENCY_FRAMEBUFFER,
- FREQUENCY_DRAW,
-};
-
extern bool benchmark;
-extern const char *compare_prefix;
-extern const char *snapshot_prefix;
-extern enum frequency snapshot_frequency;
extern unsigned dump_state;
extern const retrace::Entry wgl_callbacks[];
extern const retrace::Entry egl_callbacks[];
-void snapshot(unsigned call_no);
void frame_complete(trace::Call &call);
void updateDrawable(int width, int height);
print ' GLint __pack_buffer = 0;'
print ' glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &__pack_buffer);'
print ' if (!__pack_buffer) {'
- if function.name == 'glReadPixels':
- print ' glFinish();'
- print ' if (glretrace::snapshot_frequency == glretrace::FREQUENCY_FRAME ||'
- print ' glretrace::snapshot_frequency == glretrace::FREQUENCY_FRAMEBUFFER) {'
- print ' glretrace::snapshot(call.no);'
- print ' }'
print ' return;'
print ' }'
# Pre-snapshots
if function.name in self.bind_framebuffer_function_names:
print ' assert(call.flags & trace::CALL_FLAG_SWAP_RENDERTARGET);'
- print ' if (glretrace::snapshot_frequency == glretrace::FREQUENCY_FRAMEBUFFER) {'
- print ' glretrace::snapshot(call.no - 1);'
- print ' }'
if function.name == 'glFrameTerminatorGREMEDY':
print ' glretrace::frame_complete(call);'
return
print ' }'
if is_draw_array or is_draw_elements or is_misc_draw:
print ' assert(call.flags & trace::CALL_FLAG_RENDER);'
- print ' if (glretrace::snapshot_frequency == glretrace::FREQUENCY_DRAW) {'
- print ' glretrace::snapshot(call.no);'
- print ' }'
def invokeFunction(self, function):
print ' glretrace::insideGlBeginEnd = true;'
elif function.name.startswith('gl'):
# glGetError is not allowed inside glBegin/glEnd
- print ' if (!glretrace::benchmark && !glretrace::insideGlBeginEnd) {'
+ print ' if (!glretrace::benchmark && !retrace::profiling && !glretrace::insideGlBeginEnd) {'
print ' glretrace::checkGlError(call);'
if function.name in ('glProgramStringARB', 'glProgramStringNV'):
print r' GLint error_position = -1;'
#include "os_time.hpp"
#include "image.hpp"
#include "retrace.hpp"
+#include "trace_callset.hpp"
#include "glproc.hpp"
#include "glstate.hpp"
#include "glretrace.hpp"
bool wait = false;
bool benchmark = false;
-const char *compare_prefix = NULL;
-const char *snapshot_prefix = NULL;
-enum frequency snapshot_frequency = FREQUENCY_NEVER;
+static const char *compare_prefix = NULL;
+static const char *snapshot_prefix = NULL;
+static trace::CallSet snapshot_frequency;
+static trace::CallSet compare_frequency;
unsigned dump_state = ~0;
}
-void snapshot(unsigned call_no) {
- if (!drawable ||
- (!snapshot_prefix && !compare_prefix)) {
+static void
+snapshot(unsigned call_no) {
+ assert(snapshot_prefix || compare_prefix);
+
+ if (!drawable) {
return;
}
if (!drawable->visible) {
retrace::warning(call) << "could not infer drawable size (glViewport never called)\n";
}
-
- if (snapshot_frequency == FREQUENCY_FRAME ||
- snapshot_frequency == FREQUENCY_FRAMEBUFFER) {
- snapshot(call.no);
- }
}
trace::Call *call;
while ((call = parser.parse_call())) {
+ bool swapRenderTarget = call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET;
+ bool doSnapshot =
+ snapshot_frequency.contains(*call) ||
+ compare_frequency.contains(*call)
+ ;
+
+ // For calls which cause rendertargets to be swaped, we take the
+ // snapshot _before_ swapping the rendertargets.
+ if (doSnapshot && swapRenderTarget) {
+ if (call->flags & trace::CALL_FLAG_END_FRAME) {
+ // For swapbuffers/presents we still use this call number,
+ // spite not have been executed yet.
+ snapshot(call->no);
+ } else {
+ // Whereas for ordinate fbo/rendertarget changes we use the
+ // previous call's number.
+ snapshot(call->no - 1);
+ }
+ }
+
retracer.retrace(*call);
+ if (doSnapshot && !swapRenderTarget) {
+ snapshot(call->no);
+ }
+
if (!insideGlBeginEnd &&
drawable && context &&
call->no >= dump_state) {
long long endTime = os::getTime();
float timeInterval = (endTime - startTime) * (1.0 / os::timeFrequency);
- if (retrace::verbosity >= -1) {
+ if ((retrace::verbosity >= -1) || (retrace::profiling)) {
std::cout <<
"Rendered " << frame << " frames"
" in " << timeInterval << " secs,"
"Replay TRACE.\n"
"\n"
" -b benchmark mode (no error checking or warning messages)\n"
+ " -p profiling mode (run whole trace, dump profiling info)\n"
" -c PREFIX compare against snapshots\n"
+ " -C CALLSET calls to compare (default is every frame)\n"
" -core use core profile\n"
" -db use a double buffer visual (default)\n"
" -sb use a single buffer visual\n"
" -s PREFIX take snapshots; `-` for PNM stdout output\n"
- " -S FREQUENCY snapshot frequency: frame (default), framebuffer, or draw\n"
+ " -S CALLSET calls to snapshot (default is every frame)\n"
" -v increase output verbosity\n"
" -D CALLNO dump state at specific call no\n"
" -w wait on final frame\n";
extern "C"
int main(int argc, char **argv)
{
+ assert(compare_frequency.empty());
+ assert(snapshot_frequency.empty());
int i;
for (i = 1; i < argc; ++i) {
benchmark = true;
retrace::verbosity = -1;
glws::debug = false;
+ } else if (!strcmp(arg, "-p")) {
+ retrace::profiling = true;
+ retrace::verbosity = -1;
+ glws::debug = false;
} else if (!strcmp(arg, "-c")) {
compare_prefix = argv[++i];
- if (snapshot_frequency == FREQUENCY_NEVER) {
- snapshot_frequency = FREQUENCY_FRAME;
+ if (compare_frequency.empty()) {
+ compare_frequency = trace::CallSet(trace::FREQUENCY_FRAME);
+ }
+ } else if (!strcmp(arg, "-C")) {
+ compare_frequency = trace::CallSet(argv[++i]);
+ if (compare_prefix == NULL) {
+ compare_prefix = "";
}
} else if (!strcmp(arg, "-D")) {
dump_state = atoi(argv[++i]);
return 0;
} else if (!strcmp(arg, "-s")) {
snapshot_prefix = argv[++i];
- if (snapshot_frequency == FREQUENCY_NEVER) {
- snapshot_frequency = FREQUENCY_FRAME;
+ if (snapshot_frequency.empty()) {
+ snapshot_frequency = trace::CallSet(trace::FREQUENCY_FRAME);
}
if (snapshot_prefix[0] == '-' && snapshot_prefix[1] == 0) {
retrace::verbosity = -2;
}
} else if (!strcmp(arg, "-S")) {
- arg = argv[++i];
- if (!strcmp(arg, "frame")) {
- snapshot_frequency = FREQUENCY_FRAME;
- } else if (!strcmp(arg, "framebuffer")) {
- snapshot_frequency = FREQUENCY_FRAMEBUFFER;
- } else if (!strcmp(arg, "draw")) {
- snapshot_frequency = FREQUENCY_DRAW;
- } else {
- std::cerr << "error: unknown frequency " << arg << "\n";
- usage();
- return 1;
- }
+ snapshot_frequency = trace::CallSet(argv[++i]);
if (snapshot_prefix == NULL) {
snapshot_prefix = "";
}
}
m_argValues.reserve(call->args.size());
for (int i = 0; i < call->args.size(); ++i) {
- if (call->args[i]) {
+ if (call->args[i].value) {
VariantVisitor argVisitor(loader);
- call->args[i]->visit(argVisitor);
+ call->args[i].value->visit(argVisitor);
m_argValues.append(argVisitor.variant());
if (m_argValues[i].type() == QVariant::ByteArray) {
m_hasBinaryData = true;
overwriteValue(trace::Call *call, const QVariant &val, int index)
{
EditVisitor visitor(val);
- trace::Value *origValue = call->args[index];
+ trace::Value *origValue = call->args[index].value;
origValue->visit(visitor);
if (visitor.value() && origValue != visitor.value()) {
delete origValue;
- call->args[index] = visitor.value();
+ call->args[index].value = visitor.value();
}
}
#include <string.h>
#include <iostream>
+#include "os_time.hpp"
#include "trace_dump.hpp"
#include "retrace.hpp"
int verbosity = 0;
+bool profiling = false;
static bool call_dumped = false;
assert(callback);
assert(callbacks[id] == callback);
- callback(call);
+ if (retrace::profiling) {
+ long long startTime = os::getTime();
+ callback(call);
+ long long stopTime = os::getTime();
+ float timeInterval = (stopTime - startTime) * (1.0E6 / os::timeFrequency);
+
+ std::cout
+ << call.no << " "
+ << "[" << timeInterval << " usec] "
+ ;
+ trace::dump(call, std::cout, trace::DUMP_FLAG_NO_CALL_NO | trace::DUMP_FLAG_NO_COLOR);
+ } else {
+ callback(call);
+ }
}
*/
extern int verbosity;
+/**
+ * Add profiling data to the dump when retracing.
+ */
+extern bool profiling;
+
std::ostream &warning(trace::Call &call);
print '#include "retrace.hpp"'
print
- types = api.all_types()
+ types = api.getAllTypes()
handles = [type for type in types if isinstance(type, stdapi.Handle)]
handle_names = set()
for handle in handles:
type="float", dest="threshold", default=12.0,
help="threshold precision [default: %default]")
optparser.add_option(
- '-S', '--snapshot-frequency', metavar='FREQUENCY',
+ '-S', '--snapshot-frequency', metavar='CALLSET',
type="string", dest="snapshot_frequency", default='draw',
- help="snapshot frequency: frame, framebuffer, or draw [default: %default]")
+ help="calls to compare [default: %default]")
(options, args) = optparser.parse_args(sys.argv[1:])
ref_env = parse_env(optparser, options.ref_env)
$APITRACE dump
stripdump () {
- $APITRACE dump --color=never --no-arg-names "$1" \
+ $APITRACE dump --color=never --arg-names=no "$1" \
| sed \
-e 's/\r$//g' \
-e 's/^[0-9]\+ //' \
--- /dev/null
+#!/usr/bin/env python
+##########################################################################
+#
+# Copyright 2012 Jose Fonseca
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+'''Sample program for apitrace pickle command.
+
+Run as:
+
+ apitrace pickle foo.trace | python unpickle.py
+
+'''
+
+
+import optparse
+import cPickle as pickle
+import sys
+import time
+
+
+def main():
+ optparser = optparse.OptionParser(
+ usage="\n\tapitrace pickle trace. %prog [options]")
+ optparser.add_option(
+ '--quiet',
+ action="store_true", dest="quiet", default=False,
+ help="don't dump calls to stdout")
+
+ (options, args) = optparser.parse_args(sys.argv[1:])
+
+ if args:
+ optparser.error('unexpected arguments')
+
+ # Change stdin to binary mode
+ try:
+ import msvcrt
+ except ImportError:
+ pass
+ else:
+ import os
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+
+ calls = 0
+ startTime = time.time()
+ while True:
+ try:
+ call = pickle.load(sys.stdin)
+ except EOFError:
+ break
+ else:
+ callNo, functionName, args, ret = call
+ if not options.quiet:
+ sys.stdout.write('%u ' % callNo)
+ sys.stdout.write(functionName)
+ sys.stdout.write('(' + ', '.join(map(repr, args)) + ')')
+ if ret is not None:
+ sys.stdout.write(' = ')
+ sys.stdout.write(repr(ret))
+ sys.stdout.write('\n')
+ calls += 1
+ stopTime = time.time()
+ duration = stopTime - startTime
+ sys.stderr.write('%u calls, %.03f secs, %u calls/sec\n' % (calls, duration, calls/duration))
+
+
+if __name__ == '__main__':
+ main()
d3d10 = API("d3d10")
+
d3d10.addFunctions([
StdFunction(HRESULT, "D3D10CreateDevice", [(Pointer(IDXGIAdapter), "pAdapter"), (D3D10_DRIVER_TYPE, "DriverType"), (HMODULE, "Software"), (UINT, "Flags"), (UINT, "SDKVersion"), Out(Pointer(Pointer(ID3D10Device)), "ppDevice")]),
StdFunction(HRESULT, "D3D10CreateDeviceAndSwapChain", [(Pointer(IDXGIAdapter), "pAdapter"), (D3D10_DRIVER_TYPE, "DriverType"), (HMODULE, "Software"), (UINT, "Flags"), (UINT, "SDKVersion"), (Pointer(DXGI_SWAP_CHAIN_DESC), "pSwapChainDesc"), Out(Pointer(Pointer(IDXGISwapChain)), "ppSwapChain"), Out(Pointer(Pointer(ID3D10Device)), "ppDevice")]),
StdFunction(HRESULT, "D3D10CreateBlob", [(SIZE_T, "NumBytes"), Out(Pointer(LPD3D10BLOB), "ppBuffer")]),
])
+
+d3d10.addInterfaces([
+ ID3D10DeviceChild,
+ ID3D10Resource,
+ ID3D10Buffer,
+ ID3D10Texture1D,
+ ID3D10Texture2D,
+ ID3D10Texture3D,
+ ID3D10View,
+ ID3D10DepthStencilView,
+ ID3D10RenderTargetView,
+ ID3D10ShaderResourceView,
+ ID3D10BlendState,
+ ID3D10DepthStencilState,
+ ID3D10GeometryShader,
+ ID3D10InputLayout,
+ ID3D10PixelShader,
+ ID3D10RasterizerState,
+ ID3D10SamplerState,
+ ID3D10VertexShader,
+ ID3D10Asynchronous,
+ ID3D10Counter,
+ ID3D10Query,
+ ID3D10Predicate,
+ ID3D10Device,
+ ID3D10Multithread,
+])
])
DXGI_OUTPUT_DESC = Struct("DXGI_OUTPUT_DESC", [
- (Array(WCHAR, 32), "DeviceName"),
+ (WString, "DeviceName"),
(RECT, "DesktopCoordinates"),
(BOOL, "AttachedToDesktop"),
(DXGI_MODE_ROTATION, "Rotation"),
])
DXGI_ADAPTER_DESC = Struct("DXGI_ADAPTER_DESC", [
- (Array(WCHAR, 128), "Description"),
+ (WString, "Description"),
(UINT, "VendorId"),
(UINT, "DeviceId"),
(UINT, "SubSysId"),
class String(Type):
- def __init__(self, expr = "char *", length = None):
+ def __init__(self, expr = "char *", length = None, kind = 'String'):
Type.__init__(self, expr)
self.length = length
+ self.kind = kind
def visit(self, visitor, *args, **kwargs):
return visitor.visitString(self, *args, **kwargs)
-# C string (i.e., zero terminated)
-CString = String()
-
class Opaque(Type):
'''Opaque pointer.'''
def visitOpaque(self, opaque):
return opaque
+ def visitInterface(self, interface, *args, **kwargs):
+ return interface
+
def visitPolymorphic(self, polymorphic):
defaultType = self.visit(polymorphic.defaultType)
switchExpr = polymorphic.switchExpr
self.functions = []
self.interfaces = []
- def all_types(self):
+ def getAllTypes(self):
collector = Collector()
for function in self.functions:
for arg in function.args:
collector.visit(method.type)
return collector.types
+ def getAllInterfaces(self):
+ types = self.getAllTypes()
+ interfaces = [type for type in types if isinstance(type, Interface)]
+ for interface in self.interfaces:
+ if interface not in interfaces:
+ interfaces.append(interface)
+ return interfaces
+
def addFunction(self, function):
self.functions.append(function)
Float = Literal("float", "Float")
Double = Literal("double", "Double")
SizeT = Literal("size_t", "UInt")
-WString = Literal("wchar_t *", "WString")
+
+# C string (i.e., zero terminated)
+CString = String()
+WString = String("wchar_t *", kind="WString")
Int8 = Literal("int8_t", "SInt")
UInt8 = Literal("uint8_t", "UInt")
+++ /dev/null
-D2D1_ALPHA_MODE = Enum("D2D1_ALPHA_MODE", [
- "D2D1_ALPHA_MODE_UNKNOWN",
- "D2D1_ALPHA_MODE_PREMULTIPLIED",
- "D2D1_ALPHA_MODE_STRAIGHT",
- "D2D1_ALPHA_MODE_IGNORE",
- "D2D1_ALPHA_MODE_FORCE_DWORD",
-])
-
-D2D1_GAMMA = Enum("D2D1_GAMMA", [
- "D2D1_GAMMA_2_2",
- "D2D1_GAMMA_1_0",
- "D2D1_GAMMA_FORCE_DWORD",
-])
-
-D2D1_OPACITY_MASK_CONTENT = Enum("D2D1_OPACITY_MASK_CONTENT", [
- "D2D1_OPACITY_MASK_CONTENT_GRAPHICS",
- "D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL",
- "D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE",
- "D2D1_OPACITY_MASK_CONTENT_FORCE_DWORD",
-])
-
-D2D1_EXTEND_MODE = Enum("D2D1_EXTEND_MODE", [
- "D2D1_EXTEND_MODE_CLAMP",
- "D2D1_EXTEND_MODE_WRAP",
- "D2D1_EXTEND_MODE_MIRROR",
- "D2D1_EXTEND_MODE_FORCE_DWORD",
-])
-
-D2D1_ANTIALIAS_MODE = Enum("D2D1_ANTIALIAS_MODE", [
- "D2D1_ANTIALIAS_MODE_PER_PRIMITIVE",
- "D2D1_ANTIALIAS_MODE_ALIASED",
- "D2D1_ANTIALIAS_MODE_FORCE_DWORD",
-])
-
-D2D1_TEXT_ANTIALIAS_MODE = Enum("D2D1_TEXT_ANTIALIAS_MODE", [
- "D2D1_TEXT_ANTIALIAS_MODE_DEFAULT",
- "D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE",
- "D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE",
- "D2D1_TEXT_ANTIALIAS_MODE_ALIASED",
- "D2D1_TEXT_ANTIALIAS_MODE_FORCE_DWORD",
-])
-
-D2D1_BITMAP_INTERPOLATION_MODE = Enum("D2D1_BITMAP_INTERPOLATION_MODE", [
- "D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR",
- "D2D1_BITMAP_INTERPOLATION_MODE_LINEAR",
- "D2D1_BITMAP_INTERPOLATION_MODE_FORCE_DWORD",
-])
-
-D2D1_DRAW_TEXT_OPTIONS = Enum("D2D1_DRAW_TEXT_OPTIONS", [
- "D2D1_DRAW_TEXT_OPTIONS_NO_SNAP",
- "D2D1_DRAW_TEXT_OPTIONS_NO_CLIP",
- "D2D1_DRAW_TEXT_OPTIONS_NONE",
- "D2D1_DRAW_TEXT_OPTIONS_FORCE_DWORD",
-])
-
-D2D1_PIXEL_FORMAT = Struct("D2D1_PIXEL_FORMAT", [
- (DXGI_FORMAT, "format"),
- (D2D1_ALPHA_MODE, "alphaMode"),
-])
-
-D2D1_POINT_2U = Alias("D2D1_POINT_2U", D2D_POINT_2U)
-D2D1_POINT_2F = Alias("D2D1_POINT_2F", D2D_POINT_2F)
-D2D1_RECT_F = Alias("D2D1_RECT_F", D2D_RECT_F)
-D2D1_RECT_U = Alias("D2D1_RECT_U", D2D_RECT_U)
-D2D1_SIZE_F = Alias("D2D1_SIZE_F", D2D_SIZE_F)
-D2D1_SIZE_U = Alias("D2D1_SIZE_U", D2D_SIZE_U)
-D2D1_COLOR_F = Alias("D2D1_COLOR_F", D2D_COLOR_F)
-D2D1_MATRIX_3X2_F = Alias("D2D1_MATRIX_3X2_F", D2D_MATRIX_3X2_F)
-D2D1_TAG = Alias("D2D1_TAG", UINT64)
-D2D1_BITMAP_PROPERTIES = Struct("D2D1_BITMAP_PROPERTIES", [
- (D2D1_PIXEL_FORMAT, "pixelFormat"),
- (FLOAT, "dpiX"),
- (FLOAT, "dpiY"),
-])
-
-D2D1_GRADIENT_STOP = Struct("D2D1_GRADIENT_STOP", [
- (FLOAT, "position"),
- (D2D1_COLOR_F, "color"),
-])
-
-D2D1_BRUSH_PROPERTIES = Struct("D2D1_BRUSH_PROPERTIES", [
- (FLOAT, "opacity"),
- (D2D1_MATRIX_3X2_F, "transform"),
-])
-
-D2D1_BITMAP_BRUSH_PROPERTIES = Struct("D2D1_BITMAP_BRUSH_PROPERTIES", [
- (D2D1_EXTEND_MODE, "extendModeX"),
- (D2D1_EXTEND_MODE, "extendModeY"),
- (D2D1_BITMAP_INTERPOLATION_MODE, "interpolationMode"),
-])
-
-D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES = Struct("D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES", [
- (D2D1_POINT_2F, "startPoint"),
- (D2D1_POINT_2F, "endPoint"),
-])
-
-D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES = Struct("D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES", [
- (D2D1_POINT_2F, "center"),
- (D2D1_POINT_2F, "gradientOriginOffset"),
- (FLOAT, "radiusX"),
- (FLOAT, "radiusY"),
-])
-
-D2D1_ARC_SIZE = Enum("D2D1_ARC_SIZE", [
- "D2D1_ARC_SIZE_SMALL",
- "D2D1_ARC_SIZE_LARGE",
- "D2D1_ARC_SIZE_FORCE_DWORD",
-])
-
-D2D1_CAP_STYLE = Enum("D2D1_CAP_STYLE", [
- "D2D1_CAP_STYLE_FLAT",
- "D2D1_CAP_STYLE_SQUARE",
- "D2D1_CAP_STYLE_ROUND",
- "D2D1_CAP_STYLE_TRIANGLE",
- "D2D1_CAP_STYLE_FORCE_DWORD",
-])
-
-D2D1_DASH_STYLE = Enum("D2D1_DASH_STYLE", [
- "D2D1_DASH_STYLE_SOLID",
- "D2D1_DASH_STYLE_DASH",
- "D2D1_DASH_STYLE_DOT",
- "D2D1_DASH_STYLE_DASH_DOT",
- "D2D1_DASH_STYLE_DASH_DOT_DOT",
- "D2D1_DASH_STYLE_CUSTOM",
- "D2D1_DASH_STYLE_FORCE_DWORD",
-])
-
-D2D1_LINE_JOIN = Enum("D2D1_LINE_JOIN", [
- "D2D1_LINE_JOIN_MITER",
- "D2D1_LINE_JOIN_BEVEL",
- "D2D1_LINE_JOIN_ROUND",
- "D2D1_LINE_JOIN_MITER_OR_BEVEL",
- "D2D1_LINE_JOIN_FORCE_DWORD",
-])
-
-D2D1_COMBINE_MODE = Enum("D2D1_COMBINE_MODE", [
- "D2D1_COMBINE_MODE_UNION",
- "D2D1_COMBINE_MODE_INTERSECT",
- "D2D1_COMBINE_MODE_XOR",
- "D2D1_COMBINE_MODE_EXCLUDE",
- "D2D1_COMBINE_MODE_FORCE_DWORD",
-])
-
-D2D1_GEOMETRY_RELATION = Enum("D2D1_GEOMETRY_RELATION", [
- "D2D1_GEOMETRY_RELATION_UNKNOWN",
- "D2D1_GEOMETRY_RELATION_DISJOINT",
- "D2D1_GEOMETRY_RELATION_IS_CONTAINED",
- "D2D1_GEOMETRY_RELATION_CONTAINS",
- "D2D1_GEOMETRY_RELATION_OVERLAP",
- "D2D1_GEOMETRY_RELATION_FORCE_DWORD",
-])
-
-D2D1_GEOMETRY_SIMPLIFICATION_OPTION = Enum("D2D1_GEOMETRY_SIMPLIFICATION_OPTION", [
- "D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES",
- "D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES",
- "D2D1_GEOMETRY_SIMPLIFICATION_OPTION_FORCE_DWORD",
-])
-
-D2D1_FIGURE_BEGIN = Enum("D2D1_FIGURE_BEGIN", [
- "D2D1_FIGURE_BEGIN_FILLED",
- "D2D1_FIGURE_BEGIN_HOLLOW",
- "D2D1_FIGURE_BEGIN_FORCE_DWORD",
-])
-
-D2D1_FIGURE_END = Enum("D2D1_FIGURE_END", [
- "D2D1_FIGURE_END_OPEN",
- "D2D1_FIGURE_END_CLOSED",
- "D2D1_FIGURE_END_FORCE_DWORD",
-])
-
-D2D1_BEZIER_SEGMENT = Struct("D2D1_BEZIER_SEGMENT", [
- (D2D1_POINT_2F, "point1"),
- (D2D1_POINT_2F, "point2"),
- (D2D1_POINT_2F, "point3"),
-])
-
-D2D1_TRIANGLE = Struct("D2D1_TRIANGLE", [
- (D2D1_POINT_2F, "point1"),
- (D2D1_POINT_2F, "point2"),
- (D2D1_POINT_2F, "point3"),
-])
-
-D2D1_PATH_SEGMENT = Enum("D2D1_PATH_SEGMENT", [
- "D2D1_PATH_SEGMENT_NONE",
- "D2D1_PATH_SEGMENT_FORCE_UNSTROKED",
- "D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN",
- "D2D1_PATH_SEGMENT_FORCE_DWORD",
-])
-
-D2D1_SWEEP_DIRECTION = Enum("D2D1_SWEEP_DIRECTION", [
- "D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE",
- "D2D1_SWEEP_DIRECTION_CLOCKWISE",
- "D2D1_SWEEP_DIRECTION_FORCE_DWORD",
-])
-
-D2D1_FILL_MODE = Enum("D2D1_FILL_MODE", [
- "D2D1_FILL_MODE_ALTERNATE",
- "D2D1_FILL_MODE_WINDING",
- "D2D1_FILL_MODE_FORCE_DWORD",
-])
-
-D2D1_ARC_SEGMENT = Struct("D2D1_ARC_SEGMENT", [
- (D2D1_POINT_2F, "point"),
- (D2D1_SIZE_F, "size"),
- (FLOAT, "rotationAngle"),
- (D2D1_SWEEP_DIRECTION, "sweepDirection"),
- (D2D1_ARC_SIZE, "arcSize"),
-])
-
-D2D1_QUADRATIC_BEZIER_SEGMENT = Struct("D2D1_QUADRATIC_BEZIER_SEGMENT", [
- (D2D1_POINT_2F, "point1"),
- (D2D1_POINT_2F, "point2"),
-])
-
-D2D1_ELLIPSE = Struct("D2D1_ELLIPSE", [
- (D2D1_POINT_2F, "point"),
- (FLOAT, "radiusX"),
- (FLOAT, "radiusY"),
-])
-
-D2D1_ROUNDED_RECT = Struct("D2D1_ROUNDED_RECT", [
- (D2D1_RECT_F, "rect"),
- (FLOAT, "radiusX"),
- (FLOAT, "radiusY"),
-])
-
-D2D1_STROKE_STYLE_PROPERTIES = Struct("D2D1_STROKE_STYLE_PROPERTIES", [
- (D2D1_CAP_STYLE, "startCap"),
- (D2D1_CAP_STYLE, "endCap"),
- (D2D1_CAP_STYLE, "dashCap"),
- (D2D1_LINE_JOIN, "lineJoin"),
- (FLOAT, "miterLimit"),
- (D2D1_DASH_STYLE, "dashStyle"),
- (FLOAT, "dashOffset"),
-])
-
-D2D1_LAYER_OPTIONS = Enum("D2D1_LAYER_OPTIONS", [
- "D2D1_LAYER_OPTIONS_NONE",
- "D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE",
- "D2D1_LAYER_OPTIONS_FORCE_DWORD",
-])
-
-D2D1_LAYER_PARAMETERS = Struct("D2D1_LAYER_PARAMETERS", [
- (D2D1_RECT_F, "contentBounds"),
- (OpaquePointer(ID2D1Geometry), "geometricMask"),
- (D2D1_ANTIALIAS_MODE, "maskAntialiasMode"),
- (D2D1_MATRIX_3X2_F, "maskTransform"),
- (FLOAT, "opacity"),
- (OpaquePointer(ID2D1Brush), "opacityBrush"),
- (D2D1_LAYER_OPTIONS, "layerOptions"),
-])
-
-D2D1_WINDOW_STATE = Enum("D2D1_WINDOW_STATE", [
- "D2D1_WINDOW_STATE_NONE",
- "D2D1_WINDOW_STATE_OCCLUDED",
- "D2D1_WINDOW_STATE_FORCE_DWORD",
-])
-
-D2D1_RENDER_TARGET_TYPE = Enum("D2D1_RENDER_TARGET_TYPE", [
- "D2D1_RENDER_TARGET_TYPE_DEFAULT",
- "D2D1_RENDER_TARGET_TYPE_SOFTWARE",
- "D2D1_RENDER_TARGET_TYPE_HARDWARE",
- "D2D1_RENDER_TARGET_TYPE_FORCE_DWORD",
-])
-
-D2D1_FEATURE_LEVEL = Enum("D2D1_FEATURE_LEVEL", [
- "D2D1_FEATURE_LEVEL_DEFAULT",
- "D2D1_FEATURE_LEVEL_9",
- "D2D1_FEATURE_LEVEL_10",
- "D2D1_FEATURE_LEVEL_FORCE_DWORD",
-])
-
-D2D1_RENDER_TARGET_USAGE = Enum("D2D1_RENDER_TARGET_USAGE", [
- "D2D1_RENDER_TARGET_USAGE_NONE",
- "D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING",
- "D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE",
- "D2D1_RENDER_TARGET_USAGE_FORCE_DWORD",
-])
-
-D2D1_PRESENT_OPTIONS = Enum("D2D1_PRESENT_OPTIONS", [
- "D2D1_PRESENT_OPTIONS_NONE",
- "D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS",
- "D2D1_PRESENT_OPTIONS_IMMEDIATELY",
- "D2D1_PRESENT_OPTIONS_FORCE_DWORD",
-])
-
-D2D1_RENDER_TARGET_PROPERTIES = Struct("D2D1_RENDER_TARGET_PROPERTIES", [
- (D2D1_RENDER_TARGET_TYPE, "type"),
- (D2D1_PIXEL_FORMAT, "pixelFormat"),
- (FLOAT, "dpiX"),
- (FLOAT, "dpiY"),
- (D2D1_RENDER_TARGET_USAGE, "usage"),
- (D2D1_FEATURE_LEVEL, "minLevel"),
-])
-
-D2D1_HWND_RENDER_TARGET_PROPERTIES = Struct("D2D1_HWND_RENDER_TARGET_PROPERTIES", [
- (HWND, "hwnd"),
- (D2D1_SIZE_U, "pixelSize"),
- (D2D1_PRESENT_OPTIONS, "presentOptions"),
-])
-
-D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS = Enum("D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS", [
- "D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE",
- "D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE",
- "D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_FORCE_DWORD",
-])
-
-D2D1_DRAWING_STATE_DESCRIPTION = Struct("D2D1_DRAWING_STATE_DESCRIPTION", [
- (D2D1_ANTIALIAS_MODE, "antialiasMode"),
- (D2D1_TEXT_ANTIALIAS_MODE, "textAntialiasMode"),
- (D2D1_TAG, "tag1"),
- (D2D1_TAG, "tag2"),
- (D2D1_MATRIX_3X2_F, "transform"),
-])
-
-D2D1_DC_INITIALIZE_MODE = Enum("D2D1_DC_INITIALIZE_MODE", [
- "D2D1_DC_INITIALIZE_MODE_COPY",
- "D2D1_DC_INITIALIZE_MODE_CLEAR",
- "D2D1_DC_INITIALIZE_MODE_FORCE_DWORD",
-])
-
-D2D1_DEBUG_LEVEL = Enum("D2D1_DEBUG_LEVEL", [
- "D2D1_DEBUG_LEVEL_NONE",
- "D2D1_DEBUG_LEVEL_ERROR",
- "D2D1_DEBUG_LEVEL_WARNING",
- "D2D1_DEBUG_LEVEL_INFORMATION",
- "D2D1_DEBUG_LEVEL_FORCE_DWORD",
-])
-
-D2D1_FACTORY_TYPE = Enum("D2D1_FACTORY_TYPE", [
- "D2D1_FACTORY_TYPE_SINGLE_THREADED",
- "D2D1_FACTORY_TYPE_MULTI_THREADED",
- "D2D1_FACTORY_TYPE_FORCE_DWORD",
-])
-
-D2D1_FACTORY_OPTIONS = Struct("D2D1_FACTORY_OPTIONS", [
- (D2D1_DEBUG_LEVEL, "debugLevel"),
-])
-
-ID2D1Resource = Interface("ID2D1Resource", IUnknown)
-ID2D1Resource.methods += [
- Method(Void, "GetFactory", [Out(OpaquePointer(OpaquePointer(ID2D1Factory)), "factory")], const=True),
-]
-
-ID2D1Bitmap = Interface("ID2D1Bitmap", ID2D1Resource)
-ID2D1Bitmap.methods += [
- Method(D2D1_SIZE_F, "GetSize", [], const=True),
- Method(D2D1_SIZE_U, "GetPixelSize", [], const=True),
- Method(D2D1_PIXEL_FORMAT, "GetPixelFormat", [], const=True),
- Method(Void, "GetDpi", [Out(OpaquePointer(FLOAT), "dpiX"), Out(OpaquePointer(FLOAT), "dpiY")], const=True),
- Method(HRESULT, "CopyFromBitmap", [(OpaquePointer(Const(D2D1_POINT_2U)), "destPoint"), (OpaquePointer(ID2D1Bitmap), "bitmap"), (OpaquePointer(Const(D2D1_RECT_U)), "srcRect")]),
- Method(HRESULT, "CopyFromRenderTarget", [(OpaquePointer(Const(D2D1_POINT_2U)), "destPoint"), (OpaquePointer(ID2D1RenderTarget), "renderTarget"), (OpaquePointer(Const(D2D1_RECT_U)), "srcRect")]),
- Method(HRESULT, "CopyFromMemory", [(OpaquePointer(Const(D2D1_RECT_U)), "dstRect"), (OpaquePointer(Const(Void)), "srcData"), (UINT32, "pitch")]),
-]
-
-ID2D1GradientStopCollection = Interface("ID2D1GradientStopCollection", ID2D1Resource)
-ID2D1GradientStopCollection.methods += [
- Method(UINT32, "GetGradientStopCount", [], const=True),
- Method(Void, "GetGradientStops", [Out(OpaquePointer(D2D1_GRADIENT_STOP), "gradientStops"), (UINT, "gradientStopsCount")], const=True),
- Method(D2D1_GAMMA, "GetColorInterpolationGamma", [], const=True),
- Method(D2D1_EXTEND_MODE, "GetExtendMode", [], const=True),
-]
-
-ID2D1Brush = Interface("ID2D1Brush", ID2D1Resource)
-ID2D1Brush.methods += [
- Method(Void, "SetOpacity", [(FLOAT, "opacity")]),
- Method(Void, "SetTransform", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "transform")]),
- Method(FLOAT, "GetOpacity", [], const=True),
- Method(Void, "GetTransform", [Out(OpaquePointer(D2D1_MATRIX_3X2_F), "transform")], const=True),
-]
-
-ID2D1BitmapBrush = Interface("ID2D1BitmapBrush", ID2D1Brush)
-ID2D1BitmapBrush.methods += [
- Method(Void, "SetExtendModeX", [(D2D1_EXTEND_MODE, "extendModeX")]),
- Method(Void, "SetExtendModeY", [(D2D1_EXTEND_MODE, "extendModeY")]),
- Method(Void, "SetInterpolationMode", [(D2D1_BITMAP_INTERPOLATION_MODE, "interpolationMode")]),
- Method(Void, "SetBitmap", [(OpaquePointer(ID2D1Bitmap), "bitmap")]),
- Method(D2D1_EXTEND_MODE, "GetExtendModeX", [], const=True),
- Method(D2D1_EXTEND_MODE, "GetExtendModeY", [], const=True),
- Method(D2D1_BITMAP_INTERPOLATION_MODE, "GetInterpolationMode", [], const=True),
- Method(Void, "GetBitmap", [Out(OpaquePointer(OpaquePointer(ID2D1Bitmap)), "bitmap")], const=True),
-]
-
-ID2D1SolidColorBrush = Interface("ID2D1SolidColorBrush", ID2D1Brush)
-ID2D1SolidColorBrush.methods += [
- Method(Void, "SetColor", [(OpaquePointer(Const(D2D1_COLOR_F)), "color")]),
- Method(D2D1_COLOR_F, "GetColor", [], const=True),
-]
-
-ID2D1LinearGradientBrush = Interface("ID2D1LinearGradientBrush", ID2D1Brush)
-ID2D1LinearGradientBrush.methods += [
- Method(Void, "SetStartPoint", [(D2D1_POINT_2F, "startPoint")]),
- Method(Void, "SetEndPoint", [(D2D1_POINT_2F, "endPoint")]),
- Method(D2D1_POINT_2F, "GetStartPoint", [], const=True),
- Method(D2D1_POINT_2F, "GetEndPoint", [], const=True),
- Method(Void, "GetGradientStopCollection", [Out(OpaquePointer(OpaquePointer(ID2D1GradientStopCollection)), "gradientStopCollection")], const=True),
-]
-
-ID2D1RadialGradientBrush = Interface("ID2D1RadialGradientBrush", ID2D1Brush)
-ID2D1RadialGradientBrush.methods += [
- Method(Void, "SetCenter", [(D2D1_POINT_2F, "center")]),
- Method(Void, "SetGradientOriginOffset", [(D2D1_POINT_2F, "gradientOriginOffset")]),
- Method(Void, "SetRadiusX", [(FLOAT, "radiusX")]),
- Method(Void, "SetRadiusY", [(FLOAT, "radiusY")]),
- Method(D2D1_POINT_2F, "GetCenter", [], const=True),
- Method(D2D1_POINT_2F, "GetGradientOriginOffset", [], const=True),
- Method(FLOAT, "GetRadiusX", [], const=True),
- Method(FLOAT, "GetRadiusY", [], const=True),
- Method(Void, "GetGradientStopCollection", [Out(OpaquePointer(OpaquePointer(ID2D1GradientStopCollection)), "gradientStopCollection")], const=True),
-]
-
-ID2D1StrokeStyle = Interface("ID2D1StrokeStyle", ID2D1Resource)
-ID2D1StrokeStyle.methods += [
- Method(D2D1_CAP_STYLE, "GetStartCap", [], const=True),
- Method(D2D1_CAP_STYLE, "GetEndCap", [], const=True),
- Method(D2D1_CAP_STYLE, "GetDashCap", [], const=True),
- Method(FLOAT, "GetMiterLimit", [], const=True),
- Method(D2D1_LINE_JOIN, "GetLineJoin", [], const=True),
- Method(FLOAT, "GetDashOffset", [], const=True),
- Method(D2D1_DASH_STYLE, "GetDashStyle", [], const=True),
- Method(UINT32, "GetDashesCount", [], const=True),
- Method(Void, "GetDashes", [Out(OpaquePointer(FLOAT), "dashes"), (UINT, "dashesCount")], const=True),
-]
-
-ID2D1Geometry = Interface("ID2D1Geometry", ID2D1Resource)
-ID2D1Geometry.methods += [
- Method(HRESULT, "GetBounds", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), Out(OpaquePointer(D2D1_RECT_F), "bounds")], const=True),
- Method(HRESULT, "GetWidenedBounds", [(FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(D2D1_RECT_F), "bounds")], const=True),
- Method(HRESULT, "StrokeContainsPoint", [(D2D1_POINT_2F, "point"), (FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(BOOL), "contains")], const=True),
- Method(HRESULT, "FillContainsPoint", [(D2D1_POINT_2F, "point"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(BOOL), "contains")], const=True),
- Method(HRESULT, "CompareWithGeometry", [(OpaquePointer(ID2D1Geometry), "inputGeometry"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "inputGeometryTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(D2D1_GEOMETRY_RELATION), "relation")], const=True),
- Method(HRESULT, "Simplify", [(D2D1_GEOMETRY_SIMPLIFICATION_OPTION, "simplificationOption"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (OpaquePointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
- Method(HRESULT, "Tessellate", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (OpaquePointer(ID2D1TessellationSink), "tessellationSink")], const=True),
- Method(HRESULT, "CombineWithGeometry", [(OpaquePointer(ID2D1Geometry), "inputGeometry"), (D2D1_COMBINE_MODE, "combineMode"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "inputGeometryTransform"), (FLOAT, "flatteningTolerance"), (OpaquePointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
- Method(HRESULT, "Outline", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (OpaquePointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
- Method(HRESULT, "ComputeArea", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(FLOAT), "area")], const=True),
- Method(HRESULT, "ComputeLength", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(FLOAT), "length")], const=True),
- Method(HRESULT, "ComputePointAtLength", [(FLOAT, "length"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(OpaquePointer(D2D1_POINT_2F), "point"), Out(OpaquePointer(D2D1_POINT_2F), "unitTangentVector")], const=True),
- Method(HRESULT, "Widen", [(FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (OpaquePointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
-]
-
-ID2D1RectangleGeometry = Interface("ID2D1RectangleGeometry", ID2D1Geometry)
-ID2D1RectangleGeometry.methods += [
- Method(Void, "GetRect", [Out(OpaquePointer(D2D1_RECT_F), "rect")], const=True),
-]
-
-ID2D1RoundedRectangleGeometry = Interface("ID2D1RoundedRectangleGeometry", ID2D1Geometry)
-ID2D1RoundedRectangleGeometry.methods += [
- Method(Void, "GetRoundedRect", [Out(OpaquePointer(D2D1_ROUNDED_RECT), "roundedRect")], const=True),
-]
-
-ID2D1EllipseGeometry = Interface("ID2D1EllipseGeometry", ID2D1Geometry)
-ID2D1EllipseGeometry.methods += [
- Method(Void, "GetEllipse", [Out(OpaquePointer(D2D1_ELLIPSE), "ellipse")], const=True),
-]
-
-ID2D1GeometryGroup = Interface("ID2D1GeometryGroup", ID2D1Geometry)
-ID2D1GeometryGroup.methods += [
- Method(D2D1_FILL_MODE, "GetFillMode", [], const=True),
- Method(UINT32, "GetSourceGeometryCount", [], const=True),
- Method(Void, "GetSourceGeometries", [Out(OpaquePointer(OpaquePointer(ID2D1Geometry)), "geometries"), (UINT, "geometriesCount")], const=True),
-]
-
-ID2D1TransformedGeometry = Interface("ID2D1TransformedGeometry", ID2D1Geometry)
-ID2D1TransformedGeometry.methods += [
- Method(Void, "GetSourceGeometry", [Out(OpaquePointer(OpaquePointer(ID2D1Geometry)), "sourceGeometry")], const=True),
- Method(Void, "GetTransform", [Out(OpaquePointer(D2D1_MATRIX_3X2_F), "transform")], const=True),
-]
-
-ID2D1SimplifiedGeometrySink = Interface("ID2D1SimplifiedGeometrySink", IUnknown)
-ID2D1SimplifiedGeometrySink.methods += [
- Method(Void, "SetFillMode", [(D2D1_FILL_MODE, "fillMode")]),
- Method(Void, "SetSegmentFlags", [(D2D1_PATH_SEGMENT, "vertexFlags")]),
- Method(Void, "BeginFigure", [(D2D1_POINT_2F, "startPoint"), (D2D1_FIGURE_BEGIN, "figureBegin")]),
- Method(Void, "AddLines", [(OpaquePointer(Const(D2D1_POINT_2F)), "points"), (UINT, "pointsCount")]),
- Method(Void, "AddBeziers", [(OpaquePointer(Const(D2D1_BEZIER_SEGMENT)), "beziers"), (UINT, "beziersCount")]),
- Method(Void, "EndFigure", [(D2D1_FIGURE_END, "figureEnd")]),
- Method(HRESULT, "Close", []),
-]
-
-ID2D1GeometrySink = Interface("ID2D1GeometrySink", ID2D1SimplifiedGeometrySink)
-ID2D1GeometrySink.methods += [
- Method(Void, "AddLine", [(D2D1_POINT_2F, "point")]),
- Method(Void, "AddBezier", [(OpaquePointer(Const(D2D1_BEZIER_SEGMENT)), "bezier")]),
- Method(Void, "AddQuadraticBezier", [(OpaquePointer(Const(D2D1_QUADRATIC_BEZIER_SEGMENT)), "bezier")]),
- Method(Void, "AddQuadraticBeziers", [(OpaquePointer(Const(D2D1_QUADRATIC_BEZIER_SEGMENT)), "beziers"), (UINT, "beziersCount")]),
- Method(Void, "AddArc", [(OpaquePointer(Const(D2D1_ARC_SEGMENT)), "arc")]),
-]
-
-ID2D1TessellationSink = Interface("ID2D1TessellationSink", IUnknown)
-ID2D1TessellationSink.methods += [
- Method(Void, "AddTriangles", [(OpaquePointer(Const(D2D1_TRIANGLE)), "triangles"), (UINT, "trianglesCount")]),
- Method(HRESULT, "Close", []),
-]
-
-ID2D1PathGeometry = Interface("ID2D1PathGeometry", ID2D1Geometry)
-ID2D1PathGeometry.methods += [
- Method(HRESULT, "Open", [Out(OpaquePointer(OpaquePointer(ID2D1GeometrySink)), "geometrySink")]),
- Method(HRESULT, "Stream", [(OpaquePointer(ID2D1GeometrySink), "geometrySink")], const=True),
- Method(HRESULT, "GetSegmentCount", [Out(OpaquePointer(UINT32), "count")], const=True),
- Method(HRESULT, "GetFigureCount", [Out(OpaquePointer(UINT32), "count")], const=True),
-]
-
-ID2D1Mesh = Interface("ID2D1Mesh", ID2D1Resource)
-ID2D1Mesh.methods += [
- Method(HRESULT, "Open", [Out(OpaquePointer(OpaquePointer(ID2D1TessellationSink)), "tessellationSink")]),
-]
-
-ID2D1Layer = Interface("ID2D1Layer", ID2D1Resource)
-ID2D1Layer.methods += [
- Method(D2D1_SIZE_F, "GetSize", [], const=True),
-]
-
-ID2D1DrawingStateBlock = Interface("ID2D1DrawingStateBlock", ID2D1Resource)
-ID2D1DrawingStateBlock.methods += [
- Method(Void, "GetDescription", [Out(OpaquePointer(D2D1_DRAWING_STATE_DESCRIPTION), "stateDescription")], const=True),
- Method(Void, "SetDescription", [(OpaquePointer(Const(D2D1_DRAWING_STATE_DESCRIPTION)), "stateDescription")]),
- Method(Void, "SetTextRenderingParams", [(OpaquePointer(IDWriteRenderingParams), "textRenderingParams")]),
- Method(Void, "GetTextRenderingParams", [Out(OpaquePointer(OpaquePointer(IDWriteRenderingParams)), "textRenderingParams")], const=True),
-]
-
-ID2D1RenderTarget = Interface("ID2D1RenderTarget", ID2D1Resource)
-ID2D1RenderTarget.methods += [
- Method(HRESULT, "CreateBitmap", [(D2D1_SIZE_U, "size"), (OpaquePointer(Const(Void)), "srcData"), (UINT32, "pitch"), (OpaquePointer(Const(D2D1_BITMAP_PROPERTIES)), "bitmapProperties"), Out(OpaquePointer(OpaquePointer(ID2D1Bitmap)), "bitmap")]),
- Method(HRESULT, "CreateBitmapFromWicBitmap", [(OpaquePointer(IWICBitmapSource), "wicBitmapSource"), (OpaquePointer(Const(D2D1_BITMAP_PROPERTIES)), "bitmapProperties"), Out(OpaquePointer(OpaquePointer(ID2D1Bitmap)), "bitmap")]),
- Method(HRESULT, "CreateSharedBitmap", [(REFIID, "riid"), Out(OpaquePointer(Void), "data"), (OpaquePointer(Const(D2D1_BITMAP_PROPERTIES)), "bitmapProperties"), Out(OpaquePointer(OpaquePointer(ID2D1Bitmap)), "bitmap")]),
- Method(HRESULT, "CreateBitmapBrush", [(OpaquePointer(ID2D1Bitmap), "bitmap"), (OpaquePointer(Const(D2D1_BITMAP_BRUSH_PROPERTIES)), "bitmapBrushProperties"), (OpaquePointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), Out(OpaquePointer(OpaquePointer(ID2D1BitmapBrush)), "bitmapBrush")]),
- Method(HRESULT, "CreateSolidColorBrush", [(OpaquePointer(Const(D2D1_COLOR_F)), "color"), (OpaquePointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), Out(OpaquePointer(OpaquePointer(ID2D1SolidColorBrush)), "solidColorBrush")]),
- Method(HRESULT, "CreateGradientStopCollection", [(OpaquePointer(Const(D2D1_GRADIENT_STOP)), "gradientStops"), (UINT, "gradientStopsCount"), (D2D1_GAMMA, "colorInterpolationGamma"), (D2D1_EXTEND_MODE, "extendMode"), Out(OpaquePointer(OpaquePointer(ID2D1GradientStopCollection)), "gradientStopCollection")]),
- Method(HRESULT, "CreateLinearGradientBrush", [(OpaquePointer(Const(D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)), "linearGradientBrushProperties"), (OpaquePointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), (OpaquePointer(ID2D1GradientStopCollection), "gradientStopCollection"), Out(OpaquePointer(OpaquePointer(ID2D1LinearGradientBrush)), "linearGradientBrush")]),
- Method(HRESULT, "CreateRadialGradientBrush", [(OpaquePointer(Const(D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES)), "radialGradientBrushProperties"), (OpaquePointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), (OpaquePointer(ID2D1GradientStopCollection), "gradientStopCollection"), Out(OpaquePointer(OpaquePointer(ID2D1RadialGradientBrush)), "radialGradientBrush")]),
- Method(HRESULT, "CreateCompatibleRenderTarget", [(OpaquePointer(Const(D2D1_SIZE_F)), "desiredSize"), (OpaquePointer(Const(D2D1_SIZE_U)), "desiredPixelSize"), (OpaquePointer(Const(D2D1_PIXEL_FORMAT)), "desiredFormat"), (D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS, "options"), Out(OpaquePointer(OpaquePointer(ID2D1BitmapRenderTarget)), "bitmapRenderTarget")]),
- Method(HRESULT, "CreateLayer", [(OpaquePointer(Const(D2D1_SIZE_F)), "size"), Out(OpaquePointer(OpaquePointer(ID2D1Layer)), "layer")]),
- Method(HRESULT, "CreateMesh", [Out(OpaquePointer(OpaquePointer(ID2D1Mesh)), "mesh")]),
- Method(Void, "DrawLine", [(D2D1_POINT_2F, "point0"), (D2D1_POINT_2F, "point1"), (OpaquePointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle")]),
- Method(Void, "DrawRectangle", [(OpaquePointer(Const(D2D1_RECT_F)), "rect"), (OpaquePointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle")]),
- Method(Void, "FillRectangle", [(OpaquePointer(Const(D2D1_RECT_F)), "rect"), (OpaquePointer(ID2D1Brush), "brush")]),
- Method(Void, "DrawRoundedRectangle", [(OpaquePointer(Const(D2D1_ROUNDED_RECT)), "roundedRect"), (OpaquePointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle")]),
- Method(Void, "FillRoundedRectangle", [(OpaquePointer(Const(D2D1_ROUNDED_RECT)), "roundedRect"), (OpaquePointer(ID2D1Brush), "brush")]),
- Method(Void, "DrawEllipse", [(OpaquePointer(Const(D2D1_ELLIPSE)), "ellipse"), (OpaquePointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle")]),
- Method(Void, "FillEllipse", [(OpaquePointer(Const(D2D1_ELLIPSE)), "ellipse"), (OpaquePointer(ID2D1Brush), "brush")]),
- Method(Void, "DrawGeometry", [(OpaquePointer(ID2D1Geometry), "geometry"), (OpaquePointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (OpaquePointer(ID2D1StrokeStyle), "strokeStyle")]),
- Method(Void, "FillGeometry", [(OpaquePointer(ID2D1Geometry), "geometry"), (OpaquePointer(ID2D1Brush), "brush"), (OpaquePointer(ID2D1Brush), "opacityBrush")]),
- Method(Void, "FillMesh", [(OpaquePointer(ID2D1Mesh), "mesh"), (OpaquePointer(ID2D1Brush), "brush")]),
- Method(Void, "FillOpacityMask", [(OpaquePointer(ID2D1Bitmap), "opacityMask"), (OpaquePointer(ID2D1Brush), "brush"), (D2D1_OPACITY_MASK_CONTENT, "content"), (OpaquePointer(Const(D2D1_RECT_F)), "destinationRectangle"), (OpaquePointer(Const(D2D1_RECT_F)), "sourceRectangle")]),
- Method(Void, "DrawBitmap", [(OpaquePointer(ID2D1Bitmap), "bitmap"), (OpaquePointer(Const(D2D1_RECT_F)), "destinationRectangle"), (FLOAT, "opacity"), (D2D1_BITMAP_INTERPOLATION_MODE, "interpolationMode"), (OpaquePointer(Const(D2D1_RECT_F)), "sourceRectangle")]),
- Method(Void, "DrawText", [(OpaquePointer(Const(WCHAR)), "string"), (UINT, "stringLength"), (OpaquePointer(IDWriteTextFormat), "textFormat"), (OpaquePointer(Const(D2D1_RECT_F)), "layoutRect"), (OpaquePointer(ID2D1Brush), "defaultForegroundBrush"), (D2D1_DRAW_TEXT_OPTIONS, "options"), (DWRITE_MEASURING_MODE, "measuringMode")]),
- Method(Void, "DrawTextLayout", [(D2D1_POINT_2F, "origin"), (OpaquePointer(IDWriteTextLayout), "textLayout"), (OpaquePointer(ID2D1Brush), "defaultForegroundBrush"), (D2D1_DRAW_TEXT_OPTIONS, "options")]),
- Method(Void, "DrawGlyphRun", [(D2D1_POINT_2F, "baselineOrigin"), (OpaquePointer(Const(DWRITE_GLYPH_RUN)), "glyphRun"), (OpaquePointer(ID2D1Brush), "foregroundBrush"), (DWRITE_MEASURING_MODE, "measuringMode")]),
- Method(Void, "SetTransform", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "transform")]),
- Method(Void, "GetTransform", [Out(OpaquePointer(D2D1_MATRIX_3X2_F), "transform")], const=True),
- Method(Void, "SetAntialiasMode", [(D2D1_ANTIALIAS_MODE, "antialiasMode")]),
- Method(D2D1_ANTIALIAS_MODE, "GetAntialiasMode", [], const=True),
- Method(Void, "SetTextAntialiasMode", [(D2D1_TEXT_ANTIALIAS_MODE, "textAntialiasMode")]),
- Method(D2D1_TEXT_ANTIALIAS_MODE, "GetTextAntialiasMode", [], const=True),
- Method(Void, "SetTextRenderingParams", [(OpaquePointer(IDWriteRenderingParams), "textRenderingParams")]),
- Method(Void, "GetTextRenderingParams", [Out(OpaquePointer(OpaquePointer(IDWriteRenderingParams)), "textRenderingParams")], const=True),
- Method(Void, "SetTags", [(D2D1_TAG, "tag1"), (D2D1_TAG, "tag2")]),
- Method(Void, "GetTags", [Out(OpaquePointer(D2D1_TAG), "tag1"), Out(OpaquePointer(D2D1_TAG), "tag2")], const=True),
- Method(Void, "PushLayer", [(OpaquePointer(Const(D2D1_LAYER_PARAMETERS)), "layerParameters"), (OpaquePointer(ID2D1Layer), "layer")]),
- Method(Void, "PopLayer", []),
- Method(HRESULT, "Flush", [Out(OpaquePointer(D2D1_TAG), "tag1"), Out(OpaquePointer(D2D1_TAG), "tag2")]),
- Method(Void, "SaveDrawingState", [Out(OpaquePointer(ID2D1DrawingStateBlock), "drawingStateBlock")], const=True),
- Method(Void, "RestoreDrawingState", [(OpaquePointer(ID2D1DrawingStateBlock), "drawingStateBlock")]),
- Method(Void, "PushAxisAlignedClip", [(OpaquePointer(Const(D2D1_RECT_F)), "clipRect"), (D2D1_ANTIALIAS_MODE, "antialiasMode")]),
- Method(Void, "PopAxisAlignedClip", []),
- Method(Void, "Clear", [(OpaquePointer(Const(D2D1_COLOR_F)), "clearColor")]),
- Method(Void, "BeginDraw", []),
- Method(HRESULT, "EndDraw", [Out(OpaquePointer(D2D1_TAG), "tag1"), Out(OpaquePointer(D2D1_TAG), "tag2")]),
- Method(D2D1_PIXEL_FORMAT, "GetPixelFormat", [], const=True),
- Method(Void, "SetDpi", [(FLOAT, "dpiX"), (FLOAT, "dpiY")]),
- Method(Void, "GetDpi", [Out(OpaquePointer(FLOAT), "dpiX"), Out(OpaquePointer(FLOAT), "dpiY")], const=True),
- Method(D2D1_SIZE_F, "GetSize", [], const=True),
- Method(D2D1_SIZE_U, "GetPixelSize", [], const=True),
- Method(UINT32, "GetMaximumBitmapSize", [], const=True),
- Method(BOOL, "IsSupported", [(OpaquePointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties")], const=True),
-]
-
-ID2D1BitmapRenderTarget = Interface("ID2D1BitmapRenderTarget", ID2D1RenderTarget)
-ID2D1BitmapRenderTarget.methods += [
- Method(HRESULT, "GetBitmap", [Out(OpaquePointer(OpaquePointer(ID2D1Bitmap)), "bitmap")]),
-]
-
-ID2D1HwndRenderTarget = Interface("ID2D1HwndRenderTarget", ID2D1RenderTarget)
-ID2D1HwndRenderTarget.methods += [
- Method(D2D1_WINDOW_STATE, "CheckWindowState", []),
- Method(HRESULT, "Resize", [(OpaquePointer(Const(D2D1_SIZE_U)), "pixelSize")]),
- Method(HWND, "GetHwnd", [], const=True),
-]
-
-ID2D1GdiInteropRenderTarget = Interface("ID2D1GdiInteropRenderTarget", IUnknown)
-ID2D1GdiInteropRenderTarget.methods += [
- Method(HRESULT, "GetDC", [(D2D1_DC_INITIALIZE_MODE, "mode"), Out(OpaquePointer(HDC), "hdc")]),
- Method(HRESULT, "ReleaseDC", [(OpaquePointer(Const(RECT)), "update")]),
-]
-
-ID2D1DCRenderTarget = Interface("ID2D1DCRenderTarget", ID2D1RenderTarget)
-ID2D1DCRenderTarget.methods += [
- Method(HRESULT, "BindDC", [(Const(HDC), "hDC"), (OpaquePointer(Const(RECT)), "pSubRect")]),
-]
-
-ID2D1Factory = Interface("ID2D1Factory", IUnknown)
-ID2D1Factory.methods += [
- Method(HRESULT, "ReloadSystemMetrics", []),
- Method(Void, "GetDesktopDpi", [Out(OpaquePointer(FLOAT), "dpiX"), Out(OpaquePointer(FLOAT), "dpiY")]),
- Method(HRESULT, "CreateRectangleGeometry", [(OpaquePointer(Const(D2D1_RECT_F)), "rectangle"), Out(OpaquePointer(OpaquePointer(ID2D1RectangleGeometry)), "rectangleGeometry")]),
- Method(HRESULT, "CreateRoundedRectangleGeometry", [(OpaquePointer(Const(D2D1_ROUNDED_RECT)), "roundedRectangle"), Out(OpaquePointer(OpaquePointer(ID2D1RoundedRectangleGeometry)), "roundedRectangleGeometry")]),
- Method(HRESULT, "CreateEllipseGeometry", [(OpaquePointer(Const(D2D1_ELLIPSE)), "ellipse"), Out(OpaquePointer(OpaquePointer(ID2D1EllipseGeometry)), "ellipseGeometry")]),
- Method(HRESULT, "CreateGeometryGroup", [(D2D1_FILL_MODE, "fillMode"), (OpaquePointer(OpaquePointer(ID2D1Geometry)), "geometries"), (UINT, "geometriesCount"), Out(OpaquePointer(OpaquePointer(ID2D1GeometryGroup)), "geometryGroup")]),
- Method(HRESULT, "CreateTransformedGeometry", [(OpaquePointer(ID2D1Geometry), "sourceGeometry"), (OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "transform"), Out(OpaquePointer(OpaquePointer(ID2D1TransformedGeometry)), "transformedGeometry")]),
- Method(HRESULT, "CreatePathGeometry", [Out(OpaquePointer(OpaquePointer(ID2D1PathGeometry)), "pathGeometry")]),
- Method(HRESULT, "CreateStrokeStyle", [(OpaquePointer(Const(D2D1_STROKE_STYLE_PROPERTIES)), "strokeStyleProperties"), (OpaquePointer(Const(FLOAT)), "dashes"), (UINT, "dashesCount"), Out(OpaquePointer(OpaquePointer(ID2D1StrokeStyle)), "strokeStyle")]),
- Method(HRESULT, "CreateDrawingStateBlock", [(OpaquePointer(Const(D2D1_DRAWING_STATE_DESCRIPTION)), "drawingStateDescription"), (OpaquePointer(IDWriteRenderingParams), "textRenderingParams"), Out(OpaquePointer(OpaquePointer(ID2D1DrawingStateBlock)), "drawingStateBlock")]),
- Method(HRESULT, "CreateWicBitmapRenderTarget", [(OpaquePointer(IWICBitmap), "target"), (OpaquePointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), Out(OpaquePointer(OpaquePointer(ID2D1RenderTarget)), "renderTarget")]),
- Method(HRESULT, "CreateHwndRenderTarget", [(OpaquePointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), (OpaquePointer(Const(D2D1_HWND_RENDER_TARGET_PROPERTIES)), "hwndRenderTargetProperties"), Out(OpaquePointer(OpaquePointer(ID2D1HwndRenderTarget)), "hwndRenderTarget")]),
- Method(HRESULT, "CreateDxgiSurfaceRenderTarget", [(OpaquePointer(IDXGISurface), "dxgiSurface"), (OpaquePointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), Out(OpaquePointer(OpaquePointer(ID2D1RenderTarget)), "renderTarget")]),
- Method(HRESULT, "CreateDCRenderTarget", [(OpaquePointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), Out(OpaquePointer(OpaquePointer(ID2D1DCRenderTarget)), "dcRenderTarget")]),
-]
-
- StdFunction(HRESULT, "D2D1CreateFactory", [(D2D1_FACTORY_TYPE, "factoryType"), (REFIID, "riid"), (OpaquePointer(Const(D2D1_FACTORY_OPTIONS)), "pFactoryOptions"), Out(OpaquePointer(OpaquePointer(Void)), "ppIFactory")]),
- StdFunction(Void, "D2D1MakeRotateMatrix", [(FLOAT, "angle"), (D2D1_POINT_2F, "center"), Out(OpaquePointer(D2D1_MATRIX_3X2_F), "matrix")]),
- StdFunction(Void, "D2D1MakeSkewMatrix", [(FLOAT, "angleX"), (FLOAT, "angleY"), (D2D1_POINT_2F, "center"), Out(OpaquePointer(D2D1_MATRIX_3X2_F), "matrix")]),
- StdFunction(BOOL, "D2D1IsMatrixInvertible", [(OpaquePointer(Const(D2D1_MATRIX_3X2_F)), "matrix")]),
- StdFunction(BOOL, "D2D1InvertMatrix", [Out(OpaquePointer(D2D1_MATRIX_3X2_F), "matrix")]),
--- /dev/null
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library (getopt_bundled STATIC
+ getopt_long.c
+)
--- /dev/null
+/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */
+/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+/*
+ * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
+ */
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option {
+ /* name of long option */
+ const char *name;
+ /*
+ * one of no_argument, required_argument, and optional_argument:
+ * whether option takes an argument
+ */
+ int has_arg;
+ /* if not NULL, set *flag to val when option found */
+ int *flag;
+ /* if flag not NULL, value to set *flag to; else return value */
+ int val;
+};
+
+int getopt_long(int, char * const *, const char *,
+ const struct option *, int *);
+int getopt_long_only(int, char * const *, const char *,
+ const struct option *, int *);
+#ifndef _GETOPT_DEFINED_
+#define _GETOPT_DEFINED_
+int getopt(int, char * const *, const char *);
+int getsubopt(char **, char * const *, char **);
+
+extern char *optarg; /* getopt(3) external variables */
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern int optreset;
+extern char *suboptarg; /* getsubopt(3) external variable */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_GETOPT_H_ */
--- /dev/null
+/* $OpenBSD: getopt_long.c,v 1.24 2010/07/22 19:31:53 blambert Exp $ */
+/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+int optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define PRINT_ERROR ((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
+#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define EMSG ""
+
+static int getopt_internal(int, char * const *, const char *,
+ const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+ const struct option *, int *, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+ char * const *nargv)
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end+i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ /* LINTED const cast */
+ ((char **) nargv)[pos] = nargv[cstart];
+ /* LINTED const cast */
+ ((char **)nargv)[cstart] = swap;
+ }
+ }
+}
+
+/*
+ * parse_long_options --
+ * Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int short_too)
+{
+ char *current_argv, *has_equal;
+ size_t current_argv_len;
+ int i, match;
+
+ current_argv = place;
+ match = -1;
+
+ optind++;
+
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ } else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) == current_argv_len) {
+ /* exact match */
+ match = i;
+ break;
+ }
+ /*
+ * If this is a known short option, don't allow
+ * a partial match of a single character.
+ */
+ if (short_too && current_argv_len == 1)
+ continue;
+
+ if (match == -1) /* partial match */
+ match = i;
+ else {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ fprintf(stderr, ambig, (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+ if (PRINT_ERROR)
+ fprintf(stderr, noarg, (int)current_argv_len,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ return (BADARG);
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':' indicates no error
+ * should be generated.
+ */
+ if (PRINT_ERROR)
+ fprintf(stderr, recargstring,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return (BADARG);
+ }
+ } else { /* unknown option */
+ if (short_too) {
+ --optind;
+ return (-1);
+ }
+ if (PRINT_ERROR)
+ fprintf(stderr, illoptstring, current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (idx)
+ *idx = match;
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ return (0);
+ } else
+ return (long_options[match].val);
+}
+
+/*
+ * getopt_internal --
+ * Parse argc/argv argument vector. Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int flags)
+{
+ char *oli; /* option letter list index */
+ int optchar, short_too;
+ static int posixly_correct = -1;
+
+ if (options == NULL)
+ return (-1);
+
+ /*
+ * Disable GNU extensions if POSIXLY_CORRECT is set or options
+ * string begins with a '+'.
+ */
+ if (posixly_correct == -1)
+ posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+ if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+ else if (*options == '-')
+ flags |= FLAG_ALLARGS;
+ if (*options == '+' || *options == '-')
+ options++;
+
+ /*
+ * XXX Some GNU programs (like cvs) set optind to 0 instead of
+ * XXX using optreset. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = optreset = 1;
+
+ optarg = NULL;
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ if (*(place = nargv[optind]) != '-' ||
+ (place[1] == '\0' && strchr(options, '-') == NULL)) {
+ place = EMSG; /* found non-option */
+ if (flags & FLAG_ALLARGS) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return (INORDER);
+ }
+ if (!(flags & FLAG_PERMUTE)) {
+ /*
+ * If no permutation wanted, stop parsing
+ * at first non-option.
+ */
+ return (-1);
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+
+ /*
+ * If we have "-" do nothing, if "--" we are done.
+ */
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+ optind++;
+ place = EMSG;
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ }
+
+ /*
+ * Check long options if:
+ * 1) we were passed some
+ * 2) the arg is not just "-"
+ * 3) either the arg starts with -- we are getopt_long_only()
+ */
+ if (long_options != NULL && place != nargv[optind] &&
+ (*place == '-' || (flags & FLAG_LONGONLY))) {
+ short_too = 0;
+ if (*place == '-')
+ place++; /* --foo long option */
+ else if (*place != ':' && strchr(options, *place) != NULL)
+ short_too = 1; /* could be short option too */
+
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, short_too);
+ if (optchar != -1) {
+ place = EMSG;
+ return (optchar);
+ }
+ }
+
+ if ((optchar = (int)*place++) == (int)':' ||
+ (optchar == (int)'-' && *place != '\0') ||
+ (oli = strchr(options, optchar)) == NULL) {
+ /*
+ * If the user specified "-" and '-' isn't listed in
+ * options, return -1 (non-option) as per POSIX.
+ * Otherwise, it is an unknown option character (or ':').
+ */
+ if (optchar == (int)'-' && *place == '\0')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (PRINT_ERROR)
+ fprintf(stderr, illoptchar, optchar);
+ optopt = optchar;
+ return (BADCH);
+ }
+ if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+ /* -W long-option */
+ if (*place) /* no space */
+ /* NOTHING */;
+ else if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ fprintf(stderr, recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else /* white space */
+ place = nargv[optind];
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, 0);
+ place = EMSG;
+ return (optchar);
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ } else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = place;
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ fprintf(stderr, recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else
+ optarg = nargv[optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return (optchar);
+}
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the BSD getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+ /*
+ * We don't pass FLAG_PERMUTE to getopt_internal() since
+ * the BSD getopt(3) (unlike GNU) has never done this.
+ *
+ * Furthermore, since many privileged programs call getopt()
+ * before dropping privileges it makes sense to keep things
+ * as simple (and bug-free) as possible.
+ */
+ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+
+/*
+ * getopt_long --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE|FLAG_LONGONLY));
+}
print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
def visitString(self, string, instance):
+ if string.kind == 'String':
+ cast = 'const char *'
+ elif string.kind == 'WString':
+ cast = 'const wchar_t *'
+ else:
+ assert False
+ if cast != string.expr:
+ # reinterpret_cast is necessary for GLubyte * <=> char *
+ instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
if string.length is not None:
- print ' trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
+ length = ', %s' % string.length
else:
- print ' trace::localWriter.writeString((const char *)%s);' % instance
+ length = ''
+ print ' trace::localWriter.write%s(%s%s);' % (string.kind, instance, length)
def visitConst(self, const, instance):
self.visit(const.type, instance)
print
# Generate the serializer functions
- types = api.all_types()
+ types = api.getAllTypes()
visitor = ComplexValueSerializer(self.serializerFactory())
map(visitor.visit, types)
print
# Interfaces wrapers
- interfaces = [type for type in types if isinstance(type, stdapi.Interface)]
+ interfaces = api.getAllInterfaces()
map(self.declareWrapperInterface, interfaces)
map(self.implementWrapperInterface, interfaces)
print
print ' trace::localWriter.beginArg(0);'
print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
print ' trace::localWriter.endArg();'
+
+ from specs.winapi import REFIID
+ from specs.stdapi import Pointer, Opaque
+
+ riid = None
for arg in method.args:
if not arg.output:
self.unwrapArg(method, arg)
self.serializeArg(method, arg)
+ if arg.type is REFIID:
+ riid = arg
print ' trace::localWriter.endEnter();'
self.invokeMethod(interface, base, method)
if arg.output:
self.serializeArg(method, arg)
self.wrapArg(method, arg)
+ if riid is not None and isinstance(arg.type, Pointer):
+ assert isinstance(arg.type.type, Opaque)
+ self.wrapIid(interface, method, riid, arg)
+
if method.type is not stdapi.Void:
print ' trace::localWriter.beginReturn();'
self.serializeValue(method.type, "__result")
print ' trace::localWriter.endReturn();'
self.wrapValue(method.type, '__result')
print ' trace::localWriter.endLeave();'
- if method.name == 'QueryInterface':
- print ' if (ppvObj && *ppvObj) {'
- print ' if (*ppvObj == m_pInstance) {'
- print ' *ppvObj = this;'
+ if method.name == 'Release':
+ assert method.type is not stdapi.Void
+ print ' if (!__result)'
+ print ' delete this;'
+
+ def wrapIid(self, interface, method, riid, out):
+ print ' if (%s && *%s) {' % (out.name, out.name)
+ print ' if (*%s == m_pInstance) {' % (out.name,)
+ print ' *%s = this;' % (out.name,)
print ' }'
for iface in self.api.interfaces:
- print r' else if (riid == IID_%s) {' % iface.name
- print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
+ print r' else if (%s == IID_%s) {' % (riid.name, iface.name)
+ print r' *%s = new Wrap%s((%s *) *%s);' % (out.name, iface.name, iface.name, out.name)
print r' }'
print r' else {'
print r' os::log("apitrace: warning: unknown REFIID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
- print r' riid.Data1, riid.Data2, riid.Data3,'
- print r' riid.Data4[0],'
- print r' riid.Data4[1],'
- print r' riid.Data4[2],'
- print r' riid.Data4[3],'
- print r' riid.Data4[4],'
- print r' riid.Data4[5],'
- print r' riid.Data4[6],'
- print r' riid.Data4[7]);'
+ print r' %s.Data1, %s.Data2, %s.Data3,' % (riid.name, riid.name, riid.name)
+ print r' %s.Data4[0],' % (riid.name,)
+ print r' %s.Data4[1],' % (riid.name,)
+ print r' %s.Data4[2],' % (riid.name,)
+ print r' %s.Data4[3],' % (riid.name,)
+ print r' %s.Data4[4],' % (riid.name,)
+ print r' %s.Data4[5],' % (riid.name,)
+ print r' %s.Data4[6],' % (riid.name,)
+ print r' %s.Data4[7]);' % (riid.name,)
print r' }'
print ' }'
- if method.name == 'Release':
- assert method.type is not stdapi.Void
- print ' if (!__result)'
- print ' delete this;'
def invokeMethod(self, interface, base, method):
if method.type is stdapi.Void: