166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// Copyright (c) 2013 The Chromium Authors. All rights reserved. 266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// Use of this source code is governed by a BSD-style license that can be 366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// found in the LICENSE file. 466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis'use strict'; 666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.guid'); 866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.rect'); 966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.raf'); 1066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('tracing.trace_model.object_instance'); 116833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennisbase.require('cc.picture_as_canvas'); 1266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('cc.util'); 1366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.exportTo('cc', function() { 1566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var ObjectSnapshot = tracing.trace_model.ObjectSnapshot; 1766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis // Number of pictures created. Used as an uniqueId because we are immutable. 1966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var PictureCount = 0; 2066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /** 2266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @constructor 2366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */ 2466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis function PictureSnapshot() { 2566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ObjectSnapshot.apply(this, arguments); 2666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.guid_ = base.GUID.allocate(); 2766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 2866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis PictureSnapshot.CanRasterize = function() { 3066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome) 3166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 3266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking) 3366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 3466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking.rasterize) 3566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 3666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return true; 3766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis PictureSnapshot.CanGetOps = function() { 4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome) 4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking) 4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 4466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking.getOps) 4566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 4666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return true; 4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis PictureSnapshot.HowToEnablePictureDebugging = function() { 5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var usualReason = [ 5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 'For pictures to show up, you need to have Chrome running with ', 5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis '--enable-skia-benchmarking. Please restart chrome with this flag ', 5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 'and try again.' 5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ].join(''); 5566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome) 5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return usualReason; 5866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking) 5966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return usualReason; 6066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking.rasterize) 6166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return 'Your chrome is old'; 6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!window.chrome.skiaBenchmarking.getOps) 6366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return 'Your chrome is old, skiaBenchmarking.getOps not found'; 6466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return 'Rasterizing is on'; 6566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis PictureSnapshot.prototype = { 6866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis __proto__: ObjectSnapshot.prototype, 6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis preInitialize: function() { 7166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis cc.preInitializeObject(this); 7266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.rasterResult_ = undefined; 7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis initialize: function() { 7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!this.args.params.layerRect) 7766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis throw new Error('Missing layer rect'); 7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.layerRect_ = this.args.params.layerRect; 7966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.layerRect_ = base.Rect.FromArray(this.layerRect_); 8066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 8166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get layerRect() { 8366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.layerRect_; 8466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 8566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get guid() { 8766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.guid_; 8866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 8966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 9066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis getBase64SkpData: function() { 9166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.args.skp64; 9266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 9366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 9466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis getOps: function() { 9566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!PictureSnapshot.CanGetOps()) { 9666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis console.error(PictureSnapshot.HowToEnablePictureDebugging()); 9766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return undefined; 9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 9966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var ops = window.chrome.skiaBenchmarking.getOps({ 10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis skp64: this.args.skp64, 10266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis params: { 10366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis layer_rect: this.args.params.layerRect, 10466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis opaque_rect: this.args.params.opaqueRect 10566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 10666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }); 10766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 10866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!ops) 10966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis console.error('Failed to get picture ops.'); 11066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 11166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return ops; 11266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 11466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /** 11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Rasterize the picture. 11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * 11766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {{opt_stopIndex: number, params}} The SkPicture operation to 11866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * rasterize up to. If not defined, the entire SkPicture is rasterized. 1196833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis * @param {function(cc.PictureAsCanvas)} The callback function that is 1206833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis * called after rasterization is complete or fails. 12166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */ 12266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis rasterize: function(params, rasterCompleteCallback) { 12366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!PictureSnapshot.CanRasterize() || !PictureSnapshot.CanGetOps()) { 1246833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis rasterCompleteCallback(new cc.PictureAsCanvas( 12566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this, cc.PictureSnapshot.HowToEnablePictureDebugging())); 12666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return; 12766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 12866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 12966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var raster = window.chrome.skiaBenchmarking.rasterize( 13066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis { 13166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis skp64: this.args.skp64, 13266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis params: { 13366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis layer_rect: this.args.params.layerRect, 13466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis opaque_rect: this.args.params.opaqueRect 13566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 13666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 13766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis { 13866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis stop: params.stopIndex === undefined ? -1 : params.stopIndex, 13966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis params: { } 14066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }); 14166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 14266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (raster) { 1436833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var canvas = document.createElement('canvas'); 1446833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var ctx = canvas.getContext('2d'); 1456833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis canvas.width = raster.width; 1466833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis canvas.height = raster.height; 14766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var imageData = ctx.createImageData(raster.width, raster.height); 14866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis imageData.data.set(new Uint8ClampedArray(raster.data)); 14966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ctx.putImageData(imageData, 0, 0); 1506833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis rasterCompleteCallback(new cc.PictureAsCanvas(this, canvas)); 15166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } else { 15266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var error = 'Failed to rasterize picture. ' + 15366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 'Your recording may be from an old Chrome version. ' + 15466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 'The SkPicture format is not backward compatible.'; 1556833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis rasterCompleteCallback(new cc.PictureAsCanvas(this, error)); 15666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 15766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }; 15966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 16066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ObjectSnapshot.register('cc::Picture', PictureSnapshot); 16166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 16266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return { 16366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis PictureSnapshot: PictureSnapshot 16466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }; 16566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis}); 166