Page MenuHomePhabricator

Updated 2,018 Days AgoPublic

<zmike> src/bin/e_comp_object.c
<zmike> this is where all the magic happens
<zmike> this is an abstraction which translates clients into canvas objects
<zmike> and allows them to be moved/resized/etc just like any other object
<zmike> it works by operating on the E_Client->frame member, which is an object that intercepts basic canvas operations and determines how to interpret them in the context of a display server
<zmike> for example, when resizing a client, it will determine how much to actually resize that client based on the current pixmap/buffer size
<zmike> and, if there is a mismatch, it will send a resize callback to the display server compositing backend
<zmike> which will trigger a resize on the client, and then there will eventually be a second resize call which sets the real size
<zmike> rendering is also done in this file
<zmike> there are 3 functions which can be considered The Rendering Functions
<zmike> e_comp_object_damage
<zmike> e_comp_object_dirty
<zmike> e_comp_object_render
<devilhorn> derekf, hmm, ok, this May be something on our end. I will look into it
<zmike> damage works as expected, setting up damage regions on a rectangle tiler which spans the client geometry

  • derekf raises hand

<derekf> the fuck is a tiler?
<zmike> derekf: a tiler is the efl equivalent of a pixman_region32
<derekf> gotcha
<zmike> e_comp_object_dirty is basically the "render prep" function
<derekf> y-x banded monstrosity more intended as a memory bandwidth test than a region representation
<zmike> it sets the render size, flags the object as dirty, sets the opaque image, and then triggers rendering on proxied objects
<zmike> calling this function triggers rendering on that object if it is able to be rendered*
<zmike> *by this, I mean that the scenegraph will calculate factors such as visibility, size, layering, etc to determine whether to actually render the object
<zmike> if the object is determined to require rendering, e_comp_object_render is called
<zmike> this function gets the current pixmap/buffer data from a client, applies damage regions, and then sets the buffer into the image for rendering
<zmike> note that this function is not called directly except in one case
<zmike> this is because the comp_object abstraction uses a special kind of rendering callback which will call the render function as-needed, described above
<zmike> src/bin/e_comp_wl*.c
<zmike> these are the wayland compositor files which implement the base wayland compositor interfaces
<zmike> e_comp_wl.c controls the core functionality, while data and input are for clipboard/drag and input devices, respectively
<zmike> in e_comp_wl.c, there are a number of different types of callbacks, all of which hook onto the comp_object E_Client->frame
<zmike> the _e_comp_wl_client_cb* functions are for CLIENT_HOOK callbacks
<zmike> I'll describe these a bit later
<zmike> _e_comp_wl_evas_cb* functions all hook comp_object evas events
<zmike> evas=canvas, if you are not familiar
<zmike> these events are essentially called after the comp_object abstraction has done its magic to figure out what the client should be doing
<zmike> for example, the _e_comp_wl_evas_cb_resize() function is triggered after a resize has been called on a client's comp_object
<zmike> this sets flags on the client and adds it to an idler which will, on the next main loop iteration, send the configure event
<zmike> the reason for the idler use is to throttle huge numbers of resize calls in the same main loop iteration and prevent things such as external modules from mangling the clients
<zmike> the important thing to note here is that these functions are called AFTER the comp_object has done its work
<zmike> meaning that, in this example, the resize has already occurred on the comp_object
<zmike> and so it has been resized
<zmike> the rest of the functions are implementing various wayland interfaces which you should be familiar with, so I'll skip a bit
<zmike> e_comp_wl_surface_commit() is where most of the functionality happens in the core compositor
<zmike> you'll see a lot of called to e_pixmap* functions, which I'll also get to later
<zmike> but this is basically where we do the rendering and input region applying
<zmike> there's also some handoffs to the shell module
<zmike> which I'll get to in a bit
<zmike> src/bin/e_client.*
<zmike> this is the client abstraction in enlightenment
<zmike> it mainly won't be applicable for wayland things since it doesn't really do much of anything other than allow enlightenment actions to be performed on clients
<zmike> what's important to know here is that there is an idler (which is a type of recurring job that happens on every main loop iteration) that runs through all the clients
<zmike> this filters for "changed" clients and applies various properties
<zmike> changed clients are clients which have had the EC_CHANGED() macro called on them
<zmike> this macro exists to assist debugging efforts if someone fucks up setting the changed flag; never set the changed flag without this macro
<zmike> the primary reason for setting the changed flag is that you need a property on a client to occur at a later time, eg. after you've done something that you know will occur later in the same main loop iteration
<zmike> an example of this would be that when a client has just been created, if you attempt to set certain properties, such as a frame icon (upper left corner of a window), it may fail due to not having the frame set up yet
<zmike> so it's better to just set E_Client->changes.icon
<zmike> and let the idler handle this for you
<zmike> this is a leading cause of bugs
<zmike> ie. attempting to directly or indirectly (using "changed") set client properties when you should be doing the other
<zmike> so if you see a client behaving strangely, checking the idler here is potentially a good start
<zmike> E_Client->netwm and E_Client->icccm are substructs which implement the respective standards for X
<zmike> we also store wayland properties here, however
<zmike> e_client.x is a utility file which contains inline function helpers
<zmike> this is basically just for checking properties
<zmike> for example, e_client_util_ignored_get() will allow you to filter clients that are not focusable
<zmike> such as pointer clients
<zmike> or popups
<zmike> when doing anything with clients that the user is expected to interact with (ie. clients you would expect to show up in winlist), they should be filtered through this function first
<zmike> src/bin/e_pixmap.c
<zmike> this is the pixmap/buffer abstraction
<zmike> for wayland, it's what accesses the shm buffer
<zmike> and saves/returns various related properties
<zmike> it has a number of calls which should be self-explanatory based on the name
<zmike> dirty for marking a pixmap as needing to be refreshed, refresh for resetting the pixmap values, etc
<zmike> pixmap_image_data_get returns the buffer for a given pixmap/client
<zmike> this is the array of pixels which gets used to render a client in e_comp_object_render()
<zmike> probably not much more needs to be said about this file since the functions are very simple and seldom-used outside surface commit
<zmike> src/bin/e_win.c
<zmike> this file exists because of how internal windows are handled in enlightenment
<zmike> the toolkit, elementary, provides a window implementation (elm_win)
<zmike> in order to relate them to enlightenment clients, someone decided to implement an array of callbacks, aka traps, to intercept and override window operations
<zmike> despite being written in 2012, these traps were never tested or used until recently
<zmike> as a result, they're awful and extremely hackish
<zmike> if you see issues related to internal windows, they are probably being caused by this file
<zmike> src/bin/e_pointer.c
<zmike> this is the cursor abstraction
<zmike> in non-X enlightenment, it works by setting an object as the canvas's cursor
<zmike> again, the function to set this cursor was implemented by someone who thought that any time the cursor changed, the previous one should be deleted
<zmike> this was the cause of all cursor-related bugs in the past week
<zmike> when the cursor is an "enlightenment" cursor, which you know as the tiny white-and-sometimes-blue cursor
<zmike> it is an edje object
<zmike> when it is anything else
<zmike> it is actually an E_Client->frame comp_object that has been created in src/bin/e_comp_wl_input.c
<zmike> this client cursor client object is rendered and operated the same way as a client, but it gets moved around automatically by canvas internals
<zmike> there are some other things in here more related to X, but they aren't as relevant now so I'll skip them
<zmike> src/bin/e_dialog.c
<zmike> this is a wrapper around e_win.c for creating internal windows that look like dialogs
<zmike> it's pretty old and will hopefully be removed in the future
<zmike> if you see a dialog, it has gone through creation in this file
<zmike> src/bin/e_config_dialog.c
<derekf> internal window means non client?
<zmike> no, it's still a client
<zmike> but it was created by the enlightenment process
<zmike> all settings dialogs are internal clients
<zmike> and will have E_Client->internal set
<zmike> as well as an E_Client->internal_elm_win object
<zmike> this concludes all files in the core compositor
<zmike> the shell module is found in src/modules/wl_desktop_shell/e_mod_main.c
<zmike> it handles shell stuff like xdg surface interfaces
<devilhorn> and ancient wl_shell stuff :)
<zmike> all non-cursor wayland E_Client objects are created in the shell
<zmike> so if you have an issue with a client, this is the place to start tracing
<zmike> I think that should cover everything for enlightenment wayland compositing
<zmike> e_zone: an object representing a single screen
<zmike> e_manager: an object representing all screens combined

Last Author
Last Edited
Apr 18 2015, 10:17 AM