Commit 219fbd9c authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/vaapi: Specify the surface usage hint in vaCreateSurface()

This specifies a surface usage hint in vaCreateSurfaces(). i965 driver
doesn't change a behavior by this change. The alignment of a height of
a created surface is changed to 64 to 1 with iHD driver. Thanks to this,
the drivers' alignment rule is or equal to weaker than the minigbm
alignment rule on encoding.

Bug: 1006151
Test: VEA unittest, VDA unittest, JDA unittest
Change-Id: I4b0d0bd58c7c7f39151bc91b164b1f5aaf7c63bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1816479
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700108}
parent d687326d
......@@ -156,8 +156,9 @@ void VaapiJpegEncodeAccelerator::Encoder::EncodeWithDmaBufTask(
input_size_ = gfx::Size();
std::vector<VASurfaceID> va_surfaces;
if (!vaapi_wrapper_->CreateContextAndSurfaces(va_format, input_size, 1,
&va_surfaces)) {
if (!vaapi_wrapper_->CreateContextAndSurfaces(
va_format, input_size, VaapiWrapper::SurfaceUsageHint::kGeneric, 1,
&va_surfaces)) {
VLOGF(1) << "Failed to create VA surface";
notify_error_cb_.Run(task_id, PLATFORM_FAILURE);
return;
......@@ -308,7 +309,8 @@ void VaapiJpegEncodeAccelerator::Encoder::EncodeTask(
std::vector<VASurfaceID> va_surfaces;
if (!vaapi_wrapper_->CreateContextAndSurfaces(
VA_RT_FORMAT_YUV420, input_size, 1, &va_surfaces)) {
VA_RT_FORMAT_YUV420, input_size,
VaapiWrapper::SurfaceUsageHint::kGeneric, 1, &va_surfaces)) {
VLOGF(1) << "Failed to create VA surface";
notify_error_cb_.Run(task_id, PLATFORM_FAILURE);
return;
......
......@@ -56,7 +56,8 @@ TEST_F(VaapiUtilsTest, ScopedVAImage) {
std::vector<VASurfaceID> va_surfaces;
const gfx::Size coded_size(64, 64);
ASSERT_TRUE(vaapi_wrapper_->CreateContextAndSurfaces(
VA_RT_FORMAT_YUV420, coded_size, 1, &va_surfaces));
VA_RT_FORMAT_YUV420, coded_size, VaapiWrapper::SurfaceUsageHint::kGeneric,
1, &va_surfaces));
ASSERT_EQ(va_surfaces.size(), 1u);
std::unique_ptr<ScopedVAImage> scoped_image;
......
......@@ -700,11 +700,12 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
: pictures_.size();
CHECK_NE(requested_num_surfaces, 0u);
va_surface_ids.clear();
RETURN_AND_NOTIFY_ON_FAILURE(vaapi_wrapper_->CreateContextAndSurfaces(
va_surface_format_, requested_pic_size_,
requested_num_surfaces, &va_surface_ids),
"Failed creating VA Surfaces",
PLATFORM_FAILURE, );
RETURN_AND_NOTIFY_ON_FAILURE(
vaapi_wrapper_->CreateContextAndSurfaces(
va_surface_format_, requested_pic_size_,
VaapiWrapper::SurfaceUsageHint::kVideoDecoder,
requested_num_surfaces, &va_surface_ids),
"Failed creating VA Surfaces", PLATFORM_FAILURE, );
}
available_va_surfaces_.assign(va_surface_ids.begin(), va_surface_ids.end());
......
......@@ -68,9 +68,12 @@ class MockAcceleratedVideoDecoder : public AcceleratedVideoDecoder {
class MockVaapiWrapper : public VaapiWrapper {
public:
MockVaapiWrapper() = default;
MOCK_METHOD4(
CreateContextAndSurfaces,
bool(unsigned int, const gfx::Size&, size_t, std::vector<VASurfaceID>*));
MOCK_METHOD5(CreateContextAndSurfaces,
bool(unsigned int,
const gfx::Size&,
SurfaceUsageHint,
size_t,
std::vector<VASurfaceID>*));
MOCK_METHOD1(CreateContext, bool(const gfx::Size&));
MOCK_METHOD1(DestroyContextAndSurfaces, void(std::vector<VASurfaceID>));
......@@ -294,9 +297,11 @@ class VaapiVideoDecodeAcceleratorTest : public TestWithParam<TestParams>,
const size_t kNumReferenceFrames = 1 + num_pictures / 2;
EXPECT_CALL(
*mock_vaapi_wrapper_,
CreateContextAndSurfaces(_, picture_size, kNumReferenceFrames, _))
CreateContextAndSurfaces(
_, picture_size, VaapiWrapper::SurfaceUsageHint::kVideoDecoder,
kNumReferenceFrames, _))
.WillOnce(DoAll(
WithArg<3>(Invoke([kNumReferenceFrames](
WithArg<4>(Invoke([kNumReferenceFrames](
std::vector<VASurfaceID>* va_surface_ids) {
va_surface_ids->resize(kNumReferenceFrames);
})),
......
......@@ -369,6 +369,7 @@ void VaapiVideoEncodeAccelerator::InitializeTask(const Config& config) {
if (!vaapi_wrapper_->CreateContextAndSurfaces(
kVaSurfaceFormat, coded_size_,
VaapiWrapper::SurfaceUsageHint::kVideoEncoder,
(num_frames_in_flight + 1) * va_surfaces_per_video_frame_,
&available_va_surface_ids_)) {
NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces");
......
......@@ -1331,6 +1331,7 @@ uint32_t VaapiWrapper::BufferFormatToVARTFormat(gfx::BufferFormat fmt) {
bool VaapiWrapper::CreateContextAndSurfaces(
unsigned int va_format,
const gfx::Size& size,
SurfaceUsageHint surface_usage_hint,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces) {
DVLOG(2) << "Creating " << num_surfaces << " surfaces";
......@@ -1342,8 +1343,10 @@ bool VaapiWrapper::CreateContextAndSurfaces(
return false;
}
if (!CreateSurfaces(va_format, size, num_surfaces, va_surfaces))
if (!CreateSurfaces(va_format, size, surface_usage_hint, num_surfaces,
va_surfaces)) {
return false;
}
const bool success = CreateContext(size);
if (!success)
......@@ -2076,6 +2079,7 @@ void VaapiWrapper::DestroyContext() {
bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
const gfx::Size& size,
SurfaceUsageHint usage_hint,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces) {
DVLOG(2) << "Creating " << num_surfaces << " " << size.ToString()
......@@ -2084,13 +2088,29 @@ bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
DCHECK(va_surfaces->empty());
va_surfaces->resize(num_surfaces);
VASurfaceAttrib attribute{};
attribute.type = VASurfaceAttribUsageHint;
attribute.flags = VA_SURFACE_ATTRIB_SETTABLE;
attribute.value.type = VAGenericValueTypeInteger;
switch (usage_hint) {
case SurfaceUsageHint::kVideoDecoder:
attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER;
break;
case SurfaceUsageHint::kVideoEncoder:
attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER;
break;
case SurfaceUsageHint::kGeneric:
attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC;
break;
}
VAStatus va_res;
{
base::AutoLock auto_lock(*va_lock_);
va_res = vaCreateSurfaces(va_display_, va_format,
base::checked_cast<unsigned int>(size.width()),
base::checked_cast<unsigned int>(size.height()),
va_surfaces->data(), num_surfaces, NULL, 0);
va_res = vaCreateSurfaces(
va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
base::checked_cast<unsigned int>(size.height()), va_surfaces->data(),
num_surfaces, &attribute, 1u);
}
VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed");
return va_res == VA_STATUS_SUCCESS;
......
......@@ -94,6 +94,13 @@ class MEDIA_GPU_EXPORT VaapiWrapper
kCodecModeMax,
};
// This is enum associated with VASurfaceAttribUsageHint.
enum class SurfaceUsageHint : uint8_t {
kVideoDecoder,
kVideoEncoder,
kGeneric,
};
using InternalFormats = struct {
bool yuv420 : 1;
bool yuv422 : 1;
......@@ -189,13 +196,15 @@ class MEDIA_GPU_EXPORT VaapiWrapper
static uint32_t BufferFormatToVARTFormat(gfx::BufferFormat fmt);
// Creates |num_surfaces| VASurfaceIDs of |va_format| and |size| and, if
// successful, creates a |va_context_id_| of the same size. Returns true if
// successful, with the created IDs in |va_surfaces|. The client is
// responsible for destroying |va_surfaces| via DestroyContextAndSurfaces() to
// free the allocated surfaces.
// Creates |num_surfaces| VASurfaceIDs of |va_format|, |size| and
// |surface_usage_hint| and, if successful, creates a |va_context_id_| of the
// same size. |surface_usage_hint| may affect an alignment and tiling of the
// created surface. Returns true if successful, with the created IDs in
// |va_surfaces|. The client is responsible for destroying |va_surfaces| via
// DestroyContextAndSurfaces() to free the allocated surfaces.
virtual bool CreateContextAndSurfaces(unsigned int va_format,
const gfx::Size& size,
SurfaceUsageHint surface_usage_hint,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces);
......@@ -393,6 +402,7 @@ class MEDIA_GPU_EXPORT VaapiWrapper
// Fills |va_surfaces| and returns true if successful, or returns false.
bool CreateSurfaces(unsigned int va_format,
const gfx::Size& size,
SurfaceUsageHint usage_hint,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces);
......
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