chromium/media/capture/video/win/gpu_memory_buffer_tracker_win.h

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CAPTURE_VIDEO_WIN_GPU_MEMORY_BUFFER_TRACKER_WIN_H_
#define MEDIA_CAPTURE_VIDEO_WIN_GPU_MEMORY_BUFFER_TRACKER_WIN_H_

#include "gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h"
#include "media/base/win/dxgi_device_manager.h"
#include "media/capture/video/video_capture_buffer_tracker.h"

#include <d3d11.h>
#include <wrl.h>

namespace gfx {
class Size;
}  // namespace gfx

namespace media {

// Tracker specifics for Windows GpuMemoryBuffer.
// This class is not thread-safe.
class CAPTURE_EXPORT GpuMemoryBufferTrackerWin final
    : public VideoCaptureBufferTracker {
 public:
  explicit GpuMemoryBufferTrackerWin(
      scoped_refptr<DXGIDeviceManager> dxgi_device_manager);
  GpuMemoryBufferTrackerWin(
      gfx::GpuMemoryBufferHandle gmb_handle,
      scoped_refptr<DXGIDeviceManager> dxgi_device_manager);

  GpuMemoryBufferTrackerWin(const GpuMemoryBufferTrackerWin&) = delete;
  GpuMemoryBufferTrackerWin& operator=(const GpuMemoryBufferTrackerWin&) =
      delete;

  ~GpuMemoryBufferTrackerWin() override;

  // Implementation of VideoCaptureBufferTracker:
  bool Init(const gfx::Size& dimensions,
            VideoPixelFormat format,
            const mojom::PlaneStridesPtr& strides) override;
  bool IsSameGpuMemoryBuffer(
      const gfx::GpuMemoryBufferHandle& handle) const override;
  bool IsReusableForFormat(const gfx::Size& dimensions,
                           VideoPixelFormat format,
                           const mojom::PlaneStridesPtr& strides) override;

  uint32_t GetMemorySizeInBytes() override;

  std::unique_ptr<VideoCaptureBufferHandle> GetMemoryMappedAccess() override;

  base::UnsafeSharedMemoryRegion DuplicateAsUnsafeRegion() override;
  gfx::GpuMemoryBufferHandle GetGpuMemoryBufferHandle() override;

  VideoCaptureBufferType GetBufferType() override;

  void OnHeldByConsumersChanged(bool is_held_by_consumers) override;
  void UpdateExternalData(CapturedExternalVideoBuffer buffer) override;

 private:
  bool CreateBufferInternal(gfx::GpuMemoryBufferHandle buffer_handle,
                            const gfx::Size& dimensions);
  bool IsD3DDeviceChanged();

  std::unique_ptr<gpu::GpuMemoryBufferImplDXGI> buffer_;
  scoped_refptr<DXGIDeviceManager> dxgi_device_manager_;
  Microsoft::WRL::ComPtr<ID3D11Device> d3d_device_;
  base::UnsafeSharedMemoryRegion region_;
  base::WritableSharedMemoryMapping mapping_;
  Microsoft::WRL::ComPtr<ID3D11Texture2D> staging_texture_;
  // |external_dxgi_handle_| is valid until Init() call.
  gfx::GpuMemoryBufferHandle external_dxgi_handle_;
  // The lifetime of the D3D texture is controlled by IMFBuffer. When the buffer
  // lifetime is released, the Windows capture pipeline assumes the application
  // has finished reading from the texture and the capture pipeline is, thus,
  // free to use the texture in a subsequent write operation. We use ComPtr to
  // hold the IMFBuffer and correctly reuse external texture.
  Microsoft::WRL::ComPtr<IMFMediaBuffer> imf_buffer_;
  // If |is_external_dxgi_handle_| is true, the handle originally isn't created
  // by chromium. Currently it indicates the producer of handle is
  // MFVideoCaptureEngine.
  bool is_external_dxgi_handle_ = false;
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_WIN_GPU_MEMORY_BUFFER_TRACKER_WIN_H_