1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2013 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker *
23*d83cc019SAndroid Build Coastguard Worker */
24*d83cc019SAndroid Build Coastguard Worker
25*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
26*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
27*d83cc019SAndroid Build Coastguard Worker #include <cairo.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
35*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
36*d83cc019SAndroid Build Coastguard Worker #include <getopt.h>
37*d83cc019SAndroid Build Coastguard Worker #include <time.h>
38*d83cc019SAndroid Build Coastguard Worker #include <locale.h>
39*d83cc019SAndroid Build Coastguard Worker
40*d83cc019SAndroid Build Coastguard Worker #include "overlay.h"
41*d83cc019SAndroid Build Coastguard Worker #include "chart.h"
42*d83cc019SAndroid Build Coastguard Worker #include "config.h"
43*d83cc019SAndroid Build Coastguard Worker #include "cpu-top.h"
44*d83cc019SAndroid Build Coastguard Worker #include "debugfs.h"
45*d83cc019SAndroid Build Coastguard Worker #include "gem-interrupts.h"
46*d83cc019SAndroid Build Coastguard Worker #include "gem-objects.h"
47*d83cc019SAndroid Build Coastguard Worker #include "gpu-freq.h"
48*d83cc019SAndroid Build Coastguard Worker #include "gpu-top.h"
49*d83cc019SAndroid Build Coastguard Worker #include "gpu-perf.h"
50*d83cc019SAndroid Build Coastguard Worker #include "power.h"
51*d83cc019SAndroid Build Coastguard Worker #include "rc6.h"
52*d83cc019SAndroid Build Coastguard Worker
53*d83cc019SAndroid Build Coastguard Worker #define is_power_of_two(x) (((x) & ((x)-1)) == 0)
54*d83cc019SAndroid Build Coastguard Worker
55*d83cc019SAndroid Build Coastguard Worker #define PAD 10
56*d83cc019SAndroid Build Coastguard Worker #define HALF_PAD 5
57*d83cc019SAndroid Build Coastguard Worker #define SIZE_PAD (PAD + HALF_PAD)
58*d83cc019SAndroid Build Coastguard Worker
59*d83cc019SAndroid Build Coastguard Worker #define IDLE_TIME 30
60*d83cc019SAndroid Build Coastguard Worker
61*d83cc019SAndroid Build Coastguard Worker const cairo_user_data_key_t overlay_key;
62*d83cc019SAndroid Build Coastguard Worker
overlay_show(cairo_surface_t * surface)63*d83cc019SAndroid Build Coastguard Worker static void overlay_show(cairo_surface_t *surface)
64*d83cc019SAndroid Build Coastguard Worker {
65*d83cc019SAndroid Build Coastguard Worker struct overlay *overlay;
66*d83cc019SAndroid Build Coastguard Worker
67*d83cc019SAndroid Build Coastguard Worker overlay = cairo_surface_get_user_data(surface, &overlay_key);
68*d83cc019SAndroid Build Coastguard Worker if (overlay == NULL)
69*d83cc019SAndroid Build Coastguard Worker return;
70*d83cc019SAndroid Build Coastguard Worker
71*d83cc019SAndroid Build Coastguard Worker overlay->show(overlay);
72*d83cc019SAndroid Build Coastguard Worker }
73*d83cc019SAndroid Build Coastguard Worker
74*d83cc019SAndroid Build Coastguard Worker #if 0
75*d83cc019SAndroid Build Coastguard Worker static void overlay_position(cairo_surface_t *surface, enum position p)
76*d83cc019SAndroid Build Coastguard Worker {
77*d83cc019SAndroid Build Coastguard Worker struct overlay *overlay;
78*d83cc019SAndroid Build Coastguard Worker
79*d83cc019SAndroid Build Coastguard Worker overlay = cairo_surface_get_user_data(surface, &overlay_key);
80*d83cc019SAndroid Build Coastguard Worker if (overlay == NULL)
81*d83cc019SAndroid Build Coastguard Worker return;
82*d83cc019SAndroid Build Coastguard Worker
83*d83cc019SAndroid Build Coastguard Worker overlay->position(overlay, p);
84*d83cc019SAndroid Build Coastguard Worker }
85*d83cc019SAndroid Build Coastguard Worker
86*d83cc019SAndroid Build Coastguard Worker static void overlay_hide(cairo_surface_t *surface)
87*d83cc019SAndroid Build Coastguard Worker {
88*d83cc019SAndroid Build Coastguard Worker struct overlay *overlay;
89*d83cc019SAndroid Build Coastguard Worker
90*d83cc019SAndroid Build Coastguard Worker overlay = cairo_surface_get_user_data(surface, &overlay_key);
91*d83cc019SAndroid Build Coastguard Worker if (overlay == NULL)
92*d83cc019SAndroid Build Coastguard Worker return;
93*d83cc019SAndroid Build Coastguard Worker
94*d83cc019SAndroid Build Coastguard Worker overlay->hide(overlay);
95*d83cc019SAndroid Build Coastguard Worker }
96*d83cc019SAndroid Build Coastguard Worker #endif
97*d83cc019SAndroid Build Coastguard Worker
98*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_top {
99*d83cc019SAndroid Build Coastguard Worker struct gpu_top gpu_top;
100*d83cc019SAndroid Build Coastguard Worker struct cpu_top cpu_top;
101*d83cc019SAndroid Build Coastguard Worker struct chart busy[MAX_RINGS];
102*d83cc019SAndroid Build Coastguard Worker struct chart wait[MAX_RINGS];
103*d83cc019SAndroid Build Coastguard Worker struct chart cpu;
104*d83cc019SAndroid Build Coastguard Worker };
105*d83cc019SAndroid Build Coastguard Worker
106*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_perf {
107*d83cc019SAndroid Build Coastguard Worker struct gpu_perf gpu_perf;
108*d83cc019SAndroid Build Coastguard Worker time_t show_ctx;
109*d83cc019SAndroid Build Coastguard Worker time_t show_flips;
110*d83cc019SAndroid Build Coastguard Worker };
111*d83cc019SAndroid Build Coastguard Worker
112*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_freq {
113*d83cc019SAndroid Build Coastguard Worker struct gpu_freq gpu_freq;
114*d83cc019SAndroid Build Coastguard Worker struct rc6 rc6;
115*d83cc019SAndroid Build Coastguard Worker struct gem_interrupts irqs;
116*d83cc019SAndroid Build Coastguard Worker struct power power;
117*d83cc019SAndroid Build Coastguard Worker struct chart current;
118*d83cc019SAndroid Build Coastguard Worker struct chart request;
119*d83cc019SAndroid Build Coastguard Worker struct chart power_chart;
120*d83cc019SAndroid Build Coastguard Worker double power_max;
121*d83cc019SAndroid Build Coastguard Worker };
122*d83cc019SAndroid Build Coastguard Worker
123*d83cc019SAndroid Build Coastguard Worker struct overlay_gem_objects {
124*d83cc019SAndroid Build Coastguard Worker struct gem_objects gem_objects;
125*d83cc019SAndroid Build Coastguard Worker struct chart aperture;
126*d83cc019SAndroid Build Coastguard Worker struct chart gtt;
127*d83cc019SAndroid Build Coastguard Worker int error;
128*d83cc019SAndroid Build Coastguard Worker };
129*d83cc019SAndroid Build Coastguard Worker
130*d83cc019SAndroid Build Coastguard Worker struct overlay_context {
131*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *surface;
132*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
133*d83cc019SAndroid Build Coastguard Worker int width, height;
134*d83cc019SAndroid Build Coastguard Worker
135*d83cc019SAndroid Build Coastguard Worker time_t time;
136*d83cc019SAndroid Build Coastguard Worker
137*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_top gpu_top;
138*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_perf gpu_perf;
139*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_freq gpu_freq;
140*d83cc019SAndroid Build Coastguard Worker struct overlay_gem_objects gem_objects;
141*d83cc019SAndroid Build Coastguard Worker };
142*d83cc019SAndroid Build Coastguard Worker
init_gpu_top(struct overlay_context * ctx,struct overlay_gpu_top * gt)143*d83cc019SAndroid Build Coastguard Worker static void init_gpu_top(struct overlay_context *ctx,
144*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_top *gt)
145*d83cc019SAndroid Build Coastguard Worker {
146*d83cc019SAndroid Build Coastguard Worker const double rgba[][4] = {
147*d83cc019SAndroid Build Coastguard Worker { 1, 0.25, 0.25, 1 },
148*d83cc019SAndroid Build Coastguard Worker { 0.25, 1, 0.25, 1 },
149*d83cc019SAndroid Build Coastguard Worker { 0.25, 0.25, 1, 1 },
150*d83cc019SAndroid Build Coastguard Worker { 1, 1, 1, 1 },
151*d83cc019SAndroid Build Coastguard Worker { 1, 1, 0.25, 1 },
152*d83cc019SAndroid Build Coastguard Worker };
153*d83cc019SAndroid Build Coastguard Worker int n;
154*d83cc019SAndroid Build Coastguard Worker
155*d83cc019SAndroid Build Coastguard Worker cpu_top_init(>->cpu_top);
156*d83cc019SAndroid Build Coastguard Worker gpu_top_init(>->gpu_top);
157*d83cc019SAndroid Build Coastguard Worker
158*d83cc019SAndroid Build Coastguard Worker chart_init(>->cpu, "CPU", 120);
159*d83cc019SAndroid Build Coastguard Worker chart_set_position(>->cpu, PAD, PAD);
160*d83cc019SAndroid Build Coastguard Worker chart_set_size(>->cpu, ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
161*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_rgba(>->cpu, 0.75, 0.25, 0.75, 1.);
162*d83cc019SAndroid Build Coastguard Worker chart_set_mode(>->cpu, CHART_STROKE);
163*d83cc019SAndroid Build Coastguard Worker chart_set_range(>->cpu, 0, 100);
164*d83cc019SAndroid Build Coastguard Worker
165*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < gt->gpu_top.num_rings; n++) {
166*d83cc019SAndroid Build Coastguard Worker chart_init(>->busy[n],
167*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].name,
168*d83cc019SAndroid Build Coastguard Worker 120);
169*d83cc019SAndroid Build Coastguard Worker chart_set_position(>->busy[n], PAD, PAD);
170*d83cc019SAndroid Build Coastguard Worker chart_set_size(>->busy[n], ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
171*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_rgba(>->busy[n],
172*d83cc019SAndroid Build Coastguard Worker rgba[n][0], rgba[n][1], rgba[n][2], rgba[n][3]);
173*d83cc019SAndroid Build Coastguard Worker chart_set_mode(>->busy[n], CHART_STROKE);
174*d83cc019SAndroid Build Coastguard Worker chart_set_range(>->busy[n], 0, 100);
175*d83cc019SAndroid Build Coastguard Worker }
176*d83cc019SAndroid Build Coastguard Worker
177*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < gt->gpu_top.num_rings; n++) {
178*d83cc019SAndroid Build Coastguard Worker chart_init(>->wait[n],
179*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].name,
180*d83cc019SAndroid Build Coastguard Worker 120);
181*d83cc019SAndroid Build Coastguard Worker chart_set_position(>->wait[n], PAD, PAD);
182*d83cc019SAndroid Build Coastguard Worker chart_set_size(>->wait[n], ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
183*d83cc019SAndroid Build Coastguard Worker chart_set_fill_rgba(>->wait[n],
184*d83cc019SAndroid Build Coastguard Worker rgba[n][0], rgba[n][1], rgba[n][2], rgba[n][3] * 0.70);
185*d83cc019SAndroid Build Coastguard Worker chart_set_mode(>->wait[n], CHART_FILL);
186*d83cc019SAndroid Build Coastguard Worker chart_set_range(>->wait[n], 0, 100);
187*d83cc019SAndroid Build Coastguard Worker }
188*d83cc019SAndroid Build Coastguard Worker }
189*d83cc019SAndroid Build Coastguard Worker
show_gpu_top(struct overlay_context * ctx,struct overlay_gpu_top * gt)190*d83cc019SAndroid Build Coastguard Worker static void show_gpu_top(struct overlay_context *ctx, struct overlay_gpu_top *gt)
191*d83cc019SAndroid Build Coastguard Worker {
192*d83cc019SAndroid Build Coastguard Worker int y, y1, y2, n, update, len;
193*d83cc019SAndroid Build Coastguard Worker cairo_pattern_t *linear;
194*d83cc019SAndroid Build Coastguard Worker char txt[160];
195*d83cc019SAndroid Build Coastguard Worker int rewind;
196*d83cc019SAndroid Build Coastguard Worker int do_rewind;
197*d83cc019SAndroid Build Coastguard Worker
198*d83cc019SAndroid Build Coastguard Worker update = gpu_top_update(>->gpu_top);
199*d83cc019SAndroid Build Coastguard Worker
200*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, PAD-.5, PAD-.5, ctx->width/2-SIZE_PAD+1, ctx->height/2-SIZE_PAD+1);
201*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(ctx->cr, .15, .15, .15);
202*d83cc019SAndroid Build Coastguard Worker cairo_set_line_width(ctx->cr, 1);
203*d83cc019SAndroid Build Coastguard Worker cairo_stroke(ctx->cr);
204*d83cc019SAndroid Build Coastguard Worker
205*d83cc019SAndroid Build Coastguard Worker if (update && cpu_top_update(>->cpu_top) == 0)
206*d83cc019SAndroid Build Coastguard Worker chart_add_sample(>->cpu, gt->cpu_top.busy);
207*d83cc019SAndroid Build Coastguard Worker
208*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < gt->gpu_top.num_rings; n++) {
209*d83cc019SAndroid Build Coastguard Worker if (update)
210*d83cc019SAndroid Build Coastguard Worker chart_add_sample(>->wait[n],
211*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].u.u.wait + gt->gpu_top.ring[n].u.u.sema);
212*d83cc019SAndroid Build Coastguard Worker chart_draw(>->wait[n], ctx->cr);
213*d83cc019SAndroid Build Coastguard Worker }
214*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < gt->gpu_top.num_rings; n++) {
215*d83cc019SAndroid Build Coastguard Worker if (update)
216*d83cc019SAndroid Build Coastguard Worker chart_add_sample(>->busy[n],
217*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].u.u.busy);
218*d83cc019SAndroid Build Coastguard Worker chart_draw(>->busy[n], ctx->cr);
219*d83cc019SAndroid Build Coastguard Worker }
220*d83cc019SAndroid Build Coastguard Worker chart_draw(>->cpu, ctx->cr);
221*d83cc019SAndroid Build Coastguard Worker
222*d83cc019SAndroid Build Coastguard Worker y1 = PAD - 2;
223*d83cc019SAndroid Build Coastguard Worker y2 = y1 + (gt->gpu_top.num_rings+1) * 14 + 4;
224*d83cc019SAndroid Build Coastguard Worker
225*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, PAD, y1, ctx->width/2-SIZE_PAD, y2-y1);
226*d83cc019SAndroid Build Coastguard Worker linear = cairo_pattern_create_linear(PAD, 0, PAD+ctx->width/2-SIZE_PAD, 0);
227*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 0, 0, 0, 0, .5);
228*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 1, 0, 0, 0, .0);
229*d83cc019SAndroid Build Coastguard Worker cairo_set_source(ctx->cr, linear);
230*d83cc019SAndroid Build Coastguard Worker cairo_pattern_destroy(linear);
231*d83cc019SAndroid Build Coastguard Worker cairo_fill(ctx->cr);
232*d83cc019SAndroid Build Coastguard Worker
233*d83cc019SAndroid Build Coastguard Worker y = PAD + 12 - 2;
234*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 0.75, 0.25, 0.75, 1.);
235*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD, y);
236*d83cc019SAndroid Build Coastguard Worker rewind = len = sprintf(txt, "CPU: %3d%% busy", gt->cpu_top.busy * gt->cpu_top.nr_cpu);
237*d83cc019SAndroid Build Coastguard Worker do_rewind = 1;
238*d83cc019SAndroid Build Coastguard Worker len += sprintf(txt + len, " (");
239*d83cc019SAndroid Build Coastguard Worker if (gt->cpu_top.nr_cpu > 1) {
240*d83cc019SAndroid Build Coastguard Worker len += sprintf(txt + len, "%s%d cores", do_rewind ? "" : ", ", gt->cpu_top.nr_cpu);
241*d83cc019SAndroid Build Coastguard Worker do_rewind = 0;
242*d83cc019SAndroid Build Coastguard Worker }
243*d83cc019SAndroid Build Coastguard Worker if (gt->cpu_top.nr_running) {
244*d83cc019SAndroid Build Coastguard Worker len += sprintf(txt + len, "%s%d processes", do_rewind ? "" : ", ", gt->cpu_top.nr_running);
245*d83cc019SAndroid Build Coastguard Worker do_rewind = 0;
246*d83cc019SAndroid Build Coastguard Worker }
247*d83cc019SAndroid Build Coastguard Worker sprintf(txt + len, ")");
248*d83cc019SAndroid Build Coastguard Worker if (do_rewind)
249*d83cc019SAndroid Build Coastguard Worker txt[rewind] = '\0';
250*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, txt);
251*d83cc019SAndroid Build Coastguard Worker y += 14;
252*d83cc019SAndroid Build Coastguard Worker
253*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < gt->gpu_top.num_rings; n++) {
254*d83cc019SAndroid Build Coastguard Worker struct chart *c =>->busy[n];
255*d83cc019SAndroid Build Coastguard Worker
256*d83cc019SAndroid Build Coastguard Worker len = sprintf(txt, "%s: %3d%% busy",
257*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].name,
258*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].u.u.busy);
259*d83cc019SAndroid Build Coastguard Worker if (gt->gpu_top.ring[n].u.u.wait)
260*d83cc019SAndroid Build Coastguard Worker len += sprintf(txt + len, ", %d%% wait",
261*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].u.u.wait);
262*d83cc019SAndroid Build Coastguard Worker if (gt->gpu_top.ring[n].u.u.sema)
263*d83cc019SAndroid Build Coastguard Worker len += sprintf(txt + len, ", %d%% sema",
264*d83cc019SAndroid Build Coastguard Worker gt->gpu_top.ring[n].u.u.sema);
265*d83cc019SAndroid Build Coastguard Worker
266*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr,
267*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[0],
268*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[1],
269*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[2],
270*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[3]);
271*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD, y);
272*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, txt);
273*d83cc019SAndroid Build Coastguard Worker y += 14;
274*d83cc019SAndroid Build Coastguard Worker }
275*d83cc019SAndroid Build Coastguard Worker }
276*d83cc019SAndroid Build Coastguard Worker
init_gpu_perf(struct overlay_context * ctx,struct overlay_gpu_perf * gp)277*d83cc019SAndroid Build Coastguard Worker static void init_gpu_perf(struct overlay_context *ctx,
278*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_perf *gp)
279*d83cc019SAndroid Build Coastguard Worker {
280*d83cc019SAndroid Build Coastguard Worker gpu_perf_init(&gp->gpu_perf, 0);
281*d83cc019SAndroid Build Coastguard Worker
282*d83cc019SAndroid Build Coastguard Worker gp->show_ctx = 0;
283*d83cc019SAndroid Build Coastguard Worker gp->show_flips = 0;
284*d83cc019SAndroid Build Coastguard Worker }
285*d83cc019SAndroid Build Coastguard Worker
get_comm(pid_t pid,char * comm,int len)286*d83cc019SAndroid Build Coastguard Worker static char *get_comm(pid_t pid, char *comm, int len)
287*d83cc019SAndroid Build Coastguard Worker {
288*d83cc019SAndroid Build Coastguard Worker char filename[1024];
289*d83cc019SAndroid Build Coastguard Worker int fd;
290*d83cc019SAndroid Build Coastguard Worker
291*d83cc019SAndroid Build Coastguard Worker *comm = '\0';
292*d83cc019SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "/proc/%d/comm", pid);
293*d83cc019SAndroid Build Coastguard Worker
294*d83cc019SAndroid Build Coastguard Worker fd = open(filename, 0);
295*d83cc019SAndroid Build Coastguard Worker if (fd >= 0) {
296*d83cc019SAndroid Build Coastguard Worker len = read(fd, comm, len);
297*d83cc019SAndroid Build Coastguard Worker if (len >= 0)
298*d83cc019SAndroid Build Coastguard Worker comm[len-1] = '\0';
299*d83cc019SAndroid Build Coastguard Worker close(fd);
300*d83cc019SAndroid Build Coastguard Worker }
301*d83cc019SAndroid Build Coastguard Worker
302*d83cc019SAndroid Build Coastguard Worker return comm;
303*d83cc019SAndroid Build Coastguard Worker }
304*d83cc019SAndroid Build Coastguard Worker
show_gpu_perf(struct overlay_context * ctx,struct overlay_gpu_perf * gp)305*d83cc019SAndroid Build Coastguard Worker static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf *gp)
306*d83cc019SAndroid Build Coastguard Worker {
307*d83cc019SAndroid Build Coastguard Worker static int last_color;
308*d83cc019SAndroid Build Coastguard Worker const double rgba[][4] = {
309*d83cc019SAndroid Build Coastguard Worker { 1, 0.25, 0.25, 1 },
310*d83cc019SAndroid Build Coastguard Worker { 0.25, 1, 0.25, 1 },
311*d83cc019SAndroid Build Coastguard Worker { 0.25, 0.25, 1, 1 },
312*d83cc019SAndroid Build Coastguard Worker { 1, 1, 1, 1 },
313*d83cc019SAndroid Build Coastguard Worker };
314*d83cc019SAndroid Build Coastguard Worker struct gpu_perf_comm *comm, **prev;
315*d83cc019SAndroid Build Coastguard Worker const char *ring_name[MAX_RINGS] = {
316*d83cc019SAndroid Build Coastguard Worker "R", "?", "?", "?",
317*d83cc019SAndroid Build Coastguard Worker "B", "?", "?", "?",
318*d83cc019SAndroid Build Coastguard Worker "V0", "V1", "?", "?",
319*d83cc019SAndroid Build Coastguard Worker "VE0", "?", "?", "?",
320*d83cc019SAndroid Build Coastguard Worker };
321*d83cc019SAndroid Build Coastguard Worker double range[2];
322*d83cc019SAndroid Build Coastguard Worker char buf[1024];
323*d83cc019SAndroid Build Coastguard Worker cairo_pattern_t *linear;
324*d83cc019SAndroid Build Coastguard Worker int x, y, y1, y2, n;
325*d83cc019SAndroid Build Coastguard Worker int has_ctx = 0;
326*d83cc019SAndroid Build Coastguard Worker int has_flips = 0;
327*d83cc019SAndroid Build Coastguard Worker
328*d83cc019SAndroid Build Coastguard Worker gpu_perf_update(&gp->gpu_perf);
329*d83cc019SAndroid Build Coastguard Worker
330*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < MAX_RINGS; n++) {
331*d83cc019SAndroid Build Coastguard Worker if (gp->gpu_perf.ctx_switch[n])
332*d83cc019SAndroid Build Coastguard Worker has_ctx = n + 1;
333*d83cc019SAndroid Build Coastguard Worker if (gp->gpu_perf.flip_complete[n])
334*d83cc019SAndroid Build Coastguard Worker has_flips = n + 1;
335*d83cc019SAndroid Build Coastguard Worker }
336*d83cc019SAndroid Build Coastguard Worker
337*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, ctx->width/2+HALF_PAD-.5, PAD-.5, ctx->width/2-SIZE_PAD+1, ctx->height/2-SIZE_PAD+1);
338*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(ctx->cr, .15, .15, .15);
339*d83cc019SAndroid Build Coastguard Worker cairo_set_line_width(ctx->cr, 1);
340*d83cc019SAndroid Build Coastguard Worker cairo_stroke(ctx->cr);
341*d83cc019SAndroid Build Coastguard Worker
342*d83cc019SAndroid Build Coastguard Worker if (gp->gpu_perf.error) {
343*d83cc019SAndroid Build Coastguard Worker cairo_text_extents_t extents;
344*d83cc019SAndroid Build Coastguard Worker cairo_text_extents(ctx->cr, gp->gpu_perf.error, &extents);
345*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr,
346*d83cc019SAndroid Build Coastguard Worker ctx->width/2+HALF_PAD + (ctx->width/2-SIZE_PAD - extents.width)/2.,
347*d83cc019SAndroid Build Coastguard Worker PAD + (ctx->height/2-SIZE_PAD + extents.height)/2.);
348*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, gp->gpu_perf.error);
349*d83cc019SAndroid Build Coastguard Worker return;
350*d83cc019SAndroid Build Coastguard Worker }
351*d83cc019SAndroid Build Coastguard Worker
352*d83cc019SAndroid Build Coastguard Worker if (gp->gpu_perf.comm == NULL && (has_ctx|has_flips) == 0) {
353*d83cc019SAndroid Build Coastguard Worker cairo_text_extents_t extents;
354*d83cc019SAndroid Build Coastguard Worker cairo_text_extents(ctx->cr, gp->gpu_perf.error, &extents);
355*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr,
356*d83cc019SAndroid Build Coastguard Worker ctx->width/2+HALF_PAD + (ctx->width/2-SIZE_PAD - extents.width)/2.,
357*d83cc019SAndroid Build Coastguard Worker PAD + (ctx->height/2-SIZE_PAD + extents.height)/2.);
358*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, "idle");
359*d83cc019SAndroid Build Coastguard Worker return;
360*d83cc019SAndroid Build Coastguard Worker }
361*d83cc019SAndroid Build Coastguard Worker
362*d83cc019SAndroid Build Coastguard Worker y = PAD + 12 - 2;
363*d83cc019SAndroid Build Coastguard Worker x = ctx->width/2 + HALF_PAD;
364*d83cc019SAndroid Build Coastguard Worker
365*d83cc019SAndroid Build Coastguard Worker for (comm = gp->gpu_perf.comm; comm; comm = comm->next) {
366*d83cc019SAndroid Build Coastguard Worker int total;
367*d83cc019SAndroid Build Coastguard Worker
368*d83cc019SAndroid Build Coastguard Worker if (comm->name[0] == '\0')
369*d83cc019SAndroid Build Coastguard Worker continue;
370*d83cc019SAndroid Build Coastguard Worker
371*d83cc019SAndroid Build Coastguard Worker if (strncmp(comm->name, "kworker", 7) == 0)
372*d83cc019SAndroid Build Coastguard Worker continue;
373*d83cc019SAndroid Build Coastguard Worker
374*d83cc019SAndroid Build Coastguard Worker if (comm->user_data == NULL) {
375*d83cc019SAndroid Build Coastguard Worker comm->user_data = malloc(sizeof(struct chart));
376*d83cc019SAndroid Build Coastguard Worker if (comm->user_data == NULL)
377*d83cc019SAndroid Build Coastguard Worker continue;
378*d83cc019SAndroid Build Coastguard Worker
379*d83cc019SAndroid Build Coastguard Worker chart_init(comm->user_data, comm->name, 120);
380*d83cc019SAndroid Build Coastguard Worker chart_set_position(comm->user_data, ctx->width/2+HALF_PAD, PAD);
381*d83cc019SAndroid Build Coastguard Worker chart_set_size(comm->user_data, ctx->width/2-SIZE_PAD, ctx->height/2 - SIZE_PAD);
382*d83cc019SAndroid Build Coastguard Worker chart_set_mode(comm->user_data, CHART_STROKE);
383*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_rgba(comm->user_data,
384*d83cc019SAndroid Build Coastguard Worker rgba[last_color][0],
385*d83cc019SAndroid Build Coastguard Worker rgba[last_color][1],
386*d83cc019SAndroid Build Coastguard Worker rgba[last_color][2],
387*d83cc019SAndroid Build Coastguard Worker rgba[last_color][3]);
388*d83cc019SAndroid Build Coastguard Worker last_color = (last_color + 1) % 4;
389*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_width(comm->user_data, 1);
390*d83cc019SAndroid Build Coastguard Worker }
391*d83cc019SAndroid Build Coastguard Worker
392*d83cc019SAndroid Build Coastguard Worker total = 0;
393*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < MAX_RINGS; n++)
394*d83cc019SAndroid Build Coastguard Worker total += comm->nr_requests[n];
395*d83cc019SAndroid Build Coastguard Worker chart_add_sample(comm->user_data, total);
396*d83cc019SAndroid Build Coastguard Worker }
397*d83cc019SAndroid Build Coastguard Worker
398*d83cc019SAndroid Build Coastguard Worker range[0] = range[1] = 0;
399*d83cc019SAndroid Build Coastguard Worker for (comm = gp->gpu_perf.comm; comm; comm = comm->next) {
400*d83cc019SAndroid Build Coastguard Worker if (comm->user_data == NULL)
401*d83cc019SAndroid Build Coastguard Worker continue;
402*d83cc019SAndroid Build Coastguard Worker
403*d83cc019SAndroid Build Coastguard Worker chart_get_range(comm->user_data, range);
404*d83cc019SAndroid Build Coastguard Worker }
405*d83cc019SAndroid Build Coastguard Worker
406*d83cc019SAndroid Build Coastguard Worker y2 = y1 = y;
407*d83cc019SAndroid Build Coastguard Worker for (comm = gp->gpu_perf.comm; comm; comm = comm->next) {
408*d83cc019SAndroid Build Coastguard Worker if (comm->user_data == NULL)
409*d83cc019SAndroid Build Coastguard Worker continue;
410*d83cc019SAndroid Build Coastguard Worker
411*d83cc019SAndroid Build Coastguard Worker chart_set_range(comm->user_data, range[0], range[1]);
412*d83cc019SAndroid Build Coastguard Worker chart_draw(comm->user_data, ctx->cr);
413*d83cc019SAndroid Build Coastguard Worker y2 += 14;
414*d83cc019SAndroid Build Coastguard Worker }
415*d83cc019SAndroid Build Coastguard Worker if (has_flips || gp->show_flips)
416*d83cc019SAndroid Build Coastguard Worker y2 += 14;
417*d83cc019SAndroid Build Coastguard Worker if (has_ctx || gp->show_ctx)
418*d83cc019SAndroid Build Coastguard Worker y2 += 14;
419*d83cc019SAndroid Build Coastguard Worker y1 += -12 - 2;
420*d83cc019SAndroid Build Coastguard Worker y2 += -14 + 4;
421*d83cc019SAndroid Build Coastguard Worker
422*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, x, y1, ctx->width/2-SIZE_PAD, y2-y1);
423*d83cc019SAndroid Build Coastguard Worker linear = cairo_pattern_create_linear(x, 0, x + ctx->width/2-SIZE_PAD, 0);
424*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 0, 0, 0, 0, .5);
425*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 1, 0, 0, 0, .0);
426*d83cc019SAndroid Build Coastguard Worker cairo_set_source(ctx->cr, linear);
427*d83cc019SAndroid Build Coastguard Worker cairo_pattern_destroy(linear);
428*d83cc019SAndroid Build Coastguard Worker cairo_fill(ctx->cr);
429*d83cc019SAndroid Build Coastguard Worker
430*d83cc019SAndroid Build Coastguard Worker for (prev = &gp->gpu_perf.comm; (comm = *prev) != NULL; ) {
431*d83cc019SAndroid Build Coastguard Worker int need_comma = 0, len;
432*d83cc019SAndroid Build Coastguard Worker
433*d83cc019SAndroid Build Coastguard Worker if (comm->user_data == NULL)
434*d83cc019SAndroid Build Coastguard Worker goto skip_comm;
435*d83cc019SAndroid Build Coastguard Worker
436*d83cc019SAndroid Build Coastguard Worker len = sprintf(buf, "%s:", comm->name);
437*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < MAX_RINGS; n++) {
438*d83cc019SAndroid Build Coastguard Worker if (comm->nr_requests[n] == 0)
439*d83cc019SAndroid Build Coastguard Worker continue;
440*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%s %d%s", need_comma ? "," : "", comm->nr_requests[n], ring_name[n]);
441*d83cc019SAndroid Build Coastguard Worker need_comma = true;
442*d83cc019SAndroid Build Coastguard Worker comm->show = ctx->time;
443*d83cc019SAndroid Build Coastguard Worker }
444*d83cc019SAndroid Build Coastguard Worker if (comm->wait_time) {
445*d83cc019SAndroid Build Coastguard Worker if (comm->wait_time > 1000*1000) {
446*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%s %.1fms waits",
447*d83cc019SAndroid Build Coastguard Worker need_comma ? "," : "",
448*d83cc019SAndroid Build Coastguard Worker comm->wait_time / (1000*1000.));
449*d83cc019SAndroid Build Coastguard Worker } else if (comm->wait_time > 100) {
450*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%s %.1fus waits",
451*d83cc019SAndroid Build Coastguard Worker need_comma ? "," : "",
452*d83cc019SAndroid Build Coastguard Worker comm->wait_time / 1000.);
453*d83cc019SAndroid Build Coastguard Worker } else {
454*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf, "%s %.0fns waits",
455*d83cc019SAndroid Build Coastguard Worker need_comma ? "," : "",
456*d83cc019SAndroid Build Coastguard Worker (double)comm->wait_time);
457*d83cc019SAndroid Build Coastguard Worker }
458*d83cc019SAndroid Build Coastguard Worker need_comma = true;
459*d83cc019SAndroid Build Coastguard Worker comm->wait_time = 0;
460*d83cc019SAndroid Build Coastguard Worker comm->show = ctx->time;
461*d83cc019SAndroid Build Coastguard Worker }
462*d83cc019SAndroid Build Coastguard Worker if (comm->nr_sema) {
463*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%s %d syncs",
464*d83cc019SAndroid Build Coastguard Worker need_comma ? "," : "",
465*d83cc019SAndroid Build Coastguard Worker comm->nr_sema);
466*d83cc019SAndroid Build Coastguard Worker need_comma = true;
467*d83cc019SAndroid Build Coastguard Worker comm->nr_sema = 0;
468*d83cc019SAndroid Build Coastguard Worker comm->show = ctx->time;
469*d83cc019SAndroid Build Coastguard Worker }
470*d83cc019SAndroid Build Coastguard Worker
471*d83cc019SAndroid Build Coastguard Worker if (comm->user_data) {
472*d83cc019SAndroid Build Coastguard Worker struct chart *c = comm->user_data;
473*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr,
474*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[0],
475*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[1],
476*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[2],
477*d83cc019SAndroid Build Coastguard Worker c->stroke_rgb[3]);
478*d83cc019SAndroid Build Coastguard Worker } else
479*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
480*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, x, y);
481*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
482*d83cc019SAndroid Build Coastguard Worker y += 14;
483*d83cc019SAndroid Build Coastguard Worker
484*d83cc019SAndroid Build Coastguard Worker skip_comm:
485*d83cc019SAndroid Build Coastguard Worker memset(comm->nr_requests, 0, sizeof(comm->nr_requests));
486*d83cc019SAndroid Build Coastguard Worker if (!comm->active &&
487*d83cc019SAndroid Build Coastguard Worker (comm->show < ctx->time - IDLE_TIME ||
488*d83cc019SAndroid Build Coastguard Worker strcmp(comm->name, get_comm(comm->pid, buf, sizeof(buf))))) {
489*d83cc019SAndroid Build Coastguard Worker *prev = comm->next;
490*d83cc019SAndroid Build Coastguard Worker if (comm->user_data) {
491*d83cc019SAndroid Build Coastguard Worker chart_fini(comm->user_data);
492*d83cc019SAndroid Build Coastguard Worker free(comm->user_data);
493*d83cc019SAndroid Build Coastguard Worker }
494*d83cc019SAndroid Build Coastguard Worker free(comm);
495*d83cc019SAndroid Build Coastguard Worker } else
496*d83cc019SAndroid Build Coastguard Worker prev = &comm->next;
497*d83cc019SAndroid Build Coastguard Worker }
498*d83cc019SAndroid Build Coastguard Worker
499*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
500*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, x, y);
501*d83cc019SAndroid Build Coastguard Worker if (has_flips) {
502*d83cc019SAndroid Build Coastguard Worker int len = sprintf(buf, "Flips:");
503*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < has_flips; n++)
504*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%s %d",
505*d83cc019SAndroid Build Coastguard Worker n ? "," : "",
506*d83cc019SAndroid Build Coastguard Worker gp->gpu_perf.flip_complete[n]);
507*d83cc019SAndroid Build Coastguard Worker memset(gp->gpu_perf.flip_complete, 0, sizeof(gp->gpu_perf.flip_complete));
508*d83cc019SAndroid Build Coastguard Worker gp->show_flips = ctx->time;
509*d83cc019SAndroid Build Coastguard Worker
510*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
511*d83cc019SAndroid Build Coastguard Worker y += 14;
512*d83cc019SAndroid Build Coastguard Worker } else if (gp->show_flips) {
513*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, "Flips: 0");
514*d83cc019SAndroid Build Coastguard Worker if (ctx->time - gp->show_flips > IDLE_TIME)
515*d83cc019SAndroid Build Coastguard Worker gp->show_flips = 0;
516*d83cc019SAndroid Build Coastguard Worker y += 14;
517*d83cc019SAndroid Build Coastguard Worker }
518*d83cc019SAndroid Build Coastguard Worker
519*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
520*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, x, y);
521*d83cc019SAndroid Build Coastguard Worker if (has_ctx) {
522*d83cc019SAndroid Build Coastguard Worker int len = sprintf(buf, "Contexts:");
523*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < has_ctx; n++)
524*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%s %d",
525*d83cc019SAndroid Build Coastguard Worker n ? "," : "",
526*d83cc019SAndroid Build Coastguard Worker gp->gpu_perf.ctx_switch[n]);
527*d83cc019SAndroid Build Coastguard Worker
528*d83cc019SAndroid Build Coastguard Worker memset(gp->gpu_perf.ctx_switch, 0, sizeof(gp->gpu_perf.ctx_switch));
529*d83cc019SAndroid Build Coastguard Worker gp->show_ctx = ctx->time;
530*d83cc019SAndroid Build Coastguard Worker
531*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
532*d83cc019SAndroid Build Coastguard Worker y += 14;
533*d83cc019SAndroid Build Coastguard Worker } else if (gp->show_ctx) {
534*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, "Contexts: 0");
535*d83cc019SAndroid Build Coastguard Worker y += 14;
536*d83cc019SAndroid Build Coastguard Worker if (ctx->time - gp->show_ctx > IDLE_TIME)
537*d83cc019SAndroid Build Coastguard Worker gp->show_ctx = 0;
538*d83cc019SAndroid Build Coastguard Worker }
539*d83cc019SAndroid Build Coastguard Worker }
540*d83cc019SAndroid Build Coastguard Worker
init_gpu_freq(struct overlay_context * ctx,struct overlay_gpu_freq * gf)541*d83cc019SAndroid Build Coastguard Worker static void init_gpu_freq(struct overlay_context *ctx,
542*d83cc019SAndroid Build Coastguard Worker struct overlay_gpu_freq *gf)
543*d83cc019SAndroid Build Coastguard Worker {
544*d83cc019SAndroid Build Coastguard Worker if (gpu_freq_init(&gf->gpu_freq) == 0) {
545*d83cc019SAndroid Build Coastguard Worker chart_init(&gf->current, "current", 120);
546*d83cc019SAndroid Build Coastguard Worker chart_set_position(&gf->current, PAD, ctx->height/2 + HALF_PAD);
547*d83cc019SAndroid Build Coastguard Worker chart_set_size(&gf->current, ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
548*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_rgba(&gf->current, 0.75, 0.25, 0.50, 1.);
549*d83cc019SAndroid Build Coastguard Worker chart_set_mode(&gf->current, CHART_STROKE);
550*d83cc019SAndroid Build Coastguard Worker chart_set_smooth(&gf->current, CHART_LINE);
551*d83cc019SAndroid Build Coastguard Worker chart_set_range(&gf->current, 0, gf->gpu_freq.max);
552*d83cc019SAndroid Build Coastguard Worker
553*d83cc019SAndroid Build Coastguard Worker chart_init(&gf->request, "request", 120);
554*d83cc019SAndroid Build Coastguard Worker chart_set_position(&gf->request, PAD, ctx->height/2 + HALF_PAD);
555*d83cc019SAndroid Build Coastguard Worker chart_set_size(&gf->request, ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
556*d83cc019SAndroid Build Coastguard Worker chart_set_fill_rgba(&gf->request, 0.25, 0.25, 0.50, 1.);
557*d83cc019SAndroid Build Coastguard Worker chart_set_mode(&gf->request, CHART_FILL);
558*d83cc019SAndroid Build Coastguard Worker chart_set_smooth(&gf->request, CHART_LINE);
559*d83cc019SAndroid Build Coastguard Worker chart_set_range(&gf->request, 0, gf->gpu_freq.max);
560*d83cc019SAndroid Build Coastguard Worker }
561*d83cc019SAndroid Build Coastguard Worker
562*d83cc019SAndroid Build Coastguard Worker if (power_init(&gf->power) == 0) {
563*d83cc019SAndroid Build Coastguard Worker chart_init(&gf->power_chart, "power", 120);
564*d83cc019SAndroid Build Coastguard Worker chart_set_position(&gf->power_chart, PAD, ctx->height/2 + HALF_PAD);
565*d83cc019SAndroid Build Coastguard Worker chart_set_size(&gf->power_chart, ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
566*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_rgba(&gf->power_chart, 0.45, 0.55, 0.45, 1.);
567*d83cc019SAndroid Build Coastguard Worker gf->power_max = 0;
568*d83cc019SAndroid Build Coastguard Worker }
569*d83cc019SAndroid Build Coastguard Worker
570*d83cc019SAndroid Build Coastguard Worker rc6_init(&gf->rc6);
571*d83cc019SAndroid Build Coastguard Worker gem_interrupts_init(&gf->irqs);
572*d83cc019SAndroid Build Coastguard Worker }
573*d83cc019SAndroid Build Coastguard Worker
show_gpu_freq(struct overlay_context * ctx,struct overlay_gpu_freq * gf)574*d83cc019SAndroid Build Coastguard Worker static void show_gpu_freq(struct overlay_context *ctx, struct overlay_gpu_freq *gf)
575*d83cc019SAndroid Build Coastguard Worker {
576*d83cc019SAndroid Build Coastguard Worker char buf[160];
577*d83cc019SAndroid Build Coastguard Worker int y1, y2, y, len;
578*d83cc019SAndroid Build Coastguard Worker
579*d83cc019SAndroid Build Coastguard Worker int has_freq = gpu_freq_update(&gf->gpu_freq) == 0;
580*d83cc019SAndroid Build Coastguard Worker int has_rc6 = rc6_update(&gf->rc6) == 0;
581*d83cc019SAndroid Build Coastguard Worker int has_power = power_update(&gf->power) == 0;
582*d83cc019SAndroid Build Coastguard Worker int has_irqs = gem_interrupts_update(&gf->irqs) == 0;
583*d83cc019SAndroid Build Coastguard Worker cairo_pattern_t *linear;
584*d83cc019SAndroid Build Coastguard Worker
585*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, PAD-.5, ctx->height/2+HALF_PAD-.5, ctx->width/2-SIZE_PAD+1, ctx->height/2-SIZE_PAD+1);
586*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(ctx->cr, .15, .15, .15);
587*d83cc019SAndroid Build Coastguard Worker cairo_set_line_width(ctx->cr, 1);
588*d83cc019SAndroid Build Coastguard Worker cairo_stroke(ctx->cr);
589*d83cc019SAndroid Build Coastguard Worker
590*d83cc019SAndroid Build Coastguard Worker if (gf->gpu_freq.error) {
591*d83cc019SAndroid Build Coastguard Worker const char *txt = "GPU frequency not found in debugfs";
592*d83cc019SAndroid Build Coastguard Worker cairo_text_extents_t extents;
593*d83cc019SAndroid Build Coastguard Worker cairo_text_extents(ctx->cr, txt, &extents);
594*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr,
595*d83cc019SAndroid Build Coastguard Worker PAD + (ctx->width/2-SIZE_PAD - extents.width)/2.,
596*d83cc019SAndroid Build Coastguard Worker ctx->height/2+HALF_PAD + (ctx->height/2-SIZE_PAD + extents.height)/2.);
597*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, txt);
598*d83cc019SAndroid Build Coastguard Worker return;
599*d83cc019SAndroid Build Coastguard Worker }
600*d83cc019SAndroid Build Coastguard Worker
601*d83cc019SAndroid Build Coastguard Worker if (has_freq) {
602*d83cc019SAndroid Build Coastguard Worker if (gf->gpu_freq.current)
603*d83cc019SAndroid Build Coastguard Worker chart_add_sample(&gf->current, gf->gpu_freq.current);
604*d83cc019SAndroid Build Coastguard Worker if (gf->gpu_freq.request)
605*d83cc019SAndroid Build Coastguard Worker chart_add_sample(&gf->request, gf->gpu_freq.request);
606*d83cc019SAndroid Build Coastguard Worker
607*d83cc019SAndroid Build Coastguard Worker chart_draw(&gf->request, ctx->cr);
608*d83cc019SAndroid Build Coastguard Worker chart_draw(&gf->current, ctx->cr);
609*d83cc019SAndroid Build Coastguard Worker }
610*d83cc019SAndroid Build Coastguard Worker
611*d83cc019SAndroid Build Coastguard Worker if (has_power) {
612*d83cc019SAndroid Build Coastguard Worker chart_add_sample(&gf->power_chart, gf->power.power_mW);
613*d83cc019SAndroid Build Coastguard Worker if (gf->power.new_sample) {
614*d83cc019SAndroid Build Coastguard Worker if (gf->power.power_mW > gf->power_max)
615*d83cc019SAndroid Build Coastguard Worker gf->power_max = gf->power.power_mW;
616*d83cc019SAndroid Build Coastguard Worker chart_set_range(&gf->power_chart, 0, gf->power_max);
617*d83cc019SAndroid Build Coastguard Worker gf->power.new_sample = 0;
618*d83cc019SAndroid Build Coastguard Worker }
619*d83cc019SAndroid Build Coastguard Worker chart_draw(&gf->power_chart, ctx->cr);
620*d83cc019SAndroid Build Coastguard Worker }
621*d83cc019SAndroid Build Coastguard Worker
622*d83cc019SAndroid Build Coastguard Worker y = ctx->height/2 + HALF_PAD + 12 - 2;
623*d83cc019SAndroid Build Coastguard Worker
624*d83cc019SAndroid Build Coastguard Worker y1 = y2 = y;
625*d83cc019SAndroid Build Coastguard Worker if (has_freq) {
626*d83cc019SAndroid Build Coastguard Worker y2 += 12;
627*d83cc019SAndroid Build Coastguard Worker y2 += 12;
628*d83cc019SAndroid Build Coastguard Worker }
629*d83cc019SAndroid Build Coastguard Worker if (has_rc6)
630*d83cc019SAndroid Build Coastguard Worker y2 += 14;
631*d83cc019SAndroid Build Coastguard Worker if (has_power)
632*d83cc019SAndroid Build Coastguard Worker y2 += 14;
633*d83cc019SAndroid Build Coastguard Worker if (has_irqs)
634*d83cc019SAndroid Build Coastguard Worker y2 += 14;
635*d83cc019SAndroid Build Coastguard Worker y1 += -12 - 2;
636*d83cc019SAndroid Build Coastguard Worker y2 += -14 + 4;
637*d83cc019SAndroid Build Coastguard Worker
638*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, PAD, y1, ctx->width/2-SIZE_PAD, y2-y1);
639*d83cc019SAndroid Build Coastguard Worker linear = cairo_pattern_create_linear(PAD, 0, PAD+ctx->width/2-SIZE_PAD, 0);
640*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 0, 0, 0, 0, .5);
641*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 1, 0, 0, 0, .0);
642*d83cc019SAndroid Build Coastguard Worker cairo_set_source(ctx->cr, linear);
643*d83cc019SAndroid Build Coastguard Worker cairo_pattern_destroy(linear);
644*d83cc019SAndroid Build Coastguard Worker cairo_fill(ctx->cr);
645*d83cc019SAndroid Build Coastguard Worker
646*d83cc019SAndroid Build Coastguard Worker if (has_freq) {
647*d83cc019SAndroid Build Coastguard Worker cairo_text_extents_t extents;
648*d83cc019SAndroid Build Coastguard Worker
649*d83cc019SAndroid Build Coastguard Worker len = sprintf(buf, "Frequency: %dMHz", gf->gpu_freq.current);
650*d83cc019SAndroid Build Coastguard Worker if (gf->gpu_freq.request)
651*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
652*d83cc019SAndroid Build Coastguard Worker sprintf(buf + len, " (requested %dMHz)", gf->gpu_freq.request);
653*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD, y);
654*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
655*d83cc019SAndroid Build Coastguard Worker y += 12;
656*d83cc019SAndroid Build Coastguard Worker
657*d83cc019SAndroid Build Coastguard Worker cairo_text_extents(ctx->cr, "Frequency: ", &extents);
658*d83cc019SAndroid Build Coastguard Worker
659*d83cc019SAndroid Build Coastguard Worker cairo_set_font_size(ctx->cr, 8);
660*d83cc019SAndroid Build Coastguard Worker sprintf(buf, " min: %dMHz, max: %dMHz", gf->gpu_freq.min, gf->gpu_freq.max);
661*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, .8, .8, .8, 1);
662*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD + extents.width, y);
663*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
664*d83cc019SAndroid Build Coastguard Worker cairo_set_font_size(ctx->cr, 10);
665*d83cc019SAndroid Build Coastguard Worker y += 12;
666*d83cc019SAndroid Build Coastguard Worker }
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker if (has_rc6) {
669*d83cc019SAndroid Build Coastguard Worker len = sprintf(buf, "RC6: %d%%", gf->rc6.rc6_combined);
670*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
671*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD, y);
672*d83cc019SAndroid Build Coastguard Worker if (gf->rc6.rc6_combined) {
673*d83cc019SAndroid Build Coastguard Worker int need_comma = 0;
674*d83cc019SAndroid Build Coastguard Worker int rewind = len;
675*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, " (");
676*d83cc019SAndroid Build Coastguard Worker if (gf->rc6.rc6) {
677*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%src6=%d%%",
678*d83cc019SAndroid Build Coastguard Worker need_comma ? ", " : "",
679*d83cc019SAndroid Build Coastguard Worker gf->rc6.rc6);
680*d83cc019SAndroid Build Coastguard Worker need_comma++;
681*d83cc019SAndroid Build Coastguard Worker }
682*d83cc019SAndroid Build Coastguard Worker if (gf->rc6.rc6p) {
683*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%src6p=%d%%",
684*d83cc019SAndroid Build Coastguard Worker need_comma ? ", " : "",
685*d83cc019SAndroid Build Coastguard Worker gf->rc6.rc6p);
686*d83cc019SAndroid Build Coastguard Worker need_comma++;
687*d83cc019SAndroid Build Coastguard Worker }
688*d83cc019SAndroid Build Coastguard Worker if (gf->rc6.rc6pp) {
689*d83cc019SAndroid Build Coastguard Worker len += sprintf(buf + len, "%src6pp=%d%%",
690*d83cc019SAndroid Build Coastguard Worker need_comma ? ", " : "",
691*d83cc019SAndroid Build Coastguard Worker gf->rc6.rc6pp);
692*d83cc019SAndroid Build Coastguard Worker need_comma++;
693*d83cc019SAndroid Build Coastguard Worker }
694*d83cc019SAndroid Build Coastguard Worker sprintf(buf + len, ")");
695*d83cc019SAndroid Build Coastguard Worker if (need_comma <= 1)
696*d83cc019SAndroid Build Coastguard Worker buf[rewind] = '\0';
697*d83cc019SAndroid Build Coastguard Worker }
698*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
699*d83cc019SAndroid Build Coastguard Worker y += 14;
700*d83cc019SAndroid Build Coastguard Worker }
701*d83cc019SAndroid Build Coastguard Worker
702*d83cc019SAndroid Build Coastguard Worker if (has_power) {
703*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "Power: %llumW", (long long unsigned)gf->power.power_mW);
704*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
705*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD, y);
706*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
707*d83cc019SAndroid Build Coastguard Worker y += 14;
708*d83cc019SAndroid Build Coastguard Worker }
709*d83cc019SAndroid Build Coastguard Worker
710*d83cc019SAndroid Build Coastguard Worker if (has_irqs) {
711*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "Interrupts: %llu", (long long unsigned)gf->irqs.delta);
712*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
713*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, PAD, y);
714*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
715*d83cc019SAndroid Build Coastguard Worker y += 14;
716*d83cc019SAndroid Build Coastguard Worker }
717*d83cc019SAndroid Build Coastguard Worker }
718*d83cc019SAndroid Build Coastguard Worker
init_gem_objects(struct overlay_context * ctx,struct overlay_gem_objects * go)719*d83cc019SAndroid Build Coastguard Worker static void init_gem_objects(struct overlay_context *ctx,
720*d83cc019SAndroid Build Coastguard Worker struct overlay_gem_objects *go)
721*d83cc019SAndroid Build Coastguard Worker {
722*d83cc019SAndroid Build Coastguard Worker go->error = gem_objects_init(&go->gem_objects);
723*d83cc019SAndroid Build Coastguard Worker if (go->error)
724*d83cc019SAndroid Build Coastguard Worker return;
725*d83cc019SAndroid Build Coastguard Worker
726*d83cc019SAndroid Build Coastguard Worker chart_init(&go->aperture, "aperture", 120);
727*d83cc019SAndroid Build Coastguard Worker chart_set_position(&go->aperture, ctx->width/2+HALF_PAD, ctx->height/2 + HALF_PAD);
728*d83cc019SAndroid Build Coastguard Worker chart_set_size(&go->aperture, ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
729*d83cc019SAndroid Build Coastguard Worker chart_set_stroke_rgba(&go->aperture, 0.75, 0.25, 0.50, 1.);
730*d83cc019SAndroid Build Coastguard Worker chart_set_mode(&go->aperture, CHART_STROKE);
731*d83cc019SAndroid Build Coastguard Worker chart_set_range(&go->aperture, 0, go->gem_objects.max_gtt);
732*d83cc019SAndroid Build Coastguard Worker
733*d83cc019SAndroid Build Coastguard Worker chart_init(&go->gtt, "gtt", 120);
734*d83cc019SAndroid Build Coastguard Worker chart_set_position(&go->gtt, ctx->width/2+HALF_PAD, ctx->height/2 + HALF_PAD);
735*d83cc019SAndroid Build Coastguard Worker chart_set_size(&go->gtt, ctx->width/2 - SIZE_PAD, ctx->height/2 - SIZE_PAD);
736*d83cc019SAndroid Build Coastguard Worker chart_set_fill_rgba(&go->gtt, 0.25, 0.5, 0.5, 1.);
737*d83cc019SAndroid Build Coastguard Worker chart_set_mode(&go->gtt, CHART_FILL);
738*d83cc019SAndroid Build Coastguard Worker chart_set_range(&go->gtt, 0, go->gem_objects.max_gtt);
739*d83cc019SAndroid Build Coastguard Worker }
740*d83cc019SAndroid Build Coastguard Worker
show_gem_objects(struct overlay_context * ctx,struct overlay_gem_objects * go)741*d83cc019SAndroid Build Coastguard Worker static void show_gem_objects(struct overlay_context *ctx, struct overlay_gem_objects *go)
742*d83cc019SAndroid Build Coastguard Worker {
743*d83cc019SAndroid Build Coastguard Worker struct gem_objects_comm *comm;
744*d83cc019SAndroid Build Coastguard Worker char buf[310];
745*d83cc019SAndroid Build Coastguard Worker cairo_pattern_t *linear;
746*d83cc019SAndroid Build Coastguard Worker int x, y, y1, y2;
747*d83cc019SAndroid Build Coastguard Worker
748*d83cc019SAndroid Build Coastguard Worker if (go->error == 0)
749*d83cc019SAndroid Build Coastguard Worker go->error = gem_objects_update(&go->gem_objects);
750*d83cc019SAndroid Build Coastguard Worker if (go->error)
751*d83cc019SAndroid Build Coastguard Worker return;
752*d83cc019SAndroid Build Coastguard Worker
753*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, ctx->width/2+HALF_PAD-.5, ctx->height/2+HALF_PAD-.5, ctx->width/2-SIZE_PAD+1, ctx->height/2-SIZE_PAD+1);
754*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(ctx->cr, .15, .15, .15);
755*d83cc019SAndroid Build Coastguard Worker cairo_set_line_width(ctx->cr, 1);
756*d83cc019SAndroid Build Coastguard Worker cairo_stroke(ctx->cr);
757*d83cc019SAndroid Build Coastguard Worker
758*d83cc019SAndroid Build Coastguard Worker chart_add_sample(&go->gtt, go->gem_objects.total_gtt);
759*d83cc019SAndroid Build Coastguard Worker chart_add_sample(&go->aperture, go->gem_objects.total_aperture);
760*d83cc019SAndroid Build Coastguard Worker
761*d83cc019SAndroid Build Coastguard Worker chart_draw(&go->gtt, ctx->cr);
762*d83cc019SAndroid Build Coastguard Worker chart_draw(&go->aperture, ctx->cr);
763*d83cc019SAndroid Build Coastguard Worker
764*d83cc019SAndroid Build Coastguard Worker
765*d83cc019SAndroid Build Coastguard Worker y = ctx->height/2 + HALF_PAD + 12 - 2;
766*d83cc019SAndroid Build Coastguard Worker x = ctx->width/2 + HALF_PAD;
767*d83cc019SAndroid Build Coastguard Worker
768*d83cc019SAndroid Build Coastguard Worker y2 = y1 = y;
769*d83cc019SAndroid Build Coastguard Worker y2 += 14;
770*d83cc019SAndroid Build Coastguard Worker for (comm = go->gem_objects.comm; comm; comm = comm->next) {
771*d83cc019SAndroid Build Coastguard Worker if ((comm->bytes >> 20) == 0)
772*d83cc019SAndroid Build Coastguard Worker break;
773*d83cc019SAndroid Build Coastguard Worker y2 += 12;
774*d83cc019SAndroid Build Coastguard Worker }
775*d83cc019SAndroid Build Coastguard Worker y1 += -12 - 2;
776*d83cc019SAndroid Build Coastguard Worker y2 += -12 + 4;
777*d83cc019SAndroid Build Coastguard Worker
778*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(ctx->cr, x, y1, ctx->width/2-SIZE_PAD, y2-y1);
779*d83cc019SAndroid Build Coastguard Worker linear = cairo_pattern_create_linear(x, 0, x+ctx->width/2-SIZE_PAD, 0);
780*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 0, 0, 0, 0, .5);
781*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(linear, 1, 0, 0, 0, .0);
782*d83cc019SAndroid Build Coastguard Worker cairo_set_source(ctx->cr, linear);
783*d83cc019SAndroid Build Coastguard Worker cairo_pattern_destroy(linear);
784*d83cc019SAndroid Build Coastguard Worker cairo_fill(ctx->cr);
785*d83cc019SAndroid Build Coastguard Worker
786*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "Total: %ldMB, %ld objects",
787*d83cc019SAndroid Build Coastguard Worker go->gem_objects.total_bytes >> 20, go->gem_objects.total_count);
788*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1);
789*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, x, y);
790*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
791*d83cc019SAndroid Build Coastguard Worker y += 12;
792*d83cc019SAndroid Build Coastguard Worker
793*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(ctx->cr, .8, .8, .8, 1);
794*d83cc019SAndroid Build Coastguard Worker cairo_set_font_size(ctx->cr, 8);
795*d83cc019SAndroid Build Coastguard Worker for (comm = go->gem_objects.comm; comm; comm = comm->next) {
796*d83cc019SAndroid Build Coastguard Worker if ((comm->bytes >> 20) == 0)
797*d83cc019SAndroid Build Coastguard Worker break;
798*d83cc019SAndroid Build Coastguard Worker
799*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "%s %ldMB, %ld objects",
800*d83cc019SAndroid Build Coastguard Worker comm->name, comm->bytes >> 20, comm->count);
801*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx->cr, x, y);
802*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx->cr, buf);
803*d83cc019SAndroid Build Coastguard Worker y += 12;
804*d83cc019SAndroid Build Coastguard Worker }
805*d83cc019SAndroid Build Coastguard Worker }
806*d83cc019SAndroid Build Coastguard Worker
807*d83cc019SAndroid Build Coastguard Worker static int take_snapshot;
808*d83cc019SAndroid Build Coastguard Worker
signal_snapshot(int sig)809*d83cc019SAndroid Build Coastguard Worker static void signal_snapshot(int sig)
810*d83cc019SAndroid Build Coastguard Worker {
811*d83cc019SAndroid Build Coastguard Worker take_snapshot = sig;
812*d83cc019SAndroid Build Coastguard Worker }
813*d83cc019SAndroid Build Coastguard Worker
get_sample_period(struct config * config)814*d83cc019SAndroid Build Coastguard Worker static int get_sample_period(struct config *config)
815*d83cc019SAndroid Build Coastguard Worker {
816*d83cc019SAndroid Build Coastguard Worker const char *value;
817*d83cc019SAndroid Build Coastguard Worker
818*d83cc019SAndroid Build Coastguard Worker value = config_get_value(config, "sampling", "period");
819*d83cc019SAndroid Build Coastguard Worker if (value && atoi(value) > 0)
820*d83cc019SAndroid Build Coastguard Worker return atoi(value);
821*d83cc019SAndroid Build Coastguard Worker
822*d83cc019SAndroid Build Coastguard Worker value = config_get_value(config, "sampling", "frequency");
823*d83cc019SAndroid Build Coastguard Worker if (value && atoi(value) > 0)
824*d83cc019SAndroid Build Coastguard Worker return 1000000 / atoi(value);
825*d83cc019SAndroid Build Coastguard Worker
826*d83cc019SAndroid Build Coastguard Worker return 500000;
827*d83cc019SAndroid Build Coastguard Worker }
828*d83cc019SAndroid Build Coastguard Worker
overlay_snapshot(struct overlay_context * ctx)829*d83cc019SAndroid Build Coastguard Worker static void overlay_snapshot(struct overlay_context *ctx)
830*d83cc019SAndroid Build Coastguard Worker {
831*d83cc019SAndroid Build Coastguard Worker char buf[1024];
832*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "/tmp/overlay-snapshot-%ld.png", (long)time(NULL));
833*d83cc019SAndroid Build Coastguard Worker cairo_surface_write_to_png(ctx->surface, buf);
834*d83cc019SAndroid Build Coastguard Worker }
835*d83cc019SAndroid Build Coastguard Worker
usage(const char * progname)836*d83cc019SAndroid Build Coastguard Worker static void usage(const char *progname)
837*d83cc019SAndroid Build Coastguard Worker {
838*d83cc019SAndroid Build Coastguard Worker printf("intel-gpu-overlay -- realtime display of GPU statistics\n");
839*d83cc019SAndroid Build Coastguard Worker printf("Usage: %s [options]\n", progname);
840*d83cc019SAndroid Build Coastguard Worker printf("\t--config|-c <string> | <filename>\t\t\tSpecify an ini-style configuration string or file\n");
841*d83cc019SAndroid Build Coastguard Worker printf("\t--geometry|-G <width>x<height>+<x-offset>+<y-offset>\tExact window placement and size\n");
842*d83cc019SAndroid Build Coastguard Worker printf("\t--position|-P (top|middle|bottom)-(left|centre|right)\tPlace the window in a particular corner\n");
843*d83cc019SAndroid Build Coastguard Worker printf("\t--size|-S <width>x<height> | <scale>%%\t\t\tWindow size\n");
844*d83cc019SAndroid Build Coastguard Worker printf("\t--foreground|-f\t\t\t\t\t\tKeep the application in foreground\n");
845*d83cc019SAndroid Build Coastguard Worker printf("\t--help|-h\t\t\t\t\t\tThis help message\n");
846*d83cc019SAndroid Build Coastguard Worker }
847*d83cc019SAndroid Build Coastguard Worker
main(int argc,char ** argv)848*d83cc019SAndroid Build Coastguard Worker int main(int argc, char **argv)
849*d83cc019SAndroid Build Coastguard Worker {
850*d83cc019SAndroid Build Coastguard Worker static struct option long_options[] = {
851*d83cc019SAndroid Build Coastguard Worker {"config", 1, 0, 'c'},
852*d83cc019SAndroid Build Coastguard Worker {"geometry", 1, 0, 'G'},
853*d83cc019SAndroid Build Coastguard Worker {"position", 1, 0, 'P'},
854*d83cc019SAndroid Build Coastguard Worker {"size", 1, 0, 'S'},
855*d83cc019SAndroid Build Coastguard Worker {"foreground", 0, 0, 'f'},
856*d83cc019SAndroid Build Coastguard Worker {"help", 0, 0, 'h'},
857*d83cc019SAndroid Build Coastguard Worker {NULL, 0, 0, 0,}
858*d83cc019SAndroid Build Coastguard Worker };
859*d83cc019SAndroid Build Coastguard Worker struct overlay_context ctx;
860*d83cc019SAndroid Build Coastguard Worker struct config config;
861*d83cc019SAndroid Build Coastguard Worker int index, sample_period;
862*d83cc019SAndroid Build Coastguard Worker int daemonize = 1, renice = 0;
863*d83cc019SAndroid Build Coastguard Worker int i;
864*d83cc019SAndroid Build Coastguard Worker
865*d83cc019SAndroid Build Coastguard Worker setlocale(LC_ALL, "");
866*d83cc019SAndroid Build Coastguard Worker config_init(&config);
867*d83cc019SAndroid Build Coastguard Worker
868*d83cc019SAndroid Build Coastguard Worker opterr = 0;
869*d83cc019SAndroid Build Coastguard Worker while ((i = getopt_long(argc, argv, "c:G:fhn?", long_options, &index)) != -1) {
870*d83cc019SAndroid Build Coastguard Worker switch (i) {
871*d83cc019SAndroid Build Coastguard Worker case 'c':
872*d83cc019SAndroid Build Coastguard Worker config_parse_string(&config, optarg);
873*d83cc019SAndroid Build Coastguard Worker break;
874*d83cc019SAndroid Build Coastguard Worker case 'G':
875*d83cc019SAndroid Build Coastguard Worker config_set_value(&config, "window", "geometry", optarg);
876*d83cc019SAndroid Build Coastguard Worker break;
877*d83cc019SAndroid Build Coastguard Worker case 'P':
878*d83cc019SAndroid Build Coastguard Worker config_set_value(&config, "window", "position", optarg);
879*d83cc019SAndroid Build Coastguard Worker break;
880*d83cc019SAndroid Build Coastguard Worker case 'S':
881*d83cc019SAndroid Build Coastguard Worker config_set_value(&config, "window", "size", optarg);
882*d83cc019SAndroid Build Coastguard Worker break;
883*d83cc019SAndroid Build Coastguard Worker case 'f':
884*d83cc019SAndroid Build Coastguard Worker daemonize = 0;
885*d83cc019SAndroid Build Coastguard Worker break;
886*d83cc019SAndroid Build Coastguard Worker case 'n':
887*d83cc019SAndroid Build Coastguard Worker renice = -20;
888*d83cc019SAndroid Build Coastguard Worker if (optarg)
889*d83cc019SAndroid Build Coastguard Worker renice = atoi(optarg);
890*d83cc019SAndroid Build Coastguard Worker break;
891*d83cc019SAndroid Build Coastguard Worker case 'h':
892*d83cc019SAndroid Build Coastguard Worker usage(argv[0]);
893*d83cc019SAndroid Build Coastguard Worker return 0;
894*d83cc019SAndroid Build Coastguard Worker }
895*d83cc019SAndroid Build Coastguard Worker }
896*d83cc019SAndroid Build Coastguard Worker
897*d83cc019SAndroid Build Coastguard Worker if (argc > optind) {
898*d83cc019SAndroid Build Coastguard Worker x11_overlay_stop();
899*d83cc019SAndroid Build Coastguard Worker return 0;
900*d83cc019SAndroid Build Coastguard Worker }
901*d83cc019SAndroid Build Coastguard Worker
902*d83cc019SAndroid Build Coastguard Worker ctx.width = 640;
903*d83cc019SAndroid Build Coastguard Worker ctx.height = 236;
904*d83cc019SAndroid Build Coastguard Worker ctx.surface = NULL;
905*d83cc019SAndroid Build Coastguard Worker if (ctx.surface == NULL)
906*d83cc019SAndroid Build Coastguard Worker ctx.surface = x11_overlay_create(&config, &ctx.width, &ctx.height);
907*d83cc019SAndroid Build Coastguard Worker if (ctx.surface == NULL)
908*d83cc019SAndroid Build Coastguard Worker ctx.surface = x11_window_create(&config, &ctx.width, &ctx.height);
909*d83cc019SAndroid Build Coastguard Worker if (ctx.surface == NULL)
910*d83cc019SAndroid Build Coastguard Worker ctx.surface = kms_overlay_create(&config, &ctx.width, &ctx.height);
911*d83cc019SAndroid Build Coastguard Worker if (ctx.surface == NULL)
912*d83cc019SAndroid Build Coastguard Worker return ENXIO;
913*d83cc019SAndroid Build Coastguard Worker
914*d83cc019SAndroid Build Coastguard Worker if (daemonize && daemon(0, 0))
915*d83cc019SAndroid Build Coastguard Worker return EINVAL;
916*d83cc019SAndroid Build Coastguard Worker
917*d83cc019SAndroid Build Coastguard Worker if (renice && (nice(renice) == -1))
918*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Could not renice: %s\n", strerror(errno));
919*d83cc019SAndroid Build Coastguard Worker
920*d83cc019SAndroid Build Coastguard Worker signal(SIGUSR1, signal_snapshot);
921*d83cc019SAndroid Build Coastguard Worker
922*d83cc019SAndroid Build Coastguard Worker debugfs_init();
923*d83cc019SAndroid Build Coastguard Worker
924*d83cc019SAndroid Build Coastguard Worker init_gpu_top(&ctx, &ctx.gpu_top);
925*d83cc019SAndroid Build Coastguard Worker init_gpu_perf(&ctx, &ctx.gpu_perf);
926*d83cc019SAndroid Build Coastguard Worker init_gpu_freq(&ctx, &ctx.gpu_freq);
927*d83cc019SAndroid Build Coastguard Worker init_gem_objects(&ctx, &ctx.gem_objects);
928*d83cc019SAndroid Build Coastguard Worker
929*d83cc019SAndroid Build Coastguard Worker sample_period = get_sample_period(&config);
930*d83cc019SAndroid Build Coastguard Worker
931*d83cc019SAndroid Build Coastguard Worker i = 0;
932*d83cc019SAndroid Build Coastguard Worker while (1) {
933*d83cc019SAndroid Build Coastguard Worker ctx.time = time(NULL);
934*d83cc019SAndroid Build Coastguard Worker
935*d83cc019SAndroid Build Coastguard Worker ctx.cr = cairo_create(ctx.surface);
936*d83cc019SAndroid Build Coastguard Worker cairo_set_operator(ctx.cr, CAIRO_OPERATOR_CLEAR);
937*d83cc019SAndroid Build Coastguard Worker cairo_paint(ctx.cr);
938*d83cc019SAndroid Build Coastguard Worker cairo_set_operator(ctx.cr, CAIRO_OPERATOR_OVER);
939*d83cc019SAndroid Build Coastguard Worker
940*d83cc019SAndroid Build Coastguard Worker show_gpu_top(&ctx, &ctx.gpu_top);
941*d83cc019SAndroid Build Coastguard Worker show_gpu_perf(&ctx, &ctx.gpu_perf);
942*d83cc019SAndroid Build Coastguard Worker show_gpu_freq(&ctx, &ctx.gpu_freq);
943*d83cc019SAndroid Build Coastguard Worker show_gem_objects(&ctx, &ctx.gem_objects);
944*d83cc019SAndroid Build Coastguard Worker
945*d83cc019SAndroid Build Coastguard Worker {
946*d83cc019SAndroid Build Coastguard Worker char buf[80];
947*d83cc019SAndroid Build Coastguard Worker cairo_text_extents_t extents;
948*d83cc019SAndroid Build Coastguard Worker gethostname(buf, sizeof(buf));
949*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(ctx.cr, .5, .5, .5);
950*d83cc019SAndroid Build Coastguard Worker cairo_set_font_size(ctx.cr, PAD-2);
951*d83cc019SAndroid Build Coastguard Worker cairo_text_extents(ctx.cr, buf, &extents);
952*d83cc019SAndroid Build Coastguard Worker cairo_move_to(ctx.cr,
953*d83cc019SAndroid Build Coastguard Worker (ctx.width-extents.width)/2.,
954*d83cc019SAndroid Build Coastguard Worker 1+extents.height);
955*d83cc019SAndroid Build Coastguard Worker cairo_show_text(ctx.cr, buf);
956*d83cc019SAndroid Build Coastguard Worker }
957*d83cc019SAndroid Build Coastguard Worker
958*d83cc019SAndroid Build Coastguard Worker cairo_destroy(ctx.cr);
959*d83cc019SAndroid Build Coastguard Worker
960*d83cc019SAndroid Build Coastguard Worker overlay_show(ctx.surface);
961*d83cc019SAndroid Build Coastguard Worker
962*d83cc019SAndroid Build Coastguard Worker if (take_snapshot) {
963*d83cc019SAndroid Build Coastguard Worker overlay_snapshot(&ctx);
964*d83cc019SAndroid Build Coastguard Worker take_snapshot = 0;
965*d83cc019SAndroid Build Coastguard Worker }
966*d83cc019SAndroid Build Coastguard Worker
967*d83cc019SAndroid Build Coastguard Worker usleep(sample_period);
968*d83cc019SAndroid Build Coastguard Worker }
969*d83cc019SAndroid Build Coastguard Worker
970*d83cc019SAndroid Build Coastguard Worker return 0;
971*d83cc019SAndroid Build Coastguard Worker }
972