Please note that my post is about the unaccelerated xf86-video-armsoc, unlike most of the rest of this thread. If you use the patches I have here, I have no idea if mali acceleration will work.
tl;dr: Here's a PKGBUILD for an xf86-video-armsoc that works out of the box on Chromebooks, without acceleration but at acceptable speed:
Anyone who has tried running xf86-video-armsoc-git on a Samsung Chromebook will have noticed that the performance is surprisingly much worse than with an ordinary framebuffer driver. Yet armsoc is the only way to get proper support for external displays.
It turns out, as far as I have been able to tell, that the armsoc driver attempts to set up EXA and DRI acceleration, but if it can't get EXA working it has a dummy stub for fallback. Ordinarily this wouldn't be a problem, but the fallback is implemented in such as way that for every operation EXA will get partway through setup before hitting the stub which always fails.
By getting rid of the Soft EXA (or Null EXA) "implementation" I've been able to get performance up to an acceptable level.
However this causes some other issues, DRI won't be set up without EXA, and while armsoc is intended to work without DRI there are a few operations that are unsafe if it isn't set up.
Here's a set of patches that fixes these issues. This is against tag 1.0.0.
Don't set up the stub EXA.
$this->bbcode_second_pass_code('', '
diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
index ddd650b..8f810f5 100644
--- a/src/armsoc_driver.c
+++ b/src/armsoc_driver.c
@@ -923,10 +923,6 @@ ARMSOCAccelInit(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
- if (!pARMSOC->pARMSOCEXA)
- pARMSOC->pARMSOCEXA = InitNullEXA(pScreen, pScrn,
- pARMSOC->drmFD);
-
if (pARMSOC->pARMSOCEXA)
pARMSOC->dri = ARMSOCDRI2ScreenInit(pScreen);
else
')
Fix buffer resize when DRI is not available:
$this->bbcode_second_pass_code('', '
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index f725fd5..906888b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1524,8 +1524,10 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
/* use new scanout buffer */
set_scanout_bo(pScrn, new_scanout);
- /* Resize swap chain will delete old_scanout */
- ARMSOCDRI2ResizeSwapChain(pScrn, old_scanout, new_scanout);
+ if (pARMSOC->dri) {
+ /* Resize swap chain will delete old_scanout */
+ ARMSOCDRI2ResizeSwapChain(pScrn, old_scanout, new_scanout);
+ }
}
pScrn->displayWidth = pitch / ((pScrn->bitsPerPixel + 7) / 8);
} else
')
Fix segfault when switching to a console:
$this->bbcode_second_pass_code('', '
diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
index ddd650b..f0f73ae 100644
--- a/src/armsoc_driver.c
+++ b/src/armsoc_driver.c
@@ -1317,14 +1319,17 @@ static Bool
ARMSOCEnterVT(VT_FUNC_ARGS_DECL)
{
SCRN_INFO_PTR(arg);
+ struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
int i, ret;
TRACE_ENTER();
- for (i = 1; i < currentMaxClients; i++) {
- if (clients[i])
- AttendClient(clients[i]);
- }
+ if (pARMSOC->dri) {
+ for (i = 1; i < currentMaxClients; i++) {
+ if (clients[i])
+ AttendClient(clients[i]);
+ }
+ }
ret = ARMSOCSetDRMMaster();
if (ret) {
@@ -1352,14 +1357,17 @@ static void
ARMSOCLeaveVT(VT_FUNC_ARGS_DECL)
{
SCRN_INFO_PTR(arg);
+ struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
int i, ret;
TRACE_ENTER();
- for (i = 1; i < currentMaxClients; i++) {
- if (clients[i])
- IgnoreClient(clients[i]);
- }
+ if (pARMSOC->dri) {
+ for (i = 1; i < currentMaxClients; i++) {
+ if (clients[i])
+ IgnoreClient(clients[i]);
+ }
+ }
ret = ARMSOCDropDRMMaster();
if (ret)
')
Software mode cursor, prevents performance and flickering issues when the cursor changes:
$this->bbcode_second_pass_code('', '
diff --git a/src/drmmode_exynos/drmmode_exynos.c b/src/drmmode_exynos/drmmode_exynos.c
index 5985cfd..819451a 100644
--- a/src/drmmode_exynos/drmmode_exynos.c
+++ b/src/drmmode_exynos/drmmode_exynos.c
@@ -69,49 +69,6 @@ struct drm_exynos_gem_create {
#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
-static int init_plane_for_cursor(int drm_fd, uint32_t plane_id)
-{
- int res = -1;
- drmModeObjectPropertiesPtr props;
- props = drmModeObjectGetProperties(drm_fd, plane_id,
- DRM_MODE_OBJECT_PLANE);
-
- if (props) {
- int i;
-
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr this_prop;
- this_prop = drmModeGetProperty(drm_fd, props->props[i]);
-
- if (this_prop) {
- if (!strncmp(this_prop->name, "zpos",
- DRM_PROP_NAME_LEN)) {
- res = drmModeObjectSetProperty(drm_fd,
- plane_id,
- DRM_MODE_OBJECT_PLANE,
- this_prop->prop_id,
- 1);
- drmModeFreeProperty(this_prop);
- break;
- }
- drmModeFreeProperty(this_prop);
- }
- }
- drmModeFreeObjectProperties(props);
- }
-
- if (res) {
- /* Try the old method */
- struct drm_exynos_plane_set_zpos data;
- data.plane_id = plane_id;
- data.zpos = 1;
-
- res = ioctl(drm_fd, DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS, &data);
- }
-
- return res;
-}
-
static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
{
struct drm_exynos_gem_create create_exynos;
@@ -150,8 +107,8 @@ struct drmmode_interface exynos_interface = {
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
CURSORPAD /* cursor padding */,
- HWCURSOR_API_PLANE /* cursor_api */,
- init_plane_for_cursor /* init_plane_for_cursor */,
+ HWCURSOR_API_NONE /* cursor_api */,
+ NULL /* init_plane_for_cursor */,
0 /* vblank_query_supported */,
create_custom_gem /* create_custom_gem */,
};
')
I've tested these on a Samsung Chromebook and a HP Chromebook 11 for the past day and it hasn't given me any problems yet.
I am not confident that this is going to work properly when the accelerated driver is available, which is one reason why I am not trying to officially submit this yet. But I don't know if I will have time to clean up these patches and generally do the right things, so I'm just going to leave this here. Attached (at the top) a PKGBUILD and the patches for easy application.