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 7base.require('base.guid'); 8base.require('base.rect'); 9base.require('base.raf'); 10base.require('tracing.trace_model.object_instance'); 11base.require('cc.picture_as_canvas'); 12base.require('cc.util'); 13 14base.exportTo('cc', function() { 15 16 var ObjectSnapshot = tracing.trace_model.ObjectSnapshot; 17 18 // Number of pictures created. Used as an uniqueId because we are immutable. 19 var PictureCount = 0; 20 21 /** 22 * @constructor 23 */ 24 function PictureSnapshot() { 25 ObjectSnapshot.apply(this, arguments); 26 this.guid_ = base.GUID.allocate(); 27 } 28 29 PictureSnapshot.CanRasterize = function() { 30 if (!window.chrome) 31 return false; 32 if (!window.chrome.skiaBenchmarking) 33 return false; 34 if (!window.chrome.skiaBenchmarking.rasterize) 35 return false; 36 return true; 37 } 38 39 PictureSnapshot.CanGetOps = function() { 40 if (!window.chrome) 41 return false; 42 if (!window.chrome.skiaBenchmarking) 43 return false; 44 if (!window.chrome.skiaBenchmarking.getOps) 45 return false; 46 return true; 47 } 48 49 PictureSnapshot.HowToEnablePictureDebugging = function() { 50 var usualReason = [ 51 'For pictures to show up, you need to have Chrome running with ', 52 '--enable-skia-benchmarking. Please restart chrome with this flag ', 53 'and try again.' 54 ].join(''); 55 56 if (!window.chrome) 57 return usualReason; 58 if (!window.chrome.skiaBenchmarking) 59 return usualReason; 60 if (!window.chrome.skiaBenchmarking.rasterize) 61 return 'Your chrome is old'; 62 if (!window.chrome.skiaBenchmarking.getOps) 63 return 'Your chrome is old, skiaBenchmarking.getOps not found'; 64 return 'Rasterizing is on'; 65 } 66 67 PictureSnapshot.prototype = { 68 __proto__: ObjectSnapshot.prototype, 69 70 preInitialize: function() { 71 cc.preInitializeObject(this); 72 this.rasterResult_ = undefined; 73 }, 74 75 initialize: function() { 76 if (!this.args.params.layerRect) 77 throw new Error('Missing layer rect'); 78 this.layerRect_ = this.args.params.layerRect; 79 this.layerRect_ = base.Rect.FromArray(this.layerRect_); 80 }, 81 82 get layerRect() { 83 return this.layerRect_; 84 }, 85 86 get guid() { 87 return this.guid_; 88 }, 89 90 getBase64SkpData: function() { 91 return this.args.skp64; 92 }, 93 94 getOps: function() { 95 if (!PictureSnapshot.CanGetOps()) { 96 console.error(PictureSnapshot.HowToEnablePictureDebugging()); 97 return undefined; 98 } 99 100 var ops = window.chrome.skiaBenchmarking.getOps({ 101 skp64: this.args.skp64, 102 params: { 103 layer_rect: this.args.params.layerRect, 104 opaque_rect: this.args.params.opaqueRect 105 } 106 }); 107 108 if (!ops) 109 console.error('Failed to get picture ops.'); 110 111 return ops; 112 }, 113 114 /** 115 * Rasterize the picture. 116 * 117 * @param {{opt_stopIndex: number, params}} The SkPicture operation to 118 * rasterize up to. If not defined, the entire SkPicture is rasterized. 119 * @param {function(cc.PictureAsCanvas)} The callback function that is 120 * called after rasterization is complete or fails. 121 */ 122 rasterize: function(params, rasterCompleteCallback) { 123 if (!PictureSnapshot.CanRasterize() || !PictureSnapshot.CanGetOps()) { 124 rasterCompleteCallback(new cc.PictureAsCanvas( 125 this, cc.PictureSnapshot.HowToEnablePictureDebugging())); 126 return; 127 } 128 129 var raster = window.chrome.skiaBenchmarking.rasterize( 130 { 131 skp64: this.args.skp64, 132 params: { 133 layer_rect: this.args.params.layerRect, 134 opaque_rect: this.args.params.opaqueRect 135 } 136 }, 137 { 138 stop: params.stopIndex === undefined ? -1 : params.stopIndex, 139 params: { } 140 }); 141 142 if (raster) { 143 var canvas = document.createElement('canvas'); 144 var ctx = canvas.getContext('2d'); 145 canvas.width = raster.width; 146 canvas.height = raster.height; 147 var imageData = ctx.createImageData(raster.width, raster.height); 148 imageData.data.set(new Uint8ClampedArray(raster.data)); 149 ctx.putImageData(imageData, 0, 0); 150 rasterCompleteCallback(new cc.PictureAsCanvas(this, canvas)); 151 } else { 152 var error = 'Failed to rasterize picture. ' + 153 'Your recording may be from an old Chrome version. ' + 154 'The SkPicture format is not backward compatible.'; 155 rasterCompleteCallback(new cc.PictureAsCanvas(this, error)); 156 } 157 } 158 }; 159 160 ObjectSnapshot.register('cc::Picture', PictureSnapshot); 161 162 return { 163 PictureSnapshot: PictureSnapshot 164 }; 165}); 166