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.
7 <link rel="import" href="/tvcm.html">
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.
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.
20 * A few extra things are done by this class in the name of speed:
21 * - Viewport culling: off-viewport rectangles are discarded.
23 * - The actual discarding operation is done in world space,
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.
31 * Make sure to flush the trackRenderer before finishing drawing in order
32 * to commit any queued drawing operations.
34 tvcm.exportTo('tracing', function() {
37 * Creates a fast rect renderer with a specific set of culling rules
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.
49 function FastRectRenderer(ctx, minRectSize, maxMergeDist, pallette) {
51 this.minRectSize_ = minRectSize;
52 this.maxMergeDist_ = maxMergeDist;
53 this.pallette_ = pallette;
56 FastRectRenderer.prototype = {
66 * Changes the y position and height for subsequent fillRect
67 * calls. x and width are specifieid on the fillRect calls.
69 setYandH: function(y, h) {
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.
83 fillRect: function(x, w, colorId, alpha) {
85 if (w < this.minRectSize_) {
86 if (r - this.mergeStartX_ > this.maxMergeDist_)
90 this.mergeStartX_ = x;
91 this.mergeCurRight_ = r;
92 this.mergedColorId_ = colorId;
93 this.mergedAlpha_ = alpha;
95 this.mergeCurRight_ = r;
97 if (this.mergedAlpha_ < alpha ||
98 (this.mergedAlpha_ === alpha && this.mergedColorId_ < colorId)) {
99 this.mergedAlpha_ = alpha;
100 this.mergedColorId_ = colorId;
106 this.ctx_.fillStyle = this.pallette_[colorId];
107 this.ctx_.globalAlpha = alpha;
108 this.ctx_.fillRect(x, this.y_, w, this.h_);
113 * Commits any pending fillRect operations to the underlying graphics
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;
128 FastRectRenderer: FastRectRenderer