commit 915877024e4df3364e57d4b35272449026fa9809
parent 74b4842586984af0843a100465046288ba938f5a
Author: Michael Forney <mforney@mforney.org>
Date: Wed, 28 Aug 2019 23:36:35 -0700
drm: Move framebuffer exporting code to a shared helper
This will be needed for cursor support with universal planes.
Diffstat:
3 files changed, 73 insertions(+), 64 deletions(-)
diff --git a/libswc/drm.c b/libswc/drm.c
@@ -387,3 +387,70 @@ drm_create_screens(struct wl_list *screens)
return true;
}
+
+enum {
+ WLD_USER_OBJECT_FRAMEBUFFER = WLD_USER_ID
+};
+
+struct framebuffer {
+ struct wld_exporter exporter;
+ struct wld_destructor destructor;
+ uint32_t id;
+};
+
+static bool
+framebuffer_export(struct wld_exporter *exporter, struct wld_buffer *buffer, uint32_t type, union wld_object *object)
+{
+ struct framebuffer *framebuffer = wl_container_of(exporter, framebuffer, exporter);
+
+ switch (type) {
+ case WLD_USER_OBJECT_FRAMEBUFFER:
+ object->u32 = framebuffer->id;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static void
+framebuffer_destroy(struct wld_destructor *destructor)
+{
+ struct framebuffer *framebuffer = wl_container_of(destructor, framebuffer, destructor);
+
+ drmModeRmFB(swc.drm->fd, framebuffer->id);
+ free(framebuffer);
+}
+
+uint32_t
+drm_get_framebuffer(struct wld_buffer *buffer)
+{
+ struct framebuffer *framebuffer;
+ union wld_object object;
+ int ret;
+
+ if (wld_export(buffer, WLD_USER_OBJECT_FRAMEBUFFER, &object))
+ return object.u32;
+
+ if (!wld_export(buffer, WLD_DRM_OBJECT_HANDLE, &object)) {
+ ERROR("Could not get buffer handle\n");
+ return 0;
+ }
+
+ if (!(framebuffer = malloc(sizeof(*framebuffer))))
+ return 0;
+
+ ret = drmModeAddFB(swc.drm->fd, buffer->width, buffer->height, 24, 32, buffer->pitch, object.u32, &framebuffer->id);
+ if (ret < 0) {
+ free(framebuffer);
+ return 0;
+ }
+
+ framebuffer->exporter.export = &framebuffer_export;
+ wld_buffer_add_exporter(buffer, &framebuffer->exporter);
+ framebuffer->destructor.destroy = &framebuffer_destroy;
+ wld_buffer_add_destructor(buffer, &framebuffer->destructor);
+
+ return framebuffer->id;
+}
diff --git a/libswc/drm.h b/libswc/drm.h
@@ -5,6 +5,7 @@
#include <stdint.h>
struct wl_list;
+struct wld_buffer;
struct drm_handler {
void (*page_flip)(struct drm_handler *handler, uint32_t time);
@@ -21,5 +22,6 @@ bool drm_initialize(void);
void drm_finalize(void);
bool drm_create_screens(struct wl_list *screens);
+uint32_t drm_get_framebuffer(struct wld_buffer *buffer);
#endif
diff --git a/libswc/primary_plane.c b/libswc/primary_plane.c
@@ -34,41 +34,6 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
-enum {
- WLD_USER_OBJECT_FRAMEBUFFER = WLD_USER_ID
-};
-
-struct framebuffer {
- struct wld_exporter exporter;
- struct wld_destructor destructor;
- uint32_t id;
-};
-
-static bool
-framebuffer_export(struct wld_exporter *exporter, struct wld_buffer *buffer, uint32_t type, union wld_object *object)
-{
- struct framebuffer *framebuffer = wl_container_of(exporter, framebuffer, exporter);
-
- switch (type) {
- case WLD_USER_OBJECT_FRAMEBUFFER:
- object->u32 = framebuffer->id;
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-static void
-framebuffer_destroy(struct wld_destructor *destructor)
-{
- struct framebuffer *framebuffer = wl_container_of(destructor, framebuffer, destructor);
-
- drmModeRmFB(swc.drm->fd, framebuffer->id);
- free(framebuffer);
-}
-
static bool
update(struct view *view)
{
@@ -87,37 +52,12 @@ static int
attach(struct view *view, struct wld_buffer *buffer)
{
struct primary_plane *plane = wl_container_of(view, plane, view);
- union wld_object object;
+ uint32_t fb;
int ret;
- if (!wld_export(buffer, WLD_USER_OBJECT_FRAMEBUFFER, &object)) {
- struct framebuffer *framebuffer;
-
- if (!wld_export(buffer, WLD_DRM_OBJECT_HANDLE, &object)) {
- ERROR("Could not get buffer handle\n");
- return -EINVAL;
- }
-
- if (!(framebuffer = malloc(sizeof(*framebuffer))))
- return -ENOMEM;
-
- ret = drmModeAddFB(swc.drm->fd, buffer->width, buffer->height, 24, 32, buffer->pitch, object.u32, &framebuffer->id);
-
- if (ret < 0) {
- free(framebuffer);
- return ret;
- }
-
- framebuffer->exporter.export = &framebuffer_export;
- wld_buffer_add_exporter(buffer, &framebuffer->exporter);
- framebuffer->destructor.destroy = &framebuffer_destroy;
- wld_buffer_add_destructor(buffer, &framebuffer->destructor);
-
- object.u32 = framebuffer->id;
- }
-
+ fb = drm_get_framebuffer(buffer);
if (plane->need_modeset) {
- ret = drmModeSetCrtc(swc.drm->fd, plane->crtc, object.u32, 0, 0, plane->connectors.data, plane->connectors.size / 4, &plane->mode.info);
+ ret = drmModeSetCrtc(swc.drm->fd, plane->crtc, fb, 0, 0, plane->connectors.data, plane->connectors.size / 4, &plane->mode.info);
if (ret == 0) {
wl_event_loop_add_idle(swc.event_loop, &send_frame, plane);
@@ -127,7 +67,7 @@ attach(struct view *view, struct wld_buffer *buffer)
return ret;
}
} else {
- ret = drmModePageFlip(swc.drm->fd, plane->crtc, object.u32, DRM_MODE_PAGE_FLIP_EVENT, &plane->drm_handler);
+ ret = drmModePageFlip(swc.drm->fd, plane->crtc, fb, DRM_MODE_PAGE_FLIP_EVENT, &plane->drm_handler);
if (ret < 0) {
ERROR("Page flip failed: %s\n", strerror(errno));