// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
base.require('base.guid');
base.require('base.rect');
base.require('base.raf');
base.require('tracing.trace_model.object_instance');
base.require('cc.picture_as_canvas');
base.require('cc.util');
base.exportTo('cc', function() {
var ObjectSnapshot = tracing.trace_model.ObjectSnapshot;
// Number of pictures created. Used as an uniqueId because we are immutable.
var PictureCount = 0;
/**
* @constructor
*/
function PictureSnapshot() {
ObjectSnapshot.apply(this, arguments);
this.guid_ = base.GUID.allocate();
}
PictureSnapshot.CanRasterize = function() {
if (!window.chrome)
return false;
if (!window.chrome.skiaBenchmarking)
return false;
if (!window.chrome.skiaBenchmarking.rasterize)
return false;
return true;
}
PictureSnapshot.CanGetOps = function() {
if (!window.chrome)
return false;
if (!window.chrome.skiaBenchmarking)
return false;
if (!window.chrome.skiaBenchmarking.getOps)
return false;
return true;
}
PictureSnapshot.HowToEnablePictureDebugging = function() {
var usualReason = [
'For pictures to show up, you need to have Chrome running with ',
'--enable-skia-benchmarking. Please restart chrome with this flag ',
'and try again.'
].join('');
if (!window.chrome)
return usualReason;
if (!window.chrome.skiaBenchmarking)
return usualReason;
if (!window.chrome.skiaBenchmarking.rasterize)
return 'Your chrome is old';
if (!window.chrome.skiaBenchmarking.getOps)
return 'Your chrome is old, skiaBenchmarking.getOps not found';
return 'Rasterizing is on';
}
PictureSnapshot.prototype = {
__proto__: ObjectSnapshot.prototype,
preInitialize: function() {
cc.preInitializeObject(this);
this.rasterResult_ = undefined;
},
initialize: function() {
if (!this.args.params.layerRect)
throw new Error('Missing layer rect');
this.layerRect_ = this.args.params.layerRect;
this.layerRect_ = base.Rect.FromArray(this.layerRect_);
},
get layerRect() {
return this.layerRect_;
},
get guid() {
return this.guid_;
},
getBase64SkpData: function() {
return this.args.skp64;
},
getOps: function() {
if (!PictureSnapshot.CanGetOps()) {
console.error(PictureSnapshot.HowToEnablePictureDebugging());
return undefined;
}
var ops = window.chrome.skiaBenchmarking.getOps({
skp64: this.args.skp64,
params: {
layer_rect: this.args.params.layerRect,
opaque_rect: this.args.params.opaqueRect
}
});
if (!ops)
console.error('Failed to get picture ops.');
return ops;
},
/**
* Rasterize the picture.
*
* @param {{opt_stopIndex: number, params}} The SkPicture operation to
* rasterize up to. If not defined, the entire SkPicture is rasterized.
* @param {function(cc.PictureAsCanvas)} The callback function that is
* called after rasterization is complete or fails.
*/
rasterize: function(params, rasterCompleteCallback) {
if (!PictureSnapshot.CanRasterize() || !PictureSnapshot.CanGetOps()) {
rasterCompleteCallback(new cc.PictureAsCanvas(
this, cc.PictureSnapshot.HowToEnablePictureDebugging()));
return;
}
var raster = window.chrome.skiaBenchmarking.rasterize(
{
skp64: this.args.skp64,
params: {
layer_rect: this.args.params.layerRect,
opaque_rect: this.args.params.opaqueRect
}
},
{
stop: params.stopIndex === undefined ? -1 : params.stopIndex,
params: { }
});
if (raster) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = raster.width;
canvas.height = raster.height;
var imageData = ctx.createImageData(raster.width, raster.height);
imageData.data.set(new Uint8ClampedArray(raster.data));
ctx.putImageData(imageData, 0, 0);
rasterCompleteCallback(new cc.PictureAsCanvas(this, canvas));
} else {
var error = 'Failed to rasterize picture. ' +
'Your recording may be from an old Chrome version. ' +
'The SkPicture format is not backward compatible.';
rasterCompleteCallback(new cc.PictureAsCanvas(this, error));
}
}
};
ObjectSnapshot.register('cc::Picture', PictureSnapshot);
return {
PictureSnapshot: PictureSnapshot
};
});