blob: 95138c43b7de38af96a267e40f20bc4be2646c74 [file] [log] [blame]
// Copyright 2024 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_GPU_CHROMEOS_NATIVE_PIXMAP_FRAME_RESOURCE_H_
#define MEDIA_GPU_CHROMEOS_NATIVE_PIXMAP_FRAME_RESOURCE_H_
#include <optional>
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/types/pass_key.h"
#include "media/base/video_frame_layout.h"
#include "media/base/video_frame_metadata.h"
#include "media/gpu/chromeos/frame_resource.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/linux/native_pixmap_dmabuf.h"
namespace media {
// Implements a FrameResource that is backed by a gfx::NativePixmapDmaBuf. The
// frame's pixel content is only accessible by mapping the frame using a
// GenericDmaBufVideoFrameMapper. IsMappable() returns false and all data
// accessors return nullptr.
class NativePixmapFrameResource : public FrameResource {
public:
// The underlying NativePixmap is constructed from `handle`.
NativePixmapFrameResource(base::PassKey<NativePixmapFrameResource>,
const media::VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
base::TimeDelta timestamp,
viz::SharedImageFormat si_format,
const base::UnguessableToken& token,
std::optional<gfx::BufferUsage> buffer_usage,
gfx::NativePixmapHandle handle);
NativePixmapFrameResource(
base::PassKey<NativePixmapFrameResource>,
const media::VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
base::TimeDelta timestamp,
const base::UnguessableToken& token,
std::optional<gfx::BufferUsage> buffer_usage,
scoped_refptr<const gfx::NativePixmapDmaBuf> pixmap);
NativePixmapFrameResource() = delete;
NativePixmapFrameResource(const NativePixmapFrameResource&) = delete;
NativePixmapFrameResource& operator=(const NativePixmapFrameResource&) =
delete;
// Creates a NativePixmapFrameResource that assumes ownership of |dmabuf_fds|.
static scoped_refptr<NativePixmapFrameResource> Create(
const media::VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
std::vector<base::ScopedFD> dmabuf_fds,
base::TimeDelta timestamp);
// Uses MiniGBM to allocate a NativePixmapFrameResource.
static scoped_refptr<NativePixmapFrameResource> Create(
media::VideoPixelFormat pixel_format,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
base::TimeDelta timestamp,
gfx::BufferUsage buffer_usage);
// Creates a NativePixmapFrameResource from a NativePixmapDmaBuf.
static scoped_refptr<NativePixmapFrameResource> Create(
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
base::TimeDelta timestamp,
gfx::BufferUsage buffer_usage,
scoped_refptr<const gfx::NativePixmapDmaBuf> pixmap);
// FrameResource implementation.
const NativePixmapFrameResource* AsNativePixmapFrameResource() const override;
// IsMappable() returns false. There is no direct data access to the buffers
// without use of a GenericVideoFrameMapper.
bool IsMappable() const override;
const uint8_t* data(size_t plane) const override;
uint8_t* writable_data(size_t plane) override;
const uint8_t* visible_data(size_t plane) const override;
uint8_t* GetWritableVisibleData(size_t plane) override;
size_t NumDmabufFds() const override;
int GetDmabufFd(size_t i) const override;
scoped_refptr<const gfx::NativePixmapDmaBuf> GetNativePixmapDmaBuf()
const override;
// CreateGpuMemoryBufferHandle() will duplicate file descriptors to make a
// gfx::GpuMemoryBufferHandle.
gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferHandle() const override;
// Always returns nullptr.
std::unique_ptr<VideoFrame::ScopedMapping> MapGMBOrSharedImage()
const override;
const VideoFrameLayout& layout() const override;
VideoPixelFormat format() const override;
int stride(size_t plane) const override;
VideoFrame::StorageType storage_type() const override;
int row_bytes(size_t plane) const override;
const gfx::Size& coded_size() const override;
const gfx::Rect& visible_rect() const override;
const gfx::Size& natural_size() const override;
const VideoFrameMetadata& metadata() const override;
VideoFrameMetadata& metadata() override;
void set_metadata(const VideoFrameMetadata& metadata) override;
const base::UnguessableToken& tracking_token() const override;
gfx::ColorSpace ColorSpace() const override;
void set_color_space(const gfx::ColorSpace& color_space) override;
const std::optional<gfx::HDRMetadata>& hdr_metadata() const override;
void set_hdr_metadata(
const std::optional<gfx::HDRMetadata>& hdr_metadata) override;
base::TimeDelta timestamp() const override;
void set_timestamp(base::TimeDelta timestamp) override;
void AddDestructionObserver(base::OnceClosure callback) override;
scoped_refptr<FrameResource> CreateWrappingFrame(
const gfx::Rect& visible_rect,
const gfx::Size& natural_size) override;
std::string AsHumanReadableString() const override;
// Always returns empty handle.
gfx::GpuMemoryBufferHandle GetGpuMemoryBufferHandleForTesting()
const override;
// CreateDmabufVideoFrame() is used to create a VideoFrame from the underlying
// NativePixmap. The DMABuf FDs are duplicated and a VideoFrame with storage
// type STORAGE_DMABUFS is created.
scoped_refptr<VideoFrame> CreateDmabufVideoFrame() const;
// CreateMappableVideoFrame() is used to create a VideoFrame from the
// underlying NativePixmap. The DMABuf FDs are duplicated and a VideoFrame
// with storage type STORAGE_GPU_MEMORY_BUFFER is created.
scoped_refptr<VideoFrame> CreateMappableVideoFrame(
gpu::SharedImageInterface* sii) const;
private:
~NativePixmapFrameResource() override;
// |pixmap_| is the underlying NativePixmap. It is is set by the constructors.
const scoped_refptr<const gfx::NativePixmapDmaBuf> pixmap_;
// |buffer_usage_| affects how a buffer can be used. It is only set if it was
// provided by the caller of Create(), or if the NativePixmap was allocated by
// MiniGBM. If this not set, then a CreateVideoFrame() should not be used to
// create a STORAGE_GPU_MEMORY_BUFFER VideoFrame.
const std::optional<gfx::BufferUsage> buffer_usage_;
// VideoFrameLayout (includes format, coded_size, and strides). Per-plane
// metadata is redundant with NativePixmapDmabuf::planes. Factory functions
// ensure consistency between |layout_| and |pixmap_|.
const media::VideoFrameLayout layout_;
// Width, height, and offsets of the visible portion of the video frame. Must
// be a subrect of |coded_size_|. Can be odd with respect to the sample
// boundaries, e.g. for formats with subsampled chroma.
const gfx::Rect visible_rect_;
// Width and height of the visible portion of the video frame
// (|visible_rect_.size()|) with aspect ratio taken into account.
const gfx::Size natural_size_;
media::VideoFrameMetadata metadata_;
base::TimeDelta timestamp_;
gfx::ColorSpace color_space_;
std::optional<gfx::HDRMetadata> hdr_metadata_;
// Callbacks are added by AddDestructionObserver(). It is unclear whether
// guarding |done_callbacks_| is necessary. VideoFrame has a similar lock,
// which is why |done_callbacks_lock_| was added to NativePixmapFrameResource.
// VideoFrame's lock may not be necessary for the workflows where
// NativePixmapFrameResource is used.
// TODO(nhebert): Add a UMA to log concurrent access to
// AddDestructionObserver().
base::Lock done_callbacks_lock_;
std::vector<base::OnceClosure> done_callbacks_
GUARDED_BY(done_callbacks_lock_);
};
} // namespace media
#endif // MEDIA_GPU_CHROMEOS_NATIVE_PIXMAP_FRAME_RESOURCE_H_