Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / fast_rect_renderer.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 <link rel="import" href="/tvcm.html">
8 <script>
9 'use strict';
10
11 /**
12  * @fileoverview Provides a mechanism for drawing massive numbers of
13  * colored rectangles into a canvas in an efficient manner, provided
14  * they are drawn left to right with fixed y and height throughout.
15  *
16  * The basic idea used here is to fuse subpixel rectangles together so that
17  * we never issue a canvas fillRect for them. It turns out Javascript can
18  * do this quite efficiently, compared to asking Canvas2D to do the same.
19  *
20  * A few extra things are done by this class in the name of speed:
21  * - Viewport culling: off-viewport rectangles are discarded.
22  *
23  * - The actual discarding operation is done in world space,
24  *   e.g. pre-transform.
25  *
26  * - Rather than expending compute cycles trying to figure out an average
27  *   color for fused rectangles from css strings, you instead draw using
28  *   palletized colors. The fused rect color is choosen from the rectangle with
29  *   the higher alpha value, if equal the max pallete index encountered.
30  *
31  * Make sure to flush the trackRenderer before finishing drawing in order
32  * to commit any queued drawing operations.
33  */
34 tvcm.exportTo('tracing', function() {
35
36   /**
37    * Creates a fast rect renderer with a specific set of culling rules
38    * and color pallette.
39    * @param {GraphicsContext2D} ctx Canvas2D drawing context.
40    * @param {number} minRectSize Only rectangles with width < minRectSize are
41    *    considered for merging.
42    * @param {number} maxMergeDist Controls how many successive small rectangles
43    *    can be merged together before issuing a rectangle.
44    * @param {Array} pallette The color pallete for drawing. Pallette slots
45    *    should map to valid Canvas fillStyle strings.
46    *
47    * @constructor
48    */
49   function FastRectRenderer(ctx, minRectSize, maxMergeDist, pallette) {
50     this.ctx_ = ctx;
51     this.minRectSize_ = minRectSize;
52     this.maxMergeDist_ = maxMergeDist;
53     this.pallette_ = pallette;
54   }
55
56   FastRectRenderer.prototype = {
57     y_: 0,
58     h_: 0,
59     merging_: false,
60     mergeStartX_: 0,
61     mergeCurRight_: 0,
62     mergedColorId_: 0,
63     mergedAlpha_: 0,
64
65     /**
66      * Changes the y position and height for subsequent fillRect
67      * calls. x and width are specifieid on the fillRect calls.
68      */
69     setYandH: function(y, h) {
70       this.flush();
71       this.y_ = y;
72       this.h_ = h;
73     },
74
75     /**
76      * Fills rectangle at the specified location, if visible. If the
77      * rectangle is subpixel, it will be merged with adjacent rectangles.
78      * The drawing operation may not take effect until flush is called.
79      * @param {number} colorId The color of this rectangle, as an index
80      *     in the renderer's color pallete.
81      * @param {number} alpha The opacity of the rectangle as 0.0-1.0 number.
82      */
83     fillRect: function(x, w, colorId, alpha) {
84       var r = x + w;
85       if (w < this.minRectSize_) {
86         if (r - this.mergeStartX_ > this.maxMergeDist_)
87           this.flush();
88         if (!this.merging_) {
89           this.merging_ = true;
90           this.mergeStartX_ = x;
91           this.mergeCurRight_ = r;
92           this.mergedColorId_ = colorId;
93           this.mergedAlpha_ = alpha;
94         } else {
95           this.mergeCurRight_ = r;
96
97           if (this.mergedAlpha_ < alpha ||
98               (this.mergedAlpha_ === alpha && this.mergedColorId_ < colorId)) {
99             this.mergedAlpha_ = alpha;
100             this.mergedColorId_ = colorId;
101           }
102         }
103       } else {
104         if (this.merging_)
105           this.flush();
106         this.ctx_.fillStyle = this.pallette_[colorId];
107         this.ctx_.globalAlpha = alpha;
108         this.ctx_.fillRect(x, this.y_, w, this.h_);
109       }
110     },
111
112     /**
113      * Commits any pending fillRect operations to the underlying graphics
114      * context.
115      */
116     flush: function() {
117       if (this.merging_) {
118         this.ctx_.fillStyle = this.pallette_[this.mergedColorId_];
119         this.ctx_.globalAlpha = this.mergedAlpha_;
120         this.ctx_.fillRect(this.mergeStartX_, this.y_,
121                            this.mergeCurRight_ - this.mergeStartX_, this.h_);
122         this.merging_ = false;
123       }
124     }
125   };
126
127   return {
128     FastRectRenderer: FastRectRenderer
129   };
130 });
131 </script>