Skip to content

Commit 59064a3

Browse files
committed
chromium: add patch that enables VA-API with ozone/wayland.
Not only the HWs were tested. The patch was mostly tested with Intel Gen8 and Gen9. Also, with AMD RX460. So, bear that in mind when you enable va-api. In order to have it running, one must enable VA-API and proprietary codecs in Chromium PACKAGECONFIG_pn-chromium-ozone-wayland_append = " proprietary-codecs use_vaapi".
1 parent 80256d1 commit 59064a3

File tree

3 files changed

+268
-0
lines changed

3 files changed

+268
-0
lines changed

recipes-browser/chromium/README

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ PACKAGECONFIG knobs
6767
are desirable on embedded platforms. With this packageconfig, EGL and OpenGL
6868
ES 2.x are used instead.
6969

70+
* use-vaapi: (off by default, chromium-ozone-wayland only)
71+
Enables VA-API support with Ozone/Wayland backend that allows hardware accelerated
72+
media playback on GPUs that support VA-API. Requires proprietary-codecs to be
73+
set. Otherwise, h.264 decoding is not possible.
74+
7075
Google API keys
7176
---------------
7277
Some Chromium features use Google APIs, and to access those APIs either an API

recipes-browser/chromium/chromium-ozone-wayland_87.0.4280.141.bb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ DEPENDS += "\
1010
wayland-native \
1111
"
1212

13+
SRC_URI += "\
14+
file://0001-ozone-add-va-api-support-to-wayland.patch \
15+
"
16+
17+
# Enables VA-API for Ozone/Wayland. Remember to also use proprietary codecs
18+
# (see chromium-gn.inc).
19+
PACKAGECONFIG[use-vaapi] = "use_vaapi=true,use_vaapi=false,libva"
20+
1321
GN_ARGS += "\
1422
${PACKAGECONFIG_CONFARGS} \
1523
use_ozone=true \
@@ -35,3 +43,11 @@ GN_ARGS += "use_x11=false"
3543

3644
# The chromium binary must always be started with those arguments.
3745
CHROMIUM_EXTRA_ARGS_append = " --ozone-platform=wayland"
46+
47+
addtask do_check_config before do_configure
48+
49+
python do_check_config() {
50+
if bb.utils.contains('PACKAGECONFIG', 'use-vaapi', True, False, d) and \
51+
not bb.utils.contains('PACKAGECONFIG', 'proprietary-codecs', True, False, d):
52+
bb.fatal("use-vaapi requires the proprietary-codecs option to be set")
53+
}
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
Upstream-Status: pending
2+
3+
Signed-off-by: Maksim Sisov <msisov@igalia.com>
4+
---
5+
From f7b9671c85859ef66c9c729cb15124f306bd3098 Mon Sep 17 00:00:00 2001
6+
From: Maksim Sisov <msisov@igalia.com>
7+
Date: Wed, 20 Jan 2021 09:50:22 +0200
8+
Subject: [PATCH] ozone/wayland: add VA-API support.
9+
10+
This patch ads VA-API support utilizing old VA-API path used for
11+
ChromeOS, which can be buggy on some devices (currently tested
12+
on Intel Gen8 and Gen9 with Gen8 having some minor bugs).
13+
14+
It's known that a new VA-API is being developed atm and once it's ready,
15+
we will switch to a new path, which should be more stable.
16+
17+
---
18+
media/gpu/vaapi/vaapi_picture_factory.cc | 12 ++++--
19+
.../gpu/vaapi/vaapi_picture_native_pixmap.cc | 17 +++++++-
20+
.../vaapi/vaapi_video_decode_accelerator.cc | 40 +++++++++----------
21+
media/gpu/vaapi/vaapi_wrapper.cc | 7 ++--
22+
.../wayland/gpu/gbm_pixmap_wayland.cc | 12 +++++-
23+
.../platform/wayland/gpu/gbm_pixmap_wayland.h | 3 ++
24+
6 files changed, 58 insertions(+), 33 deletions(-)
25+
26+
diff --git a/media/gpu/vaapi/vaapi_picture_factory.cc b/media/gpu/vaapi/vaapi_picture_factory.cc
27+
index 7d850cc1d1a8..6be6f2e3704d 100644
28+
--- a/media/gpu/vaapi/vaapi_picture_factory.cc
29+
+++ b/media/gpu/vaapi/vaapi_picture_factory.cc
30+
@@ -27,10 +27,10 @@ VaapiPictureFactory::VaapiPictureFactory() {
31+
std::make_pair(gl::kGLImplementationEGLGLES2,
32+
VaapiPictureFactory::kVaapiImplementationDrm));
33+
#if defined(USE_X11)
34+
- vaapi_impl_pairs_.insert(
35+
- std::make_pair(gl::kGLImplementationEGLANGLE,
36+
- VaapiPictureFactory::kVaapiImplementationAngle));
37+
if (!features::IsUsingOzonePlatform()) {
38+
+ vaapi_impl_pairs_.insert(
39+
+ std::make_pair(gl::kGLImplementationEGLANGLE,
40+
+ VaapiPictureFactory::kVaapiImplementationAngle));
41+
vaapi_impl_pairs_.insert(
42+
std::make_pair(gl::kGLImplementationDesktopGL,
43+
VaapiPictureFactory::kVaapiImplementationX11));
44+
@@ -90,8 +90,12 @@ uint32_t VaapiPictureFactory::GetGLTextureTarget() {
45+
46+
gfx::BufferFormat VaapiPictureFactory::GetBufferFormat() {
47+
#if defined(USE_OZONE)
48+
+#if defined(OS_LINUX)
49+
if (features::IsUsingOzonePlatform())
50+
- return gfx::BufferFormat::YUV_420_BIPLANAR;
51+
+ return gfx::BufferFormat::RGBX_8888;
52+
+#else
53+
+ return gfx::BufferFormat::YUV_420_BIPLANAR;
54+
+#endif
55+
#endif
56+
return gfx::BufferFormat::RGBX_8888;
57+
}
58+
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
59+
index 941f24cc5959..42975746b5fb 100644
60+
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
61+
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
62+
@@ -12,6 +12,7 @@
63+
#include "ui/gfx/native_pixmap.h"
64+
#include "ui/gl/gl_bindings.h"
65+
#include "ui/gl/gl_image_native_pixmap.h"
66+
+#include "media/gpu/macros.h"
67+
68+
namespace media {
69+
70+
@@ -40,7 +41,21 @@ VaapiPictureNativePixmap::~VaapiPictureNativePixmap() = default;
71+
bool VaapiPictureNativePixmap::DownloadFromSurface(
72+
scoped_refptr<VASurface> va_surface) {
73+
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
74+
- return vaapi_wrapper_->BlitSurface(*va_surface, *va_surface_);
75+
+ if (!vaapi_wrapper_->SyncSurface(va_surface->id())) {
76+
+ VLOGF(1) << "Cannot sync VPP input surface";
77+
+ return false;
78+
+ }
79+
+ if (!vaapi_wrapper_->BlitSurface(*va_surface, *va_surface_)) {
80+
+ VLOGF(1) << "Cannot convert decoded image into output buffer";
81+
+ return false;
82+
+ }
83+
+
84+
+ // Sync target surface since the buffer is returning to client.
85+
+ if (!vaapi_wrapper_->SyncSurface(va_surface_->id())) {
86+
+ VLOGF(1) << "Cannot sync VPP output surface";
87+
+ return false;
88+
+ }
89+
+ return true;
90+
}
91+
92+
bool VaapiPictureNativePixmap::AllowOverlay() const {
93+
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
94+
index 3772ad5859e2..8ad259827d61 100644
95+
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
96+
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
97+
@@ -183,12 +183,6 @@ bool VaapiVideoDecodeAccelerator::Initialize(const Config& config,
98+
Client* client) {
99+
DCHECK(task_runner_->BelongsToCurrentThread());
100+
101+
-#if defined(USE_X11)
102+
- // TODO(crbug/1116701): implement decode acceleration when running with Ozone.
103+
- if (features::IsUsingOzonePlatform())
104+
- return false;
105+
-#endif
106+
-
107+
if (config.is_encrypted()) {
108+
NOTREACHED() << "Encrypted streams are not supported for this VDA";
109+
return false;
110+
@@ -559,12 +553,12 @@ void VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange(
111+
requested_visible_rect_ = visible_rect;
112+
if (buffer_allocation_mode_ == BufferAllocationMode::kSuperReduced) {
113+
// Add one to the reference frames for the one being currently egressed.
114+
- requested_num_reference_frames_ = num_reference_frames + 1;
115+
+ requested_num_reference_frames_ = num_reference_frames + 4;
116+
requested_num_pics_ = num_pics - num_reference_frames;
117+
} else if (buffer_allocation_mode_ == BufferAllocationMode::kReduced) {
118+
// Add one to the reference frames for the one being currently egressed,
119+
// and an extra allocation for both |client_| and |decoder_|.
120+
- requested_num_reference_frames_ = num_reference_frames + 2;
121+
+ requested_num_reference_frames_ = num_reference_frames + 5;
122+
requested_num_pics_ = num_pics - num_reference_frames + 1;
123+
} else {
124+
requested_num_reference_frames_ = 0;
125+
@@ -1205,19 +1199,22 @@ VaapiVideoDecodeAccelerator::GetSupportedProfiles(
126+
VaapiVideoDecodeAccelerator::BufferAllocationMode
127+
VaapiVideoDecodeAccelerator::DecideBufferAllocationMode() {
128+
#if defined(USE_X11)
129+
- // The IMPORT mode is used for Android on Chrome OS, so this doesn't apply
130+
- // here.
131+
- DCHECK_NE(output_mode_, VideoDecodeAccelerator::Config::OutputMode::IMPORT);
132+
- // TODO(crbug/1116701): get video decode acceleration working with ozone.
133+
- DCHECK(!features::IsUsingOzonePlatform());
134+
- // For H.264 on older devices, another +1 is experimentally needed for
135+
- // high-to-high resolution changes.
136+
- // TODO(mcasas): Figure out why and why only H264, see crbug.com/912295 and
137+
- // http://crrev.com/c/1363807/9/media/gpu/h264_decoder.cc#1449.
138+
- if (profile_ >= H264PROFILE_MIN && profile_ <= H264PROFILE_MAX)
139+
- return BufferAllocationMode::kReduced;
140+
- return BufferAllocationMode::kSuperReduced;
141+
-#else
142+
+ if (!features::IsUsingOzonePlatform()) {
143+
+ // The IMPORT mode is used for Android on Chrome OS, so this doesn't
144+
+ // apply here.
145+
+ DCHECK_NE(output_mode_, VideoDecodeAccelerator::Config::OutputMode::IMPORT);
146+
+ // TODO(crbug/1116701): get video decode acceleration working with ozone.
147+
+ DCHECK(!features::IsUsingOzonePlatform());
148+
+ // For H.264 on older devices, another +1 is experimentally needed for
149+
+ // high-to-high resolution changes.
150+
+ // TODO(mcasas): Figure out why and why only H264, see crbug.com/912295
151+
+ // and
152+
+ // http://crrev.com/c/1363807/9/media/gpu/h264_decoder.cc#1449.
153+
+ if (profile_ >= H264PROFILE_MIN && profile_ <= H264PROFILE_MAX)
154+
+ return BufferAllocationMode::kReduced;
155+
+ return BufferAllocationMode::kSuperReduced;
156+
+ }
157+
+#endif
158+
// TODO(crbug.com/912295): Enable a better BufferAllocationMode for IMPORT
159+
// |output_mode_| as well.
160+
if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT)
161+
@@ -1252,7 +1249,6 @@ VaapiVideoDecodeAccelerator::DecideBufferAllocationMode() {
162+
// GetNumReferenceFrames() + 1. Moreover, we also request the |client_| to
163+
// allocate less than the usual |decoder_|s GetRequiredNumOfPictures().
164+
return BufferAllocationMode::kSuperReduced;
165+
-#endif
166+
}
167+
168+
bool VaapiVideoDecodeAccelerator::IsBufferAllocationModeReducedOrSuperReduced()
169+
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
170+
index 2751b144624d..a206f02c8243 100644
171+
--- a/media/gpu/vaapi/vaapi_wrapper.cc
172+
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
173+
@@ -582,8 +582,8 @@ bool VADisplayState::InitializeOnce() {
174+
175+
#if defined(USE_X11)
176+
if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE &&
177+
- implementation_type_ == VAImplementation::kIntelIHD) {
178+
- DCHECK(!features::IsUsingOzonePlatform());
179+
+ implementation_type_ == VAImplementation::kIntelIHD &&
180+
+ !features::IsUsingOzonePlatform()) {
181+
constexpr char libva_driver_impl_env[] = "LIBVA_DRIVER_NAME";
182+
// TODO(crbug/1116703) The libva intel-media driver has a known segfault in
183+
// vaPutSurface, so until this is fixed, fall back to the i965 driver. There
184+
@@ -2245,8 +2245,7 @@ void VaapiWrapper::PreSandboxInitialization() {
185+
paths[kModuleVa].push_back(std::string("libva.so.") + va_suffix);
186+
paths[kModuleVa_drm].push_back(std::string("libva-drm.so.") + va_suffix);
187+
#if defined(USE_X11)
188+
- if (!features::IsUsingOzonePlatform())
189+
- paths[kModuleVa_x11].push_back(std::string("libva-x11.so.") + va_suffix);
190+
+ paths[kModuleVa_x11].push_back(std::string("libva-x11.so.") + va_suffix);
191+
#endif
192+
193+
// InitializeStubs dlopen() VA-API libraries
194+
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
195+
index c78ca1d02aae..9435b2f4de88 100644
196+
--- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
197+
+++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
198+
@@ -16,6 +16,7 @@
199+
#include "base/strings/stringprintf.h"
200+
#include "base/trace_event/trace_event.h"
201+
#include "ui/gfx/buffer_format_util.h"
202+
+#include "ui/gfx/buffer_types.h"
203+
#include "ui/gfx/buffer_usage_util.h"
204+
#include "ui/gfx/geometry/size_conversions.h"
205+
#include "ui/gfx/linux/drm_util_linux.h"
206+
@@ -34,7 +35,9 @@ GbmPixmapWayland::GbmPixmapWayland(WaylandBufferManagerGpu* buffer_manager)
207+
buffer_id_(buffer_manager->AllocateBufferID()) {}
208+
209+
GbmPixmapWayland::~GbmPixmapWayland() {
210+
- if (gbm_bo_)
211+
+ // gfx::BufferUsage::SCANOUT_VDA_WRITE doesn't result in creation of
212+
+ // wl_buffers.
213+
+ if (gbm_bo_ && usage_ != gfx::BufferUsage::SCANOUT_VDA_WRITE)
214+
buffer_manager_->DestroyBuffer(widget_, buffer_id_);
215+
}
216+
217+
@@ -61,7 +64,12 @@ bool GbmPixmapWayland::InitializeBuffer(gfx::Size size,
218+
return false;
219+
}
220+
221+
- CreateDmabufBasedBuffer();
222+
+ usage_ = usage;
223+
+ // Do not create wl_buffers for SCANOUT_VDA_WRITE usages. These buffers are
224+
+ // only used by video decoders and are not going to be requested to be
225+
+ // attached to Wayland surfaces.
226+
+ if (usage_ != gfx::BufferUsage::SCANOUT_VDA_WRITE)
227+
+ CreateDmabufBasedBuffer();
228+
return true;
229+
}
230+
231+
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
232+
index e344054c251d..e2d2d65dbd7b 100644
233+
--- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
234+
+++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
235+
@@ -70,6 +70,9 @@ class GbmPixmapWayland : public gfx::NativePixmap {
236+
// A unique ID to identify the buffer for this pixmap.
237+
const uint32_t buffer_id_;
238+
239+
+ // Tells the usage of this pixmap.
240+
+ gfx::BufferUsage usage_ = gfx::BufferUsage::SCANOUT;
241+
+
242+
DISALLOW_COPY_AND_ASSIGN(GbmPixmapWayland);
243+
};
244+
245+
--
246+
2.25.1
247+

0 commit comments

Comments
 (0)