[v2,4/4] kernel-shark-qt: Add an example showing how to draw shapes and Graphs.
diff mbox series

Message ID 20180824142116.21339-5-y.karadz@gmail.com
State New, archived
Headers show
Series
  • Add drawing instrumentation to be used by the Qt-based KernelShark
Related show

Commit Message

Yordan Karadzhov (VMware) Aug. 24, 2018, 2:21 p.m. UTC
This patch introduces a basic example, showing how to initialize OpenGL
and how to use the C++ API in order to draw simple shapes or to show
animated Graphs.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark-qt/examples/CMakeLists.txt |   4 +
 kernel-shark-qt/examples/dataplot.cpp   | 217 ++++++++++++++++++++++++
 2 files changed, 221 insertions(+)
 create mode 100644 kernel-shark-qt/examples/dataplot.cpp

Comments

Steven Rostedt Aug. 24, 2018, 3:23 p.m. UTC | #1
On Fri, 24 Aug 2018 17:21:16 +0300
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:

> +int main(int argc, char **argv)
> +{
> +	struct kshark_context *kshark_ctx(nullptr);
> +	struct kshark_entry **data(nullptr);
> +	static char *input_file;
> +	bool status, shapes(false);
> +	size_t r, n_rows;
> +	int c, nBins;
> +
> +	while ((c = getopt(argc, argv, "si")) != -1) {
> +		switch(c) {
> +		case 'i':
> +			input_file = optarg;
> +			break;
> +		case 's':
> +			shapes = true;
> +
> +		default:
> +			break;
> +		}
> +	}
> +
> +	/* Create a new kshark session. */
> +	if (!kshark_instance(&kshark_ctx))

Should make some warning message. I ran this from the build directory
like:

 ../bin/dplot ../../trace.dat

and it did nothing. But if I ran it from the trace-cmd.git repo as

kernel-shark-qt/bin/dplot trace.dat

Then it did something. We need to make it work when called from
anywhere with a path to any trace.dat file. And give some kind of
message if no parameter is passed in.

Hmm, we should also probably make a separate directory for example
programs. Perhaps have a "demo" directory for these?

-- Steve

> +		return 1;
> +
> +	/* Open a trace data file produced by trace-cmd. */
> +	if (input_file)
> +		status = kshark_open(kshark_ctx, input_file);
> +	else
> +		status = kshark_open(kshark_ctx, default_file);
> +
> +	if (!status) {
> +		kshark_free(kshark_ctx);
> +		return 1;
> +	}
> +
Yordan Karadzhov (VMware) Aug. 24, 2018, 9:19 p.m. UTC | #2
On 24.08.2018 18:23, Steven Rostedt wrote:
> Should make some warning message. I ran this from the build directory
> like:
> 
>   ../bin/dplot ../../trace.dat
> 
> and it did nothing. But if I ran it from the trace-cmd.git repo as
> 
> kernel-shark-qt/bin/dplot trace.dat
> 

You are right, this example is a mess. I will fix the bugs and will add 
a help message.

> Then it did something. We need to make it work when called from
> anywhere with a path to any trace.dat file. And give some kind of
> message if no parameter is passed in.
> 
> Hmm, we should also probably make a separate directory for example
> programs. Perhaps have a "demo" directory for these?

Yes, we can do this. Or maybe we can even move the examples to a 
different repo and call it "kshark_demos"?

Thanks!
Yordan

> 
> -- Steve

Patch
diff mbox series

diff --git a/kernel-shark-qt/examples/CMakeLists.txt b/kernel-shark-qt/examples/CMakeLists.txt
index a3745fa..0c83293 100644
--- a/kernel-shark-qt/examples/CMakeLists.txt
+++ b/kernel-shark-qt/examples/CMakeLists.txt
@@ -15,3 +15,7 @@  target_link_libraries(dhisto   kshark)
 message(STATUS "confogio")
 add_executable(confio          configio.c)
 target_link_libraries(confio   kshark)
+
+message(STATUS "dataplot")
+add_executable(dplot          dataplot.cpp)
+target_link_libraries(dplot   kshark-plot)
diff --git a/kernel-shark-qt/examples/dataplot.cpp b/kernel-shark-qt/examples/dataplot.cpp
new file mode 100644
index 0000000..bf43123
--- /dev/null
+++ b/kernel-shark-qt/examples/dataplot.cpp
@@ -0,0 +1,217 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <y.karadz@gmail.com>
+ */
+
+// C
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+// C++
+#include <vector>
+
+// OpenGL
+#include <GL/freeglut.h>
+
+// KernelShark
+#include "libkshark.h"
+#include "KsPlotTools.hpp"
+
+using namespace std;
+
+#define GRAPH_HEIGHT	40   // width of the graph in pixels
+#define GRAPH_H_MARGIN	50   // size of the white space surrounding the graph
+#define WINDOW_WIDTH	800  // width of the screen window in pixels
+#define WINDOW_HEIGHT	480  // height of the scrren window in pixels
+
+#define default_file (char*)"trace.dat"
+
+struct kshark_trace_histo	histo;
+vector<KsPlot::Graph *>		graphs;
+
+/* An example function drawing something. */
+void drawShapes()
+{
+	/* Clear the screen. */
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	KsPlot::Triangle t;
+	KsPlot::Point a(200, 100), b(200, 300), c(400, 100);
+	t.setPoint(0, a);
+	t.setPoint(1, b);
+	t.setPoint(2, c);
+
+	/* Set RGB color. */
+	t._color = {100, 200, 50};
+	t.draw();
+
+	KsPlot::Rectangle r;
+	KsPlot::Point d(400, 200), e(400, 300), f(500, 300), g(500, 200);
+	r.setPoint(0, d);
+	r.setPoint(1, e);
+	r.setPoint(2, f);
+	r.setPoint(3, g);
+
+	/* Set RGB color. */
+	r._color = {150, 50, 250};
+	r._size = 3;
+
+	/** Do not fiil the rectangle. Draw the contour only. */
+	r.setFill(false);
+	r.draw();
+
+	glFlush();
+}
+
+/* An example function demonstrating Zoom In and Zoom Out. */
+void play()
+{
+	KsPlot::ColorTable colors = KsPlot::getColorTable();
+	vector<int> CPUs, Tasks;
+	KsPlot::Graph *graph;
+	bool zoom_in(true);
+
+	CPUs = {3, 4, 6};
+	Tasks = {}; // Add valid pids here, if you want task plots.
+
+	auto init_graph = [&graph, &colors] (int i) {
+		int base;
+
+		/* Make a new Graph. */
+		graph = new KsPlot::Graph(&histo, &colors);
+
+		/* Set the dimensions of the Graph. */
+		graph->setHeight(GRAPH_HEIGHT);
+		graph->setHMargin(GRAPH_H_MARGIN);
+
+		/*
+		 * Set the Y coordinate of the Graph's base.
+		 * Remember that the "Y" coordinate is inverted.
+		 */
+		base = 1.7 * GRAPH_HEIGHT * (i + 1);
+		graph->setBase(base);
+
+		/* Add the Graph. */
+		graphs.push_back(graph);
+	};
+
+	for (size_t i = 0; i < CPUs.size() + Tasks.size(); ++i)
+		init_graph(i);
+
+	auto draw_graphs = [&CPUs, &Tasks] () {
+		vector<KsPlot::Graph *>::iterator it = graphs.begin();
+
+		for (int const &cpu: CPUs)
+			(*it++)->fillCPUGraph(cpu);
+
+		for (int const &pid: Tasks)
+			(*it++)->fillTaskGraph(pid);
+
+		/* Clear the screen. */
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		/* Draw all graphs. */
+		for (auto &g: graphs)
+			g->draw();
+
+		glFlush();
+	};
+
+	for (int i = 1; i < 1000; ++i) {
+		if (!(i % 250))
+			zoom_in = !zoom_in;
+
+		draw_graphs();
+
+		if (zoom_in)
+			ksmodel_zoom_in(&histo, .01, -1);
+		else
+			ksmodel_zoom_out(&histo, .01, -1);
+	}
+}
+
+int main(int argc, char **argv)
+{
+	struct kshark_context *kshark_ctx(nullptr);
+	struct kshark_entry **data(nullptr);
+	static char *input_file;
+	bool status, shapes(false);
+	size_t r, n_rows;
+	int c, nBins;
+
+	while ((c = getopt(argc, argv, "si")) != -1) {
+		switch(c) {
+		case 'i':
+			input_file = optarg;
+			break;
+		case 's':
+			shapes = true;
+
+		default:
+			break;
+		}
+	}
+
+	/* Create a new kshark session. */
+	if (!kshark_instance(&kshark_ctx))
+		return 1;
+
+	/* Open a trace data file produced by trace-cmd. */
+	if (input_file)
+		status = kshark_open(kshark_ctx, input_file);
+	else
+		status = kshark_open(kshark_ctx, default_file);
+
+	if (!status) {
+		kshark_free(kshark_ctx);
+		return 1;
+	}
+
+	/* Load the content of the file into an array of entries. */
+	n_rows = kshark_load_data_entries(kshark_ctx, &data);
+
+	/* Initialize the Visualization Model. */
+	ksmodel_init(&histo);
+
+	nBins = WINDOW_WIDTH - 2 * GRAPH_HEIGHT;
+	ksmodel_set_bining(&histo, nBins, data[0]->ts,
+					  data[n_rows - 1]->ts);
+
+	/* Fill the model with data and calculate its state. */
+	ksmodel_fill(&histo, data, n_rows);
+
+	/* Initialize OpenGL/Glut. */
+	glutInit(&argc, argv);
+	ksplot_make_scene(WINDOW_WIDTH, WINDOW_HEIGHT);
+	ksplot_init_opengl(1);
+
+	/* Display something. */
+	if (shapes)
+		glutDisplayFunc(drawShapes);
+	else
+		glutDisplayFunc(play);
+
+	glutMainLoop();
+
+	/* Free the memory. */
+	for (auto &g: graphs)
+		delete g;
+
+	for (r = 0; r < n_rows; ++r)
+		free(data[r]);
+	free(data);
+
+	/* Reset (clear) the model. */
+	ksmodel_clear(&histo);
+
+	/* Close the file. */
+	kshark_close(kshark_ctx);
+
+	/* Close the session. */
+	kshark_free(kshark_ctx);
+
+	return 0;
+}