minigbm: add resource_info callback for virtio-gpu

In ARC++, the wayland sevice and the video stack rely on
GRALLOC_DRM_GET_STRIDE and (*lock_ycbcr) with zero flags to return
the metadata associated with the buffer.

In the past, we've simply returned the metadata that was calculated
during allocation.

Since the current virtio-gpu API relies on shadow buffers, there's
actually two different sets of metadata:

1) The metadata of the shadow buffer --> useful for mapping
2) The metadata of the host resource --> useful for passing to Chrome

For the wayland_service and video stack, we want to return (2).
For the Android framework, we want to return (1).

BUG=b:132939420
TEST=compile

Change-Id: I1134d651396ba68e064eaf2e3cad3cb3225d7c5c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1681383
Reviewed-by: David Stevens <stevensd@chromium.org>
Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc
index 0a302b4..6c49d3a 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -4,6 +4,7 @@
  * found in the LICENSE file.
  */
 
+#include "../../util.h"
 #include "../cros_gralloc_driver.h"
 
 #include <cassert>
@@ -261,6 +262,8 @@
 	uint64_t *out_store;
 	buffer_handle_t handle;
 	uint32_t *out_width, *out_height, *out_stride;
+	uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 };
+	uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 };
 	auto mod = (struct gralloc0_module const *)module;
 
 	switch (op) {
@@ -286,7 +289,17 @@
 	switch (op) {
 	case GRALLOC_DRM_GET_STRIDE:
 		out_stride = va_arg(args, uint32_t *);
-		*out_stride = hnd->pixel_stride;
+		ret = mod->driver->resource_info(handle, strides, offsets);
+		if (ret)
+			break;
+
+		if (strides[0] != hnd->strides[0]) {
+			uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0);
+			*out_stride = DIV_ROUND_UP(strides[0], bytes_per_pixel);
+		} else {
+			*out_stride = hnd->pixel_stride;
+		}
+
 		break;
 	case GRALLOC_DRM_GET_FORMAT:
 		out_format = va_arg(args, int32_t *);
@@ -364,6 +377,8 @@
 {
 	int32_t ret;
 	uint32_t map_flags;
+	uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 };
+	uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 };
 	uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
 	auto mod = (struct gralloc0_module const *)module;
 	struct rectangle rect = { .x = static_cast<uint32_t>(l),
@@ -393,13 +408,22 @@
 	if (ret)
 		return ret;
 
+	if (!map_flags) {
+		ret = mod->driver->resource_info(handle, strides, offsets);
+		if (ret)
+			return ret;
+
+		for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++)
+			addr[plane] = static_cast<uint8_t *>(nullptr) + offsets[plane];
+	}
+
 	switch (hnd->format) {
 	case DRM_FORMAT_NV12:
 		ycbcr->y = addr[0];
 		ycbcr->cb = addr[1];
 		ycbcr->cr = addr[1] + 1;
-		ycbcr->ystride = hnd->strides[0];
-		ycbcr->cstride = hnd->strides[1];
+		ycbcr->ystride = (!map_flags) ? strides[0] : hnd->strides[0];
+		ycbcr->cstride = (!map_flags) ? strides[1] : hnd->strides[1];
 		ycbcr->chroma_step = 2;
 		break;
 	case DRM_FORMAT_YVU420:
@@ -407,8 +431,8 @@
 		ycbcr->y = addr[0];
 		ycbcr->cb = addr[2];
 		ycbcr->cr = addr[1];
-		ycbcr->ystride = hnd->strides[0];
-		ycbcr->cstride = hnd->strides[1];
+		ycbcr->ystride = (!map_flags) ? strides[0] : hnd->strides[0];
+		ycbcr->cstride = (!map_flags) ? strides[1] : hnd->strides[1];
 		ycbcr->chroma_step = 1;
 		break;
 	default: