Blame dom/canvas/OffscreenCanvas.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim:set ts=2 sw=2 sts=2 et cindent: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef MOZILLA_DOM_OFFSCREENCANVAS_H_
Packit f0b94e
#define MOZILLA_DOM_OFFSCREENCANVAS_H_
Packit f0b94e
Packit f0b94e
#include "gfxTypes.h"
Packit f0b94e
#include "mozilla/DOMEventTargetHelper.h"
Packit f0b94e
#include "mozilla/dom/DOMPrefs.h"
Packit f0b94e
#include "mozilla/layers/LayersTypes.h"
Packit f0b94e
#include "mozilla/RefPtr.h"
Packit f0b94e
#include "CanvasRenderingContextHelper.h"
Packit f0b94e
#include "nsCycleCollectionParticipant.h"
Packit f0b94e
Packit f0b94e
struct JSContext;
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
class ErrorResult;
Packit f0b94e
Packit f0b94e
namespace layers {
Packit f0b94e
class AsyncCanvasRenderer;
Packit f0b94e
class CanvasClient;
Packit f0b94e
}  // namespace layers
Packit f0b94e
Packit f0b94e
namespace dom {
Packit f0b94e
class Blob;
Packit f0b94e
class ImageBitmap;
Packit f0b94e
Packit f0b94e
// This is helper class for transferring OffscreenCanvas to worker thread.
Packit f0b94e
// Because OffscreenCanvas is not thread-safe. So we cannot pass Offscreen-
Packit f0b94e
// Canvas to worker thread directly. Thus, we create this helper class and
Packit f0b94e
// store necessary data in it then pass it to worker thread.
Packit f0b94e
struct OffscreenCanvasCloneData final {
Packit f0b94e
  OffscreenCanvasCloneData(layers::AsyncCanvasRenderer* aRenderer,
Packit f0b94e
                           uint32_t aWidth, uint32_t aHeight,
Packit f0b94e
                           layers::LayersBackend aCompositorBackend,
Packit f0b94e
                           bool aNeutered, bool aIsWriteOnly);
Packit f0b94e
  ~OffscreenCanvasCloneData();
Packit f0b94e
Packit f0b94e
  RefPtr<layers::AsyncCanvasRenderer> mRenderer;
Packit f0b94e
  uint32_t mWidth;
Packit f0b94e
  uint32_t mHeight;
Packit f0b94e
  layers::LayersBackend mCompositorBackendType;
Packit f0b94e
  bool mNeutered;
Packit f0b94e
  bool mIsWriteOnly;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class OffscreenCanvas final : public DOMEventTargetHelper,
Packit f0b94e
                              public CanvasRenderingContextHelper {
Packit f0b94e
 public:
Packit f0b94e
  NS_DECL_ISUPPORTS_INHERITED
Packit f0b94e
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OffscreenCanvas,
Packit f0b94e
                                           DOMEventTargetHelper)
Packit f0b94e
Packit f0b94e
  OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight,
Packit f0b94e
                  layers::LayersBackend aCompositorBackend,
Packit f0b94e
                  layers::AsyncCanvasRenderer* aRenderer);
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIGlobalObject> GetParentObject() const { return GetOwnerGlobal(); }
Packit f0b94e
Packit f0b94e
  virtual JSObject* WrapObject(JSContext* aCx,
Packit f0b94e
                               JS::Handle<JSObject*> aGivenProto) override;
Packit f0b94e
Packit f0b94e
  static already_AddRefed<OffscreenCanvas> Constructor(
Packit f0b94e
      const GlobalObject& aGlobal, uint32_t aWidth, uint32_t aHeight,
Packit f0b94e
      ErrorResult& aRv);
Packit f0b94e
Packit f0b94e
  void ClearResources();
Packit f0b94e
Packit f0b94e
  uint32_t Width() const { return mWidth; }
Packit f0b94e
Packit f0b94e
  uint32_t Height() const { return mHeight; }
Packit f0b94e
Packit f0b94e
  void SetWidth(uint32_t aWidth, ErrorResult& aRv) {
Packit f0b94e
    if (mNeutered) {
Packit f0b94e
      aRv.Throw(NS_ERROR_FAILURE);
Packit f0b94e
      return;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    if (mWidth != aWidth) {
Packit f0b94e
      mWidth = aWidth;
Packit f0b94e
      CanvasAttrChanged();
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  void SetHeight(uint32_t aHeight, ErrorResult& aRv) {
Packit f0b94e
    if (mNeutered) {
Packit f0b94e
      aRv.Throw(NS_ERROR_FAILURE);
Packit f0b94e
      return;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    if (mHeight != aHeight) {
Packit f0b94e
      mHeight = aHeight;
Packit f0b94e
      CanvasAttrChanged();
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  already_AddRefed<ImageBitmap> TransferToImageBitmap(ErrorResult& aRv);
Packit f0b94e
Packit f0b94e
  already_AddRefed<Promise> ToBlob(JSContext* aCx, const nsAString& aType,
Packit f0b94e
                                   JS::Handle<JS::Value> aParams,
Packit f0b94e
                                   ErrorResult& aRv);
Packit f0b94e
Packit f0b94e
  nsICanvasRenderingContextInternal* GetContext() const {
Packit f0b94e
    return mCurrentContext;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  already_AddRefed<gfx::SourceSurface> GetSurfaceSnapshot(
Packit f0b94e
      gfxAlphaType* aOutAlphaType = nullptr);
Packit f0b94e
Packit f0b94e
  static already_AddRefed<OffscreenCanvas> CreateFromCloneData(
Packit f0b94e
      nsIGlobalObject* aGlobal, OffscreenCanvasCloneData* aData);
Packit f0b94e
Packit f0b94e
  // Return true on main-thread, and return gfx.offscreencanvas.enabled
Packit f0b94e
  // on worker thread.
Packit f0b94e
  static bool PrefEnabledOnWorkerThread(JSContext* aCx, JSObject* aObj);
Packit f0b94e
Packit f0b94e
  OffscreenCanvasCloneData* ToCloneData();
Packit f0b94e
Packit f0b94e
  void CommitFrameToCompositor();
Packit f0b94e
Packit f0b94e
  virtual bool GetOpaqueAttr() override { return false; }
Packit f0b94e
Packit f0b94e
  virtual nsIntSize GetWidthHeight() override {
Packit f0b94e
    return nsIntSize(mWidth, mHeight);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  virtual already_AddRefed<nsICanvasRenderingContextInternal> CreateContext(
Packit f0b94e
      CanvasContextType aContextType) override;
Packit f0b94e
Packit f0b94e
  virtual already_AddRefed<nsISupports> GetContext(
Packit f0b94e
      JSContext* aCx, const nsAString& aContextId,
Packit f0b94e
      JS::Handle<JS::Value> aContextOptions, ErrorResult& aRv) override;
Packit f0b94e
Packit f0b94e
  void SetNeutered() { mNeutered = true; }
Packit f0b94e
Packit f0b94e
  bool IsNeutered() const { return mNeutered; }
Packit f0b94e
Packit f0b94e
  void SetWriteOnly() { mIsWriteOnly = true; }
Packit f0b94e
Packit f0b94e
  bool IsWriteOnly() const { return mIsWriteOnly; }
Packit f0b94e
Packit f0b94e
  layers::LayersBackend GetCompositorBackendType() const {
Packit f0b94e
    return mCompositorBackendType;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  ~OffscreenCanvas();
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIGlobalObject> GetGlobalObject();
Packit f0b94e
Packit f0b94e
  void CanvasAttrChanged() {
Packit f0b94e
    mAttrDirty = true;
Packit f0b94e
    ErrorResult dummy;
Packit f0b94e
    UpdateContext(nullptr, JS::NullHandleValue, dummy);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  bool mAttrDirty;
Packit f0b94e
  bool mNeutered;
Packit f0b94e
  bool mIsWriteOnly;
Packit f0b94e
Packit f0b94e
  uint32_t mWidth;
Packit f0b94e
  uint32_t mHeight;
Packit f0b94e
Packit f0b94e
  layers::LayersBackend mCompositorBackendType;
Packit f0b94e
Packit f0b94e
  RefPtr<layers::CanvasClient> mCanvasClient;
Packit f0b94e
  RefPtr<layers::AsyncCanvasRenderer> mCanvasRenderer;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
}  // namespace dom
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif  // MOZILLA_DOM_OFFSCREENCANVAS_H_