Compare commits
48 Commits
master
...
devs/devil
Author | SHA1 | Date |
---|---|---|
Chris Michael | 9ce8a3b4fa | |
Chris Michael | eea1f831c2 | |
Chris Michael | 50cb68dbc6 | |
Chris Michael | 1e5557469a | |
Chris Michael | 10973238e3 | |
Chris Michael | bdc4d3ebcc | |
Chris Michael | 4bbb84ceb0 | |
Chris Michael | 72af269a7a | |
Chris Michael | 677e0c0952 | |
Chris Michael | c98ac111d3 | |
Chris Michael | 382a10d7df | |
Chris Michael | bcdec3c57c | |
Chris Michael | 9b4511d6be | |
Chris Michael | 45dbff677d | |
Chris Michael | c4b7400d5a | |
Chris Michael | 06107c9720 | |
Chris Michael | 2715ce856c | |
Chris Michael | 40aff97087 | |
Chris Michael | 245a3c50a2 | |
Chris Michael | 104a43708b | |
Chris Michael | 77513e7976 | |
Chris Michael | 8bea018adc | |
Chris Michael | 36f79649e7 | |
Chris Michael | c1b625678f | |
Chris Michael | 22f2ab18ed | |
Chris Michael | 1a21ff3c13 | |
Chris Michael | 8acd29ff4a | |
Chris Michael | adfff7c05e | |
Chris Michael | 0722632c78 | |
Chris Michael | 2a4a095dbe | |
Chris Michael | 4a2425d342 | |
Chris Michael | 9c227fb56b | |
Chris Michael | 061967f67a | |
Chris Michael | ff9b8f64d3 | |
Chris Michael | e034b2a1e9 | |
Chris Michael | 135a1b8696 | |
Chris Michael | 911f253770 | |
Chris Michael | 8cbffe36c2 | |
Chris Michael | 20832a3c48 | |
Chris Michael | 10669573ac | |
Chris Michael | 8a3581f13a | |
Chris Michael | fbc7f2235c | |
Chris Michael | 1a38dc0819 | |
Chris Michael | 25927cb5c7 | |
Chris Michael | 52752072ae | |
Chris Michael | 5f9ddce261 | |
Chris Michael | e1d6cbdee9 | |
Chris Michael | a39b72c798 |
|
@ -1135,8 +1135,6 @@ endif
|
|||
if BUILD_ENGINE_DRM
|
||||
dist_installed_evasmainheaders_DATA += modules/evas/engines/drm/Evas_Engine_Drm.h
|
||||
DRM_SOURCES = \
|
||||
modules/evas/engines/drm/evas_drm.c \
|
||||
modules/evas/engines/drm/evas_bufmgr.c \
|
||||
modules/evas/engines/drm/evas_outbuf.c \
|
||||
modules/evas/engines/drm/evas_engine.c \
|
||||
modules/evas/engines/drm/evas_engine.h \
|
||||
|
|
|
@ -5,25 +5,29 @@
|
|||
# undef EAPI
|
||||
# endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifdef BUILDING_DLL
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else // ifdef BUILDING_DLL
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif // ifdef BUILDING_DLL
|
||||
#else // ifdef _MSC_VER
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else // if __GNUC__ >= 4
|
||||
# ifdef _MSC_VER
|
||||
# ifdef BUILDING_DLL
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else // ifdef BUILDING_DLL
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif // ifdef BUILDING_DLL
|
||||
# else // ifdef _MSC_VER
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else // if __GNUC__ >= 4
|
||||
# define EAPI
|
||||
# endif // if __GNUC__ >= 4
|
||||
# else // ifdef __GNUC__
|
||||
# define EAPI
|
||||
# endif // if __GNUC__ >= 4
|
||||
# else // ifdef __GNUC__
|
||||
# define EAPI
|
||||
# endif // ifdef __GNUC__
|
||||
#endif // ifdef _MSC_VER
|
||||
# endif // ifdef __GNUC__
|
||||
# endif // ifdef _MSC_VER
|
||||
|
||||
#include <Ecore.h>
|
||||
# include <xf86drm.h>
|
||||
# include <xf86drmMode.h>
|
||||
# include <drm_fourcc.h>
|
||||
# include <Ecore.h>
|
||||
# include <Eeze.h>
|
||||
|
||||
typedef enum _Ecore_Drm_Evdev_Capabilities
|
||||
{
|
||||
|
@ -61,6 +65,7 @@ typedef struct _Ecore_Drm_Fb
|
|||
unsigned int stride, size;
|
||||
int fd;
|
||||
void *mmap;
|
||||
int w, h;
|
||||
} Ecore_Drm_Fb;
|
||||
|
||||
struct _Ecore_Drm_Device
|
||||
|
@ -109,6 +114,16 @@ struct _Ecore_Drm_Device
|
|||
struct xkb_context *xkb_ctx;
|
||||
|
||||
unsigned int window;
|
||||
|
||||
Eeze_Udev_Watch *watch;
|
||||
|
||||
int current_fb;
|
||||
Ecore_Drm_Fb *current, *next;
|
||||
Ecore_Drm_Fb *dumb[2];
|
||||
|
||||
drmEventContext drm_ctx;
|
||||
|
||||
Eina_Bool active : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Drm_Event_Activate
|
||||
|
@ -158,6 +173,9 @@ typedef struct _Ecore_Drm_Event_Activate Ecore_Drm_Event_Activate;
|
|||
/** @since 1.14 */
|
||||
typedef struct _Ecore_Drm_Event_Output Ecore_Drm_Event_Output;
|
||||
|
||||
/** @since 1.14 */
|
||||
typedef void (*Ecore_Drm_Pageflip_Cb)(void *data);
|
||||
|
||||
EAPI extern int ECORE_DRM_EVENT_ACTIVATE;
|
||||
|
||||
EAPI extern int ECORE_DRM_EVENT_OUTPUT; /**< @since 1.14 */
|
||||
|
@ -179,42 +197,360 @@ EAPI extern int ECORE_DRM_EVENT_SEAT_ADD; /**< @since 1.14 */
|
|||
* @li @ref Ecore_Drm_Output_Group
|
||||
* @li @ref Ecore_Drm_Input_Group
|
||||
* @li @ref Ecore_Drm_Sprite_Group
|
||||
* @li @ref Ecore_Drm_Fb_Group
|
||||
*
|
||||
*/
|
||||
|
||||
EAPI int ecore_drm_init(void);
|
||||
EAPI int ecore_drm_shutdown(void);
|
||||
|
||||
/**
|
||||
* Find a drm device in the system.
|
||||
*
|
||||
* @param name The name of the device to find. If NULL, this function will
|
||||
* search for the default drm device.
|
||||
* @param seat The name of the seat where this device may be found. If NULL,
|
||||
* this function will use a default seat name 'seat0'.
|
||||
*
|
||||
* @return An opaque Ecore_Drm_Device structure representing the card.
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Ecore_Drm_Device *ecore_drm_device_find(const char *name, const char *seat);
|
||||
|
||||
/**
|
||||
* Free an Ecore_Drm_Device
|
||||
*
|
||||
* This function will cleanup and free any previously allocated Ecore_Drm_Device.
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to free
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI void ecore_drm_device_free(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Open an Ecore_Drm_Device
|
||||
*
|
||||
* This function will open an existing Ecore_Drm_Device for use.
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to try and open
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_device_open(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Close an Ecore_Drm_Device
|
||||
*
|
||||
* This function will close a previously opened Ecore_Drm_Device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to free
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_device_close(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Get if a given Ecore_Drm_Device is master
|
||||
*
|
||||
* This function will check if the given drm device is set to master
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to check
|
||||
*
|
||||
* @return EINA_TRUE if device is master, EINA_FALSE otherwise
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_device_master_get(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Set a given Ecore_Drm_Device to master
|
||||
*
|
||||
* This function will attempt to set a given drm device to be master
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to set
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_device_master_set(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Tell a given Ecore_Drm_Device to stop being master
|
||||
*
|
||||
* This function will attempt to ask a drm device to stop being master
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to set
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_device_master_drop(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Get the file descriptor of Ecore_Drm_Device
|
||||
*
|
||||
* This function will get the file descriptor of drm device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get
|
||||
*
|
||||
* @return fd value on success, -1 on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*
|
||||
*/
|
||||
EAPI int ecore_drm_device_fd_get(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Set the window of Ecore_Drm_Device
|
||||
*
|
||||
* This function will set the window for given drm device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device for which window is set
|
||||
* @param window The window to set
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
EAPI void ecore_drm_device_window_set(Ecore_Drm_Device *dev, unsigned int window);
|
||||
|
||||
/**
|
||||
* Get the name of the Ecore_Drm_Device
|
||||
*
|
||||
* This function will return the name of Ecore_Drm_Device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get name
|
||||
*
|
||||
* @return device name on success, NULL on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
EAPI const char *ecore_drm_device_name_get(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Setup an Ecore_Drm_Device for software rendering
|
||||
*
|
||||
* This function will setup an Ecore_Drm_Device for software rendering
|
||||
* which includes creating dumb buffers to render into
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to setup for software rendering
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_device_software_setup(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Find an Ecore_Drm_Output at the given coordinates
|
||||
*
|
||||
* This function will loop all the existing outputs in Ecore_Drm_Device and
|
||||
* return an output if one exists that encapsulates the given coordinates.
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to search
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
*
|
||||
* @return An Ecore_Drm_Output if one exists at these coordinates or NULL
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI Ecore_Drm_Output *ecore_drm_device_output_find(Ecore_Drm_Device *dev, int x, int y);
|
||||
|
||||
/**
|
||||
* Open a tty for use
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device that this tty will belong to.
|
||||
* @param name The name of the tty to try and open.
|
||||
* If NULL, /dev/tty0 will be used.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_tty_open(Ecore_Drm_Device *dev, const char *name);
|
||||
|
||||
/**
|
||||
* Close an already opened tty
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_tty_close(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Release a virtual terminal
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_tty_release(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Acquire a virtual terminal
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_tty_acquire(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Get the opened virtual terminal file descriptor
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return The tty fd opened from previous call to ecore_drm_tty_open
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
EAPI int ecore_drm_tty_get(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Create outputs for a drm device
|
||||
*
|
||||
* This function will create outputs for Ecore_Drm_Device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device device for which outputs
|
||||
* needs to be created
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure.
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_outputs_create(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Free an Ecore_Drm_Output
|
||||
*
|
||||
* This function will cleanup and free any previously allocated Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to free
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
*/
|
||||
EAPI void ecore_drm_output_free(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Set the cursor size for Ecore_Drm_Output
|
||||
*
|
||||
* This function will set the cursor size of Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to set
|
||||
* @param handle The Drm handle
|
||||
* @param w The width of cursor
|
||||
* @param h The height of cursor
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
*/
|
||||
EAPI void ecore_drm_output_cursor_size_set(Ecore_Drm_Output *output, int handle, int w, int h);
|
||||
|
||||
/* TODO: Doxy */
|
||||
EAPI Eina_Bool ecore_drm_output_enable(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Disable a Ecore_Drm_Output
|
||||
*
|
||||
* This function will disable rendering on an Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to disable
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI void ecore_drm_output_disable(Ecore_Drm_Output *output);
|
||||
|
||||
/* TODO: Doxy */
|
||||
EAPI void ecore_drm_output_fb_release(Ecore_Drm_Output *output, Ecore_Drm_Fb *fb);
|
||||
|
||||
/* TODO: Doxy */
|
||||
EAPI void ecore_drm_output_repaint(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the output size of Ecore_Drm_Device
|
||||
*
|
||||
* This function will give the output size of Ecore_Drm_Device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get output size
|
||||
* @param output The output id whose information needs to be retrived
|
||||
* @param *w The parameter in which output width is stored
|
||||
* @param *h The parameter in which output height is stored
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
*/
|
||||
EAPI void ecore_drm_output_size_get(Ecore_Drm_Device *dev, int output, int *w, int *h);
|
||||
|
||||
/**
|
||||
* TODO: Doxy
|
||||
* @since 1.12
|
||||
*/
|
||||
EAPI void ecore_drm_outputs_geometry_get(Ecore_Drm_Device *dev, int *x, int *y, int *w, int *h);
|
||||
|
||||
/**
|
||||
* Get the crtc id of an output
|
||||
*
|
||||
* This function will return the default crtc id for an output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the default crtc of
|
||||
*
|
||||
* @return The id of the default crtc for this output
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI unsigned int ecore_drm_output_crtc_id_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the crtc buffer of an output
|
||||
*
|
||||
* This function will return the default buffer id for an output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the default buffer of
|
||||
*
|
||||
* @return The id of the default buffer for this output
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI unsigned int ecore_drm_output_crtc_buffer_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the connector id of an output
|
||||
*
|
||||
* This function will return the default connector id for an output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the default connector of
|
||||
*
|
||||
* @return The id of the default connector id for this output
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI unsigned int ecore_drm_output_connector_id_get(Ecore_Drm_Output *output);
|
||||
|
||||
/* TODO: Doxy */
|
||||
EAPI Eina_Bool ecore_drm_inputs_create(Ecore_Drm_Device *dev);
|
||||
EAPI void ecore_drm_inputs_destroy(Ecore_Drm_Device *dev);
|
||||
EAPI Eina_Bool ecore_drm_inputs_enable(Ecore_Drm_Input *input);
|
||||
|
@ -229,6 +565,50 @@ EAPI Eina_Bool ecore_drm_sprites_crtc_supported(Ecore_Drm_Output *output, unsign
|
|||
EAPI Ecore_Drm_Fb *ecore_drm_fb_create(Ecore_Drm_Device *dev, int width, int height);
|
||||
EAPI void ecore_drm_fb_destroy(Ecore_Drm_Fb *fb);
|
||||
|
||||
/**
|
||||
* Mark an Ecore_Drm_Fb as dirty
|
||||
*
|
||||
* This function mark an Ecore_Drm_Fb as being dirty
|
||||
*
|
||||
* @param fb The Ecore_Drm_Fb to mark as dirty
|
||||
* @param rects The regions of the Ecore_Drm_Fb which are dirty
|
||||
* @param count The number of regions
|
||||
*
|
||||
* @ingroup Ecore_Drm_Fb_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI void ecore_drm_fb_dirty(Ecore_Drm_Fb *fb, Eina_Rectangle *rects, unsigned int count);
|
||||
|
||||
/**
|
||||
* Set an Ecore_Drm_Fb as the current framebuffer
|
||||
*
|
||||
* This function will set the given Ecore_Drm_Fb as the framebuffer used
|
||||
* across all outputs
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to use
|
||||
* @param fb The Ecore_Drm_Fb to make the current framebuffer
|
||||
*
|
||||
* @ingroup Ecore_Drm_Fb_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI void ecore_drm_fb_set(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb);
|
||||
|
||||
/**
|
||||
* Send an Ecore_Drm_Fb to the Ecore_Drm_Device
|
||||
*
|
||||
* This function will call drmModePageFlip for the given device using the
|
||||
* given Ecore_Drm_Fb as the framebuffer
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to use
|
||||
* @param fb The Ecore_Drm_Fb to send
|
||||
* @param cb The function to call when the page flip has completed
|
||||
* @param data The data to pass to the callback function
|
||||
*
|
||||
* @ingroup Ecore_Drm_Fb_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI void ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func, void *data);
|
||||
|
||||
EAPI Eina_Bool ecore_drm_launcher_connect(Ecore_Drm_Device *dev);
|
||||
EAPI void ecore_drm_launcher_disconnect(Ecore_Drm_Device *dev);
|
||||
|
||||
|
@ -314,6 +694,35 @@ EAPI Eina_Stringshare *ecore_drm_output_model_get(Ecore_Drm_Output *output);
|
|||
*/
|
||||
EAPI Eina_Stringshare *ecore_drm_output_make_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Set the dpms level of an Ecore_Drm_Output
|
||||
*
|
||||
* This function will set the DPMS level of an Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to set the dpms level on
|
||||
* @param level The level to set
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI void ecore_drm_output_dpms_set(Ecore_Drm_Output *output, int level);
|
||||
|
||||
/**
|
||||
* Set the gamma level of an Ecore_Drm_Output
|
||||
*
|
||||
* This function will set the gamma of an Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to set the gamma level on
|
||||
* @param size The gamma table size to set
|
||||
* @param r The amount to scale the red channel
|
||||
* @param g The amount to scale the green channel
|
||||
* @param b The amount to scale the blue channel
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.14
|
||||
*/
|
||||
EAPI void ecore_drm_output_gamma_set(Ecore_Drm_Output *output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
|
||||
|
||||
/**
|
||||
* Get the pointer position of Ecore_Drm_Device
|
||||
*
|
||||
|
|
|
@ -5,26 +5,51 @@
|
|||
#include "ecore_drm_private.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define INSIDE(x, y, xx, yy, ww, hh) \
|
||||
(((x) < ((xx) + (ww))) && ((y) < ((yy) + (hh))) && \
|
||||
((x) >= (xx)) && ((y) >= (yy)))
|
||||
|
||||
static Eina_List *drm_devices;
|
||||
static int flip_count = 0;
|
||||
|
||||
static void
|
||||
_ecore_drm_device_cb_page_flip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
Ecore_Drm_Pageflip_Callback *cb;
|
||||
|
||||
DBG("Drm Page Flip Event");
|
||||
|
||||
if (!(output = data)) return;
|
||||
if (!(cb = data)) return;
|
||||
|
||||
if (output->pending_flip)
|
||||
{
|
||||
ecore_drm_output_fb_release(output, output->current);
|
||||
output->current = output->next;
|
||||
output->next = NULL;
|
||||
}
|
||||
flip_count++;
|
||||
if (flip_count < cb->count) return;
|
||||
|
||||
output->pending_flip = EINA_FALSE;
|
||||
if (!output->pending_vblank) ecore_drm_output_repaint(output);
|
||||
flip_count = 0;
|
||||
if (cb->func) cb->func(cb->data);
|
||||
/* free(cb); */
|
||||
|
||||
/* Ecore_Drm_Output *output; */
|
||||
|
||||
/* DBG("Drm Page Flip Event"); */
|
||||
|
||||
/* if (!(output = data)) return; */
|
||||
|
||||
/* if (output->pending_flip) */
|
||||
/* { */
|
||||
/* if (output->dev->current) */
|
||||
/* ecore_drm_output_fb_release(output, output->dev->current); */
|
||||
/* output->dev->current = output->dev->next; */
|
||||
/* output->dev->next = NULL; */
|
||||
/* } */
|
||||
|
||||
/* output->pending_flip = EINA_FALSE; */
|
||||
/* if (output->pending_destroy) */
|
||||
/* { */
|
||||
/* output->pending_destroy = EINA_FALSE; */
|
||||
/* ecore_drm_output_free(output); */
|
||||
/* } */
|
||||
/* else if (!output->pending_vblank) */
|
||||
/* ecore_drm_output_repaint(output); */
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -51,19 +76,12 @@ static Eina_Bool
|
|||
_ecore_drm_device_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
||||
{
|
||||
Ecore_Drm_Device *dev;
|
||||
drmEventContext ctx;
|
||||
|
||||
if (!(dev = data)) return ECORE_CALLBACK_RENEW;
|
||||
|
||||
DBG("Drm Device Event");
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
||||
ctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
ctx.page_flip_handler = _ecore_drm_device_cb_page_flip;
|
||||
ctx.vblank_handler = _ecore_drm_device_cb_vblank;
|
||||
|
||||
drmHandleEvent(dev->drm.fd, &ctx);
|
||||
drmHandleEvent(dev->drm.fd, &dev->drm_ctx);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
@ -77,9 +95,11 @@ _ecore_drm_device_cb_idle(void *data)
|
|||
|
||||
if (!(dev = data)) return ECORE_CALLBACK_CANCEL;
|
||||
|
||||
if (!dev->active) return ECORE_CALLBACK_RENEW;
|
||||
|
||||
EINA_LIST_FOREACH(dev->outputs, l, output)
|
||||
{
|
||||
output->need_repaint = EINA_TRUE;
|
||||
if ((!output->enabled) || (!output->need_repaint)) continue;
|
||||
if (output->repaint_scheduled) continue;
|
||||
_ecore_drm_output_repaint_start(output);
|
||||
}
|
||||
|
@ -87,6 +107,15 @@ _ecore_drm_device_cb_idle(void *data)
|
|||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_drm_device_cb_output_event(const char *device EINA_UNUSED, Eeze_Udev_Event event EINA_UNUSED, void *data, Eeze_Udev_Watch *watch EINA_UNUSED)
|
||||
{
|
||||
Ecore_Drm_Device *dev;
|
||||
|
||||
if (!(dev = data)) return;
|
||||
_ecore_drm_outputs_update(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Drm_Device_Group Device manipulation functions
|
||||
*
|
||||
|
@ -94,18 +123,6 @@ _ecore_drm_device_cb_idle(void *data)
|
|||
* the DRM device itself.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Find a drm device in the system.
|
||||
*
|
||||
* @param name The name of the device to find. If NULL, this function will
|
||||
* search for the default drm device.
|
||||
* @param seat The name of the seat where this device may be found. If NULL,
|
||||
* this function will use a default seat name 'seat0'.
|
||||
*
|
||||
* @return An opaque Ecore_Drm_Device structure representing the card.
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Ecore_Drm_Device *
|
||||
ecore_drm_device_find(const char *name, const char *seat)
|
||||
{
|
||||
|
@ -204,23 +221,23 @@ out:
|
|||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free an Ecore_Drm_Device
|
||||
*
|
||||
* This function will cleanup and free any previously allocated Ecore_Drm_Device.
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to free
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_drm_device_free(Ecore_Drm_Device *dev)
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
unsigned int i = 0;
|
||||
|
||||
/* check for valid device */
|
||||
if (!dev) return;
|
||||
|
||||
for (; i < ALEN(dev->dumb); i++)
|
||||
{
|
||||
if (dev->dumb[i]) ecore_drm_fb_destroy(dev->dumb[i]);
|
||||
dev->dumb[i] = NULL;
|
||||
}
|
||||
|
||||
ecore_drm_inputs_destroy(dev);
|
||||
|
||||
/* free outputs */
|
||||
EINA_LIST_FREE(dev->outputs, output)
|
||||
ecore_drm_output_free(output);
|
||||
|
@ -246,21 +263,11 @@ ecore_drm_device_free(Ecore_Drm_Device *dev)
|
|||
free(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an Ecore_Drm_Device
|
||||
*
|
||||
* This function will open an existing Ecore_Drm_Device for use.
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to try and open
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_device_open(Ecore_Drm_Device *dev)
|
||||
{
|
||||
uint64_t caps;
|
||||
int events = 0;
|
||||
|
||||
/* check for valid device */
|
||||
if ((!dev) || (!dev->drm.name)) return EINA_FALSE;
|
||||
|
@ -299,33 +306,37 @@ ecore_drm_device_open(Ecore_Drm_Device *dev)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
memset(&dev->drm_ctx, 0, sizeof(dev->drm_ctx));
|
||||
dev->drm_ctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
dev->drm_ctx.page_flip_handler = _ecore_drm_device_cb_page_flip;
|
||||
dev->drm_ctx.vblank_handler = _ecore_drm_device_cb_vblank;
|
||||
|
||||
events = (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE |
|
||||
EEZE_UDEV_EVENT_CHANGE);
|
||||
|
||||
dev->watch =
|
||||
eeze_udev_watch_add(EEZE_UDEV_TYPE_DRM, events,
|
||||
_ecore_drm_device_cb_output_event, NULL);
|
||||
|
||||
dev->drm.hdlr =
|
||||
ecore_main_fd_handler_add(dev->drm.fd, ECORE_FD_READ,
|
||||
_ecore_drm_device_cb_event, dev, NULL, NULL);
|
||||
|
||||
dev->drm.idler =
|
||||
ecore_idle_enterer_add(_ecore_drm_device_cb_idle, dev);
|
||||
/* dev->drm.idler = */
|
||||
/* ecore_idle_enterer_add(_ecore_drm_device_cb_idle, dev); */
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close an Ecore_Drm_Device
|
||||
*
|
||||
* This function will close a previously opened Ecore_Drm_Device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to free
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_device_close(Ecore_Drm_Device *dev)
|
||||
{
|
||||
/* check for valid device */
|
||||
if (!dev) return EINA_FALSE;
|
||||
|
||||
/* delete udev watch */
|
||||
if (dev->watch) eeze_udev_watch_del(dev->watch);
|
||||
|
||||
/* close xkb context */
|
||||
if (dev->xkb_ctx) xkb_context_unref(dev->xkb_ctx);
|
||||
|
||||
|
@ -346,17 +357,6 @@ ecore_drm_devices_get(void)
|
|||
return drm_devices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a given Ecore_Drm_Device is master
|
||||
*
|
||||
* This function will check if the given drm device is set to master
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to check
|
||||
*
|
||||
* @return EINA_TRUE if device is master, EINA_FALSE otherwise
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_device_master_get(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -373,17 +373,6 @@ ecore_drm_device_master_get(Ecore_Drm_Device *dev)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given Ecore_Drm_Device to master
|
||||
*
|
||||
* This function will attempt to set a given drm device to be master
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to set
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_device_master_set(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -397,17 +386,6 @@ ecore_drm_device_master_set(Ecore_Drm_Device *dev)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell a given Ecore_Drm_Device to stop being master
|
||||
*
|
||||
* This function will attempt to ask a drm device to stop being master
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to set
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_device_master_drop(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -421,18 +399,6 @@ ecore_drm_device_master_drop(Ecore_Drm_Device *dev)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file descriptor of Ecore_Drm_Device
|
||||
*
|
||||
* This function will get the file descriptor of drm device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get
|
||||
*
|
||||
* @return fd value on success, -1 on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*
|
||||
*/
|
||||
EAPI int
|
||||
ecore_drm_device_fd_get(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -440,18 +406,6 @@ ecore_drm_device_fd_get(Ecore_Drm_Device *dev)
|
|||
return dev->drm.fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the window of Ecore_Drm_Device
|
||||
*
|
||||
* This function will set the window for given drm device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device for which window is set
|
||||
* @param window The window to set
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
EAPI void
|
||||
ecore_drm_device_window_set(Ecore_Drm_Device *dev, unsigned int window)
|
||||
{
|
||||
|
@ -461,19 +415,6 @@ ecore_drm_device_window_set(Ecore_Drm_Device *dev, unsigned int window)
|
|||
dev->window = window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the Ecore_Drm_Device
|
||||
*
|
||||
* This function will return the name of Ecore_Drm_Device
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get name
|
||||
*
|
||||
* @return device name on success, NULL on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
EAPI const char *
|
||||
ecore_drm_device_name_get(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -511,3 +452,78 @@ ecore_drm_device_pointer_xy_get(Ecore_Drm_Device *dev, int *x, int *y)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_device_software_setup(Ecore_Drm_Device *dev)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
int w = 0, h = 0;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
|
||||
|
||||
/* destroy any old buffers */
|
||||
for (; i < ALEN(dev->dumb); i++)
|
||||
{
|
||||
if (dev->dumb[i]) ecore_drm_fb_destroy(dev->dumb[i]);
|
||||
dev->dumb[i] = NULL;
|
||||
}
|
||||
|
||||
/* get screen size */
|
||||
ecore_drm_outputs_geometry_get(dev, NULL, NULL, &w, &h);
|
||||
|
||||
/* create new buffers */
|
||||
for (i = 0; i < ALEN(dev->dumb); i++)
|
||||
{
|
||||
if (!(dev->dumb[i] = ecore_drm_fb_create(dev, w, h)))
|
||||
{
|
||||
ERR("Could not create dumb framebuffer: %m");
|
||||
goto err;
|
||||
}
|
||||
|
||||
DBG("Ecore_Drm_Device Created Dumb Buffer");
|
||||
DBG("\tFb: %d", dev->dumb[i]->id);
|
||||
DBG("\tHandle: %d", dev->dumb[i]->hdl);
|
||||
DBG("\tStride: %d", dev->dumb[i]->stride);
|
||||
DBG("\tSize: %d", dev->dumb[i]->size);
|
||||
DBG("\tW: %d\tH: %d", dev->dumb[i]->w, dev->dumb[i]->h);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
err:
|
||||
for (i = 0; i < ALEN(dev->dumb); i++)
|
||||
{
|
||||
if (dev->dumb[i]) ecore_drm_fb_destroy(dev->dumb[i]);
|
||||
dev->dumb[i] = NULL;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Ecore_Drm_Output *
|
||||
ecore_drm_device_output_find(Ecore_Drm_Device *dev, int x, int y)
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
Eina_List *l;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dev, NULL);
|
||||
|
||||
EINA_LIST_FOREACH(dev->outputs, l, output)
|
||||
{
|
||||
int ox = 0, oy = 0;
|
||||
int ow = 0, oh = 0;
|
||||
|
||||
if (!output->cloned)
|
||||
{
|
||||
ox = output->x;
|
||||
oy = output->y;
|
||||
}
|
||||
|
||||
ow = output->current_mode->width;
|
||||
oh = output->current_mode->height;
|
||||
|
||||
if (INSIDE(x, y, ox, oy, ow, oh))
|
||||
return output;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,43 @@
|
|||
*
|
||||
* Functions that deal with frame buffers.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: DOXY !! */
|
||||
static Eina_Bool
|
||||
_ecore_drm_fb_create2(int fd, Ecore_Drm_Fb *fb)
|
||||
{
|
||||
struct drm_mode_fb_cmd2 cmd;
|
||||
uint32_t hdls[4], pitches[4], offsets[4], fmt;
|
||||
|
||||
#define _fourcc_code(a,b,c,d) \
|
||||
((uint32_t)(a) | ((uint32_t)(b) << 8) | \
|
||||
((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
|
||||
fmt = (_fourcc_code('X', 'R', '2', '4'));
|
||||
|
||||
hdls[0] = fb->hdl;
|
||||
pitches[0] = fb->stride;
|
||||
offsets[0] = 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(struct drm_mode_fb_cmd2));
|
||||
cmd.fb_id = 0;
|
||||
cmd.width = fb->w;
|
||||
cmd.height = fb->h;
|
||||
cmd.pixel_format = fmt;
|
||||
cmd.flags = 0;
|
||||
memcpy(cmd.handles, hdls, 4 * sizeof(hdls[0]));
|
||||
memcpy(cmd.pitches, pitches, 4 * sizeof(pitches[0]));
|
||||
memcpy(cmd.offsets, offsets, 4 * sizeof(offsets[0]));
|
||||
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &cmd))
|
||||
return EINA_FALSE;
|
||||
|
||||
fb->id = cmd.fb_id;
|
||||
|
||||
/* if (drmModeAddFB2(fd, w, h, fmt, hdls, pitches, offsets, &fb->id, 0)) */
|
||||
/* return EINA_FALSE; */
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Ecore_Drm_Fb *
|
||||
ecore_drm_fb_create(Ecore_Drm_Device *dev, int width, int height)
|
||||
|
@ -41,12 +74,18 @@ ecore_drm_fb_create(Ecore_Drm_Device *dev, int width, int height)
|
|||
fb->stride = carg.pitch;
|
||||
fb->size = carg.size;
|
||||
fb->fd = dev->drm.fd;
|
||||
fb->w = width;
|
||||
fb->h = height;
|
||||
|
||||
if (drmModeAddFB(dev->drm.fd, width, height, 24, 32,
|
||||
fb->stride, fb->hdl, &fb->id))
|
||||
if (!_ecore_drm_fb_create2(dev->drm.fd, fb))
|
||||
{
|
||||
ERR("Could not add framebuffer: %m");
|
||||
goto add_err;
|
||||
WRN("Could not add framebuffer2: %m");
|
||||
if (drmModeAddFB(dev->drm.fd, fb->w, fb->h, 24, 32,
|
||||
fb->stride, fb->hdl, &fb->id))
|
||||
{
|
||||
ERR("Could not add framebuffer: %m");
|
||||
goto add_err;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&marg, 0, sizeof(struct drm_mode_map_dumb));
|
||||
|
@ -95,3 +134,98 @@ ecore_drm_fb_destroy(Ecore_Drm_Fb *fb)
|
|||
drmIoctl(fb->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &darg);
|
||||
free(fb);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_drm_fb_dirty(Ecore_Drm_Fb *fb, Eina_Rectangle *rects, unsigned int count)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(fb);
|
||||
|
||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
|
||||
drmModeClip *clip;
|
||||
unsigned int i = 0;
|
||||
int ret;
|
||||
|
||||
clip = alloca(count * sizeof(drmModeClip));
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
clip[i].x1 = rects[i].x;
|
||||
clip[i].y1 = rects[i].y;
|
||||
clip[i].x2 = rects[i].w;
|
||||
clip[i].y2 = rects[i].h;
|
||||
}
|
||||
|
||||
ret = drmModeDirtyFB(fb->fd, fb->id, clip, count);
|
||||
if (ret)
|
||||
{
|
||||
if (ret == -EINVAL)
|
||||
ERR("Could not mark FB as Dirty: %m");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_drm_fb_set(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb)
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
Eina_List *l;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(dev);
|
||||
EINA_SAFETY_ON_NULL_RETURN(fb);
|
||||
|
||||
if ((fb->w != dev->dumb[0]->w) || (fb->h != dev->dumb[0]->h))
|
||||
{
|
||||
/* we need to copy from fb to dev->dumb */
|
||||
CRIT("Trying to set a Framebuffer of improper size !!");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(dev->outputs, l, output)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
|
||||
if (!output->cloned)
|
||||
{
|
||||
x = output->x;
|
||||
y = output->y;
|
||||
}
|
||||
|
||||
if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, fb->id, x, y,
|
||||
&output->conn_id, 1, &output->current_mode->info))
|
||||
{
|
||||
ERR("Failed to set Mode %dx%d for Output %s: %m",
|
||||
output->current_mode->width, output->current_mode->height,
|
||||
output->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func, void *data)
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
Eina_List *l;
|
||||
Ecore_Drm_Pageflip_Callback *cb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(dev);
|
||||
EINA_SAFETY_ON_NULL_RETURN(fb);
|
||||
EINA_SAFETY_ON_NULL_RETURN(func);
|
||||
|
||||
if (eina_list_count(dev->outputs) < 1) return;
|
||||
|
||||
if (!(cb = calloc(1, sizeof(Ecore_Drm_Pageflip_Callback))))
|
||||
return;
|
||||
|
||||
cb->func = func;
|
||||
cb->data = data;
|
||||
cb->count = eina_list_count(dev->outputs);
|
||||
|
||||
EINA_LIST_FOREACH(dev->outputs, l, output)
|
||||
{
|
||||
if (drmModePageFlip(dev->drm.fd, output->crtc_id, fb->id,
|
||||
DRM_MODE_PAGE_FLIP_EVENT, cb) < 0)
|
||||
{
|
||||
ERR("Cannot flip crtc %u for connector %u: %m",
|
||||
output->crtc_id, output->conn_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,7 +155,6 @@ _ecore_drm_launcher_device_open_no_pending(const char *device, int flags)
|
|||
}
|
||||
}
|
||||
|
||||
DBG("Device opened %s", device);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ _ecore_drm_logind_cb_activate(void *data, int type EINA_UNUSED, void *event)
|
|||
ev = event;
|
||||
dev = data;
|
||||
|
||||
dev->active = ev->active;
|
||||
|
||||
if (ev->active)
|
||||
{
|
||||
/* set output mode */
|
||||
|
@ -164,7 +166,7 @@ _ecore_drm_logind_cb_activate(void *data, int type EINA_UNUSED, void *event)
|
|||
|
||||
/* disable hardware cursor */
|
||||
EINA_LIST_FOREACH(dev->outputs, l, output)
|
||||
ecore_drm_output_cursor_size_set(output, 0, 0, 0);
|
||||
ecore_drm_output_disable(output);
|
||||
|
||||
/* disable sprites */
|
||||
EINA_LIST_FOREACH(dev->sprites, l, sprite)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,15 +26,10 @@
|
|||
# include <libinput.h>
|
||||
# include <xkbcommon/xkbcommon.h>
|
||||
|
||||
# include <xf86drm.h>
|
||||
# include <xf86drmMode.h>
|
||||
# include <drm_fourcc.h>
|
||||
|
||||
# ifdef HAVE_SYSTEMD_LOGIN
|
||||
# include <systemd/sd-login.h>
|
||||
# endif
|
||||
|
||||
# include <Eeze.h>
|
||||
# include <Eldbus.h>
|
||||
# include <Ecore_Drm.h>
|
||||
|
||||
|
@ -75,13 +70,22 @@
|
|||
|
||||
extern int _ecore_drm_log_dom;
|
||||
|
||||
#define EVDEV_MAX_SLOTS 32
|
||||
# define EVDEV_MAX_SLOTS 32
|
||||
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
#define INF(...) EINA_LOG_DOM_INFO(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
# define ERR(...) EINA_LOG_DOM_ERR(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
# define DBG(...) EINA_LOG_DOM_DBG(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
# define INF(...) EINA_LOG_DOM_INFO(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
# define WRN(...) EINA_LOG_DOM_WARN(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_drm_log_dom, __VA_ARGS__)
|
||||
|
||||
# define ALEN(array) (sizeof(array) / sizeof(array)[0])
|
||||
|
||||
typedef struct _Ecore_Drm_Pageflip_Callback
|
||||
{
|
||||
Ecore_Drm_Pageflip_Cb func;
|
||||
void *data;
|
||||
int count;
|
||||
} Ecore_Drm_Pageflip_Callback;
|
||||
|
||||
struct _Ecore_Drm_Output_Mode
|
||||
{
|
||||
|
@ -114,19 +118,14 @@ struct _Ecore_Drm_Output
|
|||
unsigned int crtc_id;
|
||||
unsigned int conn_id;
|
||||
drmModeCrtcPtr crtc;
|
||||
Eeze_Udev_Watch *watch;
|
||||
drmModePropertyPtr dpms;
|
||||
|
||||
int x, y, phys_width, phys_height;
|
||||
int drm_fd;
|
||||
|
||||
Eina_Bool need_repaint : 1;
|
||||
Eina_Bool repaint_scheduled : 1;
|
||||
|
||||
Eina_Bool pending_flip : 1;
|
||||
Eina_Bool pending_vblank : 1;
|
||||
|
||||
int pipe;
|
||||
const char *make, *model, *name;
|
||||
unsigned int subpixel;
|
||||
uint16_t gamma;
|
||||
|
||||
Ecore_Drm_Output_Mode *current_mode;
|
||||
Eina_List *modes;
|
||||
|
@ -139,9 +138,15 @@ struct _Ecore_Drm_Output
|
|||
char serial[13];
|
||||
} edid;
|
||||
|
||||
Ecore_Drm_Fb *current, *next;
|
||||
Ecore_Drm_Fb *dumb[NUM_FRAME_BUFFERS];
|
||||
Ecore_Drm_Backlight *backlight;
|
||||
|
||||
Eina_Bool enabled : 1;
|
||||
Eina_Bool cloned : 1;
|
||||
Eina_Bool need_repaint : 1;
|
||||
Eina_Bool repaint_scheduled : 1;
|
||||
Eina_Bool pending_destroy : 1;
|
||||
Eina_Bool pending_flip : 1;
|
||||
Eina_Bool pending_vblank : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Drm_Seat
|
||||
|
@ -243,7 +248,6 @@ struct _Ecore_Drm_Sprite
|
|||
typedef void (*Ecore_Drm_Open_Cb)(void *data, int fd, Eina_Bool b);
|
||||
|
||||
void _ecore_drm_event_activate_send(Eina_Bool active);
|
||||
void _ecore_drm_event_output_send(const Ecore_Drm_Output *output, Eina_Bool plug);
|
||||
|
||||
Eina_Bool _ecore_drm_launcher_device_open(const char *device, Ecore_Drm_Open_Cb callback, void *data, int flags);
|
||||
int _ecore_drm_launcher_device_open_no_pending(const char *device, int flags);
|
||||
|
@ -262,6 +266,7 @@ void _ecore_drm_fb_destroy(Ecore_Drm_Fb *fb);
|
|||
void _ecore_drm_output_fb_release(Ecore_Drm_Output *output, Ecore_Drm_Fb *fb);
|
||||
void _ecore_drm_output_repaint_start(Ecore_Drm_Output *output);
|
||||
void _ecore_drm_output_frame_finish(Ecore_Drm_Output *output);
|
||||
void _ecore_drm_outputs_update(Ecore_Drm_Device *dev);
|
||||
|
||||
Eina_Bool _ecore_drm_logind_connect(Ecore_Drm_Device *dev);
|
||||
void _ecore_drm_logind_disconnect(Ecore_Drm_Device *dev);
|
||||
|
|
|
@ -129,17 +129,6 @@ err_kmode:
|
|||
* Functions that deal with opening, closing, and otherwise using a tty
|
||||
*/
|
||||
|
||||
/**
|
||||
* Open a tty for use
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device that this tty will belong to.
|
||||
* @param name The name of the tty to try and open.
|
||||
* If NULL, /dev/tty0 will be used.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_tty_open(Ecore_Drm_Device *dev, const char *name)
|
||||
{
|
||||
|
@ -233,15 +222,6 @@ _ecore_drm_tty_restore(Ecore_Drm_Device *dev)
|
|||
ERR("Could not reset VT handling\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Close an already opened tty
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_tty_close(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -263,15 +243,6 @@ ecore_drm_tty_close(Ecore_Drm_Device *dev)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release a virtual terminal
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_tty_release(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -288,15 +259,6 @@ ecore_drm_tty_release(Ecore_Drm_Device *dev)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire a virtual terminal
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_tty_acquire(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
@ -313,17 +275,6 @@ ecore_drm_tty_acquire(Ecore_Drm_Device *dev)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the opened virtual terminal file descriptor
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device which owns this tty.
|
||||
*
|
||||
* @return The tty fd opened from previous call to ecore_drm_tty_open
|
||||
*
|
||||
* @ingroup Ecore_Drm_Tty_Group
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
EAPI int
|
||||
ecore_drm_tty_get(Ecore_Drm_Device *dev)
|
||||
{
|
||||
|
|
|
@ -172,6 +172,12 @@ ecore_evas_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED,
|
|||
/* try to init drm */
|
||||
if (_ecore_evas_drm_init(device) < 1) return NULL;
|
||||
|
||||
if (!ecore_drm_device_software_setup(dev))
|
||||
{
|
||||
ERR("Could not setup device for software");
|
||||
goto soft_err;
|
||||
}
|
||||
|
||||
/* try to allocate space for new ecore_evas */
|
||||
if (!(ee = calloc(1, sizeof(Ecore_Evas))))
|
||||
{
|
||||
|
@ -243,14 +249,33 @@ ecore_evas_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED,
|
|||
|
||||
if ((einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas)))
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
char *num;
|
||||
|
||||
einfo->info.depth = 32; // FIXME
|
||||
einfo->info.destination_alpha = ee->alpha;
|
||||
einfo->info.rotation = ee->rotation;
|
||||
einfo->info.vsync = EINA_TRUE;
|
||||
|
||||
if ((num = getenv("EVAS_DRM_VSYNC")))
|
||||
{
|
||||
if (!atoi(num))
|
||||
einfo->info.vsync = EINA_FALSE;
|
||||
else
|
||||
einfo->info.vsync = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
einfo->info.vsync = EINA_TRUE;
|
||||
|
||||
einfo->info.use_hw_accel = EINA_FALSE;
|
||||
einfo->info.fd = ecore_drm_device_fd_get(dev);
|
||||
einfo->info.dev = dev;
|
||||
|
||||
if ((output = ecore_drm_device_output_find(dev, x, y)))
|
||||
{
|
||||
einfo->info.conn_id = ecore_drm_output_connector_id_get(output);
|
||||
einfo->info.crtc_id = ecore_drm_output_crtc_id_get(output);
|
||||
einfo->info.buffer_id = ecore_drm_output_crtc_buffer_get(output);
|
||||
}
|
||||
|
||||
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
|
||||
{
|
||||
ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
|
||||
|
@ -263,7 +288,7 @@ ecore_evas_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED,
|
|||
goto eng_err;
|
||||
}
|
||||
|
||||
ee->prop.window = einfo->info.output;
|
||||
ee->prop.window = einfo->info.buffer_id;
|
||||
|
||||
_ecore_evas_register(ee);
|
||||
ecore_evas_input_event_register(ee);
|
||||
|
@ -284,6 +309,7 @@ ecore_evas_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED,
|
|||
|
||||
eng_err:
|
||||
ecore_evas_free(ee);
|
||||
soft_err:
|
||||
ee_err:
|
||||
_ecore_evas_drm_shutdown();
|
||||
return NULL;
|
||||
|
@ -862,7 +888,7 @@ _ecore_evas_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
|
|||
edata->w = ee->w;
|
||||
edata->h = ee->h;
|
||||
if ((einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas)))
|
||||
ecore_drm_output_size_get(dev, einfo->info.output, &ow, &oh);
|
||||
ecore_drm_output_size_get(dev, einfo->info.buffer_id, &ow, &oh);
|
||||
|
||||
if ((ow == 0) || (oh == 0))
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _EVAS_ENGINE_DRM_H
|
||||
# define _EVAS_ENGINE_DRM_H
|
||||
|
||||
#include <Ecore_Drm.h>
|
||||
# include <Ecore_Drm.h>
|
||||
|
||||
typedef struct _Evas_Engine_Info_Drm Evas_Engine_Info_Drm;
|
||||
|
||||
|
@ -13,16 +13,11 @@ struct _Evas_Engine_Info_Drm
|
|||
|
||||
struct
|
||||
{
|
||||
Evas *evas;
|
||||
|
||||
unsigned int rotation, depth;
|
||||
Eina_Bool destination_alpha : 1;
|
||||
Eina_Bool vsync : 1;
|
||||
|
||||
int fd;
|
||||
|
||||
int output;
|
||||
int plane;
|
||||
unsigned int crtc_id, conn_id, buffer_id;
|
||||
|
||||
Eina_Bool use_hw_accel : 1;
|
||||
Ecore_Drm_Device *dev;
|
||||
|
|
|
@ -1,538 +0,0 @@
|
|||
#include "evas_engine.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef HAVE_DRM_HW_ACCEL
|
||||
# define EGL_EGLEXT_PROTOTYPES
|
||||
# define GL_GLEXT_PROTOTYPES
|
||||
|
||||
# include <GLES2/gl2.h>
|
||||
# include <GLES2/gl2ext.h>
|
||||
# include <EGL/egl.h>
|
||||
# include <EGL/eglext.h>
|
||||
#endif
|
||||
|
||||
/* NB: This union is the same in GBM and TBM so we can use it
|
||||
* to return 'handles' */
|
||||
union _ebi_bo_handle
|
||||
{
|
||||
void *ptr;
|
||||
int32_t s32;
|
||||
uint32_t u32;
|
||||
int64_t s64;
|
||||
uint64_t u64;
|
||||
};
|
||||
|
||||
enum _ebi_bo_format
|
||||
{
|
||||
EBI_BO_FORMAT_XRGB8888,
|
||||
EBI_BO_FORMAT_ARGB8888
|
||||
};
|
||||
|
||||
enum _ebi_bo_gbm_flags
|
||||
{
|
||||
EBI_BO_GBM_SCANOUT = (1 << 0),
|
||||
EBI_BO_GBM_CURSOR = (1 << 1),
|
||||
EBI_BO_GBM_RENDER = (1 << 2),
|
||||
EBI_BO_GBM_WRITE = (1 << 3),
|
||||
};
|
||||
|
||||
enum _ebi_bo_tbm_flags
|
||||
{
|
||||
EBI_BO_TBM_DEFAULT = 0,
|
||||
EBI_BO_TBM_SCANOUT = (1 << 0),
|
||||
EBI_BO_TBM_NONCACHE = (1 << 1),
|
||||
EBI_BO_TBM_WC = (1 << 2),
|
||||
EBI_BO_TBM_VENDOR = (0xffff0000),
|
||||
};
|
||||
|
||||
typedef struct _Evas_Bufmgr_Interface Evas_Bufmgr_Interface;
|
||||
struct _Evas_Bufmgr_Interface
|
||||
{
|
||||
int fd;
|
||||
|
||||
/* actual library we linked to */
|
||||
void *lib;
|
||||
|
||||
/* actual buffer manager returned from library init */
|
||||
void *mgr;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
void *(*init)(int fd);
|
||||
void (*shutdown)(void *mgr);
|
||||
void *(*surface_create)(void *mgr, unsigned int width, unsigned int height, unsigned int format, unsigned int flags);
|
||||
void (*surface_destroy)(void *surface);
|
||||
void *(*buffer_create)(void *mgr, unsigned int width, unsigned int height, unsigned int format, unsigned int flags);
|
||||
void (*buffer_destroy)(void *buffer);
|
||||
union _ebi_bo_handle (*buffer_handle_get)(void *buffer);
|
||||
unsigned int (*buffer_stride_get)(void *buffer);
|
||||
} gbm;
|
||||
struct
|
||||
{
|
||||
void *(*init)(int fd);
|
||||
void (*shutdown)(void *mgr);
|
||||
} tbm;
|
||||
} funcs;
|
||||
|
||||
#ifdef HAVE_DRM_HW_ACCEL
|
||||
struct
|
||||
{
|
||||
EGLDisplay disp;
|
||||
EGLContext ctx;
|
||||
EGLConfig cfg;
|
||||
|
||||
PFNEGLCREATEIMAGEKHRPROC image_create;
|
||||
PFNEGLDESTROYIMAGEKHRPROC image_destroy;
|
||||
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_texture;
|
||||
} egl;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* buffer manager interface */
|
||||
static Evas_Bufmgr_Interface *_ebi;
|
||||
|
||||
static Eina_Bool
|
||||
_evas_bufmgr_egl_init(void)
|
||||
{
|
||||
#ifdef HAVE_DRM_HW_ACCEL
|
||||
/* const char *ext; */
|
||||
EGLint maj, min, n;
|
||||
EGLint atts[] =
|
||||
{
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1,
|
||||
EGL_ALPHA_SIZE, 1, EGL_DEPTH_SIZE, 1,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE
|
||||
};
|
||||
|
||||
/* try to get the egl display from the manager */
|
||||
_ebi->egl.disp = eglGetDisplay(_ebi->mgr);
|
||||
if (_ebi->egl.disp == EGL_NO_DISPLAY)
|
||||
{
|
||||
ERR("Could not get EGLDisplay: %m");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* try to init egl library */
|
||||
if (!eglInitialize(_ebi->egl.disp, &maj, &min))
|
||||
{
|
||||
ERR("Could not init EGL library: %m");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
/* check egl extensions for what we need */
|
||||
/* ext = eglQueryString(_ebi->egl.disp, EGL_EXTENSIONS); */
|
||||
/* if (!strstr(ext, "EGL_KHR_surfaceless_opengl")) */
|
||||
/* { */
|
||||
/* ERR("EGL_KHR_surfaceless_opengl Not Supported"); */
|
||||
/* goto init_err; */
|
||||
/* } */
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
/* try to find matching egl config */
|
||||
if (!eglChooseConfig(_ebi->egl.disp, atts, &_ebi->egl.cfg, 1, &n) ||
|
||||
(n != 1))
|
||||
{
|
||||
ERR("Could not find EGLConfig: %m");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
/* try to create a context */
|
||||
if (!(_ebi->egl.ctx =
|
||||
eglCreateContext(_ebi->egl.disp, _ebi->egl.cfg, EGL_NO_CONTEXT, NULL)))
|
||||
{
|
||||
ERR("Could not create EGL Context: %m");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
/* try to make this context current */
|
||||
if (!eglMakeCurrent(_ebi->egl.disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
_ebi->egl.ctx))
|
||||
{
|
||||
ERR("Could not make EGL Context current: %m");
|
||||
goto curr_err;
|
||||
}
|
||||
|
||||
/* TODO: setup shaders ?? */
|
||||
|
||||
/* link to egl functions */
|
||||
_ebi->egl.image_create = (PFNEGLCREATEIMAGEKHRPROC)
|
||||
eglGetProcAddress("eglCreateImageKHR");
|
||||
_ebi->egl.image_destroy = (PFNEGLDESTROYIMAGEKHRPROC)
|
||||
eglGetProcAddress("eglDestroyImageKHR");
|
||||
_ebi->egl.image_texture = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
|
||||
eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
curr_err:
|
||||
/* destroy the egl context */
|
||||
eglDestroyContext(_ebi->egl.disp, _ebi->egl.ctx);
|
||||
|
||||
init_err:
|
||||
/* close egl display */
|
||||
eglTerminate(_ebi->egl.disp);
|
||||
eglReleaseThread();
|
||||
#endif
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_bufmgr_egl_shutdown(void)
|
||||
{
|
||||
#ifdef HAVE_DRM_HW_ACCEL
|
||||
if (_ebi->egl.disp)
|
||||
{
|
||||
eglMakeCurrent(_ebi->egl.disp,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglTerminate(_ebi->egl.disp);
|
||||
eglReleaseThread();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_evas_bufmgr_gbm_init(void)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
/* set dlopen flags */
|
||||
flags = (RTLD_LAZY | RTLD_GLOBAL);
|
||||
|
||||
/* try to find gbm library */
|
||||
_ebi->lib = dlopen("libgbm.so", flags);
|
||||
if (!_ebi->lib) _ebi->lib = dlopen("libgbm.so.1", flags);
|
||||
if (!_ebi->lib) _ebi->lib = dlopen("libgbm.so.1.0.0", flags);
|
||||
|
||||
/* fail if we did not find the library */
|
||||
if (!_ebi->lib) return EINA_FALSE;
|
||||
|
||||
/* with the library found, lets symlink the functions we need */
|
||||
_ebi->funcs.gbm.init = dlsym(_ebi->lib, "gbm_create_device");
|
||||
_ebi->funcs.gbm.shutdown = dlsym(_ebi->lib, "gbm_device_destroy");
|
||||
_ebi->funcs.gbm.surface_create = dlsym(_ebi->lib, "gbm_surface_create");
|
||||
_ebi->funcs.gbm.surface_destroy = dlsym(_ebi->lib, "gbm_surface_destroy");
|
||||
_ebi->funcs.gbm.buffer_create = dlsym(_ebi->lib, "gbm_bo_create");
|
||||
_ebi->funcs.gbm.buffer_destroy = dlsym(_ebi->lib, "gbm_bo_destroy");
|
||||
_ebi->funcs.gbm.buffer_handle_get = dlsym(_ebi->lib, "gbm_bo_get_handle");
|
||||
_ebi->funcs.gbm.buffer_stride_get = dlsym(_ebi->lib, "gbm_bo_get_stride");
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_evas_bufmgr_tbm_init(void)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
/* set dlopen flags */
|
||||
flags = (RTLD_LAZY | RTLD_GLOBAL);
|
||||
|
||||
/* try to find gbm library */
|
||||
_ebi->lib = dlopen("libtbm.so", flags);
|
||||
if (!_ebi->lib) _ebi->lib = dlopen("libtbm.so.1", flags);
|
||||
if (!_ebi->lib) _ebi->lib = dlopen("libtbm.so.1.0.0", flags);
|
||||
|
||||
/* fail if we did not find the library */
|
||||
if (!_ebi->lib) return EINA_FALSE;
|
||||
|
||||
/* with the library found, lets symlink the functions we need */
|
||||
/* TODO */
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_bufmgr_init(int fd)
|
||||
{
|
||||
/* if we already have an interface, then we have been here before */
|
||||
if (_ebi) return EINA_TRUE;
|
||||
|
||||
/* try to allocate space for interface */
|
||||
if (!(_ebi = calloc(1, sizeof(Evas_Bufmgr_Interface)))) return EINA_FALSE;
|
||||
|
||||
/* save drm card fd for later use */
|
||||
_ebi->fd = fd;
|
||||
|
||||
/* try to find and link gbm library first */
|
||||
if (!_evas_bufmgr_gbm_init())
|
||||
{
|
||||
/* try to find and link tbm library */
|
||||
if (!_evas_bufmgr_tbm_init())
|
||||
{
|
||||
ERR("Could not init buffer library");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* with the library open and functions linked, lets try to init */
|
||||
if (_ebi->funcs.gbm.init)
|
||||
_ebi->mgr = _ebi->funcs.gbm.init(fd);
|
||||
else if (_ebi->funcs.tbm.init)
|
||||
_ebi->mgr = _ebi->funcs.tbm.init(fd);
|
||||
|
||||
if (!_ebi->mgr)
|
||||
{
|
||||
ERR("Could not init buffer manager");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
/* with the manager initialized, we need to init egl */
|
||||
if (!_evas_bufmgr_egl_init())
|
||||
WRN("Could not init egl");
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
/* egl_err: */
|
||||
/* if (_ebi->mgr) */
|
||||
/* { */
|
||||
/* if (_ebi->funcs.gbm.shutdown) _ebi->funcs.gbm.shutdown(_ebi->mgr); */
|
||||
/* else if (_ebi->funcs.tbm.shutdown) _ebi->funcs.tbm.shutdown(_ebi->mgr); */
|
||||
/* _ebi->mgr = NULL; */
|
||||
/* } */
|
||||
|
||||
init_err:
|
||||
/* close library */
|
||||
if (_ebi->lib) dlclose(_ebi->lib);
|
||||
_ebi->lib = NULL;
|
||||
err:
|
||||
/* free allocated space */
|
||||
free(_ebi);
|
||||
_ebi = NULL;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
evas_bufmgr_shutdown(void)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if (!_ebi) return;
|
||||
|
||||
/* shutdown egl */
|
||||
_evas_bufmgr_egl_shutdown();
|
||||
|
||||
/* shutdown manager */
|
||||
if (_ebi->mgr)
|
||||
{
|
||||
if (_ebi->funcs.gbm.shutdown) _ebi->funcs.gbm.shutdown(_ebi->mgr);
|
||||
else if (_ebi->funcs.tbm.shutdown) _ebi->funcs.tbm.shutdown(_ebi->mgr);
|
||||
_ebi->mgr = NULL;
|
||||
}
|
||||
|
||||
/* close library */
|
||||
if (_ebi->lib) dlclose(_ebi->lib);
|
||||
_ebi->lib = NULL;
|
||||
|
||||
/* free allocated space */
|
||||
free(_ebi);
|
||||
_ebi = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DRM_HW_ACCEL
|
||||
void *
|
||||
evas_bufmgr_window_create(void *surface)
|
||||
{
|
||||
void *win;
|
||||
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (_ebi->egl.disp == EGL_NO_DISPLAY)) return NULL;
|
||||
|
||||
/* try to create the egl window surface */
|
||||
win = eglCreateWindowSurface(_ebi->egl.disp, _ebi->egl.cfg,
|
||||
(EGLNativeWindowType)surface, NULL);
|
||||
if (win == EGL_NO_SURFACE)
|
||||
{
|
||||
ERR("Failed to create egl window surface: %m");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* try to make this window surface current */
|
||||
if (!eglMakeCurrent(_ebi->egl.disp, win, win, _ebi->egl.ctx))
|
||||
ERR("Could not make window surface current: %m");
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
void
|
||||
evas_bufmgr_window_destroy(void *win)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (_ebi->egl.disp == EGL_NO_DISPLAY)) return;
|
||||
|
||||
/* destroy the egl window */
|
||||
if (win) eglDestroySurface(_ebi->egl.disp, win);
|
||||
}
|
||||
|
||||
void *
|
||||
evas_bufmgr_surface_create(int w, int h, Eina_Bool alpha)
|
||||
{
|
||||
unsigned int format, flags;
|
||||
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (!_ebi->mgr)) return NULL;
|
||||
|
||||
format = EBI_BO_FORMAT_XRGB8888;
|
||||
if (alpha) format = EBI_BO_FORMAT_ARGB8888;
|
||||
|
||||
/* call function to create surface */
|
||||
if (_ebi->funcs.gbm.surface_create)
|
||||
{
|
||||
flags = (EBI_BO_GBM_SCANOUT | EBI_BO_GBM_RENDER);
|
||||
return _ebi->funcs.gbm.surface_create(_ebi->mgr, w, h, format, flags);
|
||||
}
|
||||
|
||||
/* else if (_ebi->funcs.tbm.surface_create) */
|
||||
/* surface = _ebi->funcs.tbm.surface_create(); */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
evas_bufmgr_surface_destroy(void *surface)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (!_ebi->mgr)) return;
|
||||
|
||||
/* check for valid surface */
|
||||
if (!surface) return;
|
||||
|
||||
/* call destroy surface */
|
||||
if (_ebi->funcs.gbm.surface_destroy)
|
||||
_ebi->funcs.gbm.surface_destroy(surface);
|
||||
|
||||
/* else if (_ebi->funcs.tbm.surface_destroy) */
|
||||
/* _ebi->funcs.tbm.surface_destroy(surface); */
|
||||
}
|
||||
|
||||
void *
|
||||
evas_bufmgr_buffer_create(int w, int h, Eina_Bool alpha)
|
||||
{
|
||||
unsigned int format, flags;
|
||||
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (!_ebi->mgr)) return NULL;
|
||||
|
||||
format = EBI_BO_FORMAT_XRGB8888;
|
||||
if (alpha) format = EBI_BO_FORMAT_ARGB8888;
|
||||
|
||||
/* call function to create surface */
|
||||
if (_ebi->funcs.gbm.buffer_create)
|
||||
{
|
||||
flags = (EBI_BO_GBM_SCANOUT | EBI_BO_GBM_RENDER);
|
||||
return _ebi->funcs.gbm.buffer_create(_ebi->mgr, w, h, format, flags);
|
||||
}
|
||||
|
||||
/* else if (_ebi->funcs.tbm.buffer_create) */
|
||||
/* surface = _ebi->funcs.tbm.buffer_create(); */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
evas_bufmgr_buffer_destroy(void *buffer)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (!_ebi->mgr)) return;
|
||||
|
||||
/* check for valid buffer */
|
||||
if (!buffer) return;
|
||||
|
||||
/* call function to destroy buffer */
|
||||
if (_ebi->funcs.gbm.buffer_destroy)
|
||||
_ebi->funcs.gbm.buffer_destroy(buffer);
|
||||
|
||||
/* else if (_ebi->funcs.tbm.buffer_destroy) */
|
||||
/* _ebi->funcs.tbm.buffer_destroy(buffer); */
|
||||
}
|
||||
|
||||
int
|
||||
evas_bufmgr_buffer_handle_get(void *buffer)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (!_ebi->mgr)) return 0;
|
||||
|
||||
/* check for valid buffer */
|
||||
if (!buffer) return 0;
|
||||
|
||||
/* call function to get buffer handle */
|
||||
if (_ebi->funcs.gbm.buffer_handle_get)
|
||||
return _ebi->funcs.gbm.buffer_handle_get(buffer).u32;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evas_bufmgr_buffer_stride_get(void *buffer)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (!_ebi->mgr)) return 0;
|
||||
|
||||
/* check for valid buffer */
|
||||
if (!buffer) return 0;
|
||||
|
||||
/* call function to get buffer stride */
|
||||
if (_ebi->funcs.gbm.buffer_stride_get)
|
||||
return _ebi->funcs.gbm.buffer_stride_get(buffer);
|
||||
|
||||
/* else if (_ebi->funcs.tbm.buffer_stride_get) */
|
||||
/* return _ebi->funcs.tbm.buffer_stride_get(buffer); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
evas_bufmgr_image_create(void *buffer)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (_ebi->egl.disp == EGL_NO_DISPLAY)) return NULL;
|
||||
|
||||
/* check for valid buffer */
|
||||
if (!buffer) return NULL;
|
||||
|
||||
/* try to create an egl image from this buffer */
|
||||
if (_ebi->egl.image_create)
|
||||
return _ebi->egl.image_create(_ebi->egl.disp, EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_PIXMAP_KHR, buffer, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
evas_bufmgr_image_destroy(void *image)
|
||||
{
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (_ebi->egl.disp == EGL_NO_DISPLAY)) return;
|
||||
|
||||
/* check for valid image */
|
||||
if (!image) return;
|
||||
|
||||
/* destroy egl image */
|
||||
if (_ebi->egl.image_destroy)
|
||||
_ebi->egl.image_destroy(_ebi->egl.disp, image);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
evas_bufmgr_texture_create(void *image)
|
||||
{
|
||||
GLuint tex;
|
||||
|
||||
/* check for valid interface */
|
||||
if ((!_ebi) || (_ebi->egl.disp == EGL_NO_DISPLAY)) return 0;
|
||||
|
||||
/* check for valid image */
|
||||
if (!image) return 0;
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
if (_ebi->egl.image_texture) _ebi->egl.image_texture(GL_TEXTURE_2D, image);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return tex;
|
||||
}
|
||||
#endif
|
|
@ -1,391 +0,0 @@
|
|||
#include "evas_engine.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
static unsigned int
|
||||
_evas_drm_crtc_buffer_get(int fd, int crtc_id)
|
||||
{
|
||||
drmModeCrtc *crtc;
|
||||
unsigned int id;
|
||||
|
||||
if (!(crtc = drmModeGetCrtc(fd, crtc_id))) return 0;
|
||||
id = crtc->buffer_id;
|
||||
drmModeFreeCrtc(crtc);
|
||||
return id;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_drm_outbuf_page_flip(int fd EINA_UNUSED, unsigned int seq EINA_UNUSED, unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED, void *data)
|
||||
{
|
||||
Outbuf *ob;
|
||||
|
||||
/* get the output buffer from data */
|
||||
if (!(ob = data)) return;
|
||||
|
||||
/* DBG("Page Flip Event"); */
|
||||
|
||||
ob->priv.pending_flip = EINA_FALSE;
|
||||
ob->priv.last = ob->priv.curr;
|
||||
ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
|
||||
}
|
||||
|
||||
/* static void */
|
||||
/* _evas_drm_outbuf_vblank(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data) */
|
||||
/* { */
|
||||
/* Outbuf *ob; */
|
||||
|
||||
/* if (!(ob = data)) return; */
|
||||
|
||||
/* DBG("VBlank Event"); */
|
||||
/* } */
|
||||
|
||||
static Eina_Bool
|
||||
_evas_drm_outbuf_planes_setup(Outbuf *ob, drmModePlaneResPtr pres)
|
||||
{
|
||||
drmModePlanePtr dplane;
|
||||
Plane *oplane;
|
||||
unsigned int p = 0;
|
||||
unsigned int f = 0;
|
||||
|
||||
for (p = 0; p < pres->count_planes; p++)
|
||||
{
|
||||
/* try to get this plane */
|
||||
if (!(dplane = drmModeGetPlane(ob->priv.fd, pres->planes[p])))
|
||||
continue;
|
||||
|
||||
/* try to allocate space for our plane */
|
||||
if (!(oplane =
|
||||
malloc(sizeof(Plane) +
|
||||
((sizeof(unsigned int)) * dplane->count_formats))))
|
||||
{
|
||||
drmModeFreePlane(dplane);
|
||||
continue;
|
||||
}
|
||||
|
||||
oplane->crtcs = dplane->possible_crtcs;
|
||||
oplane->id = dplane->plane_id;
|
||||
oplane->num_formats = dplane->count_formats;
|
||||
memcpy(oplane->formats, dplane->formats,
|
||||
dplane->count_formats * sizeof(dplane->formats[0]));
|
||||
|
||||
DBG("Plane %d, %d %d", p, dplane->x, dplane->y);
|
||||
DBG("\tFB: %d", dplane->fb_id);
|
||||
DBG("\tCrtc: %d, %d %d", dplane->crtc_id,
|
||||
dplane->crtc_x, dplane->crtc_y);
|
||||
|
||||
DBG("\tSupported Formats");
|
||||
for (f = 0; f < dplane->count_formats; f++)
|
||||
{
|
||||
DBG("\t\t%C%C%C%C", (dplane->formats[f] & 0xFF),
|
||||
((dplane->formats[f] >> 8) & 0xFF),
|
||||
((dplane->formats[f] >> 16) & 0xFF),
|
||||
((dplane->formats[f] >> 24) & 0xFF));
|
||||
}
|
||||
|
||||
/* free this plane */
|
||||
drmModeFreePlane(dplane);
|
||||
|
||||
/* append this plane */
|
||||
ob->priv.planes = eina_list_append(ob->priv.planes, oplane);
|
||||
}
|
||||
|
||||
if (eina_list_count(ob->priv.planes) < 1) return EINA_FALSE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_drm_outbuf_setup(Outbuf *ob)
|
||||
{
|
||||
drmModeRes *res;
|
||||
drmModeConnector *conn;
|
||||
drmModePlaneResPtr pres;
|
||||
drmModeEncoder *enc;
|
||||
drmModeModeInfo crtc_mode;
|
||||
int i = 0;
|
||||
|
||||
/* check for valid Output buffer */
|
||||
if ((!ob) || (ob->priv.fd < 0)) return EINA_FALSE;
|
||||
|
||||
/* setup drmHandleEvent context */
|
||||
memset(&ob->priv.ctx, 0, sizeof(ob->priv.ctx));
|
||||
ob->priv.ctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
ob->priv.ctx.page_flip_handler = _evas_drm_outbuf_page_flip;
|
||||
/* ob->priv.ctx.vblank_handler = _evas_drm_outbuf_vblank; */
|
||||
|
||||
/* try to get drm resources */
|
||||
if (!(res = drmModeGetResources(ob->priv.fd)))
|
||||
{
|
||||
CRI("Could not get drm resources: %m");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* loop the connectors */
|
||||
for (; i < res->count_connectors; ++i)
|
||||
{
|
||||
int crtc_id = -1;
|
||||
int m = 0;
|
||||
|
||||
/* try to get this connector */
|
||||
if (!(conn = drmModeGetConnector(ob->priv.fd, res->connectors[i])))
|
||||
{
|
||||
WRN("Could not get drm connector %d: %m", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* make sure this connector is actually connected */
|
||||
if (conn->connection != DRM_MODE_CONNECTED)
|
||||
{
|
||||
/* free connector resources */
|
||||
drmModeFreeConnector(conn);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* make sure it has modes */
|
||||
if (conn->count_modes == 0)
|
||||
{
|
||||
/* free connector resources */
|
||||
drmModeFreeConnector(conn);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* record the connector id */
|
||||
ob->priv.conn = conn->connector_id;
|
||||
|
||||
if ((enc = drmModeGetEncoder(ob->priv.fd, conn->encoder_id)))
|
||||
{
|
||||
drmModeCrtc *crtc;
|
||||
|
||||
if ((crtc = drmModeGetCrtc(ob->priv.fd, enc->crtc_id)))
|
||||
{
|
||||
crtc_id = enc->crtc_id;
|
||||
if (crtc->mode_valid) crtc_mode = crtc->mode;
|
||||
drmModeFreeCrtc(crtc);
|
||||
}
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
}
|
||||
|
||||
/* record the crtc id */
|
||||
ob->priv.crtc = crtc_id;
|
||||
|
||||
/* get the current framebuffer */
|
||||
ob->priv.fb = _evas_drm_crtc_buffer_get(ob->priv.fd, crtc_id);
|
||||
|
||||
/* spew out connector properties for testing */
|
||||
/* drmModePropertyPtr props; */
|
||||
/* for (m = 0; m < conn->count_props; m++) */
|
||||
/* { */
|
||||
/* props = drmModeGetProperty(ob->priv.fd, conn->props[m]); */
|
||||
/* if (!props) continue; */
|
||||
/* DBG("Property Name: %s", props->name); */
|
||||
/* } */
|
||||
|
||||
memset(&ob->priv.mode, 0, sizeof(ob->priv.mode));
|
||||
for (m = 0; m < conn->count_modes; m++)
|
||||
{
|
||||
DBG("Output Available Mode: %d: %d %d %d", ob->priv.conn,
|
||||
conn->modes[m].hdisplay, conn->modes[m].vdisplay,
|
||||
conn->modes[m].vrefresh);
|
||||
if (!memcmp(&crtc_mode, &conn->modes[m], sizeof(crtc_mode)))
|
||||
{
|
||||
/* record the current mode */
|
||||
memcpy(&ob->priv.mode, &conn->modes[m], sizeof(ob->priv.mode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!ob->priv.mode.hdisplay) && (crtc_mode.clock != 0))
|
||||
memcpy(&ob->priv.mode, &crtc_mode, sizeof(ob->priv.mode));
|
||||
|
||||
DBG("Output Current Mode: %d: %d %d", ob->priv.conn,
|
||||
ob->priv.mode.hdisplay, ob->priv.mode.vdisplay);
|
||||
|
||||
if ((ob->priv.mode.hdisplay != conn->modes[0].hdisplay) ||
|
||||
(ob->priv.mode.vdisplay != conn->modes[0].vdisplay))
|
||||
{
|
||||
/* set new crtc mode */
|
||||
drmModeSetCrtc(ob->priv.fd, ob->priv.crtc, ob->priv.fb, 0, 0,
|
||||
&ob->priv.conn, 1, &ob->priv.mode);
|
||||
}
|
||||
|
||||
/* free connector resources */
|
||||
drmModeFreeConnector(conn);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* get any plane resource from the card */
|
||||
pres = drmModeGetPlaneResources(ob->priv.fd);
|
||||
|
||||
/* if we have at least one plane, set it up */
|
||||
if (pres->count_planes > 0)
|
||||
{
|
||||
if (!_evas_drm_outbuf_planes_setup(ob, pres))
|
||||
WRN("Could not setup hardware planes");
|
||||
}
|
||||
|
||||
/* free plane resources */
|
||||
drmModeFreePlaneResources(pres);
|
||||
|
||||
/* free drm resources */
|
||||
drmModeFreeResources(res);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
evas_drm_outbuf_framebuffer_set(Outbuf *ob, Buffer *buffer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* validate params */
|
||||
if ((!ob) || (!buffer)) return;
|
||||
|
||||
/* DBG("Drm Framebuffer Set: %d", buffer->fb); */
|
||||
|
||||
buffer->valid = EINA_FALSE;
|
||||
ret = drmModeSetCrtc(ob->priv.fd, ob->priv.crtc, buffer->fb, 0, 0,
|
||||
&ob->priv.conn, 1, &ob->priv.mode);
|
||||
|
||||
if (ret) ERR("Failed to set crtc: %m");
|
||||
else buffer->valid = EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_drm_framebuffer_create(int fd, Buffer *buffer, int depth)
|
||||
{
|
||||
struct drm_mode_create_dumb carg;
|
||||
struct drm_mode_destroy_dumb darg;
|
||||
struct drm_mode_map_dumb marg;
|
||||
|
||||
/* check for valid info */
|
||||
if (fd < 0) return EINA_FALSE;
|
||||
|
||||
/* try to create a dumb buffer */
|
||||
memset(&carg, 0, sizeof(carg));
|
||||
carg.width = buffer->w;
|
||||
carg.height = buffer->h;
|
||||
carg.bpp = depth;
|
||||
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &carg) < 0)
|
||||
{
|
||||
ERR("Could not create dumb buffer: %m");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
buffer->stride = carg.pitch;
|
||||
buffer->size = carg.size;
|
||||
buffer->handle = carg.handle;
|
||||
|
||||
DBG("Buffer: %d %d", buffer->w, buffer->h);
|
||||
DBG("Buffer Stride: %d", buffer->stride);
|
||||
DBG("Buffer Size: %d", buffer->size);
|
||||
|
||||
/* try to create a framebuffer object */
|
||||
/* FIXME: Hardcoded bpp */
|
||||
if (drmModeAddFB(fd, buffer->w, buffer->h, 24, depth, buffer->stride,
|
||||
buffer->handle, &buffer->fb))
|
||||
{
|
||||
ERR("Could not create framebuffer object: %m");
|
||||
goto add_err;
|
||||
}
|
||||
|
||||
DBG("Creating dumb buffer: %d %d %d %d", buffer->fb,
|
||||
buffer->w, buffer->h, depth);
|
||||
|
||||
/* try to mmap the buffer */
|
||||
memset(&marg, 0, sizeof(marg));
|
||||
marg.handle = buffer->handle;
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &marg))
|
||||
{
|
||||
ERR("Could not map dumb buffer: %m");
|
||||
goto map_err;
|
||||
}
|
||||
|
||||
/* do actual mmap of memory */
|
||||
buffer->data =
|
||||
mmap(NULL, buffer->size, (PROT_READ | PROT_WRITE),
|
||||
MAP_SHARED, fd, marg.offset);
|
||||
if (buffer->data == MAP_FAILED)
|
||||
{
|
||||
ERR("Could not mmap dumb buffer: %m");
|
||||
goto map_err;
|
||||
}
|
||||
|
||||
/* clear memory */
|
||||
memset(buffer->data, 0, buffer->size);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
map_err:
|
||||
/* remove the framebuffer */
|
||||
drmModeRmFB(fd, buffer->fb);
|
||||
|
||||
add_err:
|
||||
/* destroy buffer */
|
||||
memset(&darg, 0, sizeof(darg));
|
||||
darg.handle = buffer->handle;
|
||||
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &darg);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
evas_drm_framebuffer_destroy(int fd, Buffer *buffer)
|
||||
{
|
||||
struct drm_mode_destroy_dumb darg;
|
||||
|
||||
/* check for valid info */
|
||||
if (fd < 0) return;
|
||||
|
||||
/* unmap the buffer data */
|
||||
if (buffer->data) munmap(buffer->data, buffer->size);
|
||||
|
||||
/* remove the framebuffer */
|
||||
drmModeRmFB(fd, buffer->fb);
|
||||
|
||||
/* destroy buffer */
|
||||
memset(&darg, 0, sizeof(darg));
|
||||
darg.handle = buffer->handle;
|
||||
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &darg);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_drm_framebuffer_send(Outbuf *ob, Buffer *buffer)
|
||||
{
|
||||
/* check for valid Output buffer */
|
||||
if ((!ob) || (ob->priv.fd < 0)) return EINA_FALSE;
|
||||
|
||||
/* check for valid buffer */
|
||||
if (!buffer) return EINA_FALSE;
|
||||
|
||||
if (ob->vsync)
|
||||
{
|
||||
if (drmModePageFlip(ob->priv.fd, ob->priv.crtc,
|
||||
buffer->fb, DRM_MODE_PAGE_FLIP_EVENT, ob) < 0)
|
||||
{
|
||||
ERR("Cannot flip crtc %u for connector %u: %m",
|
||||
ob->priv.crtc, ob->priv.conn);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ob->priv.pending_flip = EINA_TRUE;
|
||||
|
||||
while (ob->priv.pending_flip)
|
||||
drmHandleEvent(ob->priv.fd, &ob->priv.ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NB: We don't actually need to do this if we are not vsync
|
||||
* because we are drawing directly to the buffer anyway.
|
||||
* If we enable the sending of buffer to crtc, it causes vsync */
|
||||
|
||||
/* send this buffer to the crtc */
|
||||
/* evas_drm_outbuf_framebuffer_set(ob, buffer); */
|
||||
|
||||
/* increment buffer we are using */
|
||||
ob->priv.last = ob->priv.curr;
|
||||
ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
|
@ -6,8 +6,6 @@ typedef struct _Render_Engine Render_Engine;
|
|||
struct _Render_Engine
|
||||
{
|
||||
Render_Engine_Software_Generic generic;
|
||||
|
||||
Evas_Engine_Info_Drm *info;
|
||||
};
|
||||
|
||||
/* function tables - filled in later (func and parent func) */
|
||||
|
@ -33,7 +31,7 @@ _output_setup(Evas_Engine_Info_Drm *info, int w, int h)
|
|||
|
||||
if (!evas_render_engine_software_generic_init(&re->generic, ob,
|
||||
evas_outbuf_buffer_state_get,
|
||||
evas_outbuf_get_rot,
|
||||
evas_outbuf_rot_get,
|
||||
evas_outbuf_reconfigure, NULL,
|
||||
evas_outbuf_update_region_new,
|
||||
evas_outbuf_update_region_push,
|
||||
|
@ -93,12 +91,6 @@ eng_setup(Evas *evas, void *einfo)
|
|||
/* try to get the evas public data */
|
||||
if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0;
|
||||
|
||||
/* set canvas reference
|
||||
*
|
||||
* NB: We do this here so that on a vt switch, we can disable
|
||||
* rendering (or re-enable) for this canvas */
|
||||
info->info.evas = evas;
|
||||
|
||||
/* check for valid engine output */
|
||||
if (!(re = epd->engine.data.output))
|
||||
{
|
||||
|
@ -123,9 +115,6 @@ eng_setup(Evas *evas, void *einfo)
|
|||
ob->w, ob->h);
|
||||
}
|
||||
|
||||
/* update the info structure pointer */
|
||||
re->info = info;
|
||||
|
||||
/* reassign engine output */
|
||||
epd->engine.data.output = re;
|
||||
if (!epd->engine.data.output) return 0;
|
||||
|
@ -144,10 +133,13 @@ eng_setup(Evas *evas, void *einfo)
|
|||
static void
|
||||
eng_output_free(void *data)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
Render_Engine *re;
|
||||
|
||||
evas_render_engine_software_generic_clean(&re->generic);
|
||||
free(re);
|
||||
if ((re = data))
|
||||
{
|
||||
evas_render_engine_software_generic_clean(&re->generic);
|
||||
free(re);
|
||||
}
|
||||
|
||||
evas_common_shutdown();
|
||||
}
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
#ifndef EVAS_ENGINE_H
|
||||
# define EVAS_ENGINE_H
|
||||
|
||||
#include "evas_common_private.h"
|
||||
#include "evas_macros.h"
|
||||
#include "evas_private.h"
|
||||
#include "Evas.h"
|
||||
#include "Evas_Engine_Drm.h"
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
# include "evas_common_private.h"
|
||||
# include "evas_macros.h"
|
||||
# include "evas_private.h"
|
||||
# include "Evas.h"
|
||||
# include "Evas_Engine_Drm.h"
|
||||
|
||||
#include "../software_generic/Evas_Engine_Software_Generic.h"
|
||||
|
||||
|
@ -46,43 +36,6 @@ extern int _evas_engine_drm_log_dom;
|
|||
# endif
|
||||
# define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_drm_log_dom, __VA_ARGS__)
|
||||
|
||||
/* define a maximum number of 'buffers' (double-buff, triple-buff, etc) */
|
||||
# define NUM_BUFFERS 2
|
||||
|
||||
typedef struct _Buffer Buffer;
|
||||
typedef struct _Plane Plane;
|
||||
|
||||
struct _Buffer
|
||||
{
|
||||
int w, h;
|
||||
int stride, size;
|
||||
int handle;
|
||||
unsigned int fb;
|
||||
|
||||
void *data; // used for software framebuffers
|
||||
|
||||
# ifdef HAVE_DRM_HW_ACCEL
|
||||
void *bo; // used for hardware framebuffers
|
||||
# endif
|
||||
|
||||
Eina_Bool valid : 1;
|
||||
};
|
||||
|
||||
struct _Plane
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned int crtcs;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int x, y;
|
||||
unsigned int w, h;
|
||||
} src, dst;
|
||||
|
||||
unsigned int num_formats;
|
||||
unsigned int formats[];
|
||||
};
|
||||
|
||||
struct _Outbuf
|
||||
{
|
||||
Evas_Engine_Info_Drm *info;
|
||||
|
@ -93,24 +46,13 @@ struct _Outbuf
|
|||
|
||||
struct
|
||||
{
|
||||
Buffer buffer[NUM_BUFFERS];
|
||||
Ecore_Drm_Fb *buffer[4];
|
||||
|
||||
Eina_List *pending_writes;
|
||||
Eina_List *planes;
|
||||
|
||||
# ifdef HAVE_DRM_HW_ACCEL
|
||||
void *surface;
|
||||
# endif
|
||||
|
||||
int fd;
|
||||
unsigned int conn, crtc, fb;
|
||||
unsigned int crtc_id, conn_id, buffer_id;
|
||||
|
||||
int curr, last, num;
|
||||
|
||||
drmModeModeInfo mode;
|
||||
drmEventContext ctx;
|
||||
|
||||
Eina_Bool pending_flip : 1;
|
||||
} priv;
|
||||
|
||||
Eina_Bool destination_alpha : 1;
|
||||
|
@ -121,16 +63,10 @@ Outbuf *evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h);
|
|||
void evas_outbuf_free(Outbuf *ob);
|
||||
void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
|
||||
Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob);
|
||||
int evas_outbuf_get_rot(Outbuf *ob);
|
||||
int evas_outbuf_rot_get(Outbuf *ob);
|
||||
void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
|
||||
void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
|
||||
void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
|
||||
void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
|
||||
|
||||
Eina_Bool evas_drm_outbuf_setup(Outbuf *ob);
|
||||
void evas_drm_outbuf_framebuffer_set(Outbuf *ob, Buffer *buffer);
|
||||
Eina_Bool evas_drm_framebuffer_create(int fd, Buffer *buffer, int depth);
|
||||
void evas_drm_framebuffer_destroy(int fd, Buffer *buffer);
|
||||
Eina_Bool evas_drm_framebuffer_send(Outbuf *ob, Buffer *buffer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,66 +8,34 @@
|
|||
#define GREEN_MASK 0x00ff00
|
||||
#define BLUE_MASK 0x0000ff
|
||||
|
||||
static Eina_Bool
|
||||
_evas_outbuf_buffer_new(Outbuf *ob, Buffer *buff)
|
||||
static void
|
||||
_evas_outbuf_cb_pageflip(void *data)
|
||||
{
|
||||
buff->w = ob->w;
|
||||
buff->h = ob->h;
|
||||
if (buff->w < ob->priv.mode.hdisplay) buff->w = ob->priv.mode.hdisplay;
|
||||
if (buff->h < ob->priv.mode.vdisplay) buff->h = ob->priv.mode.vdisplay;
|
||||
Outbuf *ob;
|
||||
|
||||
/* create a dumb framebuffer */
|
||||
if (!evas_drm_framebuffer_create(ob->priv.fd, buff, ob->depth))
|
||||
return EINA_FALSE;
|
||||
if (!(ob = data)) return;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
DBG("Outbuf Pagelip Done");
|
||||
|
||||
static void
|
||||
_evas_outbuf_buffer_put(Outbuf *ob, Buffer *buffer, Eina_Rectangle *rects, unsigned int count)
|
||||
{
|
||||
/* validate input params */
|
||||
if ((!ob) || (!buffer)) return;
|
||||
|
||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
|
||||
drmModeClip *clip;
|
||||
unsigned int i = 0;
|
||||
int ret;
|
||||
|
||||
clip = alloca(count * sizeof(drmModeClip));
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
clip[i].x1 = rects[i].x;
|
||||
clip[i].y1 = rects[i].y;
|
||||
clip[i].x2 = rects[i].w;
|
||||
clip[i].y2 = rects[i].h;
|
||||
}
|
||||
|
||||
/* DBG("Marking FB Dirty: %d", buffer->fb); */
|
||||
ret = drmModeDirtyFB(ob->priv.fd, buffer->fb, clip, count);
|
||||
if (ret)
|
||||
{
|
||||
if (ret == -EINVAL)
|
||||
ERR("Could not set FB Dirty: %m");
|
||||
}
|
||||
#endif
|
||||
ob->priv.last = ob->priv.curr;
|
||||
ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
|
||||
{
|
||||
Buffer *buff;
|
||||
Ecore_Drm_Fb *buff;
|
||||
|
||||
buff = &(ob->priv.buffer[ob->priv.curr]);
|
||||
buff = ob->priv.buffer[ob->priv.curr];
|
||||
|
||||
/* if this buffer is not valid, we need to set it */
|
||||
if (!buff->valid) evas_drm_outbuf_framebuffer_set(ob, buff);
|
||||
ecore_drm_fb_set(ob->info->info.dev, buff);
|
||||
|
||||
/* mark the fb as dirty */
|
||||
_evas_outbuf_buffer_put(ob, buff, rects, count);
|
||||
ecore_drm_fb_dirty(buff, rects, count);
|
||||
|
||||
/* send this buffer to the crtc */
|
||||
evas_drm_framebuffer_send(ob, buff);
|
||||
ecore_drm_fb_send(ob->info->info.dev, buff, _evas_outbuf_cb_pageflip, ob);
|
||||
}
|
||||
|
||||
Outbuf *
|
||||
|
@ -84,37 +52,25 @@ evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h)
|
|||
ob->w = w;
|
||||
ob->h = h;
|
||||
|
||||
ob->info = info;
|
||||
ob->depth = info->info.depth;
|
||||
ob->rotation = info->info.rotation;
|
||||
ob->destination_alpha = info->info.destination_alpha;
|
||||
ob->vsync = info->info.vsync;
|
||||
|
||||
/* set drm card fd */
|
||||
ob->priv.fd = info->info.fd;
|
||||
ob->priv.crtc_id = info->info.crtc_id;
|
||||
ob->priv.conn_id = info->info.conn_id;
|
||||
ob->priv.buffer_id = info->info.buffer_id;
|
||||
|
||||
/* try to setup the drm card for this outbuf */
|
||||
if (!evas_drm_outbuf_setup(ob))
|
||||
{
|
||||
ERR("Could not setup output");
|
||||
free(ob);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ob->w < ob->priv.mode.hdisplay) ob->w = ob->priv.mode.hdisplay;
|
||||
if (ob->h < ob->priv.mode.vdisplay) ob->h = ob->priv.mode.vdisplay;
|
||||
|
||||
info->info.output = ob->priv.fb;
|
||||
|
||||
ob->priv.num = NUM_BUFFERS;
|
||||
/* default to double-buffer */
|
||||
ob->priv.num = 2;
|
||||
|
||||
/* check for buffer override */
|
||||
if ((num = getenv("EVAS_DRM_BUFFERS")))
|
||||
{
|
||||
ob->priv.num = atoi(num);
|
||||
|
||||
/* cap maximum # of buffers */
|
||||
if (ob->priv.num <= 0) ob->priv.num = 1;
|
||||
else if (ob->priv.num > 3) ob->priv.num = 3;
|
||||
else if (ob->priv.num > 4) ob->priv.num = 4;
|
||||
}
|
||||
|
||||
/* check for vsync override */
|
||||
|
@ -124,17 +80,25 @@ evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h)
|
|||
/* try to create buffers */
|
||||
for (; i < ob->priv.num; i++)
|
||||
{
|
||||
if (!_evas_outbuf_buffer_new(ob, &(ob->priv.buffer[i])))
|
||||
break;
|
||||
ob->priv.buffer[i] =
|
||||
ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
|
||||
if (!ob->priv.buffer[i])
|
||||
{
|
||||
ERR("Failed to create buffer %d", i);
|
||||
break;
|
||||
}
|
||||
|
||||
DBG("Evas Engine Created Dumb Buffer");
|
||||
DBG("\tFb: %d", ob->priv.buffer[i]->id);
|
||||
DBG("\tHandle: %d", ob->priv.buffer[i]->hdl);
|
||||
DBG("\tStride: %d", ob->priv.buffer[i]->stride);
|
||||
DBG("\tSize: %d", ob->priv.buffer[i]->size);
|
||||
DBG("\tW: %d\tH: %d",
|
||||
ob->priv.buffer[i]->w, ob->priv.buffer[i]->h);
|
||||
}
|
||||
|
||||
/* set the front buffer to be the one on the crtc */
|
||||
evas_drm_outbuf_framebuffer_set(ob, &(ob->priv.buffer[0]));
|
||||
|
||||
/* set back buffer as first one to draw into */
|
||||
/* ob->priv.curr = (ob->priv.num - 1); */
|
||||
|
||||
ob->info = info;
|
||||
ecore_drm_fb_set(info->info.dev, ob->priv.buffer[0]);
|
||||
|
||||
return ob;
|
||||
}
|
||||
|
@ -146,7 +110,7 @@ evas_outbuf_free(Outbuf *ob)
|
|||
|
||||
/* destroy the old buffers */
|
||||
for (; i < ob->priv.num; i++)
|
||||
evas_drm_framebuffer_destroy(ob->priv.fd, &(ob->priv.buffer[i]));
|
||||
ecore_drm_fb_destroy(ob->priv.buffer[i]);
|
||||
|
||||
/* free allocate space for outbuf */
|
||||
free(ob);
|
||||
|
@ -177,26 +141,24 @@ evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth)
|
|||
{
|
||||
ob->w = w;
|
||||
ob->h = h;
|
||||
if (ob->w < ob->priv.mode.hdisplay) ob->w = ob->priv.mode.hdisplay;
|
||||
if (ob->h < ob->priv.mode.vdisplay) ob->h = ob->priv.mode.vdisplay;
|
||||
}
|
||||
else
|
||||
{
|
||||
ob->w = h;
|
||||
ob->h = w;
|
||||
if (ob->w < ob->priv.mode.vdisplay) ob->w = ob->priv.mode.vdisplay;
|
||||
if (ob->h < ob->priv.mode.hdisplay) ob->h = ob->priv.mode.hdisplay;
|
||||
}
|
||||
|
||||
/* destroy the old buffers */
|
||||
for (; i < ob->priv.num; i++)
|
||||
evas_drm_framebuffer_destroy(ob->priv.fd, &(ob->priv.buffer[i]));
|
||||
ecore_drm_fb_destroy(ob->priv.buffer[i]);
|
||||
|
||||
for (i = 0; i < ob->priv.num; i++)
|
||||
{
|
||||
if (!_evas_outbuf_buffer_new(ob, &(ob->priv.buffer[i])))
|
||||
ob->priv.buffer[i] =
|
||||
ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
|
||||
if (!ob->priv.buffer[i])
|
||||
{
|
||||
CRI("Failed to create buffer");
|
||||
ERR("Failed to create buffer %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +252,7 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int
|
|||
Eina_Rectangle rect = {0, 0, 0, 0}, pr;
|
||||
DATA32 *src;
|
||||
DATA8 *dst;
|
||||
Buffer *buff;
|
||||
Ecore_Drm_Fb *buff;
|
||||
int bpp = 0, bpl = 0;
|
||||
int rx = 0, ry = 0;
|
||||
|
||||
|
@ -304,8 +266,8 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int
|
|||
if (!(src = update->image.data)) return;
|
||||
|
||||
/* check for valid desination data */
|
||||
buff = &(ob->priv.buffer[ob->priv.curr]);
|
||||
if (!(dst = buff->data)) return;
|
||||
buff = ob->priv.buffer[ob->priv.curr];
|
||||
if (!(dst = buff->mmap)) return;
|
||||
|
||||
if ((ob->rotation == 0) || (ob->rotation == 180))
|
||||
{
|
||||
|
@ -489,7 +451,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
|
|||
}
|
||||
|
||||
int
|
||||
evas_outbuf_get_rot(Outbuf *ob)
|
||||
evas_outbuf_rot_get(Outbuf *ob)
|
||||
{
|
||||
return ob->info->info.rotation;
|
||||
return ob->rotation;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue