goto close_1;
}
- /*
- * TODO: Size of framebuffer must be aligned to system page size before
- * it is mapped
- */
- fbdev_data->size = finfo.line_length * vinfo.yres * MAX_BUF;
-
- fbdev_data->vaddr = mmap(0, fbdev_data->size, PROT_READ|PROT_WRITE,
- MAP_SHARED, fbdev_data->fbdev_fd, 0);
- if (fbdev_data->vaddr == MAP_FAILED)
- {
- TDM_ERR("MMap framebuffer failed, errno=%d", errno);
- goto close_1;
- }
-
- memset(fbdev_data->vaddr, 0, fbdev_data->size);
-
/*
* Output framebuffer's related information
*/
goto failed;
}
+ ret = tdm_fbdev_creat_output(fbdev_data);
+ if (ret != TDM_ERROR_NONE)
+ {
+ TDM_INFO("init of output failed");
+ goto failed_2;
+ }
+
TDM_INFO("init success!");
return (tdm_backend_data*)fbdev_data;
+failed_2:
+ tdm_fbdev_destroy_output(fbdev_data);
+
failed:
if(error)
*error = ret;
tdm_error fbdev_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
tdm_error fbdev_layer_unset_buffer(tdm_layer *layer);
+/* Framebuffer moudel's internal macros, functions, structures */
+#define RETURN_VAL_IF_FAIL(cond, val) {\
+ if (!(cond)) {\
+ TDM_ERR("'%s' failed", #cond);\
+ return val;\
+ }\
+}
+
+typedef struct _tdm_fbdev_output_data tdm_fbdev_output_data;
+
typedef struct _tdm_fbdev_data
{
int fbdev_fd;
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
+ tdm_fbdev_output_data *fbdev_output;
+} tdm_fbdev_data;
+
+struct _tdm_fbdev_output_data
+{
+ tdm_fbdev_data *fbdev_data;
+
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+ uint32_t bpp;
+ size_t size;
+
+ /*
+ * Poinetr to Framebuffers's mapped memory
+ */
void *vaddr;
- size_t size;
-}tdm_fbdev_data;
+ tdm_output_mode *output_modes;
+};
+
+
+
+tdm_error tdm_fbdev_creat_output(tdm_fbdev_data *fbdev_data);
+void tdm_fbdev_destroy_output(tdm_fbdev_data *fbdev_data);
#endif /* _TDM_fbdev_H_ */
#endif
#include <tdm_helper.h>
+#include <stdint.h>
#include "tdm_fbdev.h"
+tdm_error tdm_fbdev_creat_output(tdm_fbdev_data *fbdev_data)
+{
+ tdm_fbdev_output_data *output = NULL;
+ size_t size;
+
+ output = calloc(1, sizeof(tdm_fbdev_output_data));
+ if (output == NULL)
+ {
+ TDM_ERR("alloc output failed");
+ return TDM_ERROR_OUT_OF_MEMORY;
+ }
+
+ /*
+ * TODO: Size of framebuffer must be aligned to system page size before
+ * it is mapped
+ */
+ size = fbdev_data->finfo.line_length * fbdev_data->vinfo.yres * MAX_BUF;
+
+ output->vaddr = mmap(0, size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fbdev_data->fbdev_fd, 0);
+ if (output->vaddr == MAP_FAILED)
+ {
+ TDM_ERR("MMap framebuffer failed, errno=%d", errno);
+ return TDM_ERROR_OPERATION_FAILED;
+ }
+
+ memset(output->vaddr, 0, size);
+
+ output->width = fbdev_data->vinfo.width;
+ output->height = fbdev_data->vinfo.height;
+ output->pitch = fbdev_data->finfo.line_length;
+ output->bpp = fbdev_data->vinfo.bits_per_pixel;
+ output->size = size;
+
+ output->fbdev_data = fbdev_data;
+
+ fbdev_data->fbdev_output = output;
+
+ return TDM_ERROR_NONE;
+}
+
+void tdm_fbdev_destroy_output(tdm_fbdev_data *fbdev_data)
+{
+ tdm_fbdev_output_data *fbdev_output = fbdev_data->fbdev_output;
+
+ if (fbdev_output == NULL)
+ goto close;
+
+ if (fbdev_output->vaddr == NULL)
+ goto close_2;
+
+ munmap(fbdev_output->vaddr, fbdev_output->size);
+
+close_2:
+ free(fbdev_output);
+close:
+ return;
+}
+
+
+
tdm_error
fbdev_display_get_capabilitiy(tdm_backend_data *bdata, tdm_caps_display *caps)
{
+ RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+
+ /*
+ * Framebuffer device does not support layers
+ */
+ caps->max_layer_count = 1;
+
return TDM_ERROR_NONE;
}
tdm_output**
fbdev_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
{
+ tdm_fbdev_data *fbdev_data = bdata;
+ tdm_fbdev_output_data *fbdev_output = fbdev_data->fbdev_output;
+ tdm_output **outputs;
+ tdm_error ret;
+
+ RETURN_VAL_IF_FAIL(fbdev_data, NULL);
+ RETURN_VAL_IF_FAIL(count, NULL);
+
+ if (fbdev_output == NULL)
+ {
+ ret = TDM_ERROR_NONE;
+ goto failed_get;
+ }
+
+ /*
+ * Since it is Framebuffer device there is only one output
+ */
+ *count = 1;
+
+ /* will be freed in frontend */
+ outputs = calloc(*count, sizeof(tdm_fbdev_output_data*));
+ if (!outputs)
+ {
+ TDM_ERR("failed: alloc memory");
+ *count = 0;
+ ret = TDM_ERROR_OUT_OF_MEMORY;
+ goto failed_get;
+ }
+
+ outputs[0] = fbdev_output;
+
+ if (error)
+ *error = TDM_ERROR_NONE;
+
+ return outputs;
+
+failed_get:
+ if (error)
+ *error = ret;
return NULL;
}
tdm_error
fbdev_display_get_fd(tdm_backend_data *bdata, int *fd)
{
+ RETURN_VAL_IF_FAIL(bdata, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
+
+ /*
+ * TODO: It is tricky place since we don't know how drm
+ * file descriptor is used by software above in drm backend;
+ */
+ *fd = -1;
+
return TDM_ERROR_NONE;
}
tdm_error
fbdev_display_handle_events(tdm_backend_data *bdata)
{
+ /*
+ * Framebuffer does not produce events
+ */
return TDM_ERROR_NONE;
}