blob: dcb988d6913e5c08351baea2baa1de40961ed2cf [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/capture/video/mac/gpu_memory_buffer_tracker_mac.h"
#include "base/logging.h"
namespace media {
GpuMemoryBufferTrackerMac::GpuMemoryBufferTrackerMac() {}
GpuMemoryBufferTrackerMac::GpuMemoryBufferTrackerMac(
base::ScopedCFTypeRef<IOSurfaceRef> io_surface)
: is_external_io_surface_(true), io_surface_(std::move(io_surface)) {}
GpuMemoryBufferTrackerMac::~GpuMemoryBufferTrackerMac() {}
bool GpuMemoryBufferTrackerMac::Init(const gfx::Size& dimensions,
VideoPixelFormat format,
const mojom::PlaneStridesPtr& strides) {
DCHECK(!io_surface_);
if (format != PIXEL_FORMAT_NV12) {
NOTREACHED() << "Unsupported VideoPixelFormat "
<< VideoPixelFormatToString(format);
return false;
}
if (IOSurfaceRef io_surface =
CreateIOSurface(dimensions, gfx::BufferFormat::YUV_420_BIPLANAR,
/*should_clear=*/false)) {
io_surface_.reset(io_surface, base::scoped_policy::ASSUME);
DVLOG(2) << __func__ << " id " << IOSurfaceGetID(io_surface_);
return true;
} else {
LOG(ERROR) << "Unable to create IOSurface!";
return false;
}
}
bool GpuMemoryBufferTrackerMac::IsSameGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle) const {
if (!is_external_io_surface_)
return false;
return IOSurfaceGetID(io_surface_) == IOSurfaceGetID(handle.io_surface);
}
bool GpuMemoryBufferTrackerMac::IsReusableForFormat(
const gfx::Size& dimensions,
VideoPixelFormat format,
const mojom::PlaneStridesPtr& strides) {
if (is_external_io_surface_)
return false;
gfx::Size surface_size(IOSurfaceGetWidth(io_surface_),
IOSurfaceGetHeight(io_surface_));
return format == PIXEL_FORMAT_NV12 && dimensions == surface_size;
}
uint32_t GpuMemoryBufferTrackerMac::GetMemorySizeInBytes() {
return IOSurfaceGetAllocSize(io_surface_);
}
std::unique_ptr<VideoCaptureBufferHandle>
GpuMemoryBufferTrackerMac::GetMemoryMappedAccess() {
NOTREACHED() << "Unsupported operation";
return std::make_unique<NullHandle>();
}
base::UnsafeSharedMemoryRegion
GpuMemoryBufferTrackerMac::DuplicateAsUnsafeRegion() {
NOTREACHED() << "Unsupported operation";
return base::UnsafeSharedMemoryRegion();
}
mojo::ScopedSharedBufferHandle
GpuMemoryBufferTrackerMac::DuplicateAsMojoBuffer() {
NOTREACHED() << "Unsupported operation";
return mojo::ScopedSharedBufferHandle();
}
gfx::GpuMemoryBufferHandle
GpuMemoryBufferTrackerMac::GetGpuMemoryBufferHandle() {
DVLOG(2) << __func__ << " id " << IOSurfaceGetID(io_surface_);
gfx::GpuMemoryBufferHandle gmb_handle;
gmb_handle.type = gfx::GpuMemoryBufferType::IO_SURFACE_BUFFER;
gmb_handle.id.id = -1;
gmb_handle.io_surface = io_surface_;
return gmb_handle;
}
void GpuMemoryBufferTrackerMac::OnHeldByConsumersChanged(
bool is_held_by_consumers) {
if (!is_external_io_surface_)
return;
if (is_held_by_consumers) {
DCHECK(!in_use_for_consumers_);
in_use_for_consumers_.reset(io_surface_.get(), base::scoped_policy::RETAIN);
} else {
DCHECK(in_use_for_consumers_);
in_use_for_consumers_.reset();
}
}
} // namespace media