Commit b29640a7 authored by Maksim Sisov's avatar Maksim Sisov Committed by Commit Bot

[ozone/wayland/drm] Implement gbm bo wrapper in common.

This CL is a part of the Wayland gpu/ui split effort, which fixes the
Ozone/Wayland and makes it functional when the gpu service is running
out of the browser process.

The patch does not bring any functionality changes, but rather
prepares Ozone/Wayland for a dmabuf based approach, which uses ozone/drm code,
to be landed in the upstream.

In particular, gbm_bo_wrapper.cc/h is now a wrapper around gbm_bo, which
is going to be used by ozone/drm and ozone/wayland.

This is only compiled for wayland (downstream now) and drm backends, and
does not bring any additional load on other backends.

TEST: compile ozone/drm.

Bug: 820047
Change-Id: I10cf2bcb990aa6de8acb67e941cc4e774747682a
Reviewed-on: https://chromium-review.googlesource.com/1078247
Commit-Queue: Maksim Sisov <msisov@igalia.com>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575225}
parent 80bede87
......@@ -42,27 +42,3 @@ source_set("common") {
visibility = [ "//ui/ozone/platform/*" ]
}
if (ozone_platform_gbm) {
source_set("linux") {
assert(ozone_platform_gbm)
sources = [
"linux/drm_util_linux.cc",
"linux/drm_util_linux.h",
"linux/gbm_device_linux.cc",
"linux/gbm_device_linux.h",
]
deps = [
"//base:base",
"//third_party/libdrm",
"//third_party/minigbm",
"//ui/gfx:buffer_types",
"//ui/gfx:memory_buffer",
"//ui/gfx/geometry:geometry",
]
visibility = [ "//ui/ozone/platform/drm/*" ]
}
}
# 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.
import("//build/config/ui.gni")
import("//ui/ozone/ozone.gni")
assert(ozone_platform_gbm)
source_set("linux") {
sources = [
"drm_util_linux.cc",
"drm_util_linux.h",
"gbm_bo_wrapper.cc",
"gbm_bo_wrapper.h",
"gbm_device_linux.cc",
"gbm_device_linux.h",
]
deps = [
"//base:base",
"//third_party/libdrm",
"//third_party/minigbm",
"//ui/gfx:buffer_types",
"//ui/gfx:memory_buffer",
"//ui/gfx/geometry:geometry",
"//ui/ozone:ozone_base",
]
}
// 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.
#ifndef UI_OZONE_COMMON_LINUX_GBM_BO_WRAPPER_H_
#define UI_OZONE_COMMON_LINUX_GBM_BO_WRAPPER_H_
#include <vector>
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "ui/gfx/geometry/size.h"
struct gbm_bo;
namespace gfx {
struct NativePixmapPlane;
}
namespace ui {
// Generic gbm_bo wrapper for ozone backends.
class GbmBoWrapper {
public:
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);
~GbmBoWrapper();
uint32_t format() const { return format_; }
uint64_t format_modifier() const { return format_modifier_; }
uint32_t flags() const { return flags_; }
size_t fd_count() const { return fds_.size(); }
gbm_bo* bo() const { return bo_; }
// TODO(reveman): This should not be needed once crbug.com/597932 is fixed,
// as the size would be queried directly from the underlying bo.
gfx::Size size() const { return size_; }
bool AreFdsValid() const;
int GetFd(size_t plane) const;
int GetStride(size_t plane) const;
int GetOffset(size_t plane) const;
size_t GetPlaneSize(size_t plane) const;
uint32_t GetBoHandle() const;
private:
gbm_bo* bo_ = nullptr;
uint64_t format_modifier_ = 0;
uint32_t format_ = 0;
uint32_t flags_ = 0;
std::vector<base::ScopedFD> fds_;
gfx::Size size_;
std::vector<gfx::NativePixmapPlane> planes_;
DISALLOW_COPY_AND_ASSIGN(GbmBoWrapper);
};
} // namespace ui
#endif // UI_OZONE_COMMON_LINUX_GBM_BO_WRAPPER_H_
......@@ -145,7 +145,7 @@ source_set("gbm") {
"//ui/gl",
"//ui/ozone:ozone_base",
"//ui/ozone/common",
"//ui/ozone/common:linux",
"//ui/ozone/common/linux",
"//ui/ozone/public/interfaces",
"//ui/platform_window",
]
......@@ -192,6 +192,6 @@ source_set("gbm_unittests") {
"//ui/gfx",
"//ui/ozone:platform",
"//ui/ozone/common",
"//ui/ozone/common:linux",
"//ui/ozone/common/linux",
]
}
......@@ -32,7 +32,7 @@
namespace ui {
GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
gbm_bo* bo,
struct gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
......@@ -40,24 +40,26 @@ GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
const gfx::Size& size,
std::vector<gfx::NativePixmapPlane> planes)
: drm_(gbm),
bo_(bo),
format_modifier_(modifier),
format_(format),
flags_(flags),
fds_(std::move(fds)),
size_(size),
planes_(std::move(planes)) {
if (flags & GBM_BO_USE_SCANOUT) {
DCHECK(bo_);
framebuffer_pixel_format_ = format;
gbm_bo_(bo,
format,
flags,
modifier,
std::move(fds),
size,
std::move(planes)) {
if (gbm_bo_.flags() & GBM_BO_USE_SCANOUT) {
struct gbm_bo* bo = gbm_bo_.bo();
DCHECK(bo);
framebuffer_pixel_format_ = gbm_bo_.format();
opaque_framebuffer_pixel_format_ = GetFourCCFormatForOpaqueFramebuffer(
GetBufferFormatFromFourCCFormat(format));
GetBufferFormatFromFourCCFormat(framebuffer_pixel_format_));
uint32_t handles[4] = {0};
uint32_t strides[4] = {0};
uint32_t offsets[4] = {0};
uint64_t modifiers[4] = {0};
uint64_t modifier = gbm_bo_.format_modifier();
for (size_t i = 0; i < gbm_bo_get_num_planes(bo); ++i) {
handles[i] = gbm_bo_get_plane_handle(bo, i).u32;
strides[i] = gbm_bo_get_plane_stride(bo, i);
......@@ -93,43 +95,6 @@ GbmBuffer::~GbmBuffer() {
drm_->RemoveFramebuffer(framebuffer_);
if (opaque_framebuffer_)
drm_->RemoveFramebuffer(opaque_framebuffer_);
if (bo())
gbm_bo_destroy(bo());
}
bool GbmBuffer::AreFdsValid() const {
if (fds_.empty())
return false;
for (const auto& fd : fds_) {
if (fd.get() == -1)
return false;
}
return true;
}
size_t GbmBuffer::GetFdCount() const {
return fds_.size();
}
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::GetSize(size_t index) const {
DCHECK_LT(index, planes_.size());
return planes_[index].size;
}
uint32_t GbmBuffer::GetFramebufferId() const {
......@@ -140,14 +105,16 @@ uint32_t GbmBuffer::GetOpaqueFramebufferId() const {
return opaque_framebuffer_ ? opaque_framebuffer_ : framebuffer_;
}
uint64_t GbmBuffer::GetFormatModifier() const {
return gbm_bo_.format_modifier();
}
uint32_t GbmBuffer::GetHandle() const {
return bo() ? gbm_bo_get_handle(bo()).u32 : 0;
return gbm_bo_.GetBoHandle();
}
// TODO(reveman): This should not be needed once crbug.com/597932 is fixed,
// as the size would be queried directly from the underlying bo.
gfx::Size GbmBuffer::GetSize() const {
return size_;
return gbm_bo_.size();
}
uint32_t GbmBuffer::GetFramebufferPixelFormat() const {
......@@ -160,10 +127,6 @@ uint32_t GbmBuffer::GetOpaqueFramebufferPixelFormat() const {
return opaque_framebuffer_pixel_format_;
}
uint64_t GbmBuffer::GetFormatModifier() const {
return format_modifier_;
}
const GbmDeviceLinux* GbmBuffer::GetGbmDeviceLinux() const {
return drm_->AsGbmDeviceLinux();
}
......@@ -174,7 +137,7 @@ bool GbmBuffer::RequiresGlFinish() const {
scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferForBO(
const scoped_refptr<GbmDevice>& gbm,
gbm_bo* bo,
struct gbm_bo* bo,
uint32_t format,
const gfx::Size& size,
uint32_t flags) {
......@@ -222,7 +185,7 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferWithModifiers(
TRACE_EVENT2("drm", "GbmBuffer::CreateBufferWithModifiers", "device",
gbm->device_path().value(), "size", size.ToString());
gbm_bo* bo =
struct gbm_bo* bo =
gbm_bo_create_with_modifiers(gbm->device(), size.width(), size.height(),
format, modifiers.data(), modifiers.size());
if (!bo)
......@@ -240,7 +203,7 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer(
TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device",
gbm->device_path().value(), "size", size.ToString());
gbm_bo* bo =
struct gbm_bo* bo =
gbm_bo_create(gbm->device(), size.width(), size.height(), format, flags);
if (!bo)
return nullptr;
......@@ -265,7 +228,7 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds(
if (!gbm_device_is_format_supported(gbm->device(), format, gbm_flags))
gbm_flags &= ~GBM_BO_USE_SCANOUT;
gbm_bo* bo = nullptr;
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();
......@@ -304,13 +267,13 @@ GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager,
gfx::NativePixmapHandle GbmPixmap::ExportHandle() {
gfx::NativePixmapHandle handle;
gfx::BufferFormat format =
ui::GetBufferFormatFromFourCCFormat(buffer_->GetFormat());
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_->GetFdCount()) {
base::ScopedFD scoped_fd(HANDLE_EINTR(dup(buffer_->GetFd(i))));
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();
......@@ -318,9 +281,10 @@ gfx::NativePixmapHandle GbmPixmap::ExportHandle() {
handle.fds.emplace_back(
base::FileDescriptor(scoped_fd.release(), true /* auto_close */));
}
handle.planes.emplace_back(buffer_->GetStride(i), buffer_->GetOffset(i),
buffer_->GetSize(i),
buffer_->GetFormatModifier());
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;
}
......@@ -329,23 +293,23 @@ GbmPixmap::~GbmPixmap() {
}
bool GbmPixmap::AreDmaBufFdsValid() const {
return buffer_->AreFdsValid();
return buffer_->gbm_bo()->AreFdsValid();
}
size_t GbmPixmap::GetDmaBufFdCount() const {
return buffer_->GetFdCount();
return buffer_->gbm_bo()->fd_count();
}
int GbmPixmap::GetDmaBufFd(size_t plane) const {
return buffer_->GetFd(plane);
return buffer_->gbm_bo()->GetFd(plane);
}
int GbmPixmap::GetDmaBufPitch(size_t plane) const {
return buffer_->GetStride(plane);
return buffer_->gbm_bo()->GetStride(plane);
}
int GbmPixmap::GetDmaBufOffset(size_t plane) const {
return buffer_->GetOffset(plane);
return buffer_->gbm_bo()->GetOffset(plane);
}
uint64_t GbmPixmap::GetDmaBufModifier(size_t plane) const {
......@@ -353,11 +317,11 @@ uint64_t GbmPixmap::GetDmaBufModifier(size_t plane) const {
}
gfx::BufferFormat GbmPixmap::GetBufferFormat() const {
return ui::GetBufferFormatFromFourCCFormat(buffer_->GetFormat());
return ui::GetBufferFormatFromFourCCFormat(buffer_->gbm_bo()->format());
}
gfx::Size GbmPixmap::GetBufferSize() const {
return buffer_->GetSize();
return buffer_->gbm_bo()->size();
}
uint32_t GbmPixmap::GetUniqueId() const {
......@@ -371,7 +335,7 @@ bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) {
DCHECK(buffer_->GetFlags() & GBM_BO_USE_SCANOUT);
DCHECK(buffer_->gbm_bo()->flags() & GBM_BO_USE_SCANOUT);
// |framebuffer_id| might be 0 if AddFramebuffer2 failed, in that case we
// already logged the error in GbmBuffer ctor. We avoid logging the error
// here since this method might be called every pageflip.
......
......@@ -7,11 +7,8 @@
#include <vector>
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/ozone/common/linux/gbm_bo_wrapper.h"
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
struct gbm_bo;
......@@ -42,32 +39,23 @@ class GbmBuffer : public ScanoutBuffer {
const gfx::Size& size,
std::vector<base::ScopedFD> fds,
const std::vector<gfx::NativePixmapPlane>& planes);
uint32_t GetFormat() const { return format_; }
uint32_t GetFlags() const { return flags_; }
bool AreFdsValid() const;
size_t GetFdCount() const;
int GetFd(size_t plane) const;
int GetStride(size_t plane) const;
int GetOffset(size_t plane) const;
size_t GetSize(size_t plane) const;
gbm_bo* bo() const { return bo_; }
const scoped_refptr<GbmDevice>& drm() const { return drm_; }
const GbmBoWrapper* gbm_bo() const { return &gbm_bo_; }
// ScanoutBuffer:
uint32_t GetFramebufferId() const override;
uint32_t GetOpaqueFramebufferId() const override;
uint32_t GetHandle() const override;
gfx::Size GetSize() const override;
uint32_t GetFramebufferPixelFormat() const override;
uint32_t GetOpaqueFramebufferPixelFormat() const override;
uint64_t GetFormatModifier() const override;
uint32_t GetHandle() const override;
gfx::Size GetSize() const override;
const GbmDeviceLinux* GetGbmDeviceLinux() const override;
bool RequiresGlFinish() const override;
private:
GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
gbm_bo* bo,
struct gbm_bo* bo,
uint32_t format,
uint32_t flags,
uint64_t modifier,
......@@ -78,13 +66,16 @@ class GbmBuffer : public ScanoutBuffer {
static scoped_refptr<GbmBuffer> CreateBufferForBO(
const scoped_refptr<GbmDevice>& gbm,
gbm_bo* bo,
struct gbm_bo* bo,
uint32_t format,
const gfx::Size& size,
uint32_t flags);
scoped_refptr<GbmDevice> drm_;
gbm_bo* bo_;
// Owned gbm_bo wrapper.
GbmBoWrapper gbm_bo_;
uint32_t framebuffer_ = 0;
uint32_t framebuffer_pixel_format_ = 0;
// If |opaque_framebuffer_pixel_format_| differs from
......@@ -92,13 +83,6 @@ class GbmBuffer : public ScanoutBuffer {
// otherwise it is set to 0.
uint32_t opaque_framebuffer_ = 0;
uint32_t opaque_framebuffer_pixel_format_ = 0;
uint64_t format_modifier_ = 0;
uint32_t format_;
uint32_t flags_;
std::vector<base::ScopedFD> fds_;
gfx::Size size_;
std::vector<gfx::NativePixmapPlane> planes_;
DISALLOW_COPY_AND_ASSIGN(GbmBuffer);
};
......
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