Home | History | Annotate | Download | only in tracks
      1 // Copyright (c) 2013 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 base.requireStylesheet('tracing.tracks.drawing_container');
      8 
      9 base.require('base.raf');
     10 base.require('tracing.tracks.track');
     11 base.require('ui');
     12 
     13 base.exportTo('tracing.tracks', function() {
     14   var DrawType = {
     15     SLICE: 1,
     16     INSTANT_EVENT: 2
     17   };
     18 
     19   var DrawingContainer = ui.define('drawing-container', tracing.tracks.Track);
     20 
     21   DrawingContainer.prototype = {
     22     __proto__: tracing.tracks.Track.prototype,
     23 
     24     decorate: function(viewport) {
     25       tracing.tracks.Track.prototype.decorate.call(this, viewport);
     26       this.classList.add('drawing-container');
     27 
     28       this.canvas_ = document.createElement('canvas');
     29       this.canvas_.className = 'drawing-container-canvas';
     30       this.canvas_.style.left = tracing.constants.HEADING_WIDTH + 'px';
     31       this.appendChild(this.canvas_);
     32 
     33       this.ctx_ = this.canvas_.getContext('2d');
     34 
     35       this.viewportChange_ = this.viewportChange_.bind(this);
     36       this.viewport.addEventListener('change', this.viewportChange_);
     37     },
     38 
     39     // Needed to support the calls in TimelineTrackView.
     40     get canvas() {
     41       return this.canvas_;
     42     },
     43 
     44     context: function() {
     45       return this.ctx_;
     46     },
     47 
     48     viewportChange_: function() {
     49       this.invalidate();
     50     },
     51 
     52     invalidate: function() {
     53       if (this.rafPending_)
     54         return;
     55       this.rafPending_ = true;
     56 
     57       base.requestPreAnimationFrame(function() {
     58         this.rafPending_ = false;
     59         this.ctx_.clearRect(0, 0, this.canvas_.width, this.canvas_.height);
     60         this.updateCanvasSizeIfNeeded_();
     61 
     62         base.requestAnimationFrameInThisFrameIfPossible(function() {
     63           for (var i = 0; i < this.children.length; ++i) {
     64             if (!(this.children[i] instanceof tracing.tracks.Track))
     65               continue;
     66             this.children[i].drawTrack(DrawType.INSTANT_EVENT);
     67           }
     68 
     69           for (var i = 0; i < this.children.length; ++i) {
     70             if (!(this.children[i] instanceof tracing.tracks.Track))
     71               continue;
     72             this.children[i].drawTrack(DrawType.SLICE);
     73           }
     74 
     75           var pixelRatio = window.devicePixelRatio || 1;
     76           var bounds = this.canvas_.getBoundingClientRect();
     77           var viewLWorld = this.viewport.xViewToWorld(0);
     78           var viewRWorld = this.viewport.xViewToWorld(
     79               bounds.width * pixelRatio);
     80 
     81           this.viewport.drawGridLines(this.ctx_, viewLWorld, viewRWorld);
     82           this.viewport.drawMarkerLines(this.ctx_, viewLWorld, viewRWorld);
     83         }, this);
     84       }, this);
     85     },
     86 
     87     updateCanvasSizeIfNeeded_: function() {
     88       var visibleChildTracks =
     89           base.asArray(this.children).filter(this.visibleFilter_);
     90 
     91       var thisBounds = this.getBoundingClientRect();
     92 
     93       var firstChildTrackBounds = visibleChildTracks[0].getBoundingClientRect();
     94       var lastChildTrackBounds =
     95           visibleChildTracks[visibleChildTracks.length - 1].
     96               getBoundingClientRect();
     97 
     98       var innerWidth = firstChildTrackBounds.width -
     99           tracing.constants.HEADING_WIDTH;
    100       var innerHeight = lastChildTrackBounds.bottom - firstChildTrackBounds.top;
    101 
    102       var pixelRatio = window.devicePixelRatio || 1;
    103       if (this.canvas_.width != innerWidth * pixelRatio) {
    104         this.canvas_.width = innerWidth * pixelRatio;
    105         this.canvas_.style.width = innerWidth + 'px';
    106       }
    107 
    108       if (this.canvas_.height != innerHeight * pixelRatio) {
    109         this.canvas_.height = innerHeight * pixelRatio;
    110         this.canvas_.style.height = innerHeight + 'px';
    111       }
    112 
    113       var canvasTop =
    114           firstChildTrackBounds.top - thisBounds.top + this.scrollTop;
    115       if (this.canvas_.style.top + 'px' !== canvasTop)
    116         this.canvas_.style.top = canvasTop + 'px';
    117     },
    118 
    119     visibleFilter_: function(element) {
    120       if (!(element instanceof tracing.tracks.Track))
    121         return false;
    122       return window.getComputedStyle(element).display !== 'none';
    123     }
    124   };
    125 
    126   return {
    127     DrawingContainer: DrawingContainer,
    128     DrawType: DrawType
    129   };
    130 });
    131