Exemple #1
0
already_AddRefed<ImageBitmap> OffscreenCanvas::TransferToImageBitmap(
    ErrorResult& aRv) {
  nsCOMPtr<nsIGlobalObject> globalObject = GetGlobalObject();
  RefPtr<ImageBitmap> result =
      ImageBitmap::CreateFromOffscreenCanvas(globalObject, *this, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  // TODO: Clear the content?
  return result.forget();
}
already_AddRefed<ImageBitmap>
OffscreenCanvas::TransferToImageBitmap()
{
  ErrorResult rv;
  nsCOMPtr<nsIGlobalObject> globalObject = GetGlobalObject();
  RefPtr<ImageBitmap> result = ImageBitmap::CreateFromOffscreenCanvas(globalObject, *this, rv);

  // Clear the content.
  if ((mCurrentContextType == CanvasContextType::WebGL1 ||
       mCurrentContextType == CanvasContextType::WebGL2))
  {
    WebGLContext* webGL = static_cast<WebGLContext*>(mCurrentContext.get());
    webGL->ClearScreen();
  }

  return result.forget();
}
already_AddRefed<Promise>
OffscreenCanvas::ToBlob(JSContext* aCx,
                        const nsAString& aType,
                        JS::Handle<JS::Value> aParams,
                        ErrorResult& aRv)
{
  // do a trust check if this is a write-only canvas
  if (mIsWriteOnly) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return nullptr;
  }

  nsCOMPtr<nsIGlobalObject> global = GetGlobalObject();

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  // Encoder callback when encoding is complete.
  class EncodeCallback : public EncodeCompleteCallback
  {
  public:
    EncodeCallback(nsIGlobalObject* aGlobal, Promise* aPromise)
      : mGlobal(aGlobal)
      , mPromise(aPromise) {}

    // This is called on main thread.
    nsresult ReceiveBlob(already_AddRefed<Blob> aBlob)
    {
      RefPtr<Blob> blob = aBlob;

      ErrorResult rv;
      uint64_t size = blob->GetSize(rv);
      if (rv.Failed()) {
        rv.SuppressException();
      } else {
        AutoJSAPI jsapi;
        if (jsapi.Init(mGlobal)) {
          JS_updateMallocCounter(jsapi.cx(), size);
        }
      }

      if (mPromise) {
        RefPtr<Blob> newBlob = Blob::Create(mGlobal, blob->Impl());
        mPromise->MaybeResolve(newBlob);
      }

      mGlobal = nullptr;
      mPromise = nullptr;

      return rv.StealNSResult();
    }

    nsCOMPtr<nsIGlobalObject> mGlobal;
    RefPtr<Promise> mPromise;
  };

  RefPtr<EncodeCompleteCallback> callback =
    new EncodeCallback(global, promise);

  CanvasRenderingContextHelper::ToBlob(aCx, global,
                                       callback, aType, aParams, aRv);

  return promise.forget();
}