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