| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library heap_map_element; |
| 6 |
| 7 import 'dart:async'; |
| 8 import 'dart:html'; |
| 9 import 'dart:math'; |
| 10 import 'observatory_element.dart'; |
| 11 import 'package:observatory/service.dart'; |
| 12 import 'package:logging/logging.dart'; |
| 13 import 'package:polymer/polymer.dart'; |
| 14 import 'package:observatory/app.dart'; |
| 15 |
| 16 /// Displays an Error response. |
| 17 @CustomTag('heap-map') |
| 18 class HeapMapElement extends ObservatoryElement { |
| 19 var _fragmentationCanvas; |
| 20 var _fragmentationData; |
| 21 |
| 22 @observable String status; |
| 23 @published ServiceMap fragmentation; |
| 24 |
| 25 HeapMapElement.created() : super.created() { |
| 26 } |
| 27 |
| 28 void enteredView() { |
| 29 super.enteredView(); |
| 30 _fragmentationCanvas = shadowRoot.querySelector("#fragmentation"); |
| 31 } |
| 32 |
| 33 List<int> _classIdToRGBA(int classId) { |
| 34 if (classId == fragmentation['free_class_id']) { |
| 35 return [255, 255, 255, 255]; |
| 36 } else { |
| 37 // TODO(koda): Pick random hue, but fixed saturation and value. |
| 38 var rng = new Random(classId); |
| 39 return [rng.nextInt(128), |
| 40 rng.nextInt(128), |
| 41 rng.nextInt(128), |
| 42 255]; |
| 43 } |
| 44 } |
| 45 |
| 46 void _updateFragmentationData() { |
| 47 if (fragmentation == null || _fragmentationCanvas == null) { |
| 48 return; |
| 49 } |
| 50 var pages = fragmentation['pages']; |
| 51 // Calculate dimensions. |
| 52 var numPixels = 0; |
| 53 var colorMap = {}; |
| 54 for (var page in pages) { |
| 55 for (int i = 0; i < page.length; i += 2) { |
| 56 numPixels += page[i]; |
| 57 var classId = page[i + 1]; |
| 58 colorMap.putIfAbsent(classId, () => _classIdToRGBA(classId)); |
| 59 } |
| 60 } |
| 61 var width = _fragmentationCanvas.parent.client.width; |
| 62 var height = (numPixels + width - 1) ~/ width; |
| 63 // Render image. |
| 64 _fragmentationData = |
| 65 _fragmentationCanvas.context2D.createImageData(width, height); |
| 66 _fragmentationCanvas.width = _fragmentationData.width; |
| 67 _fragmentationCanvas.height = _fragmentationData.height; |
| 68 _renderPages(0, 0, colorMap); |
| 69 } |
| 70 |
| 71 // Renders and draws asynchronously, one page at a time to avoid |
| 72 // blocking the UI. |
| 73 void _renderPages(int startPage, int dataIndex, var colorMap) { |
| 74 var pages = fragmentation['pages']; |
| 75 status = 'Loaded $startPage of ${pages.length} pages'; |
| 76 if (startPage >= pages.length) { |
| 77 return; |
| 78 } |
| 79 var width = _fragmentationData.width; |
| 80 var dirtyBegin = (dataIndex / 4) ~/ width; |
| 81 var page = pages[startPage]; |
| 82 for (var i = 0; i < page.length; i += 2) { |
| 83 var count = page[i]; |
| 84 var color = colorMap[page[i + 1]]; |
| 85 for (var j = 0; j < count; ++j) { |
| 86 for (var component in color) { |
| 87 _fragmentationData.data[dataIndex++] = component; |
| 88 } |
| 89 } |
| 90 } |
| 91 var dirtyEnd = (dataIndex / 4 + width - 1) ~/ width; |
| 92 _fragmentationCanvas.context2D.putImageData( |
| 93 _fragmentationData, 0, 0, 0, dirtyBegin, width, dirtyEnd - dirtyBegin); |
| 94 // Continue with the next page, asynchronously. |
| 95 new Future(() { |
| 96 _renderPages(startPage + 1, dataIndex, colorMap); |
| 97 }); |
| 98 } |
| 99 |
| 100 void refresh(var done) { |
| 101 if (fragmentation == null) { |
| 102 return; |
| 103 } |
| 104 fragmentation.isolate.get('heapmap').then((ServiceMap response) { |
| 105 assert(response['type'] == 'HeapMap'); |
| 106 fragmentation = response; |
| 107 }).catchError((e, st) { |
| 108 Logger.root.info('$e $st'); |
| 109 }).whenComplete(done); |
| 110 } |
| 111 |
| 112 void fragmentationChanged(oldValue) { |
| 113 // Async, in case enteredView has not yet run (observed in JS version). |
| 114 new Future(() { |
| 115 _updateFragmentationData(); |
| 116 }); |
| 117 } |
| 118 } |
| OLD | NEW |