172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be
321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file.
421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsencr.define('gpu', function() {
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  /**
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * This class provides a 'bridge' for communicating between javascript and the
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * browser. When run outside of WebUI, e.g. as a regular webpage, it provides
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * synthetic data to assist in testing.
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   * @constructor
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   */
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  function BrowserBridge() {
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // If we are not running inside WebUI, output chrome.send messages
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // to the console to help with quick-iteration debugging.
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (chrome.send === undefined && console.log) {
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.debugMode_ = true;
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var browserBridgeTests = document.createElement('script');
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browserBridgeTests.src = './gpu_internals/browser_bridge_tests.js';
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      document.body.appendChild(browserBridgeTests);
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.debugMode_ = false;
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    this.nextRequestId_ = 0;
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    this.pendingCallbacks_ = [];
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.logMessages_ = [];
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Tell c++ code that we are ready to receive GPU Info.
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!this.debugMode_) {
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chrome.send('browserBridgeInitialized');
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.beginRequestClientInfo_();
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.beginRequestLogMessages_();
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BrowserBridge.prototype = {
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    __proto__: cr.EventTarget.prototype,
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    applySimulatedData_: function applySimulatedData(data) {
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // set up things according to the simulated data
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.gpuInfo_ = data.gpuInfo;
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.clientInfo_ = data.clientInfo;
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.logMessages_ = data.logMessages;
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.dispatchSimpleEvent(this, 'gpuInfoUpdate');
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.dispatchSimpleEvent(this, 'clientInfoChange');
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.dispatchSimpleEvent(this, 'logMessagesChange');
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Returns true if the page is hosted inside Chrome WebUI
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Helps have behavior conditional to emulate_webui.py
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    get debugMode() {
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return this.debugMode_;
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    /**
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     * Sends a message to the browser with specified args. The
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     * browser will reply asynchronously via the provided callback.
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     */
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    callAsync: function(submessage, args, callback) {
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      var requestId = this.nextRequestId_;
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      this.nextRequestId_ += 1;
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      this.pendingCallbacks_[requestId] = callback;
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (!args) {
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        chrome.send('callAsync', [requestId.toString(), submessage]);
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      } else {
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        var allArgs = [requestId.toString(), submessage].concat(args);
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        chrome.send('callAsync', allArgs);
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    },
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    /**
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     * Called by gpu c++ code when client info is ready.
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     */
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    onCallAsyncReply: function(requestId, args) {
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (this.pendingCallbacks_[requestId] === undefined) {
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        throw new Error('requestId ' + requestId + ' is not pending');
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      var callback = this.pendingCallbacks_[requestId];
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      callback(args);
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      delete this.pendingCallbacks_[requestId];
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    },
83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    /**
85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     * Get gpuInfo data.
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     */
87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    get gpuInfo() {
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return this.gpuInfo_;
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    },
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    /**
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     * Called from gpu c++ code when GPU Info is updated.
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     */
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    onGpuInfoUpdate: function(gpuInfo) {
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      this.gpuInfo_ = gpuInfo;
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      cr.dispatchSimpleEvent(this, 'gpuInfoUpdate');
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * This function begins a request for the ClientInfo. If it comes back
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * as undefined, then we will issue the request again in 250ms.
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    beginRequestClientInfo_: function() {
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.callAsync('requestClientInfo', undefined, (function(data) {
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (data === undefined) { // try again in 250 ms
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          window.setTimeout(this.beginRequestClientInfo_.bind(this), 250);
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else {
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.clientInfo_ = data;
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          cr.dispatchSimpleEvent(this, 'clientInfoChange');
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }).bind(this));
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Returns information about the currently runnign Chrome build.
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    get clientInfo() {
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return this.clientInfo_;
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * This function checks for new GPU_LOG messages.
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * If any are found, a refresh is triggered.
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    beginRequestLogMessages_: function() {
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.callAsync('requestLogMessages', undefined,
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          (function(messages) {
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            if (messages.length != this.logMessages_.length) {
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              this.logMessages_ = messages;
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              cr.dispatchSimpleEvent(this, 'logMessagesChange');
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            }
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            // check again in 250 ms
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            window.setTimeout(this.beginRequestLogMessages_.bind(this), 250);
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }).bind(this));
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Returns an array of log messages issued by the GPU process, if any.
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    get logMessages() {
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return this.logMessages_;
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  };
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return {
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserBridge: BrowserBridge
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  };
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen});
150