Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / importer / linux_perf / mali_parser.html
1 <!DOCTYPE html>
2 <!--
3 Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
6 -->
7
8 <link rel="import" href="/tracing/importer/linux_perf/parser.html">
9
10 <script>
11 'use strict';
12
13 /**
14  * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format.
15  */
16 tvcm.exportTo('tracing.importer.linux_perf', function() {
17
18   var Parser = tracing.importer.linux_perf.Parser;
19
20   /**
21    * Parses Mali DDK/kernel trace events.
22    * @constructor
23    */
24   function MaliParser(importer) {
25     Parser.call(this, importer);
26
27     // kernel DVFS events
28     importer.registerEventHandler('mali_dvfs_event',
29         MaliParser.prototype.dvfsEventEvent.bind(this));
30     importer.registerEventHandler('mali_dvfs_set_clock',
31         MaliParser.prototype.dvfsSetClockEvent.bind(this));
32     importer.registerEventHandler('mali_dvfs_set_voltage',
33         MaliParser.prototype.dvfsSetVoltageEvent.bind(this));
34
35     // kernel Mali hw counter events
36     this.addJMCounter('mali_hwc_MESSAGES_SENT', 'Messages Sent');
37     this.addJMCounter('mali_hwc_MESSAGES_RECEIVED', 'Messages Received');
38     this.addJMCycles('mali_hwc_GPU_ACTIVE', 'GPU Active');
39     this.addJMCycles('mali_hwc_IRQ_ACTIVE', 'IRQ Active');
40
41     for (var i = 0; i < 7; i++) {
42       var jobStr = 'JS' + i;
43       var jobHWCStr = 'mali_hwc_' + jobStr;
44       this.addJMCounter(jobHWCStr + '_JOBS', jobStr + ' Jobs');
45       this.addJMCounter(jobHWCStr + '_TASKS', jobStr + ' Tasks');
46       this.addJMCycles(jobHWCStr + '_ACTIVE', jobStr + ' Active');
47       this.addJMCycles(jobHWCStr + '_WAIT_READ', jobStr + ' Wait Read');
48       this.addJMCycles(jobHWCStr + '_WAIT_ISSUE', jobStr + ' Wait Issue');
49       this.addJMCycles(jobHWCStr + '_WAIT_DEPEND', jobStr + ' Wait Depend');
50       this.addJMCycles(jobHWCStr + '_WAIT_FINISH', jobStr + ' Wait Finish');
51     }
52
53     this.addTilerCounter('mali_hwc_TRIANGLES', 'Triangles');
54     this.addTilerCounter('mali_hwc_QUADS', 'Quads');
55     this.addTilerCounter('mali_hwc_POLYGONS', 'Polygons');
56     this.addTilerCounter('mali_hwc_POINTS', 'Points');
57     this.addTilerCounter('mali_hwc_LINES', 'Lines');
58     this.addTilerCounter('mali_hwc_VCACHE_HIT', 'VCache Hit');
59     this.addTilerCounter('mali_hwc_VCACHE_MISS', 'VCache Miss');
60     this.addTilerCounter('mali_hwc_FRONT_FACING', 'Front Facing');
61     this.addTilerCounter('mali_hwc_BACK_FACING', 'Back Facing');
62     this.addTilerCounter('mali_hwc_PRIM_VISIBLE', 'Prim Visible');
63     this.addTilerCounter('mali_hwc_PRIM_CULLED', 'Prim Culled');
64     this.addTilerCounter('mali_hwc_PRIM_CLIPPED', 'Prim Clipped');
65
66     this.addTilerCounter('mali_hwc_WRBUF_HIT', 'Wrbuf Hit');
67     this.addTilerCounter('mali_hwc_WRBUF_MISS', 'Wrbuf Miss');
68     this.addTilerCounter('mali_hwc_WRBUF_LINE', 'Wrbuf Line');
69     this.addTilerCounter('mali_hwc_WRBUF_PARTIAL', 'Wrbuf Partial');
70     this.addTilerCounter('mali_hwc_WRBUF_STALL', 'Wrbuf Stall');
71
72     this.addTilerCycles('mali_hwc_ACTIVE', 'Tiler Active');
73     this.addTilerCycles('mali_hwc_INDEX_WAIT', 'Index Wait');
74     this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT', 'Index Range Wait');
75     this.addTilerCycles('mali_hwc_VERTEX_WAIT', 'Vertex Wait');
76     this.addTilerCycles('mali_hwc_PCACHE_WAIT', 'Pcache Wait');
77     this.addTilerCycles('mali_hwc_WRBUF_WAIT', 'Wrbuf Wait');
78     this.addTilerCycles('mali_hwc_BUS_READ', 'Bus Read');
79     this.addTilerCycles('mali_hwc_BUS_WRITE', 'Bus Write');
80
81     this.addTilerCycles('mali_hwc_TILER_UTLB_STALL', 'Tiler UTLB Stall');
82     this.addTilerCycles('mali_hwc_TILER_UTLB_HIT', 'Tiler UTLB Hit');
83
84     this.addFragCycles('mali_hwc_FRAG_ACTIVE', 'Active');
85     /* NB: don't propagate spelling mistakes to labels */
86     this.addFragCounter('mali_hwc_FRAG_PRIMATIVES', 'Primitives');
87     this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED',
88         'Primitives Dropped');
89     this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC', 'Descriptor Processing');
90     this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR', 'PLR Processing??');
91     this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT', 'Vertex Processing');
92     this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP', 'Triangle Setup');
93     this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST', 'Rasterization???');
94     this.addFragCounter('mali_hwc_FRAG_THREADS', 'Threads');
95     this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS', 'Dummy Threads');
96     this.addFragCounter('mali_hwc_FRAG_QUADS_RAST', 'Quads Rast');
97     this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST', 'Quads EZS Test');
98     this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED', 'Quads EZS Killed');
99     this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST', 'Quads LZS Test');
100     this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED', 'Quads LZS Killed');
101     this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE', 'No Tiles');
102     this.addFragCounter('mali_hwc_FRAG_NUM_TILES', 'Tiles');
103     this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM', 'Transactions Eliminated');
104
105     this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE', 'Active');
106     this.addComputeCounter('mali_hwc_COMPUTE_TASKS', 'Tasks');
107     this.addComputeCounter('mali_hwc_COMPUTE_THREADS', 'Threads Started');
108     this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC',
109         'Waiting for Descriptors');
110
111     this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE', 'Active');
112
113     this.addArithCounter('mali_hwc_ARITH_WORDS', 'Instructions (/Pipes)');
114     this.addArithCycles('mali_hwc_ARITH_CYCLES_REG',
115         'Reg scheduling stalls (/Pipes)');
116     this.addArithCycles('mali_hwc_ARITH_CYCLES_L0',
117         'L0 cache miss stalls (/Pipes)');
118     this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND',
119         'Frag dep check failures (/Pipes)');
120
121     this.addLSCounter('mali_hwc_LS_WORDS', 'Instruction Words Completed');
122     this.addLSCounter('mali_hwc_LS_ISSUES', 'Full Pipeline Issues');
123     this.addLSCounter('mali_hwc_LS_RESTARTS', 'Restarts (unpairable insts)');
124     this.addLSCounter('mali_hwc_LS_REISSUES_MISS',
125         'Pipeline reissue (cache miss/uTLB)');
126     this.addLSCounter('mali_hwc_LS_REISSUES_VD',
127         'Pipeline reissue (varying data)');
128     /* TODO(sleffler) fix kernel event typo */
129     this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS',
130         'Pipeline reissue (attribute cache miss)');
131     this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB', 'Writeback not used');
132
133     this.addTexCounter('mali_hwc_TEX_WORDS', 'Words');
134     this.addTexCounter('mali_hwc_TEX_BUBBLES', 'Bubbles');
135     this.addTexCounter('mali_hwc_TEX_WORDS_L0', 'Words L0');
136     this.addTexCounter('mali_hwc_TEX_WORDS_DESC', 'Words Desc');
137     this.addTexCounter('mali_hwc_TEX_THREADS', 'Threads');
138     this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS', 'Recirc due to Full Miss');
139     this.addTexCounter('mali_hwc_TEX_RECIRC_DESC', 'Recirc due to Desc Miss');
140     this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI', 'Recirc due to Multipass');
141     this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS',
142         'Recirc due to Partial Cache Miss');
143     this.addTexCounter('mali_hwc_TEX_RECIRC_CONF',
144         'Recirc due to Cache Conflict');
145
146     this.addLSCCounter('mali_hwc_LSC_READ_HITS', 'Read Hits');
147     this.addLSCCounter('mali_hwc_LSC_READ_MISSES', 'Read Misses');
148     this.addLSCCounter('mali_hwc_LSC_WRITE_HITS', 'Write Hits');
149     this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES', 'Write Misses');
150     this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS', 'Atomic Hits');
151     this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES', 'Atomic Misses');
152     this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES', 'Line Fetches');
153     this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE', 'Dirty Lines');
154     this.addLSCCounter('mali_hwc_LSC_SNOOPS', 'Snoops');
155
156     this.addAXICounter('mali_hwc_AXI_TLB_STALL', 'Address channel stall');
157     this.addAXICounter('mali_hwc_AXI_TLB_MISS', 'Cache Miss');
158     this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION', 'Transactions');
159     this.addAXICounter('mali_hwc_LS_TLB_MISS', 'LS Cache Miss');
160     this.addAXICounter('mali_hwc_LS_TLB_HIT', 'LS Cache Hit');
161     this.addAXICounter('mali_hwc_AXI_BEATS_READ', 'Read Beats');
162     this.addAXICounter('mali_hwc_AXI_BEATS_WRITE', 'Write Beats');
163
164     this.addMMUCounter('mali_hwc_MMU_TABLE_WALK', 'Page Table Walks');
165     this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS',
166         'Cache Miss from Replay Buffer');
167     this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL', 'Replay Buffer Full');
168     this.addMMUCounter('mali_hwc_MMU_NEW_MISS', 'Cache Miss on New Request');
169     this.addMMUCounter('mali_hwc_MMU_HIT', 'Cache Hit');
170
171     this.addMMUCycles('mali_hwc_UTLB_STALL', 'UTLB Stalled');
172     this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS', 'UTLB Replay Miss');
173     this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL', 'UTLB Replay Full');
174     this.addMMUCycles('mali_hwc_UTLB_NEW_MISS', 'UTLB New Miss');
175     this.addMMUCycles('mali_hwc_UTLB_HIT', 'UTLB Hit');
176
177     this.addL2Counter('mali_hwc_L2_READ_BEATS', 'Read Beats');
178     this.addL2Counter('mali_hwc_L2_WRITE_BEATS', 'Write Beats');
179     this.addL2Counter('mali_hwc_L2_ANY_LOOKUP', 'Any Lookup');
180     this.addL2Counter('mali_hwc_L2_READ_LOOKUP', 'Read Lookup');
181     this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP', 'Shareable Read Lookup');
182     this.addL2Counter('mali_hwc_L2_READ_REPLAY', 'Read Replayed');
183     this.addL2Counter('mali_hwc_L2_READ_SNOOP', 'Read Snoop');
184     this.addL2Counter('mali_hwc_L2_READ_HIT', 'Read Cache Hit');
185     this.addL2Counter('mali_hwc_L2_CLEAN_MISS', 'CleanUnique Miss');
186     this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP', 'Write Lookup');
187     this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP', 'Shareable Write Lookup');
188     this.addL2Counter('mali_hwc_L2_WRITE_REPLAY', 'Write Replayed');
189     this.addL2Counter('mali_hwc_L2_WRITE_SNOOP', 'Write Snoop');
190     this.addL2Counter('mali_hwc_L2_WRITE_HIT', 'Write Cache Hit');
191     this.addL2Counter('mali_hwc_L2_EXT_READ_FULL', 'ExtRD with BIU Full');
192     this.addL2Counter('mali_hwc_L2_EXT_READ_HALF', 'ExtRD with BIU >1/2 Full');
193     this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL', 'ExtWR with BIU Full');
194     this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF', 'ExtWR with BIU >1/2 Full');
195
196     this.addL2Counter('mali_hwc_L2_EXT_READ', 'External Read (ExtRD)');
197     this.addL2Counter('mali_hwc_L2_EXT_READ_LINE', 'ExtRD (linefill)');
198     this.addL2Counter('mali_hwc_L2_EXT_WRITE', 'External Write (ExtWR)');
199     this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE', 'ExtWR (linefill)');
200     this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL', 'ExtWR (burst size <64B)');
201     this.addL2Counter('mali_hwc_L2_EXT_BARRIER', 'External Barrier');
202     this.addL2Counter('mali_hwc_L2_EXT_AR_STALL', 'Address Read stalls');
203     this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL',
204         'Response Buffer full stalls');
205     this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL',
206         'Read Data Buffer full stalls');
207     this.addL2Counter('mali_hwc_L2_EXT_R_RAW', 'RAW hazard stalls');
208     this.addL2Counter('mali_hwc_L2_EXT_W_STALL', 'Write Data stalls');
209     this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL', 'Write Data Buffer full');
210     this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD', 'WAW or WAR hazard stalls');
211     this.addL2Counter('mali_hwc_L2_TAG_HAZARD', 'Tag hazard replays');
212     this.addL2Cycles('mali_hwc_L2_SNOOP_FULL', 'Snoop buffer full');
213     this.addL2Cycles('mali_hwc_L2_REPLAY_FULL', 'Replay buffer full');
214
215     // DDK events (from X server)
216     importer.registerEventHandler('tracing_mark_write:mali_driver',
217         MaliParser.prototype.maliDDKEvent.bind(this));
218
219     this.model_ = importer.model_;
220   }
221
222   MaliParser.prototype = {
223     __proto__: Parser.prototype,
224
225     maliDDKOpenSlice: function(pid, tid, ts, func, blockinfo) {
226       var thread = this.importer.model_.getOrCreateProcess(pid)
227         .getOrCreateThread(tid);
228       var funcArgs = /^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);
229       thread.sliceGroup.beginSlice('gpu-driver', funcArgs[1], ts,
230           { 'args': funcArgs[2],
231             'blockinfo': blockinfo });
232     },
233
234     maliDDKCloseSlice: function(pid, tid, ts, args, blockinfo) {
235       var thread = this.importer.model_.getOrCreateProcess(pid)
236         .getOrCreateThread(tid);
237       if (!thread.sliceGroup.openSliceCount) {
238         // Discard unmatched ends.
239         return;
240       }
241       thread.sliceGroup.endSlice(ts);
242     },
243
244     /**
245      * Deduce the format of Mali perf events.
246      *
247      * @return {RegExp} the regular expression for parsing data when the format
248      * is recognized; otherwise null.
249      */
250     autoDetectLineRE: function(line) {
251       // Matches Mali perf events with thread info
252       var lineREWithThread =
253           /^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;
254       if (lineREWithThread.test(line))
255         return lineREWithThread;
256
257       // Matches old-style Mali perf events
258       var lineRENoThread = /^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;
259       if (lineRENoThread.test(line))
260         return lineRENoThread;
261       return null;
262     },
263
264     lineRE: null,
265
266     /**
267      * Parses maliDDK events and sets up state in the importer.
268      * events will come in pairs with a cros_trace_print_enter
269      * like this (line broken here for formatting):
270      *
271      * tracing_mark_write: mali_driver: (mali-012345) cros_trace_print_enter: \
272      *   gles/src/texture/mali_gles_texture_slave.c@1505: gles2_texturep_upload
273      *
274      * and a cros_trace_print_exit like this:
275      *
276      * tracing_mark_write: mali_driver: (mali-012345) cros_trace_print_exit: \
277      *   gles/src/texture/mali_gles_texture_slave.c@1505:
278      */
279     maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
280       if (this.lineRE == null) {
281         this.lineRE = this.autoDetectLineRE(eventBase.details);
282         if (this.lineRE == null)
283           return false;
284       }
285       var maliEvent = this.lineRE.exec(eventBase.details);
286       // Old-style Mali perf events have no thread id, so make one.
287       var tid = (maliEvent[1] === '' ? 'mali' : maliEvent[1]);
288       switch (maliEvent[2]) {
289         case 'cros_trace_print_enter':
290           this.maliDDKOpenSlice(pid, tid, ts, maliEvent[4],
291               maliEvent[3]);
292           break;
293         case 'cros_trace_print_exit':
294           this.maliDDKCloseSlice(pid, tid, ts, [], maliEvent[3]);
295       }
296       return true;
297     },
298
299     /*
300      * Kernel event support.
301      */
302
303     dvfsSample: function(counterName, seriesName, ts, s) {
304       var value = parseInt(s);
305       var counter = this.model_.getOrCreateProcess(0).
306           getOrCreateCounter('DVFS', counterName);
307       if (counter.numSeries === 0) {
308         counter.addSeries(new tracing.trace_model.CounterSeries(seriesName,
309             tvcm.ui.getStringColorId(counter.name)));
310       }
311       counter.series.forEach(function(series) {
312         series.addCounterSample(ts, value);
313       });
314     },
315
316     dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
317       var event = /utilization=(\d+)/.exec(eventBase.details);
318       if (!event)
319         return false;
320
321       this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]);
322       return true;
323     },
324
325     dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
326       var event = /frequency=(\d+)/.exec(eventBase.details);
327       if (!event)
328         return false;
329
330       this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]);
331       return true;
332     },
333
334     dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
335       var event = /voltage=(\d+)/.exec(eventBase.details);
336       if (!event)
337         return false;
338
339       this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]);
340       return true;
341     },
342
343     hwcSample: function(cat, counterName, seriesName, ts, eventBase) {
344       var event = /val=(\d+)/.exec(eventBase.details);
345       if (!event)
346         return false;
347       var value = parseInt(event[1]);
348
349       var counter = this.model_.getOrCreateProcess(0).
350           getOrCreateCounter(cat, counterName);
351       if (counter.numSeries === 0) {
352         counter.addSeries(new tracing.trace_model.CounterSeries(seriesName,
353             tvcm.ui.getStringColorId(counter.name)));
354       }
355       counter.series.forEach(function(series) {
356         series.addCounterSample(ts, value);
357       });
358       return true;
359     },
360
361     /*
362      * Job Manager block counters.
363      */
364     jmSample: function(ctrName, seriesName, ts, eventBase) {
365       return this.hwcSample('mali:jm', 'JM: ' + ctrName, seriesName, ts,
366           eventBase);
367     },
368     addJMCounter: function(hwcEventName, hwcTitle) {
369       function handler(eventName, cpuNumber, pid, ts, eventBase) {
370         return this.jmSample(hwcTitle, 'count', ts, eventBase);
371       }
372       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
373     },
374     addJMCycles: function(hwcEventName, hwcTitle) {
375       function handler(eventName, cpuNumber, pid, ts, eventBase) {
376         return this.jmSample(hwcTitle, 'cycles', ts, eventBase);
377       }
378       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
379     },
380
381     /*
382      * Tiler block counters.
383      */
384     tilerSample: function(ctrName, seriesName, ts, eventBase) {
385       return this.hwcSample('mali:tiler', 'Tiler: ' + ctrName, seriesName,
386           ts, eventBase);
387     },
388     addTilerCounter: function(hwcEventName, hwcTitle) {
389       function handler(eventName, cpuNumber, pid, ts, eventBase) {
390         return this.tilerSample(hwcTitle, 'count', ts, eventBase);
391       }
392       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
393     },
394     addTilerCycles: function(hwcEventName, hwcTitle) {
395       function handler(eventName, cpuNumber, pid, ts, eventBase) {
396         return this.tilerSample(hwcTitle, 'cycles', ts, eventBase);
397       }
398       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
399     },
400
401     /*
402      * Fragment counters.
403      */
404     fragSample: function(ctrName, seriesName, ts, eventBase) {
405       return this.hwcSample('mali:fragment', 'Fragment: ' + ctrName,
406           seriesName, ts, eventBase);
407     },
408     addFragCounter: function(hwcEventName, hwcTitle) {
409       function handler(eventName, cpuNumber, pid, ts, eventBase) {
410         return this.fragSample(hwcTitle, 'count', ts, eventBase);
411       }
412       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
413     },
414     addFragCycles: function(hwcEventName, hwcTitle) {
415       function handler(eventName, cpuNumber, pid, ts, eventBase) {
416         return this.fragSample(hwcTitle, 'cycles', ts, eventBase);
417       }
418       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
419     },
420
421     /*
422      * Compute counters.
423      */
424     computeSample: function(ctrName, seriesName, ts, eventBase) {
425       return this.hwcSample('mali:compute', 'Compute: ' + ctrName,
426           seriesName, ts, eventBase);
427     },
428     addComputeCounter: function(hwcEventName, hwcTitle) {
429       function handler(eventName, cpuNumber, pid, ts, eventBase) {
430         return this.computeSample(hwcTitle, 'count', ts, eventBase);
431       }
432       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
433     },
434     addComputeCycles: function(hwcEventName, hwcTitle) {
435       function handler(eventName, cpuNumber, pid, ts, eventBase) {
436         return this.computeSample(hwcTitle, 'cycles', ts, eventBase);
437       }
438       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
439     },
440
441     /*
442      * Tripipe counters.
443      */
444     addTripipeCycles: function(hwcEventName, hwcTitle) {
445       function handler(eventName, cpuNumber, pid, ts, eventBase) {
446         return this.hwcSample('mali:shader', 'Tripipe: ' + hwcTitle, 'cycles',
447             ts, eventBase);
448       }
449       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
450     },
451
452     /*
453      * Arith counters.
454      */
455     arithSample: function(ctrName, seriesName, ts, eventBase) {
456       return this.hwcSample('mali:arith', 'Arith: ' + ctrName, seriesName, ts,
457           eventBase);
458     },
459     addArithCounter: function(hwcEventName, hwcTitle) {
460       function handler(eventName, cpuNumber, pid, ts, eventBase) {
461         return this.arithSample(hwcTitle, 'count', ts, eventBase);
462       }
463       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
464     },
465     addArithCycles: function(hwcEventName, hwcTitle) {
466       function handler(eventName, cpuNumber, pid, ts, eventBase) {
467         return this.arithSample(hwcTitle, 'cycles', ts, eventBase);
468       }
469       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
470     },
471
472     /*
473      * Load/Store counters.
474      */
475     addLSCounter: function(hwcEventName, hwcTitle) {
476       function handler(eventName, cpuNumber, pid, ts, eventBase) {
477         return this.hwcSample('mali:ls', 'LS: ' + hwcTitle, 'count', ts,
478             eventBase);
479       }
480       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
481     },
482
483     /*
484      * Texture counters.
485      */
486     textureSample: function(ctrName, seriesName, ts, eventBase) {
487       return this.hwcSample('mali:texture', 'Texture: ' + ctrName,
488           seriesName, ts, eventBase);
489     },
490     addTexCounter: function(hwcEventName, hwcTitle) {
491       function handler(eventName, cpuNumber, pid, ts, eventBase) {
492         return this.textureSample(hwcTitle, 'count', ts, eventBase);
493       }
494       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
495     },
496
497     /*
498      * LSC counters.
499      */
500     addLSCCounter: function(hwcEventName, hwcTitle) {
501       function handler(eventName, cpuNumber, pid, ts, eventBase) {
502         return this.hwcSample('mali:lsc', 'LSC: ' + hwcTitle, 'count', ts,
503             eventBase);
504       }
505       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
506     },
507
508     /*
509      * TLB counters.
510      */
511     addAXICounter: function(hwcEventName, hwcTitle) {
512       function handler(eventName, cpuNumber, pid, ts, eventBase) {
513         return this.hwcSample('mali:axi', 'AXI: ' + hwcTitle, 'count', ts,
514             eventBase);
515       }
516       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
517     },
518
519     /*
520      * MMU counters.
521      */
522     mmuSample: function(ctrName, seriesName, ts, eventBase) {
523       return this.hwcSample('mali:mmu', 'MMU: ' + ctrName, seriesName, ts,
524           eventBase);
525     },
526     addMMUCounter: function(hwcEventName, hwcTitle) {
527       function handler(eventName, cpuNumber, pid, ts, eventBase) {
528         return this.mmuSample(hwcTitle, 'count', ts, eventBase);
529       }
530       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
531     },
532     addMMUCycles: function(hwcEventName, hwcTitle) {
533       function handler(eventName, cpuNumber, pid, ts, eventBase) {
534         return this.mmuSample(hwcTitle, 'cycles', ts, eventBase);
535       }
536       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
537     },
538
539     /*
540      * L2 counters.
541      */
542     l2Sample: function(ctrName, seriesName, ts, eventBase) {
543       return this.hwcSample('mali:l2', 'L2: ' + ctrName, seriesName, ts,
544           eventBase);
545     },
546     addL2Counter: function(hwcEventName, hwcTitle) {
547       function handler(eventName, cpuNumber, pid, ts, eventBase) {
548         return this.l2Sample(hwcTitle, 'count', ts, eventBase);
549       }
550       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
551     },
552     addL2Cycles: function(hwcEventName, hwcTitle) {
553       function handler(eventName, cpuNumber, pid, ts, eventBase) {
554         return this.l2Sample(hwcTitle, 'cycles', ts, eventBase);
555       }
556       this.importer.registerEventHandler(hwcEventName, handler.bind(this));
557     }
558   };
559
560   Parser.registerSubtype(MaliParser);
561
562   return {
563     MaliParser: MaliParser
564   };
565 });
566 </script>
567