Compare commits

...

48 Commits

Author SHA1 Message Date
Chris Michael 9ce8a3b4fa evas-drm: Add back in the r, g, b masks for conversion
Summary: This is a big oopsie !! Should not have been removed during
previous commit.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:37:53 -04:00
Chris Michael eea1f831c2 evas-drm: Remove evas_drm file from build order
Summary: The Evas Drm engine makes use of Ecore_Drm functions now so
we no longer need private versions of the same code

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 50cb68dbc6 evas-drm: Make evas drm engine use new ecore_drm functions
Summary: As we already have Ecore_Drm which handles all things drm
related, let's make use of it in the Evas Drm Engine. This modifies
the 'meat' of the Evas Drm engine to use Ecore_Drm functions rather
than keeping private versions of the same code.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 1e5557469a evas-drm: Cleanup drm engine code
Summary: With the evas drm engine refactor, some of the fields in the
Render_Engine structure are unused so remove them.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 10973238e3 evas-drm: Cleanup evas_engine header file
Summary: With the evas drm engine refactor, a lot of these fields in
the Outbuf structure are unused so remove them. This also removes
unused private function declarations.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael bdc4d3ebcc evas-drm: Cleanup Engine Info structure
Summary: A few of these engine fields are no longer needed or were
unused in the Evas Drm engine so remove them.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 4bbb84ceb0 ecore-evas-drm: Use new Ecore_Drm functions to get properties of the output
Summary: This makes use of the newly added Ecore_Drm API functions to
get information about the output so we can setup the Evas engine
properly

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 72af269a7a ecore-drm: Change @since 1.15 to @since 1.14 for newly added APIs
Summary: As requested by stefan, change newly added APIs to be @since
1.15

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 677e0c0952 ecore-drm: Modify device pageflip function to accept ecore_drm_fb callbacks
Summary: This modifies the ecore_drm_device pageflip function to make
use of the ecore_drm_fb callbacks passed into the ecore_drm_fb_send
function

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael c98ac111d3 ecore-drm: Add private structure used during pageflip calls
Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 382a10d7df ecore-drm: Add 2 new API functions for setting and sending framebuffers
Summary: This adds 2 new API functions we can use from within the evas
drm engine to set framebuffers as current, and to call a pageflip on
given buffers.

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael bcdec3c57c ecore-drm: Add an API function to return the connector id of an output
Summary: This adds an API function to return the connector id of a
given output.

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 9b4511d6be ecore-drm: Whitespace removal
Summary: No functional changes, just removing whitespace

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 45dbff677d ecore-drm: Add API function to return an output's crtc id
Summary: This adds an API function to return the crtc id of an output

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael c4b7400d5a ecore-drm: Add API function to return an output crtc buffer id
Summary: This adds an API function to return an output's crtc buffer id

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 06107c9720 ecore-drm: Add API function to find an output at given coordinates
Summary: This commit adds an API function that can be used to find an
output given an x/y coordinate pair.

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 2715ce856c ecore-drm: Move doxygen documentation to main Ecore_Drm header
Summary: This moves all doxygen to the main Ecore_Drm header to match
rest of efl.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 40aff97087 ecore-drm: Remove unused API function that should not have been committed
Summary: This API was added in the header while testing a theory, and
should not have been committed.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 245a3c50a2 ecore-drm: Move drm headers to Ecore_Drm
Summary: Since we only create one drm context in the drm_device
structure now, we need the drm headers to be included in Ecore_Drm.h

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 104a43708b ecore-drm: Create drmEventContext Once during device open
Summary: This changes allows us to reuse the same drmEventContext once
so that when we get drm events, we are not constantly recreating the
drmEventContext.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 77513e7976 ecore-drm: Skip repaints if we are VT switched away
Summary: This allows us to skip output rendering if we are VT switched
away.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 8bea018adc ecore-drm: Update device active state on VT switch and use new output_disable function
Summary: This marks an Ecore_Drm_Device as active or not when we VT
switch. We do this so we can skip rendering if we are not active.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 36f79649e7 ecore-drm: Add API function to disable an output
Summary: This adds a new API function we can call to disable an Ecore_Drm_Output

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael c1b625678f ecore-evas-drm: Setup Ecore_Drm_Device for software rendering
Summary: If we are using the software version of ecore_evas_drm, then
make API call to setup the Ecore_Drm_Device for software rendering.
This creates the dumb buffers on the Ecore_Drm_Device.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 22f2ab18ed ecore-drm: Update drm device & output code to remove per-output dumb buffers
Summary: Since we now create the dumb buffers in the ecore_drm_device
structure, we don't need them on a per-output basis. This commit fixes
the output & device code to adjust to this.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 1a21ff3c13 ecore-drm: Add API to setup the drm device for software rendering
Summary: This adds an API we can call from ecore_evas to setup the
device for software rendering which will cause dumb buffers to be
created in the Ecore_Drm_Device structure.

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 8acd29ff4a ecore-drm: Remove per-output framebuffers
Summary: No real need for each output to have its own framebuffers as
we can just create dumb buffers in the drm device structure

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael adfff7c05e ecore-drm: Fix issue of outputs_geometry_get not skipping cloned outputs
Summary: When we make the call to outputs_geometry_get, we should NOT
include cloned outputs in the final size.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:49 -04:00
Chris Michael 0722632c78 ecore-drm: Delay destroy of output if there is a pending flip
Summary: If an output has a pending page flip, we cannot destroy it
until the page flip has completed. This commit adds support to delay
destroying an output until the page flip is completed.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 2a4a095dbe evas-drm: Use ecore_drm_fb_dirty function to mark framebuffer as dirty
Summary: This removes an internal evas drm engine function and instead
uses the new ecore_drm_fb_dirty function call to mark the framebuffer
as dirty

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 4a2425d342 ecore-drm: Add API function to mark a Framebuffer as dirty
Summary: This adds an API function used to mark a framebuffer as dirty

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 9c227fb56b ecore-drm: Fix output_geometry_get function
Summary: This fixes an issue where heights of all outputs would get
added, thus causing the ecore_evas to be created at the wrong size.
Now, the height will be whichever output is larger.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 061967f67a ecore-drm: Remove debug line from launcher
Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael ff9b8f64d3 ecore-drm: Set mode flag for preferred if this is the preferred mode
Summary: This fixes a minor oversight in ecore_drm_output_mode_add
which was not setting the mode->flag to preferred if this is a
preferred mode.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael e034b2a1e9 ecore-drm: Add API function to set output gamma
Summary: This commit adds new API for setting gamma of an Ecore_Drm_Output

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 135a1b8696 ecore-drm: Improve drm output creation, mode detection, and cloning support
Summary: This refactors the output creation code to support better
mode detection, cloning of hotplugged outputs, and initial support for
setting of output gamma (API to follow)

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 911f253770 ecore-drm: Send ECORE_DRM_EVENT_OUTPUT on unplug also
Summary: If we unplug an output, we should still be sending this event
so that the compositor can remove any unplugged outputs

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 8cbffe36c2 ecore-drm: Add support for DPMS on an output
Summary: This commit adds support for setting DPMS level of an output.
This adds a new API function 'ecore_drm_output_dpms_set' to set the
level.

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 20832a3c48 ecore-drm: Better output name format
Summary: Make output names match format reported from kernel

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 10669573ac ecore-drm: Fix formatting
Summary: NO functional changes, just formatting

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 8a3581f13a ecore-drm: Fix issue with edid_parse_string truncating strings
Summary: We should only truncate the string if it's greater than 4

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael fbc7f2235c ecore-drm: Add more connector types
Summary: libdrm has support for Virtual and DSI connector types, so
add those to the connector types

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 1a38dc0819 ecore-drm: Fix formatting
Summary: NO functional changes, just formatting.

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 25927cb5c7 ecore-drm: Move Eeze Udev Watch to Drm Device
Summary: Move the Eeze udev watch to inside the ecore_drm_device. This
allows us to only create One watch to catch all output changes. No
need for more than one watch (one per output) as was done previously

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 52752072ae evas-drm: Use Ecore_Drm_Fb for framebuffers
Summary: This commit changes the evas drm engine to use Ecore_Drm_Fb
for framebuffers. We remove the old 'Buffer' structure from the evas
engine and replace it in Outbuf with Ecore_Drm_Fb. This also removes
unused functions from the evas_drm.c file as we can now use
ecore_drm_fb calls

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael 5f9ddce261 ecore-drm: Add width & height to Ecore_Drm_Fb structure
Summary: This adds a w & h field to the Ecore_Drm_Fb structure so it
can be used from within the Evas engine

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael e1d6cbdee9 evas-drm: Remove evas_bufmgr.c from the Evas Drm engine
Summary: This file is not needed for the software drm engine. This was
added (initially) for combining the drm software & hardware engines
into one. As that is not the case, this file is unused.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
Chris Michael a39b72c798 ecore-drm: Create all framebuffers using XRGB8888 by default
Summary: By default, we should be creating dumb buffers using XRGB8888
that way it does not matter if we have an alpha channel or not in the
buffer.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
2015-04-08 14:03:48 -04:00
16 changed files with 1182 additions and 1711 deletions

View File

@ -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 \

View File

@ -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
*

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -155,7 +155,6 @@ _ecore_drm_launcher_device_open_no_pending(const char *device, int flags)
}
}
DBG("Device opened %s", device);
return fd;
}

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View File

@ -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))
{

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}