Add support for dma_buf import modifiers extension.
Remove the gbo_bo_get_strides_or_tiling hack, and use the dma_buf import
modifiers extension instead.
BUG=chromium:650465
TEST=null_platform_test on nyan_big doesn't fail at the beginning
Change-Id: I1c52c66ebcc98a8f8388a152d35424c99341952f
Reviewed-on: https://chromium-review.googlesource.com/391141
Commit-Ready: Haixia Shi <hshi@chromium.org>
Tested-by: Haixia Shi <hshi@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
diff --git a/bsdrm/include/bs_drm.h b/bsdrm/include/bs_drm.h
index 90626ba..f493ff1 100644
--- a/bsdrm/include/bs_drm.h
+++ b/bsdrm/include/bs_drm.h
@@ -148,6 +148,9 @@
EGLImageKHR bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
uint32_t format, int pitch, int offset);
+EGLImageKHR bs_egl_image_create_with_modifier(struct bs_egl *self, int prime_fd, int width,
+ int height, uint32_t format, int pitch, int offset,
+ uint64_t format_modifier);
EGLImageKHR bs_egl_image_create_gbm(struct bs_egl *self, struct gbm_bo *bo);
void bs_egl_image_destroy(struct bs_egl *self, EGLImageKHR *image);
bool bs_egl_image_flush_external(struct bs_egl *self, EGLImageKHR image);
diff --git a/bsdrm/src/egl.c b/bsdrm/src/egl.c
index 31a298d..9bfa1ef 100644
--- a/bsdrm/src/egl.c
+++ b/bsdrm/src/egl.c
@@ -15,6 +15,7 @@
EGLDisplay display;
EGLContext ctx;
bool use_image_flush_external;
+ bool use_dma_buf_import_modifiers;
// Names are the original gl/egl function names with the prefix chopped off.
PFNEGLCREATEIMAGEKHRPROC CreateImageKHR;
@@ -85,10 +86,7 @@
// Get any EGLConfig. We need one to create a context, but it isn't used to create any
// surfaces.
- const EGLint config_attribs[] = {
- EGL_SURFACE_TYPE, EGL_DONT_CARE,
- EGL_NONE
- };
+ const EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_DONT_CARE, EGL_NONE };
EGLConfig egl_config;
EGLint num_configs;
if (!eglChooseConfig(self->display, config_attribs, &egl_config, 1,
@@ -129,12 +127,14 @@
if (has_extension("EGL_EXT_image_flush_external", egl_extensions)) {
if (!self->ImageFlushExternal) {
bs_debug_print("WARNING", __func__, __FILE__, __LINE__,
- "EGL_EXT_image_flush_external extension is supported, but "\
- "eglGetProcAddress returned NULL.");
+ "EGL_EXT_image_flush_external extension is supported, but "
+ "eglGetProcAddress returned NULL.");
} else {
self->use_image_flush_external = true;
}
}
+ if (has_extension("EGL_EXT_image_dma_buf_import_modifiers", egl_extensions))
+ self->use_dma_buf_import_modifiers = true;
const char *gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
if (!has_extension("GL_OES_EGL_image", gl_extensions)) {
@@ -163,25 +163,36 @@
EGL_NO_SURFACE /* No default draw read */, self->ctx);
}
-EGLImageKHR bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
- uint32_t format, int pitch, int offset)
+static EGLImageKHR _bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
+ uint32_t format, int pitch, int offset,
+ uint64_t *format_modifier)
{
assert(self);
assert(self->CreateImageKHR);
assert(self->display != EGL_NO_DISPLAY);
- const EGLint khr_image_attrs[] = { EGL_DMA_BUF_PLANE0_FD_EXT,
- prime_fd,
- EGL_WIDTH,
- width,
- EGL_HEIGHT,
- height,
- EGL_LINUX_DRM_FOURCC_EXT,
- (int)format,
- EGL_DMA_BUF_PLANE0_PITCH_EXT,
- pitch,
- EGL_DMA_BUF_PLANE0_OFFSET_EXT,
- offset,
- EGL_NONE };
+ EGLint khr_image_attrs[17] = { EGL_DMA_BUF_PLANE0_FD_EXT,
+ prime_fd,
+ EGL_WIDTH,
+ width,
+ EGL_HEIGHT,
+ height,
+ EGL_LINUX_DRM_FOURCC_EXT,
+ (int)format,
+ EGL_DMA_BUF_PLANE0_PITCH_EXT,
+ pitch,
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT,
+ offset,
+ EGL_NONE };
+
+ if (self->use_dma_buf_import_modifiers) {
+ assert(format_modifier);
+ uint64_t modifier = format_modifier ? *format_modifier : 0;
+ khr_image_attrs[12] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
+ khr_image_attrs[13] = modifier & 0xfffffffful;
+ khr_image_attrs[14] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
+ khr_image_attrs[15] = modifier >> 32;
+ khr_image_attrs[16] = EGL_NONE;
+ }
EGLImageKHR image =
self->CreateImageKHR(self->display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
@@ -195,6 +206,20 @@
return image;
}
+EGLImageKHR bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
+ uint32_t format, int pitch, int offset)
+{
+ return _bs_egl_image_create(self, prime_fd, width, height, format, pitch, offset, NULL);
+}
+
+EGLImageKHR bs_egl_image_create_with_modifier(struct bs_egl *self, int prime_fd, int width,
+ int height, uint32_t format, int pitch, int offset,
+ uint64_t format_modifier)
+{
+ return _bs_egl_image_create(self, prime_fd, width, height, format, pitch, offset,
+ &format_modifier);
+}
+
EGLImageKHR bs_egl_image_create_gbm(struct bs_egl *self, struct gbm_bo *bo)
{
assert(bo);
@@ -203,8 +228,10 @@
bs_debug_error("failed to get fb for bo: %d", fd);
return EGL_NO_IMAGE_KHR;
}
- return bs_egl_image_create(self, fd, gbm_bo_get_width(bo), gbm_bo_get_height(bo),
- gbm_bo_get_format(bo), gbm_bo_get_stride_or_tiling(bo), 0 /* no offset */);
+ uint64_t modifier = self->use_dma_buf_import_modifiers ? gbm_bo_get_format_modifier(bo) : 0;
+ return bs_egl_image_create_with_modifier(
+ self, fd, gbm_bo_get_width(bo), gbm_bo_get_height(bo), gbm_bo_get_format(bo),
+ gbm_bo_get_stride(bo), 0 /* no offset */, modifier);
}
void bs_egl_image_destroy(struct bs_egl *self, EGLImageKHR *image)