Revert "ozone: Remove mesa i965 same-fd workaround restriction"
This reverts commit 46eb9e2770083a3789d4bde29645f905a5a9c417.
Reason for revert: causing tast failures on amd64-generic VM bot
See https://bugs.chromium.org/p/chromium/issues/detail?id=923061#c2
Original change's description:
> ozone: Remove mesa i965 same-fd workaround restriction
>
> NOTE: This is based on crrev.com/c/549576.
>
> After Mesa same-fd for eglCreateImageKHR restriction was relaxed in
> crrev.com/c/378198/, it is now possible to remove the workaround in chromium.
>
> The changes are as follows:
> 1. ClientNativePixmapDmaBuf can map multiple plane using multiple FDs.
> 2. GLImageNativePixmap can create EGLImage using multiple FDs.
> 3. GbmBuffer/GbmPixmap manages multiple FDs.
>
> BUG=642410, 911370
> TEST=VDA unittest and VEA unittest
> TEST=Playback with Chrome ARC++ and ARC++ DRM L1 on kevin, hana, eve
> TEST=Playback with Chrome on peach_pit and nyan_big
>
> Change-Id: I23848b8bcd0e240307633a5201b4b8e58b374282
> Reviewed-on: https://chromium-review.googlesource.com/c/1362777
> Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
> Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Daniele Castagna <dcastagna@chromium.org>
> Reviewed-by: Pawel Osciak <posciak@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#623686}
TBR=rjkroege@chromium.org,posciak@chromium.org,dcheng@chromium.org,dcastagna@chromium.org,hiroh@chromium.org
Change-Id: Ie9620b2022ec37ca5e55613d4fbe63247d357862
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 642410, 911370, 923061
Reviewed-on: https://chromium-review.googlesource.com/c/1418124
Reviewed-by: Ben Pastene <bpastene@chromium.org>
Commit-Queue: Ben Pastene <bpastene@chromium.org>
Cr-Commit-Position: refs/heads/master@{#623761}
diff --git a/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc b/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
index 2af5d03..29193169 100644
--- a/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
+++ b/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
@@ -537,27 +537,8 @@
mojom::VideoDecodeAccelerator::Result::INVALID_ARGUMENT);
return;
}
-
- const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format);
-
- // TODO(crbug.com/911370): Remove this workaround once Android passes one fd
- // per plane.
- std::array<base::ScopedFD, media::VideoFrame::kMaxPlanes> scoped_fds;
- scoped_fds[0].reset(handle_fd.release());
- for (size_t i = 1; i < num_planes; ++i) {
- scoped_fds[i].reset(HANDLE_EINTR(dup(scoped_fds[0].get())));
- if (!scoped_fds[i].is_valid()) {
- VLOGF(1) << "Failed to duplicate fd.";
- client_->NotifyError(
- mojom::VideoDecodeAccelerator::Result::PLATFORM_FAILURE);
- return;
- }
- }
- for (size_t i = 0; i < num_planes; ++i) {
- gmb_handle.native_pixmap_handle.fds.push_back(
- base::FileDescriptor(scoped_fds[i].release(), true));
- }
-
+ gmb_handle.native_pixmap_handle.fds.push_back(
+ base::FileDescriptor(handle_fd.release(), true));
for (const auto& plane : planes) {
gmb_handle.native_pixmap_handle.planes.emplace_back(plane.stride,
plane.offset, 0);
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
index c8bac21..38c2569 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
@@ -35,11 +35,11 @@
const DestructionCallback& callback,
std::unique_ptr<gfx::ClientNativePixmap> pixmap,
const std::vector<gfx::NativePixmapPlane>& planes,
- std::vector<base::ScopedFD> fds)
+ base::ScopedFD fd)
: GpuMemoryBufferImpl(id, size, format, callback),
pixmap_(std::move(pixmap)),
planes_(planes),
- fds_(std::move(fds)) {}
+ fd_(std::move(fd)) {}
GpuMemoryBufferImplNativePixmap::~GpuMemoryBufferImplNativePixmap() = default;
@@ -52,33 +52,42 @@
gfx::BufferFormat format,
gfx::BufferUsage usage,
const DestructionCallback& callback) {
- std::vector<base::ScopedFD> fds;
- std::vector<base::ScopedFD> dup_fds;
- for (auto& fd : handle.native_pixmap_handle.fds) {
- DCHECK(fd.auto_close);
- // Take ownership of FD
- fds.emplace_back(fd.fd);
+ // GpuMemoryBufferImpl needs the FD to implement GetHandle() but
+ // gfx::ClientNativePixmapFactory::ImportFromHandle is expected to take
+ // ownership of the FD passed in the handle so we have to dup it here in
+ // order to pass a valid FD to the GpuMemoryBufferImpl ctor.
+ base::ScopedFD scoped_native_pixmap_handle_fd;
+ base::ScopedFD scoped_fd;
+ if (!handle.native_pixmap_handle.fds.empty()) {
+ // Take ownership of FD at index 0.
+ scoped_native_pixmap_handle_fd.reset(handle.native_pixmap_handle.fds[0].fd);
+
+ // Close all remaining FDs.
+ for (size_t i = 1; i < handle.native_pixmap_handle.fds.size(); ++i)
+ base::ScopedFD scoped_fd(handle.native_pixmap_handle.fds[i].fd);
+
// Duplicate FD for GpuMemoryBufferImplNativePixmap ctor.
- dup_fds.emplace_back(HANDLE_EINTR(dup(fd.fd)));
- if (!dup_fds.back().is_valid()) {
+ scoped_fd.reset(HANDLE_EINTR(dup(scoped_native_pixmap_handle_fd.get())));
+ if (!scoped_fd.is_valid()) {
PLOG(ERROR) << "dup";
return nullptr;
}
}
gfx::NativePixmapHandle native_pixmap_handle;
- for (auto& fd : dup_fds) {
- native_pixmap_handle.fds.emplace_back(fd.release(), true /* auto_close */);
+ if (scoped_native_pixmap_handle_fd.is_valid()) {
+ native_pixmap_handle.fds.emplace_back(
+ scoped_native_pixmap_handle_fd.release(), true /* auto_close */);
}
native_pixmap_handle.planes = handle.native_pixmap_handle.planes;
std::unique_ptr<gfx::ClientNativePixmap> native_pixmap =
- client_native_pixmap_factory->ImportFromHandle(
- std::move(native_pixmap_handle), size, usage);
+ client_native_pixmap_factory->ImportFromHandle(native_pixmap_handle, size,
+ usage);
DCHECK(native_pixmap);
return base::WrapUnique(new GpuMemoryBufferImplNativePixmap(
handle.id, size, format, callback, std::move(native_pixmap),
- handle.native_pixmap_handle.planes, std::move(fds)));
+ handle.native_pixmap_handle.planes, std::move(scoped_fd)));
}
// static
@@ -135,9 +144,8 @@
handle.type = gfx::NATIVE_PIXMAP;
handle.id = id_;
gfx::NativePixmapHandle native_pixmap_handle;
- for (const auto& fd : fds_) {
- native_pixmap_handle.fds.emplace_back(fd.get(), false /* auto_close */);
- }
+ if (fd_.is_valid())
+ native_pixmap_handle.fds.emplace_back(fd_.get(), false /* auto_close */);
native_pixmap_handle.planes = planes_;
handle.native_pixmap_handle = gfx::CloneHandleForIPC(native_pixmap_handle);
return handle;
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h
index 7117b56..ede8d50 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h
@@ -56,11 +56,11 @@
const DestructionCallback& callback,
std::unique_ptr<gfx::ClientNativePixmap> native_pixmap,
const std::vector<gfx::NativePixmapPlane>& planes,
- std::vector<base::ScopedFD> fds);
+ base::ScopedFD fd);
- const std::unique_ptr<gfx::ClientNativePixmap> pixmap_;
+ std::unique_ptr<gfx::ClientNativePixmap> pixmap_;
std::vector<gfx::NativePixmapPlane> planes_;
- std::vector<base::ScopedFD> fds_;
+ base::ScopedFD fd_;
DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplNativePixmap);
};
diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
index 6246b375..d59dc6c 100644
--- a/media/gpu/v4l2/generic_v4l2_device.cc
+++ b/media/gpu/v4l2/generic_v4l2_device.cc
@@ -299,14 +299,8 @@
gfx::NativePixmapHandle native_pixmap_handle;
std::vector<base::ScopedFD> duped_fds;
- // The number of file descriptors can be less than the number of planes when
- // v4l2 pix fmt, |fourcc|, is a single plane format. Duplicating the last
- // file descriptor should be safely used for the later planes, because they
- // are on the last buffer.
- for (size_t i = 0; i < num_planes; ++i) {
- int fd =
- i < dmabuf_fds.size() ? dmabuf_fds[i].get() : dmabuf_fds.back().get();
- duped_fds.emplace_back(HANDLE_EINTR(dup(fd)));
+ for (const auto& fd : dmabuf_fds) {
+ duped_fds.emplace_back(HANDLE_EINTR(dup(fd.get())));
if (!duped_fds.back().is_valid()) {
VPLOGF(1) << "Failed duplicating a dmabuf fd";
return nullptr;
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
index 586a6e2..a2450e0 100644
--- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -1484,29 +1484,11 @@
DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id;
DCHECK(child_task_runner_->BelongsToCurrentThread());
- std::vector<base::ScopedFD> dmabuf_fds;
+ std::vector<base::ScopedFD> passed_dmabuf_fds;
#if defined(USE_OZONE)
- DCHECK_EQ(gpu_memory_buffer_handle.native_pixmap_handle.fds.size(),
- gpu_memory_buffer_handle.native_pixmap_handle.planes.size());
- // If the driver does not accept as many fds as we received from the client,
- // we have to check if the additional fds are actually duplicated fds pointing
- // to previous planes; if so, we can close the duplicates and keep only the
- // original fd(s).
- // Assume that an fd is a duplicate of a previous plane's fd if offset != 0.
- // Otherwise, if offset == 0, return error as it may be pointing to a new
- // plane.
- for (auto& fd : gpu_memory_buffer_handle.native_pixmap_handle.fds) {
- dmabuf_fds.emplace_back(fd.fd);
- }
- for (size_t i = dmabuf_fds.size() - 1; i >= output_planes_count_; i--) {
- if (gpu_memory_buffer_handle.native_pixmap_handle.planes[i].offset == 0) {
- VLOGF(1) << "The dmabuf fd points to a new buffer, ";
- NOTIFY_ERROR(INVALID_ARGUMENT);
- return;
- }
- // Drop safely, because this fd is duplicate dmabuf fd pointing to previous
- // buffer and the appropriate address can be accessed by associated offset.
- dmabuf_fds.pop_back();
+ for (const auto& fd : gpu_memory_buffer_handle.native_pixmap_handle.fds) {
+ DCHECK_NE(fd.fd, -1);
+ passed_dmabuf_fds.push_back(base::ScopedFD(fd.fd));
}
#endif
@@ -1528,7 +1510,8 @@
FROM_HERE,
base::BindOnce(
&V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureTask,
- base::Unretained(this), picture_buffer_id, std::move(dmabuf_fds)));
+ base::Unretained(this), picture_buffer_id,
+ std::move(passed_dmabuf_fds)));
}
void V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureTask(
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 69a91530..13bd1af 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -544,40 +544,6 @@
DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id;
DCHECK(child_task_runner_->BelongsToCurrentThread());
- std::vector<base::ScopedFD> dmabuf_fds;
- int32_t stride = 0;
-#if defined(USE_OZONE)
- DCHECK_EQ(gpu_memory_buffer_handle.native_pixmap_handle.fds.size(),
- gpu_memory_buffer_handle.native_pixmap_handle.planes.size());
-
- // If the driver does not accept as many fds as we received from the client,
- // we have to check if the additional fds are actually duplicated fds pointing
- // to previous planes; if so, we can close the duplicates and keep only the
- // original fd(s).
- // Assume that an fd is a duplicate of a previous plane's fd if offset != 0.
- // Otherwise, if offset == 0, return error as it may be pointing to a new
- // plane.
- for (auto& fd : gpu_memory_buffer_handle.native_pixmap_handle.fds) {
- dmabuf_fds.emplace_back(fd.fd);
- }
- for (size_t i = dmabuf_fds.size() - 1; i >= egl_image_planes_count_; i--) {
- if (gpu_memory_buffer_handle.native_pixmap_handle.planes[i].offset == 0) {
- VLOGF(1) << "The dmabuf fd points to a new buffer, ";
- NOTIFY_ERROR(INVALID_ARGUMENT);
- return;
- }
- // Drop safely, because this fd is duplicate dmabuf fd pointing to previous
- // buffer and the appropriate address can be accessed by associated offset.
- dmabuf_fds.pop_back();
- }
-
- stride = gpu_memory_buffer_handle.native_pixmap_handle.planes[0].stride;
- for (const auto& plane :
- gpu_memory_buffer_handle.native_pixmap_handle.planes) {
- DVLOGF(3) << ": offset=" << plane.offset << ", stride=" << plane.stride;
- }
-#endif
-
if (output_mode_ != Config::OutputMode::IMPORT) {
VLOGF(1) << "Cannot import in non-import mode";
NOTIFY_ERROR(INVALID_ARGUMENT);
@@ -594,6 +560,20 @@
return;
}
+ std::vector<base::ScopedFD> dmabuf_fds;
+ int32_t stride = 0;
+#if defined(USE_OZONE)
+ for (const auto& fd : gpu_memory_buffer_handle.native_pixmap_handle.fds) {
+ DCHECK_NE(fd.fd, -1);
+ dmabuf_fds.push_back(base::ScopedFD(fd.fd));
+ }
+ stride = gpu_memory_buffer_handle.native_pixmap_handle.planes[0].stride;
+ for (const auto& plane :
+ gpu_memory_buffer_handle.native_pixmap_handle.planes) {
+ DVLOGF(3) << ": offset=" << plane.offset << ", stride=" << plane.stride;
+ }
+#endif
+
decoder_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&V4L2VideoDecodeAccelerator::ImportBufferForPictureTask,
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
index 57ebec3..76f6b0b 100644
--- a/ui/gfx/linux/client_native_pixmap_dmabuf.cc
+++ b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
@@ -12,10 +12,8 @@
#include <xf86drm.h>
#include "base/memory/ptr_util.h"
-#include "base/numerics/safe_conversions.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/memory.h"
-#include "base/process/process_metrics.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -61,24 +59,6 @@
} // namespace
-ClientNativePixmapDmaBuf::PlaneInfo::PlaneInfo() {}
-
-ClientNativePixmapDmaBuf::PlaneInfo::PlaneInfo(PlaneInfo&& info)
- : fd(std::move(info.fd)),
- data(info.data),
- offset(info.offset),
- size(info.size) {
- // Set nullptr to info.data in order not to call munmap in |info| dtor.
- info.data = nullptr;
-}
-
-ClientNativePixmapDmaBuf::PlaneInfo::~PlaneInfo() {
- if (data) {
- int ret = munmap(data, size);
- DCHECK(!ret);
- }
-}
-
// static
bool ClientNativePixmapDmaBuf::IsConfigurationSupported(
gfx::BufferFormat format,
@@ -157,74 +137,59 @@
ClientNativePixmapDmaBuf::ImportFromDmabuf(
const gfx::NativePixmapHandle& handle,
const gfx::Size& size) {
- std::array<PlaneInfo, kMaxPlanes> plane_info;
- for (size_t i = 0; i < handle.fds.size(); ++i) {
- const auto& fd = handle.fds[i];
- DCHECK(fd.auto_close);
- plane_info[i].fd.reset(fd.fd);
- DCHECK(plane_info[i].fd.is_valid());
- }
-
- DCHECK_EQ(handle.planes.size(), handle.fds.size());
-
- const size_t page_size = base::GetPageSize();
- for (size_t i = 0; i < handle.fds.size(); ++i) {
- // mmap() fails if the offset argument is not page-aligned.
- // Since handle.planes[i].offset is possibly not page-aligned, we
- // have to map with an additional offset to be aligned to the page.
- const size_t extra_offset = handle.planes[i].offset % page_size;
- size_t map_size =
- base::checked_cast<size_t>(handle.planes[i].size + extra_offset);
- plane_info[i].offset = extra_offset;
- plane_info[i].size = map_size;
-
- void* data =
- mmap(nullptr, map_size, (PROT_READ | PROT_WRITE), MAP_SHARED,
- plane_info[i].fd.get(), handle.planes[i].offset - extra_offset);
- if (data == MAP_FAILED) {
- logging::SystemErrorCode mmap_error = logging::GetLastSystemErrorCode();
- if (mmap_error == ENOMEM)
- base::TerminateBecauseOutOfMemory(map_size);
- LOG(ERROR) << "Failed to mmap dmabuf: "
- << logging::SystemErrorCodeToString(mmap_error);
- return nullptr;
- }
- plane_info[i].data = data;
- }
-
- return base::WrapUnique(
- new ClientNativePixmapDmaBuf(handle, size, std::move(plane_info)));
+ return base::WrapUnique(new ClientNativePixmapDmaBuf(handle, size));
}
ClientNativePixmapDmaBuf::ClientNativePixmapDmaBuf(
const gfx::NativePixmapHandle& handle,
- const gfx::Size& size,
- std::array<PlaneInfo, kMaxPlanes> plane_info)
- : pixmap_handle_(handle), size_(size), plane_info_(std::move(plane_info)) {
+ const gfx::Size& size)
+ : pixmap_handle_(handle), size_(size), data_{0} {
TRACE_EVENT0("drm", "ClientNativePixmapDmaBuf");
+ // TODO(dcastagna): support multiple fds.
+ DCHECK_EQ(1u, handle.fds.size());
+ DCHECK_GE(handle.fds.front().fd, 0);
+ dmabuf_fd_.reset(handle.fds.front().fd);
+
+ DCHECK_GE(handle.planes.back().size, 0u);
+ size_t map_size = handle.planes.back().offset + handle.planes.back().size;
+ data_ = mmap(nullptr, map_size, (PROT_READ | PROT_WRITE), MAP_SHARED,
+ dmabuf_fd_.get(), 0);
+ if (data_ == MAP_FAILED) {
+ logging::SystemErrorCode mmap_error = logging::GetLastSystemErrorCode();
+ if (mmap_error == ENOMEM)
+ base::TerminateBecauseOutOfMemory(map_size);
+
+ CHECK(false) << "Failed to mmap dmabuf: "
+ << logging::SystemErrorCodeToString(mmap_error);
+ }
}
ClientNativePixmapDmaBuf::~ClientNativePixmapDmaBuf() {
TRACE_EVENT0("drm", "~ClientNativePixmapDmaBuf");
+ size_t map_size =
+ pixmap_handle_.planes.back().offset + pixmap_handle_.planes.back().size;
+ int ret = munmap(data_, map_size);
+ DCHECK(!ret);
}
bool ClientNativePixmapDmaBuf::Map() {
TRACE_EVENT0("drm", "DmaBuf:Map");
- for (size_t i = 0; i < pixmap_handle_.planes.size(); ++i)
- PrimeSyncStart(plane_info_[i].fd.get());
- return true;
+ if (data_ != nullptr) {
+ PrimeSyncStart(dmabuf_fd_.get());
+ return true;
+ }
+ return false;
}
void ClientNativePixmapDmaBuf::Unmap() {
TRACE_EVENT0("drm", "DmaBuf:Unmap");
- for (size_t i = 0; i < pixmap_handle_.planes.size(); ++i)
- PrimeSyncEnd(plane_info_[i].fd.get());
+ PrimeSyncEnd(dmabuf_fd_.get());
}
void* ClientNativePixmapDmaBuf::GetMemoryAddress(size_t plane) const {
DCHECK_LT(plane, pixmap_handle_.planes.size());
- return static_cast<uint8_t*>(plane_info_[plane].data) +
- plane_info_[plane].offset;
+ uint8_t* address = reinterpret_cast<uint8_t*>(data_);
+ return address + pixmap_handle_.planes[plane].offset;
}
int ClientNativePixmapDmaBuf::GetStride(size_t plane) const {
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.h b/ui/gfx/linux/client_native_pixmap_dmabuf.h
index ddd9006..f5da2b3 100644
--- a/ui/gfx/linux/client_native_pixmap_dmabuf.h
+++ b/ui/gfx/linux/client_native_pixmap_dmabuf.h
@@ -7,7 +7,6 @@
#include <stdint.h>
-#include <array>
#include <memory>
#include "base/files/scoped_file.h"
@@ -39,25 +38,13 @@
int GetStride(size_t plane) const override;
private:
- static constexpr size_t kMaxPlanes = 4;
-
- struct PlaneInfo {
- PlaneInfo();
- PlaneInfo(PlaneInfo&& plane_info);
- ~PlaneInfo();
-
- base::ScopedFD fd;
- void* data = nullptr;
- size_t offset = 0;
- size_t size = 0;
- };
ClientNativePixmapDmaBuf(const gfx::NativePixmapHandle& handle,
- const gfx::Size& size,
- std::array<PlaneInfo, kMaxPlanes> plane_info);
+ const gfx::Size& size);
const gfx::NativePixmapHandle pixmap_handle_;
const gfx::Size size_;
- const std::array<PlaneInfo, kMaxPlanes> plane_info_;
+ base::ScopedFD dmabuf_fd_;
+ void* data_;
DISALLOW_COPY_AND_ASSIGN(ClientNativePixmapDmaBuf);
};
diff --git a/ui/gfx/native_pixmap.h b/ui/gfx/native_pixmap.h
index a4cbe0b..1e6fda1 100644
--- a/ui/gfx/native_pixmap.h
+++ b/ui/gfx/native_pixmap.h
@@ -26,8 +26,6 @@
NativePixmap() {}
virtual bool AreDmaBufFdsValid() const = 0;
- // TODO(crbug.com/911370): Remove this because the number of fds will always
- // be equal to the number of planes.
virtual size_t GetDmaBufFdCount() const = 0;
virtual int GetDmaBufFd(size_t plane) const = 0;
virtual int GetDmaBufPitch(size_t plane) const = 0;
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc
index 0bae74d..a29c9c67 100644
--- a/ui/gl/gl_image_native_pixmap.cc
+++ b/ui/gl/gl_image_native_pixmap.cc
@@ -181,7 +181,8 @@
size_t pixmap_plane = attrs_plane;
- attrs.push_back(pixmap->GetDmaBufFd(pixmap_plane));
+ attrs.push_back(pixmap->GetDmaBufFd(
+ pixmap_plane < pixmap->GetDmaBufFdCount() ? pixmap_plane : 0));
attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + attrs_plane * 3);
attrs.push_back(pixmap->GetDmaBufOffset(pixmap_plane));
attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + attrs_plane * 3);
diff --git a/ui/gl/test/gl_image_test_template.h b/ui/gl/test/gl_image_test_template.h
index edc0f1d..a9fa046 100644
--- a/ui/gl/test/gl_image_test_template.h
+++ b/ui/gl/test/gl_image_test_template.h
@@ -80,8 +80,8 @@
return;
// NOTE: On some drm devices (mediatek) the mininum width/height to add an fb
- // for a bo must be 64, and YVU_420 in i915 requires at least 128 length.
- const gfx::Size small_image_size(128, 128);
+ // for a bo must be 64.
+ const gfx::Size small_image_size(64, 64);
const gfx::Size large_image_size(512, 512);
const uint8_t* image_color = this->delegate_.GetImageColor();
diff --git a/ui/ozone/common/linux/gbm_buffer.h b/ui/ozone/common/linux/gbm_buffer.h
index e72b531..c6e0dac 100644
--- a/ui/ozone/common/linux/gbm_buffer.h
+++ b/ui/ozone/common/linux/gbm_buffer.h
@@ -23,8 +23,6 @@
virtual uint32_t GetFormat() const = 0;
virtual uint64_t GetFormatModifier() const = 0;
virtual uint32_t GetFlags() const = 0;
- // TODO(crbug.com/911370): Remove this because the number of fds will always
- // be equal to the number of planes.
virtual size_t GetFdCount() const = 0;
// TODO(reveman): This should not be needed once crbug.com/597932 is
// fixed, as the size would be queried directly from the underlying bo.
diff --git a/ui/ozone/common/linux/gbm_wrapper.cc b/ui/ozone/common/linux/gbm_wrapper.cc
index 0e0a9b56..15efd7b 100644
--- a/ui/ozone/common/linux/gbm_wrapper.cc
+++ b/ui/ozone/common/linux/gbm_wrapper.cc
@@ -38,9 +38,7 @@
flags_(flags),
fds_(std::move(fds)),
size_(size),
- planes_(std::move(planes)) {
- DCHECK_EQ(fds_.size(), planes_.size());
- }
+ planes_(std::move(planes)) {}
~Buffer() override {
DCHECK(!mmap_data_);
@@ -95,13 +93,16 @@
// TODO(dcastagna): Use gbm_bo_get_num_planes once all the formats we use
// are supported by gbm.
for (size_t i = 0; i < gfx::NumberOfPlanesForBufferFormat(format); ++i) {
- base::ScopedFD scoped_fd(HANDLE_EINTR(dup(GetPlaneFd(i))));
- if (!scoped_fd.is_valid()) {
- PLOG(ERROR) << "dup";
- return gfx::NativePixmapHandle();
+ // Some formats (e.g: YVU_420) might have less than one fd per plane.
+ if (i < fds_.size()) {
+ base::ScopedFD scoped_fd(HANDLE_EINTR(dup(GetPlaneFd(i))));
+ if (!scoped_fd.is_valid()) {
+ PLOG(ERROR) << "dup";
+ return gfx::NativePixmapHandle();
+ }
+ handle.fds.emplace_back(
+ base::FileDescriptor(scoped_fd.release(), true /* auto_close */));
}
- handle.fds.emplace_back(
- base::FileDescriptor(scoped_fd.release(), true /* auto_close */));
handle.planes.emplace_back(GetPlaneStride(i), GetPlaneOffset(i),
GetPlaneSize(i), GetFormatModifier());
}
@@ -160,12 +161,16 @@
// kept open for the lifetime of the buffer.
base::ScopedFD fd(gbm_bo_get_plane_fd(bo, i));
- if (!fd.is_valid()) {
- PLOG(ERROR) << "Failed to export buffer to dma_buf";
- gbm_bo_destroy(bo);
- return nullptr;
+ // TODO(dcastagna): support multiple fds.
+ // crbug.com/642410
+ if (!i) {
+ if (!fd.is_valid()) {
+ PLOG(ERROR) << "Failed to export buffer to dma_buf";
+ gbm_bo_destroy(bo);
+ return nullptr;
+ }
+ fds.emplace_back(std::move(fd));
}
- fds.emplace_back(std::move(fd));
planes.emplace_back(gbm_bo_get_plane_stride(bo, i),
gbm_bo_get_plane_offset(bo, i),
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
index c9c5c56..6d08b23 100644
--- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
+++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -244,15 +244,15 @@
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle) {
size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format);
- DCHECK_GE(num_planes, handle.fds.size());
- if (handle.planes.size() != num_planes) {
+ if (handle.planes.size() != num_planes ||
+ (handle.fds.size() != 1 && handle.fds.size() != num_planes)) {
return nullptr;
}
-
std::vector<base::ScopedFD> scoped_fds;
for (auto& fd : handle.fds) {
scoped_fds.emplace_back(fd.fd);
}
+
std::vector<gfx::NativePixmapPlane> planes;
for (const auto& plane : handle.planes) {
planes.push_back(plane);