Skip to contentSkip to conversation

Atomic Display Framework

RFC In review Greg Hackmann 7 participants 22 messages Aug 29, 2013 – Sep 2, 2013 Framebuffer layer

lore
Share & tools
lore
#0 lore raw

cover Atomic Display Framework

Hi,

ADF is an experimental display framework that I designed after experimenting with a KMS-based hardware composer for Android. ADF started as an proof-of-concept implemented from scratch, so right now it's a separate framework rather than a patchstack on top of KMS. If there's community interest, moving forward I'd like to merge its functionality into KMS rather than keep it as a separate thing.

I'm going to talk about ADF at the Android and Graphics session at Linux Plumbers. The documentation's not done but I wanted to post these patches to people a heads-up about ADF. If there's interest I can write up some more formal documentation ahead of Plumbers.

I designed ADF to deal with some serious issues I had working with KMS:

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

4. KMS doesn't have a way to exchange sync fences. As a hack I managed to pass sync fences into the kernel as properties of the atomic pageflip, but there was no good way to get them back out of the kernel without a side channel.

ADF represents display devices as collections of overlay engines and interfaces. Overlay engines (struct adf_overlay_engine) scan out images and interfaces (struct adf_interface) display those images. Overlay engines and interfaces can be connected in any n-to-n configuration that the hardware supports.

Clients issue atomic updates to the screen by passing in a list of buffers (struct adf_buffer) consisting of dma-buf handles, sync fences, and basic metadata like format and size. If this involves composing multiple buffers, clients include a block of custom data describing the actual composition (scaling, z-order, blending, etc.) in a driver-specific format.

Drivers provide hooks to validate these custom data blocks and commit the new configuration to hardware. ADF handles importing the dma-bufs and fences, waiting on incoming sync fences before committing, advancing the display's sync timeline, and releasing dma-bufs once they're removed from the screen.

ADF represents pixel formats using DRM-style fourccs, and automatically sanity-checks buffer sizes when using one of the formats listed in drm_fourcc.h. Drivers can support custom fourccs if they provide hooks to validate buffers that use them.

ADF also provides driver hooks for modesetting, managing and reporting hardware events like vsync, and changing DPMS state. These are documented in struct adf_{obj,overlay_engine,interface,device}_ops, and are similar to the equivalent DRM ops.

Greg Hackmann (3):
video: add atomic display framework
video: adf: add display core helper
video: adf: add memblock helper

Laurent Pinchart (1):
video: Add generic display entity core

 drivers/video/Kconfig                |    2 +
 drivers/video/Makefile               |    2 +
 drivers/video/adf/Kconfig            |   15 +
 drivers/video/adf/Makefile           |   14 +
 drivers/video/adf/adf.c              | 1013 ++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf.h              |   49 ++
 drivers/video/adf/adf_client.c       |  853 ++++++++++++++++++++++++++++
 drivers/video/adf/adf_display.c      |  123 +++++
 drivers/video/adf/adf_fops.c         |  982 ++++++++++++++++++++++++++++++++
 drivers/video/adf/adf_fops.h         |   37 ++
 drivers/video/adf/adf_fops32.c       |  217 ++++++++
 drivers/video/adf/adf_fops32.h       |   78 +++
 drivers/video/adf/adf_memblock.c     |  150 +++++
 drivers/video/adf/adf_sysfs.c        |  291 ++++++++++
 drivers/video/adf/adf_sysfs.h        |   33 ++
 drivers/video/adf/adf_trace.h        |   93 ++++
 drivers/video/display/Kconfig        |    4 +
 drivers/video/display/Makefile       |    1 +
 drivers/video/display/display-core.c |  362 ++++++++++++
 include/video/adf.h                  |  743 +++++++++++++++++++++++++
 include/video/adf_client.h           |   61 ++
 include/video/adf_display.h          |   31 ++
 include/video/adf_format.h           |  282 ++++++++++
 include/video/adf_memblock.h         |   20 +
 include/video/display.h              |  150 +++++
 25 files changed, 5606 insertions(+)
 create mode 100644 drivers/video/adf/Kconfig
 create mode 100644 drivers/video/adf/Makefile
 create mode 100644 drivers/video/adf/adf.c
 create mode 100644 drivers/video/adf/adf.h
 create mode 100644 drivers/video/adf/adf_client.c
 create mode 100644 drivers/video/adf/adf_display.c
 create mode 100644 drivers/video/adf/adf_fops.c
 create mode 100644 drivers/video/adf/adf_fops.h
 create mode 100644 drivers/video/adf/adf_fops32.c
 create mode 100644 drivers/video/adf/adf_fops32.h
 create mode 100644 drivers/video/adf/adf_memblock.c
 create mode 100644 drivers/video/adf/adf_sysfs.c
 create mode 100644 drivers/video/adf/adf_sysfs.h
 create mode 100644 drivers/video/adf/adf_trace.h
 create mode 100644 drivers/video/display/Kconfig
 create mode 100644 drivers/video/display/Makefile
 create mode 100644 drivers/video/display/display-core.c
 create mode 100644 include/video/adf.h
 create mode 100644 include/video/adf_client.h
 create mode 100644 include/video/adf_display.h
 create mode 100644 include/video/adf_format.h
 create mode 100644 include/video/adf_memblock.h
 create mode 100644 include/video/display.h
Signature · 1 line
1.8.0
#1 lore raw

RFC 1/4 video: Add generic display entity core

From: Laurent Pinchart <[email protected]>

---
 drivers/video/Kconfig                |   1 +
 drivers/video/Makefile               |   1 +
 drivers/video/display/Kconfig        |   4 +
 drivers/video/display/Makefile       |   1 +
 drivers/video/display/display-core.c | 362 +++++++++++++++++++++++++++++++++++
 include/video/display.h              | 150 +++++++++++++++
 6 files changed, 519 insertions(+)
 create mode 100644 drivers/video/display/Kconfig
 create mode 100644 drivers/video/display/Makefile
 create mode 100644 drivers/video/display/display-core.c
 create mode 100644 include/video/display.h
drivers/video/Kconfig +1 -0
index 2e937bd..6d9788d 100644
@@ -2475,6 +2475,7 @@ source "drivers/video/omap2/Kconfig"
 source "drivers/video/exynos/Kconfig"
 source "drivers/video/mmp/Kconfig"
 source "drivers/video/backlight/Kconfig"
+source "drivers/video/display/Kconfig"
 
 if VT
 	source "drivers/video/console/Kconfig"
drivers/video/Makefile +1 -0
index e8bae8d..d7fd4a2 100644
@@ -15,6 +15,7 @@ fb-objs                           := $(fb-y)
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/
+obj-y				  += display/
 
 obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
 
drivers/video/display/Kconfig new file +4 -0
new file mode 100644
index 0000000..1d533e7
@@ -0,0 +1,4 @@
+menuconfig DISPLAY_CORE
+	tristate "Display Core"
+	---help---
+	  Support common display framework for graphics devices.
drivers/video/display/Makefile new file +1 -0
new file mode 100644
index 0000000..bd93496
@@ -0,0 +1 @@
+obj-$(CONFIG_DISPLAY_CORE) += display-core.o
drivers/video/display/display-core.c new file +362 -0

362 lines not on this page · raw message

include/video/display.h new file +150 -0

150 lines not on this page · raw message

Signature · 1 line
1.8.0
#2 lore raw

RFC 2/4 video: add atomic display framework

In reply to Greg Hackmann
---
 drivers/video/Kconfig          |   1 +
 drivers/video/Makefile         |   1 +
 drivers/video/adf/Kconfig      |   5 +
 drivers/video/adf/Makefile     |  10 +
 drivers/video/adf/adf.c        | 987 +++++++++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf.h        |  48 ++
 drivers/video/adf/adf_client.c | 853 +++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf_fops.c   | 982 ++++++++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf_fops.h   |  37 ++
 drivers/video/adf/adf_fops32.c | 217 +++++++++
 drivers/video/adf/adf_fops32.h |  78 ++++
 drivers/video/adf/adf_sysfs.c  | 291 ++++++++++++
 drivers/video/adf/adf_sysfs.h  |  33 ++
 drivers/video/adf/adf_trace.h  |  93 ++++
 include/video/adf.h            | 743 +++++++++++++++++++++++++++++++
 include/video/adf_client.h     |  61 +++
 include/video/adf_format.h     | 282 ++++++++++++
 17 files changed, 4722 insertions(+)
 create mode 100644 drivers/video/adf/Kconfig
 create mode 100644 drivers/video/adf/Makefile
 create mode 100644 drivers/video/adf/adf.c
 create mode 100644 drivers/video/adf/adf.h
 create mode 100644 drivers/video/adf/adf_client.c
 create mode 100644 drivers/video/adf/adf_fops.c
 create mode 100644 drivers/video/adf/adf_fops.h
 create mode 100644 drivers/video/adf/adf_fops32.c
 create mode 100644 drivers/video/adf/adf_fops32.h
 create mode 100644 drivers/video/adf/adf_sysfs.c
 create mode 100644 drivers/video/adf/adf_sysfs.h
 create mode 100644 drivers/video/adf/adf_trace.h
 create mode 100644 include/video/adf.h
 create mode 100644 include/video/adf_client.h
 create mode 100644 include/video/adf_format.h
drivers/video/Kconfig +1 -0
index 6d9788d..a77df10 100644
@@ -2476,6 +2476,7 @@ source "drivers/video/exynos/Kconfig"
 source "drivers/video/mmp/Kconfig"
 source "drivers/video/backlight/Kconfig"
 source "drivers/video/display/Kconfig"
+source "drivers/video/adf/Kconfig"
 
 if VT
 	source "drivers/video/console/Kconfig"
drivers/video/Makefile +1 -0
index d7fd4a2..aa6a247 100644
@@ -12,6 +12,7 @@ fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
                                      modedb.o fbcvt.o
 fb-objs                           := $(fb-y)
 
+obj-$(CONFIG_ADF)		  += adf/
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/
drivers/video/adf/Kconfig new file +5 -0
new file mode 100644
index 0000000..0b64408
@@ -0,0 +1,5 @@
+menuconfig ADF
+	depends on SYNC
+	depends on SW_SYNC
+	depends on DMA_SHARED_BUFFER
+	tristate "Atomic Display Framework"
drivers/video/adf/Makefile new file +10 -0
new file mode 100644
index 0000000..2af5f79
@@ -0,0 +1,10 @@
+ccflags-y := -Idrivers/staging/android -Idrivers/staging/android/sync
+
+CFLAGS_adf.o := -I$(src)
+
+obj-$(CONFIG_ADF) += adf.o \
+	adf_client.o \
+	adf_fops.o \
+	adf_sysfs.o
+
+obj-$(CONFIG_COMPAT) += adf_fops32.o
drivers/video/adf/adf.c new file +987 -0

987 lines not on this page · raw message

drivers/video/adf/adf.h new file +48 -0

48 lines not on this page · raw message

drivers/video/adf/adf_client.c new file +853 -0

853 lines not on this page · raw message

drivers/video/adf/adf_fops.c new file +982 -0

982 lines not on this page · raw message

drivers/video/adf/adf_fops.h new file +37 -0
new file mode 100644
index 0000000..2458c63
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ADF_FOPS_H
+#define __ADF_FOPS_H
+
+#include <linux/bitmap.h>
+#include <linux/fs.h>
+
+extern const struct file_operations adf_fops;
+
+struct adf_file {
+	struct list_head head;
+	struct adf_obj *obj;
+
+	DECLARE_BITMAP(event_subscriptions, ADF_EVENT_TYPE_MAX);
+	u8 event_buf[4096];
+	int event_head;
+	int event_tail;
+	wait_queue_head_t event_wait;
+};
+
+void adf_file_queue_event(struct adf_file *file, struct adf_event *event);
+long adf_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+#endif /* __ADF_FOPS_H */
drivers/video/adf/adf_fops32.c new file +217 -0

64 lines not on this page · raw message

drivers/video/adf/adf_fops32.h new file +78 -0

78 lines not on this page · raw message

drivers/video/adf/adf_sysfs.c new file +291 -0

291 lines not on this page · raw message

drivers/video/adf/adf_sysfs.h new file +33 -0
new file mode 100644
index 0000000..4272040

Lines of this file are not shown. View the raw message.

drivers/video/adf/adf_trace.h new file +93 -0

93 lines not on this page · raw message

include/video/adf.h new file +743 -0

743 lines not on this page · raw message

include/video/adf_client.h new file +61 -0

61 lines not on this page · raw message

include/video/adf_format.h new file +282 -0

282 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.8.0

Part of the diff is not shown here. View the raw message.

#3 lore raw

RFC 3/4 video: adf: add display core helper

In reply to Greg Hackmann

Optional helper which implements some ADF interface ops for displays using the Display Core framework

---
 drivers/video/adf/Kconfig       |   5 ++
 drivers/video/adf/Makefile      |   2 +
 drivers/video/adf/adf.c         |  28 ++++++++-
 drivers/video/adf/adf.h         |   1 +
 drivers/video/adf/adf_display.c | 123 ++++++++++++++++++++++++++++++++++++++++
 include/video/adf_display.h     |  31 ++++++++++
 6 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/adf/adf_display.c
 create mode 100644 include/video/adf_display.h
drivers/video/adf/Kconfig +5 -0
index 0b64408..30b0611 100644
@@ -3,3 +3,8 @@ menuconfig ADF
 	depends on SW_SYNC
 	depends on DMA_SHARED_BUFFER
 	tristate "Atomic Display Framework"
+
+menuconfig ADF_DISPLAY_CORE
+	depends on ADF
+	depends on DISPLAY_CORE
+	tristate "Helper for implementing ADF interface ops with Display Core devices"
drivers/video/adf/Makefile +2 -0
index 2af5f79..30164ee 100644
@@ -8,3 +8,5 @@ obj-$(CONFIG_ADF) += adf.o \
 	adf_sysfs.o
 
 obj-$(CONFIG_COMPAT) += adf_fops32.o
+
+obj-$(CONFIG_ADF_DISPLAY_CORE) += adf_display.o
drivers/video/adf/adf.c +27 -1
index 5dc04af..b3b57dd 100644
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2013 Google, Inc.
- * adf_modeinfo_set_name modified from drm_mode_set_name in
+ * adf_modeinfo_{set_name,set_vrefresh} modified from
  * drivers/gpu/drm/drm_modes.c
  *
  * This software is licensed under the terms of the GNU General Public
@@ -966,6 +966,32 @@ void adf_modeinfo_set_name(struct drm_mode_modeinfo *mode)
 		 interlaced ? "i" : "");
 }
 
+void adf_modeinfo_set_vrefresh(struct drm_mode_modeinfo *mode)
+{
+	int refresh = 0;
+	unsigned int calc_val;
+
+	if (mode->vrefresh > 0)
+		return;
+	else if (mode->htotal > 0 && mode->vtotal > 0) {
+		int vtotal;
+		vtotal = mode->vtotal;
+		/* work out vrefresh the value will be x1000 */
+		calc_val = (mode->clock * 1000);
+		calc_val /= mode->htotal;
+		refresh = (calc_val + vtotal / 2) / vtotal;
+
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			refresh *= 2;
+		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			refresh /= 2;
+		if (mode->vscan > 1)
+			refresh /= mode->vscan;
+
+		mode->vrefresh = refresh;
+	}
+}
+
 static void __exit adf_exit(void);
 static int __init adf_init(void)
 {
drivers/video/adf/adf.h +1 -0
index acad631..5f7260d 100644
@@ -44,5 +44,6 @@ struct adf_event_refcount *adf_obj_find_refcount(struct adf_obj *obj,
 		enum adf_event_type type);
 
 void adf_modeinfo_set_name(struct drm_mode_modeinfo *mode);
+void adf_modeinfo_set_vrefresh(struct drm_mode_modeinfo *mode);
 
 #endif /* __ADF_H */
drivers/video/adf/adf_display.c new file +123 -0

123 lines not on this page · raw message

include/video/adf_display.h new file +31 -0
new file mode 100644
index 0000000..af8cb6b
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDEO_ADF_DISPLAY_H
+#define _VIDEO_ADF_DISPLAY_H
+
+#include <video/adf.h>
+#include <video/display.h>
+#include <video/videomode.h>
+
+int adf_display_entity_screen_size(struct display_entity *display,
+		u16 *width_mm, u16 *height_mm);
+
+int adf_display_entity_notify_connected(struct adf_interface *intf,
+		struct display_entity *display);
+
+void adf_modeinfo_from_videomode(const struct videomode *vm,
+		struct drm_mode_modeinfo *dmode);
+
+#endif /* _VIDEO_ADF_DISPLAY_H */
Signature · 1 line
1.8.0
#4 lore raw

RFC 4/4 video: adf: add memblock helper

In reply to Greg Hackmann

Provides a dma-buf exporter for memblocks, mainly useful for ADF devices to wrap their bootloader logos

---
 drivers/video/adf/Kconfig        |   5 ++
 drivers/video/adf/Makefile       |   2 +
 drivers/video/adf/adf_memblock.c | 150 +++++++++++++++++++++++++++++++++++++++
 include/video/adf_memblock.h     |  20 ++++++
 4 files changed, 177 insertions(+)
 create mode 100644 drivers/video/adf/adf_memblock.c
 create mode 100644 include/video/adf_memblock.h
drivers/video/adf/Kconfig +5 -0
index 30b0611..ad0c0eb 100644
@@ -8,3 +8,8 @@ menuconfig ADF_DISPLAY_CORE
 	depends on ADF
 	depends on DISPLAY_CORE
 	tristate "Helper for implementing ADF interface ops with Display Core devices"
+
+menuconfig ADF_MEMBLOCK
+	depends on ADF
+	depends on HAVE_MEMBLOCK
+	tristate "Helper for using memblocks as buffers in ADF drivers"
drivers/video/adf/Makefile +2 -0
index 30164ee..97f9c98 100644
@@ -10,3 +10,5 @@ obj-$(CONFIG_ADF) += adf.o \
 obj-$(CONFIG_COMPAT) += adf_fops32.o
 
 obj-$(CONFIG_ADF_DISPLAY_CORE) += adf_display.o
+
+obj-$(CONFIG_ADF_MEMBLOCK) += adf_memblock.o
drivers/video/adf/adf_memblock.c new file +150 -0

150 lines not on this page · raw message

include/video/adf_memblock.h new file +20 -0
new file mode 100644
index 0000000..6256e0e
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDEO_ADF_MEMBLOCK_H_
+#define _VIDEO_ADF_MEMBLOCK_H_
+
+struct dma_buf *adf_memblock_export(phys_addr_t base, size_t size, int flags);
+
+#endif /* _VIDEO_ADF_MEMBLOCK_H_ */
Signature · 1 line
1.8.0
#5 lore raw
In reply to Greg Hackmann
Quoted 10 lines · Greg Hackmann

Hi,

ADF is an experimental display framework that I designed after experimenting with a KMS-based hardware composer for Android. ADF started as an proof-of-concept implemented from scratch, so right now it's a separate framework rather than a patchstack on top of KMS. If there's community interest, moving forward I'd like to merge its functionality into KMS rather than keep it as a separate thing.

I'm going to talk about ADF at the Android and Graphics session at Linux Plumbers. The documentation's not done but I wanted to post these patches to people a heads-up about ADF. If there's interest I can write up some more formal documentation ahead of Plumbers.

I designed ADF to deal with some serious issues I had working with KMS:

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible. I'm open to suggestions, of course, but the approach I was going for was to at least do most of the boring work for this in drm/kms core (ie. w/ the drm_{plane,crtc,etc}_state stuff)

Quoted 2 lines

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

currently you can connect a crtc to multiple encoders (at least for some hw).. I suppose w/ the small addition of having a way to specify an encoder's x/y offset, we could cover this sort of case?

Quoted 1 line

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

for custom formats, use a custom fourcc value, this should work.

err, hmm, looks like some of the error checking that was added is a bit too aggressive. What I'd propose is:

  #define DRM_FORMAT_CUSTOM 0x80000000

and then 'if (format & DRM_FORMAT_CUSTOM) ... pass through to driver ..'

Quoted 2 lines

4. KMS doesn't have a way to exchange sync fences. As a hack I managed to pass sync fences into the kernel as properties of the atomic pageflip, but there was no good way to get them back out of the kernel without a side channel.

I was going to recommend property to pass in. Or, we could possibly even just add a generic fence parameter to the pageflip/modeset ioctl, and just pass it through opaquely to the driver. I guess it should not be any harm to the upstream gpu drivers, they'd just ignore it and do same 'ol implicit synchronization.

for returning to userspace, just put the new fence value (if there is just one?) in the ioctl as an out param.

BR,
-R

Quoted 75 lines

ADF represents display devices as collections of overlay engines and interfaces. Overlay engines (struct adf_overlay_engine) scan out images and interfaces (struct adf_interface) display those images. Overlay engines and interfaces can be connected in any n-to-n configuration that the hardware supports.

Clients issue atomic updates to the screen by passing in a list of buffers (struct adf_buffer) consisting of dma-buf handles, sync fences, and basic metadata like format and size. If this involves composing multiple buffers, clients include a block of custom data describing the actual composition (scaling, z-order, blending, etc.) in a driver-specific format.

Drivers provide hooks to validate these custom data blocks and commit the new configuration to hardware. ADF handles importing the dma-bufs and fences, waiting on incoming sync fences before committing, advancing the display's sync timeline, and releasing dma-bufs once they're removed from the screen.

ADF represents pixel formats using DRM-style fourccs, and automatically sanity-checks buffer sizes when using one of the formats listed in drm_fourcc.h. Drivers can support custom fourccs if they provide hooks to validate buffers that use them.

ADF also provides driver hooks for modesetting, managing and reporting hardware events like vsync, and changing DPMS state. These are documented in struct adf_{obj,overlay_engine,interface,device}_ops, and are similar to the equivalent DRM ops.

Greg Hackmann (3):
video: add atomic display framework
video: adf: add display core helper
video: adf: add memblock helper

Laurent Pinchart (1):
video: Add generic display entity core

 drivers/video/Kconfig                |    2 +
 drivers/video/Makefile               |    2 +
 drivers/video/adf/Kconfig            |   15 +
 drivers/video/adf/Makefile           |   14 +
 drivers/video/adf/adf.c              | 1013 ++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf.h              |   49 ++
 drivers/video/adf/adf_client.c       |  853 ++++++++++++++++++++++++++++
 drivers/video/adf/adf_display.c      |  123 +++++
 drivers/video/adf/adf_fops.c         |  982 ++++++++++++++++++++++++++++++++
 drivers/video/adf/adf_fops.h         |   37 ++
 drivers/video/adf/adf_fops32.c       |  217 ++++++++
 drivers/video/adf/adf_fops32.h       |   78 +++
 drivers/video/adf/adf_memblock.c     |  150 +++++
 drivers/video/adf/adf_sysfs.c        |  291 ++++++++++
 drivers/video/adf/adf_sysfs.h        |   33 ++
 drivers/video/adf/adf_trace.h        |   93 ++++
 drivers/video/display/Kconfig        |    4 +
 drivers/video/display/Makefile       |    1 +
 drivers/video/display/display-core.c |  362 ++++++++++++
 include/video/adf.h                  |  743 +++++++++++++++++++++++++
 include/video/adf_client.h           |   61 ++
 include/video/adf_display.h          |   31 ++
 include/video/adf_format.h           |  282 ++++++++++
 include/video/adf_memblock.h         |   20 +
 include/video/display.h              |  150 +++++
 25 files changed, 5606 insertions(+)
 create mode 100644 drivers/video/adf/Kconfig
 create mode 100644 drivers/video/adf/Makefile
 create mode 100644 drivers/video/adf/adf.c
 create mode 100644 drivers/video/adf/adf.h
 create mode 100644 drivers/video/adf/adf_client.c
 create mode 100644 drivers/video/adf/adf_display.c
 create mode 100644 drivers/video/adf/adf_fops.c
 create mode 100644 drivers/video/adf/adf_fops.h
 create mode 100644 drivers/video/adf/adf_fops32.c
 create mode 100644 drivers/video/adf/adf_fops32.h
 create mode 100644 drivers/video/adf/adf_memblock.c
 create mode 100644 drivers/video/adf/adf_sysfs.c
 create mode 100644 drivers/video/adf/adf_sysfs.h
 create mode 100644 drivers/video/adf/adf_trace.h
 create mode 100644 drivers/video/display/Kconfig
 create mode 100644 drivers/video/display/Makefile
 create mode 100644 drivers/video/display/display-core.c
 create mode 100644 include/video/adf.h
 create mode 100644 include/video/adf_client.h
 create mode 100644 include/video/adf_display.h
 create mode 100644 include/video/adf_format.h
 create mode 100644 include/video/adf_memblock.h
 create mode 100644 include/video/display.h

--
1.8.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#6 lore raw
Quoted 8 lines · Rob Clark
Quoted 2 lines

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible. I'm open to suggestions, of course, but the approach I was going for was to at least do most of the boring work for this in drm/kms core (ie. w/ the drm_{plane,crtc,etc}_state stuff)

Yeah, I think Rob's design that trickle-feeds the entire state to the driver is ok (preferrably using a driver-allocated state tracking object or so). And then we'll let some helper code make this sane for most drivers.

I guess especially for pageflips a mode where we just pass in new buffers (and leave all the blending as-is) would be useful, maybe we could add a flag that says "keep all other properties as-is". A second flag for "reset properties to defaults" would also be good, where default = the primary plane can display unobstructed. So mostly just for boot splash screens, fbcon, ...

Quoted 6 lines
Quoted 2 lines

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

currently you can connect a crtc to multiple encoders (at least for some hw).. I suppose w/ the small addition of having a way to specify an encoder's x/y offset, we could cover this sort of case?

Hm, I've thought that if we convert the primary plane to a real plane we'd already have that. Then you can just place planes at x/y offset to construct the entire scanout area. Planes also have a crtc mask, as do connectors (through the encoders) so the n-to-m mapping is also possible on the output side afaics.

Quoted 10 lines
Quoted 1 line

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

for custom formats, use a custom fourcc value, this should work.

err, hmm, looks like some of the error checking that was added is a bit too aggressive. What I'd propose is:

  #define DRM_FORMAT_CUSTOM 0x80000000

and then 'if (format & DRM_FORMAT_CUSTOM) ... pass through to driver ..'

Imo we should just convert primary planes to real planes so that we can do the same table-based checking for them as we do for secondary planes right now. And then we can just ditch format_check and allow drivers to use whatever pleases them. Of course reserving a driver specific range would be good, otoh we could just add more stuff to the drm_fourcc.h header.

Cheers, Daniel

Signature · 3 lines
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
#7 lore raw
Quoted 10 lines · Daniel Vetter
Quoted 8 lines · Rob Clark
Quoted 2 lines

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible. I'm open to suggestions, of course, but the approach I was going for was to at least do most of the boring work for this in drm/kms core (ie. w/ the drm_{plane,crtc,etc}_state stuff)

Quoted 8 lines

Yeah, I think Rob's design that trickle-feeds the entire state to the driver is ok (preferrably using a driver-allocated state tracking object or so). And then we'll let some helper code make this sane for most drivers.

I guess especially for pageflips a mode where we just pass in new buffers (and leave all the blending as-is) would be useful, maybe we could add a flag that says "keep all other properties as-is".

That's the normal mode of operation as far as I'm concerned. If the user doesn't specify a prop, it retains its current value.

Also I don't generally want magic properties that flip their state in response to a change in other seemingly unrelated property. Either the user specifies a coherent state, or we return an error.

Quoted 4 lines

A second
flag for "reset properties to defaults" would also be good, where default = the primary plane can display unobstructed. So mostly just for boot splash screens, fbcon, ...

That could be useful, or we could maintain per-master state/context.

But I don't consider the planes themselves the major issue here. It's very easy for the client to disable all unneeded planes explicitly. It's all the other stuff like various methods of gamma adjustments, various other color adjustemnt thingys, possibly some blending modes, the output quantization range stuff, etc.

Quoted 7 lines
Quoted 6 lines
Quoted 2 lines

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

currently you can connect a crtc to multiple encoders (at least for some hw).. I suppose w/ the small addition of having a way to specify an encoder's x/y offset, we could cover this sort of case?

Quoted 5 lines

Hm, I've thought that if we convert the primary plane to a real plane we'd already have that. Then you can just place planes at x/y offset to construct the entire scanout area. Planes also have a crtc mask, as do connectors (through the encoders) so the n-to-m mapping is also possible on the output side afaics.

The all planes approach only works here if your drm_crtc is an abstract thing composed of multiple hardware mixers/blenders/whatever you call them.

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

for custom formats, use a custom fourcc value, this should work.

err, hmm, looks like some of the error checking that was added is a bit too aggressive. What I'd propose is:

Quoted 7 lines
Quoted 3 lines
  #define DRM_FORMAT_CUSTOM 0x80000000

and then 'if (format & DRM_FORMAT_CUSTOM) ... pass through to driver ..'

Imo we should just convert primary planes to real planes so that we can do the same table-based checking for them as we do for secondary planes right now.

My plan for i915 is to convert them to drm_planes but first keep them hidden via Rob's private plane mechanism.

After that we need to figure out how we can expose them to userspace w/o risking breaking stuff too much. Maybe a new ioctl to enumerate private planes only? And the maybe only accept direct use of private planes via the atomic API, not through the old setplane API. Or if people want to use setplane we could add a flag there indicating that the user is aware of private planes and wants to use them.

Quoted 1 line

And then we can just ditch format_check

I'd like to keep the check because it provides a small barrier against people just adding formats in driver code w/o even updating drm_fourcc.h. If we need the extra flexibility, let's add the custom bit, and then user space will know all bets are off when dealing with such formats.

Quoted 14 lines

and allow
drivers to use whatever pleases them. Of course reserving a driver specific range would be good, otoh we could just add more stuff to the drm_fourcc.h header.

Cheers, Daniel

Signature · 7 lines
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 2 lines
Ville Syrjälä
Intel OTC
#8 lore raw
Quoted 6 lines · Ville Syrjälä

After that we need to figure out how we can expose them to userspace w/o risking breaking stuff too much. Maybe a new ioctl to enumerate private planes only? And the maybe only accept direct use of private planes via the atomic API, not through the old setplane API. Or if people want to use setplane we could add a flag there indicating that the user is aware of private planes and wants to use them.

FWIW, in my yet to be published new stereo 3D series, I added a DRM_SET_CAP ioctl for userspace to tell DRM to expose some stereo bits in the mode structure.

Making it possible for the primary plane to be exposed as a drm_plane could be the second user of this ioctl (well, assuming people are fine with this new ioctl, a whole different story, but now that'd be 2 users of it).

Signature · 1 line
Damien
#9 lore raw
In reply to Ville Syrjälä
Quoted 7 lines · Ville Syrjälä
Quoted 3 lines

Imo we should just convert primary planes to real planes so that we can do the same table-based checking for them as we do for secondary planes right now.

My plan for i915 is to convert them to drm_planes but first keep them hidden via Rob's private plane mechanism.

Quoted 6 lines

After that we need to figure out how we can expose them to userspace w/o risking breaking stuff too much. Maybe a new ioctl to enumerate private planes only? And the maybe only accept direct use of private planes via the atomic API, not through the old setplane API. Or if people want to use setplane we could add a flag there indicating that the user is aware of private planes and wants to use them.

just fwiw, my thinking for private/primary[1] planes was to add a new array at the end of getplaneresources. This is really all we need. Old userspace doesn't see the new field, and continues on happily. New userspace sees the primary planes (and their possible_crtcs), and realizes that if it is not using a crtc, it can possibly grab that plane for other use.

BR,
-R

[1] I think "primary" is actually a better name, despite the fact that I initially called 'em "private"

#10 lore raw
In reply to Daniel Vetter
Quoted 29 lines · Daniel Vetter
Quoted 8 lines · Rob Clark
Quoted 2 lines

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible. I'm open to suggestions, of course, but the approach I was going for was to at least do most of the boring work for this in drm/kms core (ie. w/ the drm_{plane,crtc,etc}_state stuff)

Yeah, I think Rob's design that trickle-feeds the entire state to the driver is ok (preferrably using a driver-allocated state tracking object or so). And then we'll let some helper code make this sane for most drivers.

I guess especially for pageflips a mode where we just pass in new buffers (and leave all the blending as-is) would be useful, maybe we could add a flag that says "keep all other properties as-is". A second flag for "reset properties to defaults" would also be good, where default = the primary plane can display unobstructed. So mostly just for boot splash screens, fbcon, ...

Quoted 6 lines
Quoted 2 lines

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

currently you can connect a crtc to multiple encoders (at least for some hw).. I suppose w/ the small addition of having a way to specify an encoder's x/y offset, we could cover this sort of case?

Quoted 5 lines

Hm, I've thought that if we convert the primary plane to a real plane we'd already have that. Then you can just place planes at x/y offset to construct the entire scanout area. Planes also have a crtc mask, as do connectors (through the encoders) so the n-to-m mapping is also possible on the output side afaics.

yeah, that is probably better

Quoted 9 lines
Quoted 9 lines
Quoted 1 line

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

for custom formats, use a custom fourcc value, this should work.

err, hmm, looks like some of the error checking that was added is a bit too aggressive. What I'd propose is:

  #define DRM_FORMAT_CUSTOM 0x80000000
Quoted 8 lines
Quoted 1 line

and then 'if (format & DRM_FORMAT_CUSTOM) ... pass through to driver ..'

Imo we should just convert primary planes to real planes so that we can do the same table-based checking for them as we do for secondary planes right now. And then we can just ditch format_check and allow drivers to use whatever pleases them. Of course reserving a driver specific range would be good, otoh we could just add more stuff to the drm_fourcc.h header.

agreed. But we also have to fix the format_check() when you try to create an fb ;-)

BR,
-R

Quoted 5 lines

Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

#11 lore raw
In reply to Rob Clark
Quoted 7 lines · Rob Clark
Quoted 6 lines · Greg Hackmann

Hi,

ADF is an experimental display framework that I designed after experimenting with a KMS-based hardware composer for Android. ADF started as an proof-of-concept implemented from scratch, so right now it's a separate framework rather than a patchstack on top of KMS. If there's community interest, moving forward I'd like to merge its functionality into KMS rather than keep it as a separate thing.

I'm going to talk about ADF at the Android and Graphics session at Linux Plumbers. The documentation's not done but I wanted to post these patches to people a heads-up about ADF. If there's interest I can write up some more formal documentation ahead of Plumbers.

Quoted 8 lines
Quoted 4 lines

I designed ADF to deal with some serious issues I had working with KMS:

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible.

I guess the only reason adf is a bit different is that there can only be one custom (driver specific!) blob in the ioctl, so the driver is just free to dump that directly into whatever internal structure it uses to store the full state. So it just frees you from the per-prop state buildup process.

But if the idea would to be totally driver specific anyway, I wouldn't even bother with any of this fancy framework stuff. Just specify some massive driver specific structure with a custom ioctl and call it a day.

Quoted 3 lines

I'm open to suggestions, of course, but the approach I was going for was to at least do most of the boring work for this in drm/kms core (ie. w/ the drm_{plane,crtc,etc}_state stuff)

I'm of two minds about this. On the other hand it would be great to have the core take care of the boring stuff as you say, but on the other hand the driver most likely will duplicate a bunch of that stuff to some internal structures. So there's a slight danger of getting those two out of sync somehow.

But I guess relieving the drivers from the boring stuff wins, and we can live with the duplication. Or maybe if we get the core stuff right, we can avoid most duplication on the driver side.

Quoted 6 lines
Quoted 2 lines

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

currently you can connect a crtc to multiple encoders (at least for some hw).. I suppose w/ the small addition of having a way to specify an encoder's x/y offset, we could cover this sort of case?

Hmm. Yeah simply killing the fb->crtc link (which is definitely on my TODO list for the atomic API) isn't enough to cover this case. At first glance the x/y offset in the encoder seems like a reasonable approach to me.

But there is one other issue here, and that is how to represent the connector level. Do we have multiple active connectors for such displays, or just one? If we would go with one connector, we'd need to link multiple encoders to the same connector, which isn't possibly currently.

The other option would be to abstract the hardware a bit, and just expose one crtc to userspace, but internally build it up from multiple mixers.

Quoted 10 lines
Quoted 1 line

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

for custom formats, use a custom fourcc value, this should work.

err, hmm, looks like some of the error checking that was added is a bit too aggressive. What I'd propose is:

  #define DRM_FORMAT_CUSTOM 0x80000000

and then 'if (format & DRM_FORMAT_CUSTOM) ... pass through to driver ..'

Bit 31 is already taken :) It has to be one of the other three high bits.

The aggresive checking was added precisely to avoid people adding formats at a moments whim. We kind of blew that with the exynos NV12MT format, but then again that thing still hasn't been added to format_check() so I guess it's not _that_ important. Maybe we could "rewrite" history a bit and move that to live under the new DRM_FORMAT_CUSTOM bit as well (assuming we add such a thing).

Quoted 4 lines
Quoted 3 lines

4. KMS doesn't have a way to exchange sync fences. As a hack I managed to pass sync fences into the kernel as properties of the atomic pageflip, but there was no good way to get them back out of the kernel without a side channel.

Quoted 8 lines

I was going to recommend property to pass in. Or, we could possibly even just add a generic fence parameter to the pageflip/modeset ioctl, and just pass it through opaquely to the driver. I guess it should not be any harm to the upstream gpu drivers, they'd just ignore it and do same 'ol implicit synchronization.

for returning to userspace, just put the new fence value (if there is just one?) in the ioctl as an out param.

Or just add an array of them if we need many. My design for the atomic ioctl is already variable size, so adding one more special purpose list of things isn't that far fetched, assuming there's a good reason for it. Of course the caller has to specify the max number of things it's expecting back since it has to reserve enough space for them.

Another "multiple return values" issue I was thinking is the error reporting. It might be semi-useful to hand back per object errors. Then the user might be able to just drop those objects from the list and try again. But there are probably too many ways that things can still fail, and it's just not worth trying to iterate the config too much as that would take time, possibly leading to missed deadline.

Quoted 83 lines

BR,
-R

Quoted 68 lines

ADF represents display devices as collections of overlay engines and interfaces. Overlay engines (struct adf_overlay_engine) scan out images and interfaces (struct adf_interface) display those images. Overlay engines and interfaces can be connected in any n-to-n configuration that the hardware supports.

Clients issue atomic updates to the screen by passing in a list of buffers (struct adf_buffer) consisting of dma-buf handles, sync fences, and basic metadata like format and size. If this involves composing multiple buffers, clients include a block of custom data describing the actual composition (scaling, z-order, blending, etc.) in a driver-specific format.

Drivers provide hooks to validate these custom data blocks and commit the new configuration to hardware. ADF handles importing the dma-bufs and fences, waiting on incoming sync fences before committing, advancing the display's sync timeline, and releasing dma-bufs once they're removed from the screen.

ADF represents pixel formats using DRM-style fourccs, and automatically sanity-checks buffer sizes when using one of the formats listed in drm_fourcc.h. Drivers can support custom fourccs if they provide hooks to validate buffers that use them.

ADF also provides driver hooks for modesetting, managing and reporting hardware events like vsync, and changing DPMS state. These are documented in struct adf_{obj,overlay_engine,interface,device}_ops, and are similar to the equivalent DRM ops.

Greg Hackmann (3):
video: add atomic display framework
video: adf: add display core helper
video: adf: add memblock helper

Laurent Pinchart (1):
video: Add generic display entity core

 drivers/video/Kconfig                |    2 +
 drivers/video/Makefile               |    2 +
 drivers/video/adf/Kconfig            |   15 +
 drivers/video/adf/Makefile           |   14 +
 drivers/video/adf/adf.c              | 1013 ++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf.h              |   49 ++
 drivers/video/adf/adf_client.c       |  853 ++++++++++++++++++++++++++++
 drivers/video/adf/adf_display.c      |  123 +++++
 drivers/video/adf/adf_fops.c         |  982 ++++++++++++++++++++++++++++++++
 drivers/video/adf/adf_fops.h         |   37 ++
 drivers/video/adf/adf_fops32.c       |  217 ++++++++
 drivers/video/adf/adf_fops32.h       |   78 +++
 drivers/video/adf/adf_memblock.c     |  150 +++++
 drivers/video/adf/adf_sysfs.c        |  291 ++++++++++
 drivers/video/adf/adf_sysfs.h        |   33 ++
 drivers/video/adf/adf_trace.h        |   93 ++++
 drivers/video/display/Kconfig        |    4 +
 drivers/video/display/Makefile       |    1 +
 drivers/video/display/display-core.c |  362 ++++++++++++
 include/video/adf.h                  |  743 +++++++++++++++++++++++++
 include/video/adf_client.h           |   61 ++
 include/video/adf_display.h          |   31 ++
 include/video/adf_format.h           |  282 ++++++++++
 include/video/adf_memblock.h         |   20 +
 include/video/display.h              |  150 +++++
 25 files changed, 5606 insertions(+)
 create mode 100644 drivers/video/adf/Kconfig
 create mode 100644 drivers/video/adf/Makefile
 create mode 100644 drivers/video/adf/adf.c
 create mode 100644 drivers/video/adf/adf.h
 create mode 100644 drivers/video/adf/adf_client.c
 create mode 100644 drivers/video/adf/adf_display.c
 create mode 100644 drivers/video/adf/adf_fops.c
 create mode 100644 drivers/video/adf/adf_fops.h
 create mode 100644 drivers/video/adf/adf_fops32.c
 create mode 100644 drivers/video/adf/adf_fops32.h
 create mode 100644 drivers/video/adf/adf_memblock.c
 create mode 100644 drivers/video/adf/adf_sysfs.c
 create mode 100644 drivers/video/adf/adf_sysfs.h
 create mode 100644 drivers/video/adf/adf_trace.h
 create mode 100644 drivers/video/display/Kconfig
 create mode 100644 drivers/video/display/Makefile
 create mode 100644 drivers/video/display/display-core.c
 create mode 100644 include/video/adf.h
 create mode 100644 include/video/adf_client.h
 create mode 100644 include/video/adf_display.h
 create mode 100644 include/video/adf_format.h
 create mode 100644 include/video/adf_memblock.h
 create mode 100644 include/video/display.h
Quoted 7 lines

--
1.8.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Signature · 2 lines
Ville Syrjälä
Intel OTC
#12 lore raw
Quoted 32 lines · Ville Syrjälä
Quoted 7 lines · Rob Clark
Quoted 6 lines · Greg Hackmann

Hi,

ADF is an experimental display framework that I designed after experimenting with a KMS-based hardware composer for Android. ADF started as an proof-of-concept implemented from scratch, so right now it's a separate framework rather than a patchstack on top of KMS. If there's community interest, moving forward I'd like to merge its functionality into KMS rather than keep it as a separate thing.

I'm going to talk about ADF at the Android and Graphics session at Linux Plumbers. The documentation's not done but I wanted to post these patches to people a heads-up about ADF. If there's interest I can write up some more formal documentation ahead of Plumbers.

Quoted 8 lines
Quoted 4 lines

I designed ADF to deal with some serious issues I had working with KMS:

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible.

I guess the only reason adf is a bit different is that there can only be one custom (driver specific!) blob in the ioctl, so the driver is just free to dump that directly into whatever internal structure it uses to store the full state. So it just frees you from the per-prop state buildup process.

But if the idea would to be totally driver specific anyway, I wouldn't even bother with any of this fancy framework stuff. Just specify some massive driver specific structure with a custom ioctl and call it a day.

Quoted 3 lines

I'm open to suggestions, of course, but the approach I was going for was to at least do most of the boring work for this in drm/kms core (ie. w/ the drm_{plane,crtc,etc}_state stuff)

Quoted 5 lines

I'm of two minds about this. On the other hand it would be great to have the core take care of the boring stuff as you say, but on the other hand the driver most likely will duplicate a bunch of that stuff to some internal structures. So there's a slight danger of getting those two out of sync somehow.

re: duplicating a bunch of stuff.. I suppose we could make the state objects opaque (void *), and split everything in core that deals with 'em into helpers. That seems a bit like overkill (ie. would only make sense if there was some hw that *only* needed the driver specific derived parameters), but someone speak up if they have hw like this and I can try to make all the core state tracker stuff just helpers instead.

as far as getting out of sync, it should only happen if there is a driver bug (which should be fixed) or if the validate step fails (in which case the new state is thrown away anyway)

Quoted 16 lines

But I guess relieving the drivers from the boring stuff wins, and we can live with the duplication. Or maybe if we get the core stuff right, we can avoid most duplication on the driver side.

Quoted 6 lines
Quoted 2 lines

2. Some SoCs don't map well to KMS's CRTC + planes + encoders + connector model. At the time I was dealing with hardware where the blending engines didn't have their own framebuffer (they could only scan out constant colors or mix the output of other blocks), and you needed to gang several mixers together to drive high-res displays.

currently you can connect a crtc to multiple encoders (at least for some hw).. I suppose w/ the small addition of having a way to specify an encoder's x/y offset, we could cover this sort of case?

Hmm. Yeah simply killing the fb->crtc link (which is definitely on my TODO list for the atomic API) isn't enough to cover this case. At first glance the x/y offset in the encoder seems like a reasonable approach to me.

Quoted 5 lines

But there is one other issue here, and that is how to represent the connector level. Do we have multiple active connectors for such displays, or just one? If we would go with one connector, we'd need to link multiple encoders to the same connector, which isn't possibly currently.

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

Quoted 8 lines

The other option would be to abstract the hardware a bit, and just expose one crtc to userspace, but internally build it up from multiple mixers.

Quoted 4 lines
Quoted 1 line

3. KMS doesn't support custom pixel formats, which a lot of newer SoCs use internally to cut down on bandwidth between hardware blocks.

for custom formats, use a custom fourcc value, this should work.

Quoted 8 lines
Quoted 6 lines

err, hmm, looks like some of the error checking that was added is a bit too aggressive. What I'd propose is:

  #define DRM_FORMAT_CUSTOM 0x80000000

and then 'if (format & DRM_FORMAT_CUSTOM) ... pass through to driver ..'

Bit 31 is already taken :) It has to be one of the other three high bits.

oh, right, missed that.. ok, then 0x00800000 ;-)

Quoted 7 lines

The aggresive checking was added precisely to avoid people adding formats at a moments whim. We kind of blew that with the exynos NV12MT format, but then again that thing still hasn't been added to format_check() so I guess it's not _that_ important. Maybe we could "rewrite" history a bit and move that to live under the new DRM_FORMAT_CUSTOM bit as well (assuming we add such a thing).

perhaps even dev->driver->validate_custom_format() could be useful?

we probably do want to keep an eye on custom formats that are added to make sure they are really actually custom.. but either way, we do want to allow for custom tiled and/or compressed formats.

Quoted 10 lines
Quoted 10 lines
Quoted 3 lines

4. KMS doesn't have a way to exchange sync fences. As a hack I managed to pass sync fences into the kernel as properties of the atomic pageflip, but there was no good way to get them back out of the kernel without a side channel.

I was going to recommend property to pass in. Or, we could possibly even just add a generic fence parameter to the pageflip/modeset ioctl, and just pass it through opaquely to the driver. I guess it should not be any harm to the upstream gpu drivers, they'd just ignore it and do same 'ol implicit synchronization.

Quoted 8 lines
Quoted 2 lines

for returning to userspace, just put the new fence value (if there is just one?) in the ioctl as an out param.

Or just add an array of them if we need many. My design for the atomic ioctl is already variable size, so adding one more special purpose list of things isn't that far fetched, assuming there's a good reason for it. Of course the caller has to specify the max number of things it's expecting back since it has to reserve enough space for them.

I wasn't completely sure if it was one fence, or N fences. Either way, drm core doesn't really need to know what they are, just that it should pass 'em through to the driver. So if it helps align android and upstream, I'm ok with adding something.

Quoted 7 lines

Another "multiple return values" issue I was thinking is the error reporting. It might be semi-useful to hand back per object errors. Then the user might be able to just drop those objects from the list and try again. But there are probably too many ways that things can still fail, and it's just not worth trying to iterate the config too much as that would take time, possibly leading to missed deadline.

yeah.. maybe not worth it on the page flip due to the time constraint. At least for mode set, it would be worthwhile to try to explain to userspace why it failed. (Ie. think 3x display on ivb sort of scenario where you have inter-dependencies between modes.) I'm ok to punt on this for v1 though. The nice thing about how drm_ioctl() works, if some care is taken we can actually extend ioctls rather than having to add a new ioctl.

BR,
-R

Quoted 87 lines
Quoted 75 lines

BR,
-R

Quoted 71 lines

ADF represents display devices as collections of overlay engines and interfaces. Overlay engines (struct adf_overlay_engine) scan out images and interfaces (struct adf_interface) display those images. Overlay engines and interfaces can be connected in any n-to-n configuration that the hardware supports.

Clients issue atomic updates to the screen by passing in a list of buffers (struct adf_buffer) consisting of dma-buf handles, sync fences, and basic metadata like format and size. If this involves composing multiple buffers, clients include a block of custom data describing the actual composition (scaling, z-order, blending, etc.) in a driver-specific format.

Drivers provide hooks to validate these custom data blocks and commit the new configuration to hardware. ADF handles importing the dma-bufs and fences, waiting on incoming sync fences before committing, advancing the display's sync timeline, and releasing dma-bufs once they're removed from the screen.

ADF represents pixel formats using DRM-style fourccs, and automatically sanity-checks buffer sizes when using one of the formats listed in drm_fourcc.h. Drivers can support custom fourccs if they provide hooks to validate buffers that use them.

ADF also provides driver hooks for modesetting, managing and reporting hardware events like vsync, and changing DPMS state. These are documented in struct adf_{obj,overlay_engine,interface,device}_ops, and are similar to the equivalent DRM ops.

Greg Hackmann (3):
video: add atomic display framework
video: adf: add display core helper
video: adf: add memblock helper

Laurent Pinchart (1):
video: Add generic display entity core

 drivers/video/Kconfig                |    2 +
 drivers/video/Makefile               |    2 +
 drivers/video/adf/Kconfig            |   15 +
 drivers/video/adf/Makefile           |   14 +
 drivers/video/adf/adf.c              | 1013 ++++++++++++++++++++++++++++++++++
 drivers/video/adf/adf.h              |   49 ++
 drivers/video/adf/adf_client.c       |  853 ++++++++++++++++++++++++++++
 drivers/video/adf/adf_display.c      |  123 +++++
 drivers/video/adf/adf_fops.c         |  982 ++++++++++++++++++++++++++++++++
 drivers/video/adf/adf_fops.h         |   37 ++
 drivers/video/adf/adf_fops32.c       |  217 ++++++++
 drivers/video/adf/adf_fops32.h       |   78 +++
 drivers/video/adf/adf_memblock.c     |  150 +++++
 drivers/video/adf/adf_sysfs.c        |  291 ++++++++++
 drivers/video/adf/adf_sysfs.h        |   33 ++
 drivers/video/adf/adf_trace.h        |   93 ++++
 drivers/video/display/Kconfig        |    4 +
 drivers/video/display/Makefile       |    1 +
 drivers/video/display/display-core.c |  362 ++++++++++++
 include/video/adf.h                  |  743 +++++++++++++++++++++++++
 include/video/adf_client.h           |   61 ++
 include/video/adf_display.h          |   31 ++
 include/video/adf_format.h           |  282 ++++++++++
 include/video/adf_memblock.h         |   20 +
 include/video/display.h              |  150 +++++
 25 files changed, 5606 insertions(+)
 create mode 100644 drivers/video/adf/Kconfig
 create mode 100644 drivers/video/adf/Makefile
 create mode 100644 drivers/video/adf/adf.c
 create mode 100644 drivers/video/adf/adf.h
 create mode 100644 drivers/video/adf/adf_client.c
 create mode 100644 drivers/video/adf/adf_display.c
 create mode 100644 drivers/video/adf/adf_fops.c
 create mode 100644 drivers/video/adf/adf_fops.h
 create mode 100644 drivers/video/adf/adf_fops32.c
 create mode 100644 drivers/video/adf/adf_fops32.h
 create mode 100644 drivers/video/adf/adf_memblock.c
 create mode 100644 drivers/video/adf/adf_sysfs.c
 create mode 100644 drivers/video/adf/adf_sysfs.h
 create mode 100644 drivers/video/adf/adf_trace.h
 create mode 100644 drivers/video/display/Kconfig
 create mode 100644 drivers/video/display/Makefile
 create mode 100644 drivers/video/display/display-core.c
 create mode 100644 include/video/adf.h
 create mode 100644 include/video/adf_client.h
 create mode 100644 include/video/adf_display.h
 create mode 100644 include/video/adf_format.h
 create mode 100644 include/video/adf_memblock.h
 create mode 100644 include/video/display.h

--
1.8.0

Quoted 8 lines
Quoted 4 lines

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

--
Ville Syrjälä
Intel OTC

#13 lore raw
Quoted 7 lines · Rob Clark

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

I don't have the hardware anymore so this is all working from memory, it didn't look like two independent displays. You had to explicitly set up connections between the two mixers to deal with things like scaled overlays that spanned both mixers (there was some in-hardware magic to make sure there wasn't a visible seam where the two mixers met).

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#14 lore raw
Quoted 11 lines · Greg Hackmann
Quoted 8 lines · Rob Clark

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

Quoted 5 lines

I don't have the hardware anymore so this is all working from memory, it didn't look like two independent displays. You had to explicitly set up connections between the two mixers to deal with things like scaled overlays that spanned both mixers (there was some in-hardware magic to make sure there wasn't a visible seam where the two mixers met).

Ok, sounds like mixer == crtc (ie. the thing the combines one or more planes)? So it sounds maybe a bit like:

 plane0_0 -\
    ...    +---> CRTC -\
 plane0_n -/           |
                       +--> encoder -> connector
 plane1_0 -\           |
    ...    +---> CRTC -/

plane1_n -/

?

BR,
-R

#15 lore raw
Quoted 21 lines · Rob Clark
Quoted 11 lines · Greg Hackmann
Quoted 8 lines · Rob Clark

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

Quoted 5 lines

I don't have the hardware anymore so this is all working from memory, it didn't look like two independent displays. You had to explicitly set up connections between the two mixers to deal with things like scaled overlays that spanned both mixers (there was some in-hardware magic to make sure there wasn't a visible seam where the two mixers met).

Ok, sounds like mixer == crtc (ie. the thing the combines one or more planes)? So it sounds maybe a bit like:

Quoted 7 lines
 plane0_0 -\
    ...    +---> CRTC -\
 plane0_n -/           |
                       +--> encoder -> connector
 plane1_0 -\           |
    ...    +---> CRTC -/

plane1_n -/

So I wonder if we should just add the x,y,w,h output parameters to crtc. That could also be used to specify borders in the normal one crtc per encoder case. Although the border color is then a bit a question mark. Supposedly the crtc can have its own background color, but i guess the border color need not match that necessarily. So maybe add an encoder bg color property too (or maybe just slap it to the connector since we don't currently have encoder properties).

Another related thing I really want to expose is the crtc input size (ie. the coordinate space that the planes' output coordinates live in). That way the user will get explicit control over the scaler in the crtc (panel fitter in i915 lingo).

Signature · 2 lines
Ville Syrjälä
Intel OTC
#16 lore raw
In reply to Rob Clark
Quoted 21 lines · Rob Clark
Quoted 11 lines · Greg Hackmann
Quoted 8 lines · Rob Clark

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

Quoted 5 lines

I don't have the hardware anymore so this is all working from memory, it didn't look like two independent displays. You had to explicitly set up connections between the two mixers to deal with things like scaled overlays that spanned both mixers (there was some in-hardware magic to make sure there wasn't a visible seam where the two mixers met).

Ok, sounds like mixer == crtc (ie. the thing the combines one or more planes)? So it sounds maybe a bit like:

Quoted 7 lines
 plane0_0 -\
    ...    +---> CRTC -\
 plane0_n -/           |
                       +--> encoder -> connector
 plane1_0 -\           |
    ...    +---> CRTC -/

plane1_n -/

More than one crtc to the same encoder feels funny. Can't we just keep this mixer thing internal to the kms driver by making the failure conditions a bit more obtuse to userspace? Either way we need highly special userspace to get this thing going, since a generic modesetting driver probably can't figure out that it needs to split up the logical framebuffer into smaller planes to be able to actually shovel all the pixels to the screen. Thus far the assumption we've backed into all dumb kms drivers is that the crtc/plane limit is also the limit for the maximum output resolution ...

Could we have a notch more details on how this is exactly wired up?

Another approach would be a set of encoders for each part of the display and some metadata (like left/right-of, ...) so that userspace understands how the aggregate display is stitched togeter.

Cheers, Daniel

Signature · 3 lines
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
#17 lore raw
Quoted 30 lines · Daniel Vetter
Quoted 21 lines · Rob Clark
Quoted 11 lines · Greg Hackmann
Quoted 8 lines · Rob Clark

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

Quoted 5 lines

I don't have the hardware anymore so this is all working from memory, it didn't look like two independent displays. You had to explicitly set up connections between the two mixers to deal with things like scaled overlays that spanned both mixers (there was some in-hardware magic to make sure there wasn't a visible seam where the two mixers met).

Ok, sounds like mixer == crtc (ie. the thing the combines one or more planes)? So it sounds maybe a bit like:

Quoted 7 lines
 plane0_0 -\
    ...    +---> CRTC -\
 plane0_n -/           |
                       +--> encoder -> connector
 plane1_0 -\           |
    ...    +---> CRTC -/

plane1_n -/

Quoted 3 lines

More than one crtc to the same encoder feels funny. Can't we just keep this mixer thing internal to the kms driver by making the failure conditions a bit more obtuse to userspace?

If there is not also a case where you'd want userspace to be able to use the two CRTC's independently, then I guess we can hide it in kernel. Otherwise, it seems that would get a bit awkward.

Quoted 7 lines

Either way we need highly
special userspace to get this thing going, since a generic modesetting driver probably can't figure out that it needs to split up the logical framebuffer into smaller planes to be able to actually shovel all the pixels to the screen. Thus far the assumption we've backed into all dumb kms drivers is that the crtc/plane limit is also the limit for the maximum output resolution ...

Yeah, that is the case today. But seems like we should be able to expose crtc/plane limits so that userspace can figure it out in a generic way.

Note that nothing actually has to split up fb's, but just setup planes to scanout a single fb at the appropriate x/y offsets.

Quoted 5 lines

Could we have a notch more details on how this is exactly wired up?

Another approach would be a set of encoders for each part of the display and some metadata (like left/right-of, ...) so that userspace understands how the aggregate display is stitched togeter.

yeah, I think understanding the hw better should help understand whether N CRTCs to one encoder, or N encoders to one connector, or ??

BR,
-R

Quoted 5 lines

Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

#18 lore raw
Quoted 54 lines · Rob Clark
Quoted 30 lines · Daniel Vetter
Quoted 21 lines · Rob Clark
Quoted 11 lines · Greg Hackmann
Quoted 8 lines · Rob Clark

I guess if you have multiple encoders + multiple connectors for the "ganging" case, then it probably just looks like 2x displays, and nothing more really needed?

I'm a bit fuzzy on what the hw looks like in this "ganging" scenario, so I'm not completely sure what the best approach is. But if we do have hw like this, then it makes sense to support it *somehow* in KMS.

Quoted 5 lines

I don't have the hardware anymore so this is all working from memory, it didn't look like two independent displays. You had to explicitly set up connections between the two mixers to deal with things like scaled overlays that spanned both mixers (there was some in-hardware magic to make sure there wasn't a visible seam where the two mixers met).

Ok, sounds like mixer == crtc (ie. the thing the combines one or more planes)? So it sounds maybe a bit like:

Quoted 7 lines
 plane0_0 -\
    ...    +---> CRTC -\
 plane0_n -/           |
                       +--> encoder -> connector
 plane1_0 -\           |
    ...    +---> CRTC -/

plane1_n -/

Quoted 3 lines

More than one crtc to the same encoder feels funny. Can't we just keep this mixer thing internal to the kms driver by making the failure conditions a bit more obtuse to userspace?

If there is not also a case where you'd want userspace to be able to use the two CRTC's independently, then I guess we can hide it in kernel. Otherwise, it seems that would get a bit awkward.

Quoted 7 lines

Either way we need highly
special userspace to get this thing going, since a generic modesetting driver probably can't figure out that it needs to split up the logical framebuffer into smaller planes to be able to actually shovel all the pixels to the screen. Thus far the assumption we've backed into all dumb kms drivers is that the crtc/plane limit is also the limit for the maximum output resolution ...

Yeah, that is the case today. But seems like we should be able to expose crtc/plane limits so that userspace can figure it out in a generic way.

Note that nothing actually has to split up fb's, but just setup planes to scanout a single fb at the appropriate x/y offsets.

Quoted 8 lines
Quoted 5 lines

Could we have a notch more details on how this is exactly wired up?

Another approach would be a set of encoders for each part of the display and some metadata (like left/right-of, ...) so that userspace understands how the aggregate display is stitched togeter.

yeah, I think understanding the hw better should help understand whether N CRTCs to one encoder, or N encoders to one connector, or ??

On our hardware there is basically a crossbar between the crtcs and the encoders:

     GRPH -\
           +---> CRTC -|
     OVL  -/           |
                       +--> encoder -> connector
     GRPH -\           |
           +---> CRTC -|
     OVL  -/           |
                       +--> encoder -> connector
     GRPH -\           |
           +---> CRTC -|
     OVL  -/           |
                       +--> encoder -> connector
     GRPH -\           |
           +---> CRTC -|
     OVL  -/

Encoders are hardcoded to connectors, planes (GRPH and OVL) are hardcoded to crtcs, but crtcs can be routed between encoders. There are also cases where you can gang crtcs (e.g., map multiple crtcs to a single encoder) for handling certain corner cases.

Alex

Quoted 13 lines

BR,
-R

Quoted 5 lines

Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#19 lore raw
In reply to Ville Syrjälä
Quoted 15 lines · Ville Syrjälä
Quoted 1 line · Rob Clark

On Wed, Aug 28, 2013 at 9:51 PM, Greg Hackmann <[email protected]>

Quoted 1 line · wrote:

1. The API is geared toward updating one object at a time. Android's

graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

Quoted 5 lines
Quoted 1 line

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible.

Quoted 6 lines

I guess the only reason adf is a bit different is that there can only be one custom (driver specific!) blob in the ioctl, so the driver is just free to dump that directly into whatever internal structure it uses to store the full state. So it just frees you from the per-prop state buildup process.

Right, the difference is that clients send the complete state they want rather than deltas against the current state. This means the driver doesn't have to track its current state and duplicate it at the beginning of the flip operation, which is a minor pain on hardware with a ton of knobs to twist across different hardware blocks.

Maybe the important question is whether incremental atomic updates is a use-case that clients need in practice. SurfaceFlinger tells the HW composer each frame "here's a complete description of what I want onscreen, make it so" and IIRC Weston works the same way.

I used a blob rather than property/value pairs because the composition is going to be inherently device specific anyway. Display controllers have such different features and constraints that you'd end up with each driver exposing a bunch of hardware-specific properties, and I'm not convinced that's any better than just letting the driver dictate how the requests are structured (modulo a handful of hardware-agnostic properties). I'm not strongly tied to blobs over properties but I think the former's easier on driver developers.

Quoted 5 lines

But if the idea would to be totally driver specific anyway, I wouldn't even bother with any of this fancy framework stuff. Just specify some massive driver specific structure with a custom ioctl and call it a day.

I disagree -- this is basically what vendors do today to support Android, and there's a lot of common scaffolding that could go into a framework.
The custom ioctl handlers all look reasonably close to this:

1) import dma-bufs and fences from their respective fds
2) map the buffers into the display device
3) validate the buffer sizes against their formats and width/stride/height
4) validate the requested layout doesn't violate hardware constraints
5) hand everything off to a worker that waits for the buffers' sync fences to fire
6) commit the requested layout to hardware
7) unmap and release all the buffers that just left the screen
8) advance the sync timeline

with some leeway on the ordering of (2)-(4) and (7)-(8). ADF handles all of this except for (4) and (6), which are inherently hardware-specific and delegated to driver ops.

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#20 lore raw
Quoted 31 lines · Greg Hackmann
Quoted 16 lines · Ville Syrjälä
Quoted 10 lines · Rob Clark
Quoted 6 lines · Greg Hackmann

1. The API is geared toward updating one object at a time. Android's graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

Quoted 3 lines

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible.

Quoted 5 lines

I guess the only reason adf is a bit different is that there can only be one custom (driver specific!) blob in the ioctl, so the driver is just free to dump that directly into whatever internal structure it uses to store the full state. So it just frees you from the per-prop state buildup process.

Right, the difference is that clients send the complete state they want rather than deltas against the current state. This means the driver doesn't have to track its current state and duplicate it at the beginning of the flip operation, which is a minor pain on hardware with a ton of knobs to twist across different hardware blocks.

Quoted 4 lines

Maybe the important question is whether incremental atomic updates is a use-case that clients need in practice. SurfaceFlinger tells the HW composer each frame "here's a complete description of what I want onscreen, make it so" and IIRC Weston works the same way.

weston works this way (although per-display, it handles independent displays each with their own display loop).

But X does things more independently.. although effective use of overlays is a bit difficult with X.. but at least a couple drivers for hw that does not have dedicated hw cursor do use overlays/planes to implement hw cursor.

Quoted 8 lines

I used a blob rather than property/value pairs because the composition is going to be inherently device specific anyway. Display controllers have such different features and constraints that you'd end up with each driver exposing a bunch of hardware-specific properties, and I'm not convinced that's any better than just letting the driver dictate how the requests are structured (modulo a handful of hardware-agnostic properties). I'm not strongly tied to blobs over properties but I think the former's easier on driver developers.

weston (or other upcoming wayland compositors) use kms in a relatively generic way, so you don't have a userspace component to to the driver handling the display. This gets rid of a lot of duplicate kms code, which is currently duplicated in each xf86-video-foo.

The idea w/ property based "atomic" KMS is that you would have standard properties for all the generic/core KMS fields (mode, x/y, w/h, etc). And driver custom and semi-custom properties for things that are more hw specific. Ie. if multiple different hw supports some particular feature, for example solid-fill bg color, they would align on the same property name. In userspace you could query the properties on the plane/crtc/etc to see what custom things are supported. I guess you could think of it as the display/kms equivalent to GL extensions.

There are some things which are hard to express, like upscale/downscale/bandwidth limits. So possibly we eventually need to define some userspace plugin API where some hw specific module can help make better decisions about which surfaces to assign to which planes. But I think we want to try to share as much code in common as possible.

BR,
-R

Quoted 24 lines
Quoted 5 lines

But if the idea would to be totally driver specific anyway, I wouldn't even bother with any of this fancy framework stuff. Just specify some massive driver specific structure with a custom ioctl and call it a day.

I disagree -- this is basically what vendors do today to support Android, and there's a lot of common scaffolding that could go into a framework. The custom ioctl handlers all look reasonably close to this:

1) import dma-bufs and fences from their respective fds
2) map the buffers into the display device
3) validate the buffer sizes against their formats and width/stride/height
4) validate the requested layout doesn't violate hardware constraints
5) hand everything off to a worker that waits for the buffers' sync fences to fire
6) commit the requested layout to hardware
7) unmap and release all the buffers that just left the screen
8) advance the sync timeline

with some leeway on the ordering of (2)-(4) and (7)-(8). ADF handles all of this except for (4) and (6), which are inherently hardware-specific and delegated to driver ops.

#21 lore raw
In reply to Greg Hackmann
Quoted 25 lines · Greg Hackmann
Quoted 15 lines · Ville Syrjälä
Quoted 1 line · Rob Clark

On Wed, Aug 28, 2013 at 9:51 PM, Greg Hackmann <[email protected]>

Quoted 1 line · wrote:

1. The API is geared toward updating one object at a time. Android's

graphics stack needs the entire screen updated atomically to avoid tearing, and on some SoCs to avoid wedging the display hardware. Rob Clark's atomic modeset patchset worked, but copy/update/commit design meant the driver had to keep a lot more internal state.

Quoted 5 lines
Quoted 1 line

I'm not entirely sure how to avoid that, because at least some hw we need to have the entire new-state in order to validate if it is possible.

Quoted 6 lines

I guess the only reason adf is a bit different is that there can only be one custom (driver specific!) blob in the ioctl, so the driver is just free to dump that directly into whatever internal structure it uses to store the full state. So it just frees you from the per-prop state buildup process.

Quoted 5 lines

Right, the difference is that clients send the complete state they want rather than deltas against the current state. This means the driver doesn't have to track its current state and duplicate it at the beginning of the flip operation, which is a minor pain on hardware with a ton of knobs to twist across different hardware blocks.

You could just keep around the same big blob you would expect from the client, and incrementally update it. Not a big problem in my mind.

Quoted 5 lines

Maybe the important question is whether incremental atomic updates is a use-case that clients need in practice. SurfaceFlinger tells the HW composer each frame "here's a complete description of what I want onscreen, make it so" and IIRC Weston works the same way.

Complete is a big word. There can be quite a bit of (either per plane, or per crtc) state that doesn't change all that often, like gamma ramps/luts, color adjustemnt knobs, etc. Some user space applications probably won't even care about most of that, but with your approach they're anyway forced to deal with it.

Quoted 9 lines

I used a blob rather than property/value pairs because the composition is going to be inherently device specific anyway. Display controllers have such different features and constraints that you'd end up with each driver exposing a bunch of hardware-specific properties, and I'm not convinced that's any better than just letting the driver dictate how the requests are structured (modulo a handful of hardware-agnostic properties). I'm not strongly tied to blobs over properties but I think the former's easier on driver developers.

Sure, there's a certainly stuff that's hardware specific, but I'm sure most of the properties can be abstracted reasonably well for "normal" hardware.

There are of course hardware specific restrictions on which combinations of property values are valid. I have no good solution to this problem. ATM the plan is just return EINVAL for the whole operation, or possibly allow the driver to adjust things a bit to make it work almost like the user requested. We may need some knob to select between strict and relaxed modes.

Signature · 2 lines
Ville Syrjälä
Intel OTC