Commit 3f074a06 authored by Michael Spang's avatar Michael Spang Committed by Commit Bot

ozone: drm: Merge GbmBuffer and GbmBoWrapper together

Since there's no longer any DRM-master specifics in GbmBuffer, move it
to //ui/ozone/common/linux and remove GbmBoWrapper.

Bug: 869206

Change-Id: I079f157e2f8ad46ea1f68670421d6d700abba25d
Reviewed-on: https://chromium-review.googlesource.com/1155919
Commit-Queue: Michael Spang <spang@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579704}
parent b521e13f
...@@ -11,8 +11,8 @@ source_set("linux") { ...@@ -11,8 +11,8 @@ source_set("linux") {
sources = [ sources = [
"drm_util_linux.cc", "drm_util_linux.cc",
"drm_util_linux.h", "drm_util_linux.h",
"gbm_bo_wrapper.cc", "gbm_buffer.cc",
"gbm_bo_wrapper.h", "gbm_buffer.h",
"gbm_device_linux.cc", "gbm_device_linux.cc",
"gbm_device_linux.h", "gbm_device_linux.h",
] ]
......
// Copyright 2018 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 "ui/ozone/common/linux/gbm_bo_wrapper.h"
#include <gbm.h>
#include "ui/gfx/native_pixmap_handle.h"
namespace ui {
GbmBoWrapper::GbmBoWrapper(gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
std::vector<base::ScopedFD> fds,
const gfx::Size& size,
std::vector<gfx::NativePixmapPlane> planes)
: bo_(bo),
format_modifier_(modifier),
format_(format),
flags_(flags),
fds_(std::move(fds)),
size_(size),
planes_(std::move(planes)) {}
GbmBoWrapper::~GbmBoWrapper() {
if (bo_)
gbm_bo_destroy(bo_);
}
bool GbmBoWrapper::AreFdsValid() const {
if (fds_.empty())
return false;
for (const auto& fd : fds_) {
if (fd.get() == -1)
return false;
}
return true;
}
int GbmBoWrapper::GetFd(size_t index) const {
DCHECK_LT(index, fds_.size());
return fds_[index].get();
}
int GbmBoWrapper::GetStride(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].stride;
}
int GbmBoWrapper::GetOffset(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].offset;
}
size_t GbmBoWrapper::GetPlaneSize(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].size;
}
uint32_t GbmBoWrapper::GetBoHandle() const {
return bo_ ? gbm_bo_get_handle(bo_).u32 : 0;
}
} // namespace ui
// Copyright 2018 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 "ui/ozone/common/linux/gbm_buffer.h"
#include <gbm.h>
#include "base/posix/eintr_wrapper.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/native_pixmap_handle.h"
#include "ui/ozone/common/linux/drm_util_linux.h"
namespace ui {
namespace {
std::unique_ptr<GbmBuffer> CreateBufferForBO(gbm_device* gbm,
struct gbm_bo* bo,
uint32_t format,
const gfx::Size& size,
uint32_t flags) {
DCHECK(bo);
std::vector<base::ScopedFD> fds;
std::vector<gfx::NativePixmapPlane> planes;
const uint64_t modifier = gbm_bo_get_format_modifier(bo);
for (size_t i = 0; i < gbm_bo_get_num_planes(bo); ++i) {
// The fd returned by gbm_bo_get_fd is not ref-counted and need to be
// kept open for the lifetime of the buffer.
base::ScopedFD fd(gbm_bo_get_plane_fd(bo, i));
// 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));
}
planes.emplace_back(gbm_bo_get_plane_stride(bo, i),
gbm_bo_get_plane_offset(bo, i),
gbm_bo_get_plane_size(bo, i), modifier);
}
return std::make_unique<GbmBuffer>(bo, format, flags, modifier,
std::move(fds), size, std::move(planes));
}
} // namespace
// static
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBufferWithModifiers(
gbm_device* gbm,
uint32_t format,
const gfx::Size& size,
uint32_t flags,
const std::vector<uint64_t>& modifiers) {
struct gbm_bo* bo =
gbm_bo_create_with_modifiers(gbm, size.width(), size.height(), format,
modifiers.data(), modifiers.size());
if (!bo)
return nullptr;
return CreateBufferForBO(gbm, bo, format, size, flags);
}
// static
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBuffer(gbm_device* gbm,
uint32_t format,
const gfx::Size& size,
uint32_t flags) {
struct gbm_bo* bo =
gbm_bo_create(gbm, size.width(), size.height(), format, flags);
if (!bo)
return nullptr;
return CreateBufferForBO(gbm, bo, format, size, flags);
}
// static
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBufferFromFds(
gbm_device* gbm,
uint32_t format,
const gfx::Size& size,
std::vector<base::ScopedFD> fds,
const std::vector<gfx::NativePixmapPlane>& planes) {
DCHECK_LE(fds.size(), planes.size());
DCHECK_EQ(planes[0].offset, 0);
// Try to use scanout if supported.
int gbm_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING;
if (!gbm_device_is_format_supported(gbm, format, gbm_flags))
gbm_flags &= ~GBM_BO_USE_SCANOUT;
struct gbm_bo* bo = nullptr;
if (gbm_device_is_format_supported(gbm, format, gbm_flags)) {
struct gbm_import_fd_planar_data fd_data;
fd_data.width = size.width();
fd_data.height = size.height();
fd_data.format = format;
DCHECK_LE(planes.size(), 3u);
for (size_t i = 0; i < planes.size(); ++i) {
fd_data.fds[i] = fds[i < fds.size() ? i : 0].get();
fd_data.strides[i] = planes[i].stride;
fd_data.offsets[i] = planes[i].offset;
fd_data.format_modifiers[i] = planes[i].modifier;
}
// The fd passed to gbm_bo_import is not ref-counted and need to be
// kept open for the lifetime of the buffer.
bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD_PLANAR, &fd_data, gbm_flags);
if (!bo) {
LOG(ERROR) << "nullptr returned from gbm_bo_import";
return nullptr;
}
}
return std::make_unique<GbmBuffer>(bo, format, gbm_flags, planes[0].modifier,
std::move(fds), size, std::move(planes));
}
GbmBuffer::GbmBuffer(struct gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
std::vector<base::ScopedFD> fds,
const gfx::Size& size,
std::vector<gfx::NativePixmapPlane> planes)
: bo_(bo),
format_(format),
format_modifier_(modifier),
flags_(flags),
fds_(std::move(fds)),
size_(size),
planes_(std::move(planes)) {}
GbmBuffer::~GbmBuffer() {
gbm_bo_destroy(bo_);
}
gfx::BufferFormat GbmBuffer::GetBufferFormat() const {
return ui::GetBufferFormatFromFourCCFormat(format_);
}
bool GbmBuffer::AreFdsValid() const {
if (fds_.empty())
return false;
for (const auto& fd : fds_) {
if (fd.get() == -1)
return false;
}
return true;
}
int GbmBuffer::GetFd(size_t index) const {
DCHECK_LT(index, fds_.size());
return fds_[index].get();
}
int GbmBuffer::GetStride(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].stride;
}
int GbmBuffer::GetOffset(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].offset;
}
size_t GbmBuffer::GetPlaneSize(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].size;
}
uint32_t GbmBuffer::GetHandle() const {
return gbm_bo_get_handle(bo_).u32;
}
gfx::NativePixmapHandle GbmBuffer::ExportHandle() const {
gfx::NativePixmapHandle handle;
gfx::BufferFormat format = ui::GetBufferFormatFromFourCCFormat(format_);
// 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) {
// Some formats (e.g: YVU_420) might have less than one fd per plane.
if (i < fd_count()) {
base::ScopedFD scoped_fd(HANDLE_EINTR(dup(GetFd(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.planes.emplace_back(GetStride(i), GetOffset(i), GetPlaneSize(i),
format_modifier());
}
return handle;
}
} // namespace ui
...@@ -2,34 +2,53 @@ ...@@ -2,34 +2,53 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef UI_OZONE_COMMON_LINUX_GBM_BO_WRAPPER_H_ #ifndef UI_OZONE_COMMON_LINUX_GBM_BUFFER_H_
#define UI_OZONE_COMMON_LINUX_GBM_BO_WRAPPER_H_ #define UI_OZONE_COMMON_LINUX_GBM_BUFFER_H_
#include <vector> #include <vector>
#include "base/files/scoped_file.h" #include "base/files/scoped_file.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
struct gbm_bo; struct gbm_bo;
struct gbm_device;
namespace gfx { namespace gfx {
struct NativePixmapHandle;
struct NativePixmapPlane; struct NativePixmapPlane;
} } // namespace gfx
namespace ui { namespace ui {
// Generic gbm_bo wrapper for ozone backends. class GbmBuffer {
class GbmBoWrapper {
public: public:
GbmBoWrapper(gbm_bo* bo, static std::unique_ptr<GbmBuffer> CreateBuffer(gbm_device* gbm,
uint32_t format, uint32_t format,
uint32_t flags, const gfx::Size& size,
uint64_t modifier, uint32_t flags);
std::vector<base::ScopedFD> fds, static std::unique_ptr<GbmBuffer> CreateBufferWithModifiers(
const gfx::Size& size, gbm_device* gbm,
std::vector<gfx::NativePixmapPlane> planes); uint32_t format,
~GbmBoWrapper(); const gfx::Size& size,
uint32_t flags,
const std::vector<uint64_t>& modifiers);
static std::unique_ptr<GbmBuffer> CreateBufferFromFds(
gbm_device* gbm,
uint32_t format,
const gfx::Size& size,
std::vector<base::ScopedFD> fds,
const std::vector<gfx::NativePixmapPlane>& planes);
GbmBuffer(gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
std::vector<base::ScopedFD> fds,
const gfx::Size& size,
std::vector<gfx::NativePixmapPlane> planes);
~GbmBuffer();
uint32_t format() const { return format_; } uint32_t format() const { return format_; }
uint64_t format_modifier() const { return format_modifier_; } uint64_t format_modifier() const { return format_modifier_; }
...@@ -39,18 +58,20 @@ class GbmBoWrapper { ...@@ -39,18 +58,20 @@ class GbmBoWrapper {
// TODO(reveman): This should not be needed once crbug.com/597932 is fixed, // TODO(reveman): This should not be needed once crbug.com/597932 is fixed,
// as the size would be queried directly from the underlying bo. // as the size would be queried directly from the underlying bo.
gfx::Size size() const { return size_; } gfx::Size size() const { return size_; }
gfx::BufferFormat GetBufferFormat() const;
bool AreFdsValid() const; bool AreFdsValid() const;
int GetFd(size_t plane) const; int GetFd(size_t plane) const;
int GetStride(size_t plane) const; int GetStride(size_t plane) const;
int GetOffset(size_t plane) const; int GetOffset(size_t plane) const;
size_t GetPlaneSize(size_t plane) const; size_t GetPlaneSize(size_t plane) const;
uint32_t GetBoHandle() const; uint32_t GetHandle() const;
gfx::NativePixmapHandle ExportHandle() const;
private: private:
gbm_bo* bo_ = nullptr; gbm_bo* bo_ = nullptr;
uint64_t format_modifier_ = 0;
uint32_t format_ = 0; uint32_t format_ = 0;
uint64_t format_modifier_ = 0;
uint32_t flags_ = 0; uint32_t flags_ = 0;
std::vector<base::ScopedFD> fds_; std::vector<base::ScopedFD> fds_;
...@@ -59,9 +80,9 @@ class GbmBoWrapper { ...@@ -59,9 +80,9 @@ class GbmBoWrapper {
std::vector<gfx::NativePixmapPlane> planes_; std::vector<gfx::NativePixmapPlane> planes_;
DISALLOW_COPY_AND_ASSIGN(GbmBoWrapper); DISALLOW_COPY_AND_ASSIGN(GbmBuffer);
}; };
} // namespace ui } // namespace ui
#endif // UI_OZONE_COMMON_LINUX_GBM_BO_WRAPPER_H_ #endif // UI_OZONE_COMMON_LINUX_GBM_BUFFER_H_
...@@ -97,18 +97,17 @@ void CreateBufferWithGbmFlags(const scoped_refptr<GbmDevice>& gbm, ...@@ -97,18 +97,17 @@ void CreateBufferWithGbmFlags(const scoped_refptr<GbmDevice>& gbm,
scoped_refptr<DrmFramebuffer>* out_framebuffer) { scoped_refptr<DrmFramebuffer>* out_framebuffer) {
std::unique_ptr<GbmBuffer> buffer; std::unique_ptr<GbmBuffer> buffer;
if (modifiers.empty()) if (modifiers.empty())
buffer = GbmBuffer::CreateBuffer(gbm, fourcc_format, size, flags); buffer = GbmBuffer::CreateBuffer(gbm->device(), fourcc_format, size, flags);
else else
buffer = GbmBuffer::CreateBufferWithModifiers(gbm, fourcc_format, size, buffer = GbmBuffer::CreateBufferWithModifiers(gbm->device(), fourcc_format,
flags, modifiers); size, flags, modifiers);
if (!buffer) if (!buffer)
return; return;
scoped_refptr<DrmFramebuffer> framebuffer; scoped_refptr<DrmFramebuffer> framebuffer;
if (flags & GBM_BO_USE_SCANOUT) { if (flags & GBM_BO_USE_SCANOUT) {
framebuffer = AddFramebuffersForBo(gbm, buffer->gbm_bo()->bo(), framebuffer = AddFramebuffersForBo(gbm, buffer->bo(), buffer->format(),
buffer->gbm_bo()->format(), buffer->format_modifier());
buffer->gbm_bo()->format_modifier());
if (!framebuffer) if (!framebuffer)
return; return;
} }
...@@ -132,17 +131,17 @@ class GbmBufferGenerator : public DrmFramebufferGenerator { ...@@ -132,17 +131,17 @@ class GbmBufferGenerator : public DrmFramebufferGenerator {
if (modifiers.size() > 0) { if (modifiers.size() > 0) {
buffer = GbmBuffer::CreateBufferWithModifiers( buffer = GbmBuffer::CreateBufferWithModifiers(
gbm, format, size, GBM_BO_USE_SCANOUT, modifiers); gbm->device(), format, size, GBM_BO_USE_SCANOUT, modifiers);
} else { } else {
buffer = GbmBuffer::CreateBuffer(gbm, format, size, GBM_BO_USE_SCANOUT); buffer = GbmBuffer::CreateBuffer(gbm->device(), format, size,
GBM_BO_USE_SCANOUT);
} }
if (!buffer) if (!buffer)
return nullptr; return nullptr;
return AddFramebuffersForBo(gbm, buffer->gbm_bo()->bo(), return AddFramebuffersForBo(gbm, buffer->bo(), buffer->format(),
buffer->gbm_bo()->format(), buffer->format_modifier());
buffer->gbm_bo()->format_modifier());
} }
protected: protected:
...@@ -225,7 +224,7 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget, ...@@ -225,7 +224,7 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
// but it happens during init. Need to figure out why. // but it happens during init. Need to figure out why.
std::vector<uint64_t> modifiers; std::vector<uint64_t> modifiers;
if (window && window->GetController() && !(flags & GBM_BO_USE_LINEAR) && if (window && window->GetController() && !(flags & GBM_BO_USE_LINEAR) &&
!(client_flags & GbmBuffer::kFlagNoModifiers)) { !(client_flags & GbmPixmap::kFlagNoModifiers)) {
modifiers = window->GetController()->GetFormatModifiers(fourcc_format); modifiers = window->GetController()->GetFormatModifiers(fourcc_format);
} }
...@@ -256,16 +255,15 @@ void DrmThread::CreateBufferFromFds( ...@@ -256,16 +255,15 @@ void DrmThread::CreateBufferFromFds(
DCHECK(gbm); DCHECK(gbm);
std::unique_ptr<GbmBuffer> buffer = GbmBuffer::CreateBufferFromFds( std::unique_ptr<GbmBuffer> buffer = GbmBuffer::CreateBufferFromFds(
gbm, ui::GetFourCCFormatFromBufferFormat(format), size, std::move(fds), gbm->device(), ui::GetFourCCFormatFromBufferFormat(format), size,
planes); std::move(fds), planes);
if (!buffer) if (!buffer)
return; return;
scoped_refptr<DrmFramebuffer> framebuffer; scoped_refptr<DrmFramebuffer> framebuffer;
if (buffer->gbm_bo()->flags() & GBM_BO_USE_SCANOUT) { if (buffer->flags() & GBM_BO_USE_SCANOUT) {
framebuffer = AddFramebuffersForBo(gbm, buffer->gbm_bo()->bo(), framebuffer = AddFramebuffersForBo(gbm, buffer->bo(), buffer->format(),
buffer->gbm_bo()->format(), buffer->format_modifier());
buffer->gbm_bo()->format_modifier());
if (!framebuffer) if (!framebuffer)
return; return;
} }
......
...@@ -4,170 +4,17 @@ ...@@ -4,170 +4,17 @@
#include "ui/ozone/platform/drm/gpu/gbm_buffer.h" #include "ui/ozone/platform/drm/gpu/gbm_buffer.h"
#include <drm.h>
#include <drm_fourcc.h>
#include <fcntl.h>
#include <gbm.h> #include <gbm.h>
#include <xf86drm.h>
#include <utility>
#include "base/files/platform_file.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/gpu_fence.h" #include "ui/gfx/gpu_fence.h"
#include "ui/gfx/native_pixmap_handle.h" #include "ui/gfx/native_pixmap_handle.h"
#include "ui/ozone/common/linux/drm_util_linux.h" #include "ui/ozone/platform/drm/gpu/drm_overlay_plane.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_window.h"
#include "ui/ozone/platform/drm/gpu/gbm_device.h"
#include "ui/ozone/platform/drm/gpu/gbm_surface_factory.h" #include "ui/ozone/platform/drm/gpu/gbm_surface_factory.h"
#include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h" #include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/surface_factory_ozone.h"
namespace ui { namespace ui {
GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
struct gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
std::vector<base::ScopedFD> fds,
const gfx::Size& size,
std::vector<gfx::NativePixmapPlane> planes)
: drm_(gbm),
gbm_bo_(bo,
format,
flags,
modifier,
std::move(fds),
size,
std::move(planes)) {}
GbmBuffer::~GbmBuffer() {}
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBufferForBO(
const scoped_refptr<GbmDevice>& gbm,
struct gbm_bo* bo,
uint32_t format,
const gfx::Size& size,
uint32_t flags) {
DCHECK(bo);
std::vector<base::ScopedFD> fds;
std::vector<gfx::NativePixmapPlane> planes;
const uint64_t modifier = gbm_bo_get_format_modifier(bo);
for (size_t i = 0; i < gbm_bo_get_num_planes(bo); ++i) {
// The fd returned by gbm_bo_get_fd is not ref-counted and need to be
// kept open for the lifetime of the buffer.
base::ScopedFD fd(gbm_bo_get_plane_fd(bo, i));
// 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));
}
planes.emplace_back(gbm_bo_get_plane_stride(bo, i),
gbm_bo_get_plane_offset(bo, i),
gbm_bo_get_plane_size(bo, i), modifier);
}
return std::make_unique<GbmBuffer>(gbm, bo, format, flags, modifier,
std::move(fds), size, std::move(planes));
}
// static
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBufferWithModifiers(
const scoped_refptr<GbmDevice>& gbm,
uint32_t format,
const gfx::Size& size,
uint32_t flags,
const std::vector<uint64_t>& modifiers) {
TRACE_EVENT2("drm", "GbmBuffer::CreateBufferWithModifiers", "device",
gbm->device_path().value(), "size", size.ToString());
struct gbm_bo* bo =
gbm_bo_create_with_modifiers(gbm->device(), size.width(), size.height(),
format, modifiers.data(), modifiers.size());
if (!bo)
return nullptr;
return CreateBufferForBO(gbm, bo, format, size, flags);
}
// static
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBuffer(
const scoped_refptr<GbmDevice>& gbm,
uint32_t format,
const gfx::Size& size,
uint32_t flags) {
TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device",
gbm->device_path().value(), "size", size.ToString());
struct gbm_bo* bo =
gbm_bo_create(gbm->device(), size.width(), size.height(), format, flags);
if (!bo)
return nullptr;
return CreateBufferForBO(gbm, bo, format, size, flags);
}
// static
std::unique_ptr<GbmBuffer> GbmBuffer::CreateBufferFromFds(
const scoped_refptr<GbmDevice>& gbm,
uint32_t format,
const gfx::Size& size,
std::vector<base::ScopedFD> fds,
const std::vector<gfx::NativePixmapPlane>& planes) {
TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device",
gbm->device_path().value(), "size", size.ToString());
DCHECK_LE(fds.size(), planes.size());
DCHECK_EQ(planes[0].offset, 0);
// Try to use scanout if supported.
int gbm_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING;
if (!gbm_device_is_format_supported(gbm->device(), format, gbm_flags))
gbm_flags &= ~GBM_BO_USE_SCANOUT;
struct gbm_bo* bo = nullptr;
if (gbm_device_is_format_supported(gbm->device(), format, gbm_flags)) {
struct gbm_import_fd_planar_data fd_data;
fd_data.width = size.width();
fd_data.height = size.height();
fd_data.format = format;
DCHECK_LE(planes.size(), 3u);
for (size_t i = 0; i < planes.size(); ++i) {
fd_data.fds[i] = fds[i < fds.size() ? i : 0].get();
fd_data.strides[i] = planes[i].stride;
fd_data.offsets[i] = planes[i].offset;
fd_data.format_modifiers[i] = planes[i].modifier;
}
// The fd passed to gbm_bo_import is not ref-counted and need to be
// kept open for the lifetime of the buffer.
bo = gbm_bo_import(gbm->device(), GBM_BO_IMPORT_FD_PLANAR, &fd_data,
gbm_flags);
if (!bo) {
LOG(ERROR) << "nullptr returned from gbm_bo_import";
return nullptr;
}
}
return std::make_unique<GbmBuffer>(gbm, bo, format, gbm_flags,
planes[0].modifier, std::move(fds), size,
std::move(planes));
}
GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager,
std::unique_ptr<GbmBuffer> buffer, std::unique_ptr<GbmBuffer> buffer,
scoped_refptr<DrmFramebuffer> framebuffer) scoped_refptr<DrmFramebuffer> framebuffer)
...@@ -176,64 +23,43 @@ GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, ...@@ -176,64 +23,43 @@ GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager,
framebuffer_(std::move(framebuffer)) {} framebuffer_(std::move(framebuffer)) {}
gfx::NativePixmapHandle GbmPixmap::ExportHandle() { gfx::NativePixmapHandle GbmPixmap::ExportHandle() {
gfx::NativePixmapHandle handle; return buffer_->ExportHandle();
gfx::BufferFormat format =
ui::GetBufferFormatFromFourCCFormat(buffer_->gbm_bo()->format());
// 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) {
// Some formats (e.g: YVU_420) might have less than one fd per plane.
if (i < buffer_->gbm_bo()->fd_count()) {
base::ScopedFD scoped_fd(HANDLE_EINTR(dup(buffer_->gbm_bo()->GetFd(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.planes.emplace_back(buffer_->gbm_bo()->GetStride(i),
buffer_->gbm_bo()->GetOffset(i),
buffer_->gbm_bo()->GetPlaneSize(i),
buffer_->gbm_bo()->format_modifier());
}
return handle;
} }
bool GbmPixmap::AreDmaBufFdsValid() const { bool GbmPixmap::AreDmaBufFdsValid() const {
return buffer_->gbm_bo()->AreFdsValid(); return buffer_->AreFdsValid();
} }
size_t GbmPixmap::GetDmaBufFdCount() const { size_t GbmPixmap::GetDmaBufFdCount() const {
return buffer_->gbm_bo()->fd_count(); return buffer_->fd_count();
} }
int GbmPixmap::GetDmaBufFd(size_t plane) const { int GbmPixmap::GetDmaBufFd(size_t plane) const {
return buffer_->gbm_bo()->GetFd(plane); return buffer_->GetFd(plane);
} }
int GbmPixmap::GetDmaBufPitch(size_t plane) const { int GbmPixmap::GetDmaBufPitch(size_t plane) const {
return buffer_->gbm_bo()->GetStride(plane); return buffer_->GetStride(plane);
} }
int GbmPixmap::GetDmaBufOffset(size_t plane) const { int GbmPixmap::GetDmaBufOffset(size_t plane) const {
return buffer_->gbm_bo()->GetOffset(plane); return buffer_->GetOffset(plane);
} }
uint64_t GbmPixmap::GetDmaBufModifier(size_t plane) const { uint64_t GbmPixmap::GetDmaBufModifier(size_t plane) const {
return buffer_->gbm_bo()->format_modifier(); return buffer_->format_modifier();
} }
gfx::BufferFormat GbmPixmap::GetBufferFormat() const { gfx::BufferFormat GbmPixmap::GetBufferFormat() const {
return ui::GetBufferFormatFromFourCCFormat(buffer_->gbm_bo()->format()); return buffer_->GetBufferFormat();
} }
gfx::Size GbmPixmap::GetBufferSize() const { gfx::Size GbmPixmap::GetBufferSize() const {
return buffer_->gbm_bo()->size(); return buffer_->size();
} }
uint32_t GbmPixmap::GetUniqueId() const { uint32_t GbmPixmap::GetUniqueId() const {
return buffer_->gbm_bo()->GetBoHandle(); return buffer_->GetHandle();
} }
bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
...@@ -243,7 +69,7 @@ bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, ...@@ -243,7 +69,7 @@ bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
const gfx::RectF& crop_rect, const gfx::RectF& crop_rect,
bool enable_blend, bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) { std::unique_ptr<gfx::GpuFence> gpu_fence) {
DCHECK(buffer_->gbm_bo()->flags() & GBM_BO_USE_SCANOUT); DCHECK(buffer_->flags() & GBM_BO_USE_SCANOUT);
// |framebuffer_id| might be 0 if AddFramebuffer2 failed, in that case we // |framebuffer_id| might be 0 if AddFramebuffer2 failed, in that case we
// already logged the error in GbmBuffer ctor. We avoid logging the error // already logged the error in GbmBuffer ctor. We avoid logging the error
// here since this method might be called every pageflip. // here since this method might be called every pageflip.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <vector> #include <vector>
#include "ui/gfx/native_pixmap.h" #include "ui/gfx/native_pixmap.h"
#include "ui/ozone/common/linux/gbm_bo_wrapper.h" #include "ui/ozone/common/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h" #include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
struct gbm_bo; struct gbm_bo;
...@@ -18,58 +18,10 @@ namespace ui { ...@@ -18,58 +18,10 @@ namespace ui {
class GbmDevice; class GbmDevice;
class GbmSurfaceFactory; class GbmSurfaceFactory;
class GbmBuffer { class GbmPixmap : public gfx::NativePixmap {
public: public:
static constexpr uint32_t kFlagNoModifiers = 1U << 0; static constexpr uint32_t kFlagNoModifiers = 1U << 0;
static std::unique_ptr<GbmBuffer> CreateBuffer(
const scoped_refptr<GbmDevice>& gbm,
uint32_t format,
const gfx::Size& size,
uint32_t flags);
static std::unique_ptr<GbmBuffer> CreateBufferWithModifiers(
const scoped_refptr<GbmDevice>& gbm,
uint32_t format,
const gfx::Size& size,
uint32_t flags,
const std::vector<uint64_t>& modifiers);
static std::unique_ptr<GbmBuffer> CreateBufferFromFds(
const scoped_refptr<GbmDevice>& gbm,
uint32_t format,
const gfx::Size& size,
std::vector<base::ScopedFD> fds,
const std::vector<gfx::NativePixmapPlane>& planes);
GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
struct gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
std::vector<base::ScopedFD> fds,
const gfx::Size& size,
std::vector<gfx::NativePixmapPlane> planes);
~GbmBuffer();
const GbmBoWrapper* gbm_bo() const { return &gbm_bo_; }
private:
static std::unique_ptr<GbmBuffer> CreateBufferForBO(
const scoped_refptr<GbmDevice>& gbm,
struct gbm_bo* bo,
uint32_t format,
const gfx::Size& size,
uint32_t flags);
const scoped_refptr<GbmDevice> drm_;
// Owned gbm_bo wrapper.
GbmBoWrapper gbm_bo_;
DISALLOW_COPY_AND_ASSIGN(GbmBuffer);
};
class GbmPixmap : public gfx::NativePixmap {
public:
GbmPixmap(GbmSurfaceFactory* surface_manager, GbmPixmap(GbmSurfaceFactory* surface_manager,
std::unique_ptr<GbmBuffer> buffer, std::unique_ptr<GbmBuffer> buffer,
scoped_refptr<DrmFramebuffer> framebuffer); scoped_refptr<DrmFramebuffer> framebuffer);
......
...@@ -168,7 +168,7 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan( ...@@ -168,7 +168,7 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan(
scoped_refptr<DrmFramebuffer> framebuffer; scoped_refptr<DrmFramebuffer> framebuffer;
drm_thread_proxy_->CreateBuffer(widget, size, format, usage, drm_thread_proxy_->CreateBuffer(widget, size, format, usage,
GbmBuffer::kFlagNoModifiers, &buffer, GbmPixmap::kFlagNoModifiers, &buffer,
&framebuffer); &framebuffer);
if (!buffer) if (!buffer)
return nullptr; return nullptr;
...@@ -182,10 +182,10 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan( ...@@ -182,10 +182,10 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan(
return nullptr; return nullptr;
} }
DCHECK(buffer->gbm_bo()->AreFdsValid()); DCHECK(buffer->AreFdsValid());
DCHECK_EQ(buffer->gbm_bo()->fd_count(), 1U); DCHECK_EQ(buffer->fd_count(), 1U);
base::ScopedFD vk_image_fd(dup(buffer->gbm_bo()->GetFd(0))); base::ScopedFD vk_image_fd(dup(buffer->GetFd(0)));
DCHECK(vk_image_fd.is_valid()); DCHECK(vk_image_fd.is_valid());
VkDmaBufImageCreateInfo dma_buf_image_create_info = { VkDmaBufImageCreateInfo dma_buf_image_create_info = {
...@@ -194,7 +194,7 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan( ...@@ -194,7 +194,7 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan(
.fd = vk_image_fd.release(), .fd = vk_image_fd.release(),
.format = VK_FORMAT_B8G8R8A8_SRGB, .format = VK_FORMAT_B8G8R8A8_SRGB,
.extent = (VkExtent3D){size.width(), size.height(), 1}, .extent = (VkExtent3D){size.width(), size.height(), 1},
.strideInBytes = buffer->gbm_bo()->GetStride(0), .strideInBytes = buffer->GetStride(0),
}; };
VkResult result = VkResult result =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment