author Ted Mielczarek <>
Fri, 06 Jan 2017 05:57:10 -0500
changeset 328603 dedf4f49b3756b09986e78dc5519a291b81f133f
parent 301499 232a786cf87fb0f68f9bda6e9316515524d2ac8a
child 329013 c5ca5b7fcacd561812eae29c41a2b68e3fcdb824
permissions -rw-r--r--
bug 1329320 - replace makecab with rust-makecab in symbolstore. r=gps It turns out that running makecab to compress PDB files takes a significant amount of time in the buildsymbols step. I wrote an implementation of makecab in Rust that implements only the subset of features we use and it's significantly faster: This patch adds a makecab check to moz.configure, adds a release build of the makecab binary to the Windows tooltool manifests, points the build at it from, and changes to use MAKECAB from substs instead of calling `makecab.exe` directly. MozReview-Commit-ID: 76FHLIZFCXS

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */


#include "LayersTypes.h"
#include "mozilla/gfx/Point.h"          // for IntSize
#include "mozilla/Mutex.h"
#include "nsCOMPtr.h"                   // for nsCOMPtr

class nsICanvasRenderingContextInternal;
class nsIInputStream;
class nsIThread;

namespace mozilla {

namespace gfx {
class DataSourceSurface;

namespace gl {
class GLContext;

namespace dom {
class HTMLCanvasElement;

namespace layers {

class CanvasClient;
class TextureClient;

 * Since HTMLCanvasElement and OffscreenCanvas are not thread-safe, we create
 * AsyncCanvasRenderer which is thread-safe wrapper object for communicating
 * among main, worker and ImageBridgeChild threads.
 * Each HTMLCanvasElement object is responsible for creating
 * AsyncCanvasRenderer object. Once Canvas is transfered to worker,
 * OffscreenCanvas will keep reference pointer of this object.
 * Sometimes main thread needs AsyncCanvasRenderer's result, such as layers
 * fallback to BasicLayerManager or calling toDataURL in Javascript. Simply call
 * GetSurface() in main thread will readback the result to mSurface.
 * If layers backend is LAYERS_CLIENT, this object will pass to ImageBridgeChild
 * for submitting frames to Compositor.
class AsyncCanvasRenderer final


  void NotifyElementAboutAttributesChanged();
  void NotifyElementAboutInvalidation();

  void SetCanvasClient(CanvasClient* aClient);

  void SetWidth(uint32_t aWidth)
    mWidth = aWidth;

  void SetHeight(uint32_t aHeight)
    mHeight = aHeight;

  void SetIsAlphaPremultiplied(bool aIsAlphaPremultiplied)
    mIsAlphaPremultiplied = aIsAlphaPremultiplied;

  // Active thread means the thread which spawns GLContext.
  void SetActiveThread();
  void ResetActiveThread();

  // This will readback surface and return the surface
  // in the DataSourceSurface.
  // Can be called in main thread only.
  already_AddRefed<gfx::DataSourceSurface> GetSurface();

  // For SharedSurface_Basic case, before the frame sending to the compositor,
  // we readback it to a texture client because SharedSurface_Basic cannot shared.
  // We don't want to readback it again here, so just copy the content of that
  // texture client here to avoid readback again.
  void CopyFromTextureClient(TextureClient *aClient);

  // Readback current WebGL's content and convert it to InputStream. This
  // function called GetSurface implicitly and GetSurface handles only get
  // called in the main thread. So this function can be called in main thread.
  GetInputStream(const char *aMimeType,
                 const char16_t *aEncoderOptions,
                 nsIInputStream **aStream);

  gfx::IntSize GetSize() const
    return gfx::IntSize(mWidth, mHeight);

  uint64_t GetCanvasClientAsyncID() const
    return mCanvasClientAsyncID;

  CanvasClient* GetCanvasClient() const
    return mCanvasClient;

  already_AddRefed<nsIThread> GetActiveThread();

  // The lifetime is controllered by HTMLCanvasElement.
  // Only accessed in main thread.
  dom::HTMLCanvasElement* mHTMLCanvasElement;

  // Only accessed in active thread.
  nsICanvasRenderingContextInternal* mContext;

  // We need to keep a reference to the context around here, otherwise the
  // canvas' surface texture destructor will deref and destroy it too early
  // Only accessed in active thread.
  RefPtr<gl::GLContext> mGLContext;

  virtual ~AsyncCanvasRenderer();

  // Readback current WebGL's content and return it as DataSourceSurface.
  already_AddRefed<gfx::DataSourceSurface> UpdateTarget();

  bool mIsAlphaPremultiplied;

  uint32_t mWidth;
  uint32_t mHeight;
  uint64_t mCanvasClientAsyncID;

  // The lifetime of this pointer is controlled by OffscreenCanvas
  // Can be accessed in active thread and ImageBridge thread.
  // But we never accessed it at the same time on both thread. So no
  // need to protect this member.
  CanvasClient* mCanvasClient;

  // When backend is LAYER_BASIC and SharedSurface type is Basic.
  // CanvasClient will readback the GLContext to a TextureClient
  // in order to send frame to compositor. To avoid readback again,
  // we copy from this TextureClient to this mSurfaceForBasic directly
  // by calling CopyFromTextureClient().
  RefPtr<gfx::DataSourceSurface> mSurfaceForBasic;

  // Protect non thread-safe objects.
  Mutex mMutex;

  // Can be accessed in any thread, need protect by mutex.
  nsCOMPtr<nsIThread> mActiveThread;

} // namespace layers
} // namespace mozilla