Home | History | Annotate | Download | only in cc
      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 
      7 base.require('base.guid');
      8 base.require('base.rect');
      9 base.require('base.raf');
     10 base.require('tracing.trace_model.object_instance');
     11 base.require('cc.picture_as_canvas');
     12 base.require('cc.util');
     13 
     14 base.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