/* 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 http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_media_RemoteImageHolder_h
#define mozilla_dom_media_RemoteImageHolder_h

#include "MediaData.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/VideoBridgeUtils.h"

namespace mozilla {
namespace layers {
class BufferRecycleBin;
class IGPUVideoSurfaceManager;
class SurfaceDescriptor;
}  // namespace layers
class RemoteImageHolder final {
  friend struct IPC::ParamTraits<RemoteImageHolder>;

 public:
  RemoteImageHolder();
  explicit RemoteImageHolder(layers::SurfaceDescriptor&& aSD);
  RemoteImageHolder(
      layers::IGPUVideoSurfaceManager* aManager,
      layers::VideoBridgeSource aSource, const gfx::IntSize& aSize,
      const gfx::ColorDepth& aColorDepth, const layers::SurfaceDescriptor& aSD,
      gfx::YUVColorSpace aYUVColorSpace, gfx::ColorSpace2 aColorPrimaries,
      gfx::TransferFunction aTransferFunction, gfx::ColorRange aColorRange);
  RemoteImageHolder(RemoteImageHolder&& aOther);
  // Ensure we never copy this object.
  RemoteImageHolder(const RemoteImageHolder& aOther) = delete;
  RemoteImageHolder& operator=(const RemoteImageHolder& aOther) = delete;
  ~RemoteImageHolder();

  bool IsEmpty() const { return mSD.isNothing(); }
  // Move content of RemoteImageHolder into a usable Image. Ownership is
  // transfered to that Image.
  already_AddRefed<layers::Image> TransferToImage(
      layers::BufferRecycleBin* aBufferRecycleBin = nullptr);

 private:
  already_AddRefed<layers::Image> DeserializeImage(
      layers::BufferRecycleBin* aBufferRecycleBin);
  // We need a default for the default constructor, never used in practice.
  layers::VideoBridgeSource mSource = layers::VideoBridgeSource::GpuProcess;
  gfx::IntSize mSize;
  gfx::ColorDepth mColorDepth = gfx::ColorDepth::COLOR_8;
  Maybe<layers::SurfaceDescriptor> mSD;
  RefPtr<layers::IGPUVideoSurfaceManager> mManager;
  gfx::YUVColorSpace mYUVColorSpace = {};
  gfx::ColorSpace2 mColorPrimaries = {};
  gfx::TransferFunction mTransferFunction = {};
  gfx::ColorRange mColorRange = {};
};

}  // namespace mozilla

template <>
struct IPC::ParamTraits<mozilla::RemoteImageHolder> {
  static void Write(MessageWriter* aWriter,
                    mozilla::RemoteImageHolder&& aParam);
  static bool Read(MessageReader* aReader, mozilla::RemoteImageHolder* aResult);
};

#endif  // mozilla_dom_media_RemoteImageHolder_h
