GUI responsiveness (was Re: SHR first impression : it's slow ?)

Joel Newkirk freerunner at newkirk.us
Thu Feb 26 05:43:00 CET 2009


On Wed, 25 Feb 2009 12:43:59 +0100
Helge Hafting <helge.hafting at hist.no> wrote:

> Joel Newkirk wrote:

> > With the default.edj theme (Illume doesn't override it for Fileman,
> > which includes Illume icons) every icon on the 'desktop' initially
> > displays just the icon image, be it png, jpg, animated edj,
> > whatever. When you touch the screen to scroll it, it will highlight
> > the touched icon even if you don't actually select it.
> Hm - it shoudln't highlight unless it actually is selected. :-/
> >  When it highlights it, it
> > makes visible a 'background' png behind the icon, and two or three
> > layers of transparent pngs on top of the icon, to give the 'glass
> > button with an icon embedded in it' effect. Even when not visible
> > (IE, on at least all but one icon at a time) those extra pngs are
> > there, their positions are calculated AFAIK and their bitmaps are
> > loaded.
> 
> I'm not sure if I understand that. Only one icon looks like a glass 
> button - sure. Now, I understand that illume may have precomputed the 
> glass button look for every icon there is, spending some memory. But
> why should that need any cpu when scrolling? The glass button effect
> isn't applied to the other icons, so those glass images should just
> sit in memory somewhere untouched?
> 
> > (again, AFAIK - those two are internals of Enlightenment and I'm
> > guessing)  

As I said, I'm guessing, but when I removed the extra PNG images and
leav just one, enlightenment average CPU drops and the display is more
responsive. The glass button effect /is/ applied to every icon,
it's just that the parts ('parts' in edc syntax) relevant to the effect
are flagged as non-visible by default.  I'm assuming that even when a
element in the GUI is flagged visible=0 that it still calculates its
position onscreen, so that if you have 20 icons in Illume then you're
trying to scroll at least 100 transparent png images. ('icon' image,
background, shine, highlight, shadow - there are actually 9 png images
specified, plus the icon image itself) Pasted at the end is the entire
group "e/fileman/desktop/icon/fixed" from default.edc. You can see that
each icon actually contains eight png images, and twelve programs,
including six that specify animated transitions.

it also doesn't help that Enlightenment is advanced enough to perform
some very nice scaling tricks - like specifying that 6 pixels inward
from each edge should not be stretched away from that edge, so for
example you can have a 13x13 PNG that functions as a 6-pixel border,
with the central pixel being scaled as large as needed, while the edges
are only stretched in one dimension, along the edge.  Wonderful feature
to have, but I suspect that the calculations involved in this scaling
and other nice effects E offers are at least a slight detriment to the
(integer) FR user experience...

> > But to make the user experience worse, whenever those extra pngs are
> > made visible or invisible, it uses an animated fade-in/fade-out.  So
> > every time you drag to scroll, it's busy animating a fade-out on the
> > previously highlighted icon, animating a fade-in on the one under
> > your finger, and scrolling all the transparent and invisible PNGs.
> > The effect is quite attractive, if only the FR had the horsepower
> > to manage it while running a phone, GPS, and frameworkd. :(
> 
> I see no fade effect. When I click an icon, it gets the "glass"
> effect. It appear with a slight delay, but there is no visible "fade
> in". One minute there is just the icon, the next moment it is
> "glassed". So if much work goes into this - then it is all wasted.

If you watch an icon closely when you press your stylus against it, you
can usually perceive the fade-in taking place, particularly if your FR
is straining, in which case you can sometimes see a few distinct delayed
steps.  The linear transition is set to occur in 0.2 seconds fading in,
and 0.1 seconds fading out - so it is quite brief.  I believe it
abides by the "Framerate" setting in Illume config (the spanner), such
that a 30fps setting and a 0.2 second fade equal a 6-frame animation.
You can see it in the first two program sections below, "go_active" and
"go_passive". The thumb_gen series with the decelerated and sinusoidal
transitions aren't used on the Illume desktop it seems, but if you for
example open the wallpaper settings in Illume config you can observer
thumbnails that 'zoom' out from zero size when displayed, to become
clickable 'icons'.

> > 
> > With the present state of my altered Illume theme (serenity.edj)
> > I've trimmed the icons down to just the 'icon' image itself and a
> > single png that appears behind it when highlighted.  Outside the
> > theme itself I've disabled dropshadows and changed rendering, and
> > disabled the battery applet display (pending debugging - it sucks
> > CPU apparently) and it reduced Enlightenment cpu usage
> > dramatically.  
> > 
> > But I found significant further savings by tweaking icons.  
> [...]
> I am looking forward to see all this.  :-) It should definitely
> improve the user experience.
> 
> Helge Hafting

Thanks for the encouragement. :)  It's already improved my user
experience, but in my poking about I've broken things as well, which is
why I'm not offering the .edj to anyone yet.  I plan to start from a
clean extraction from illume.edj and default.edj once more, applying
only the changes confirmed to be beneficial and not cause E to segfault.
But at the pace I'm going that'll be a couple weeks still.  Hopefully
at that point I'll be able to offer tarball and ipk versions of the
theme for both enlightenment in general and for elementary (shr-dialer
and kin, paroli, Raster's alarm, shr-config, etc all use elementary) as
well as my iconset, which consists about 85% of Oxygen icons, renamed
to match up with our common apps.  (for a 'release' of that I think I
should retain the original names and symlink to the ones useful for
us)  At that time I'd be honored if the theme were of 'official'
interest, but regardless I hope it will help nudge the distributions
toward optimizing the default (state, not default.edj specifically)
themes.

j

/*
below are lines 14053 through 14438 of 'default.edc', inside
'default.edj', this copy extracted from FSO M5 IIRC but I believe the
same utilized in SHR. At the top it specifies what images are required
for this 'group', which defines a single icon on the desktop. (Illume in
our case) It also uses 'pager_base2.png' which is defined in a global
images stanza.  
*/

   group { name: "e/fileman/desktop/icon/fixed";
      images {
         image: "bt_sm_base1.png" COMP;
	 image: "bt_sm_shine.png" COMP;
	 image: "bt_sm_hilight.png" COMP;

	 image: "e17_mini_button_shadow2.png" COMP;
	 image: "e17_fileman_thumb_bg.png" COMP;
	 image: "icon_efm_dnd_copy.png" COMP;
	 image: "icon_efm_dnd_ask.png" COMP;
	 image: "icon_efm_dnd_move.png" COMP;
      }
      parts {
	 part { name: "bg";
	    mouse_events: 0;
	    description { state: "default" 0.0;
	       visible: 0;
	       color: 255 255 255 0;
	       rel1 {
		  relative: 0.0 0.0;
		  offset: -5 -5;
	       }
	       rel2 {
		  relative: 1.0 1.0;
		  offset: 4 4;
	       }
	       image {
		  normal: "bt_sm_base1.png";
		  border: 6 6 6 6;
	       }
	    }
	    description { state: "selected" 0.0;
	       inherit: "default" 0.0;
	       visible: 1;
	       color: 255 255 255 255;
	       rel1 {
		  relative: 0.0 0.0;
		  offset: -2 -2;
	       }
	       rel2 {
		  relative: 1.0 1.0;
		  offset: 1 1;
	       }
	    }
	 }
	 part {	name: "icon_box_shadow";
	    mouse_events: 0;
	    description { state: "default" 0.0;
	       visible: 0;
	       rel1 {
		  to: "icon_box";
		  relative: 0.0 0.0;
		  offset: -1 -1;
	       }
	       rel2 {
		  to: "icon_box";
		  relative: 1.0 1.0;
		  offset: 2 2;
	       }
	       image {
		  normal: "e17_mini_button_shadow2.png";
		  border: 6 6 6 6;
	       }
	    }
	    description { state: "visible" 0.0;
	       inherit: "default" 0.0;
	       visible: 1;
	    }
	 }
	 part { name: "icon_box";
	    type: RECT;
	    mouse_events:  0;
	    description { state: "default" 0.0;
	       visible: 0;
	       align: 0.5 0.5;
	       rel1 {
		  to: "e.swallow.icon";
		  relative: 0.0 0.0;
		  offset: -1 -1;
	       }
	       rel2 {
		  to: "e.swallow.icon";
		  relative: 1.0 1.0;
		  offset: 0 0;
	       }
	       color: 0 0 0 64;
	    }
	    description { state: "visible" 0.0;
	       inherit: "default" 0.0;
	       visible: 1;
	    }
	 }
	 part { name: "icon_box_bg";
	    mouse_events:  0;
	    description { state: "default" 0.0;
	       visible: 0;
	       rel1 {
		  to: "icon_box";
		  relative: 0.0 0.0;
		  offset: 1 1;
	       }
	       rel2 {
		  to: "icon_box";
		  relative: 1.0 1.0;
		  offset: -2 -2;
	       }
	       image.normal: "pager_base2.png";
	       fill {
		  smooth: 0;
		  size {
		     relative: 0 0;
		     offset:   32 32;
		  }
	       }
	    }
	    description { state: "visible" 0.0;
	       inherit: "default" 0.0;
	       visible: 1;
	    }
	 }
	 part { name: "icon0";
	    type: RECT;
	    mouse_events: 0;
	    description { state: "default" 0.0;
	       align: 0.5 0.5;
	       aspect: 1.0 1.0;
	       aspect_preference: VERTICAL;
	       visible: 0;
	       rel1 {
		  relative: 0.0 0.0;
		  offset: 2 2;
	       }
	       rel2 {
		  to_y: "e.text.label";
		  relative: 1.0 0.0;
		  offset: -3 -1;
	       }
	       color: 0 0 0 0;
	    }
	 }
	 part { name: "icon";
	    type: RECT;
	    mouse_events: 0;
	    description { state: "default" 0.0;
	       align: 0.5 0.5;
	       aspect: 1.0 1.0;
	       aspect_preference: BOTH;
	       visible:  0;
	       rel1.to: "icon0";
	       rel2.to: "icon0";
	       color: 0 0 0 0;
	    }
	    description { state: "min" 0.0;
	       inherit: "default" 0.0;
	       max: 0 0;
	    }
	    description { state: "max" 0.0;
	       inherit: "default" 0.0;
	       rel1 {
		  to: "icon0";
		  relative: 0.0  0.0;
		  offset:   -4   -4;
	       }
	       rel2 {
		  to: "icon0";
		  relative: 1.0  1.0;
		  offset:   3    3;
	       }
	    }
	    description { state: "max2" 0.0;
	       inherit:  "default" 0.0;
	       rel1 {
		  to: "icon0";
		  relative: 0.0  0.0;
		  offset:   -2   -2;
	       }
	       rel2 {
		  to: "icon0";
		  relative: 1.0  1.0;
		  offset:   1    1;
	       }
	    }
	 }
	 part { name: "e.swallow.icon";
	    type: SWALLOW;
	    description { state: "default" 0.0;
	       aspect: 1.0 1.0;
	       aspect_preference: BOTH;
	       align: 0.5 0.5;
	       //          fixed:    1 1;
	       rel1.to: "icon";
	       rel2.to: "icon";
	    }
	 }
	 part { name: "e.text.label";
	    type: TEXT;
	    effect: SOFT_SHADOW;
	    mouse_events:  0;
	    scale: 1;
	    description { state: "default" 0.0;
	       align: 0.5 1.0;
	       fixed: 0 1;
	       rel1 {
		  relative: 0.0 1.0;
		  offset:   2 -2;
	       }
	       rel2 {
		  relative: 1.0 1.0;
		  offset:   -3 -2;
	       }
	       color: 224 224 224 255;
	       color3: 0 0 0 32;
	       text {
                  font: "Sans:style=Bold";
		  size: 10;
		  min: 0 1;
		  align: 0.5 0.5;
		  text_class: "desktop_icon";
	       }
	    }
	    description { state: "selected" 0.0;
	       inherit: "default" 0.0;
	       color: 224 224 224 255;
	       color3: 0 0 0 64;
	    }
	 }
	 part { name: "fg1";
	    mouse_events: 0;
	    description { state: "default" 0.0;
	       visible: 0;
	       color: 255 255 255 0;
	       rel1.to: "bg";
	       rel2.relative: 1.0 0.5;
	       rel2.to: "bg";
	       image {
		  normal: "bt_sm_hilight.png";
		  border: 6 6 6 0;
	       }
	    }
	    description { state: "selected" 0.0;
	       inherit: "default" 0.0;
	       visible: 1;
	       color: 255 255 255 255;
	    }
	 }
	 part { name: "fg2";
	    mouse_events: 0;
	    description { state: "default" 0.0;
	       visible: 0;
	       color: 255 255 255 0;
	       rel1.to: "bg";
	       rel2.to: "bg";
	       image {
		  normal: "bt_sm_shine.png";
		  border: 6 6 6 0;
	       }
	    }
	    description { state: "selected" 0.0;
	       inherit: "default" 0.0;
	       visible: 1;
	       color: 255 255 255 255;
	    }
	 }
	 part { name: "event";
	    type: RECT;
	    mouse_events: 1;
	    description { state: "default" 0.0;
	       color: 0 0 0 0;
	    }
	 }
	 part { name: "dnd_action";
	    type: IMAGE;
	    mouse_events:  0;
	    repeat_events: 0;
	    description { state: "default" 0.0;
	       color:      0 0 0 0;
	    }
	    description { state: "visible" 0.0;
	       aspect: 1.0 1.0;
	       aspect_preference: BOTH;
	       align: 1.0 1.0;
	       min: 24 24;
	       rel1.relative: 0.75 0.0;
	       rel2.relative: 1.0 1.0;
	    }
	    description { state: "copy" 0.0;
	       inherit: "visible" 0.0;
	       image.normal:  "icon_efm_dnd_copy.png";
	    }
	    description { state: "ask" 0.0;
	       inherit: "visible" 0.0;
	       image.normal:  "icon_efm_dnd_ask.png";
	    }
	    description { state: "move" 0.0;
	       inherit: "visible" 0.0;
	       image.normal:  "icon_efm_dnd_move.png";
	    }
	 }
      }
      programs {
	 program { name: "go_active";
	    signal:  "e,state,selected";
	    source:  "e";
	    action:  STATE_SET "selected" 0.0;
	    target:  "bg";
	    target:  "fg1";
	    target:  "fg2";
	    target:  "e.text.label";
	    transition: LINEAR 0.2;
	 }
	 program { name: "go_passive";
	    signal:  "e,state,unselected";
	    source:  "e";
	    action:  STATE_SET "default" 0.0;
	    target:  "bg";
	    target:  "fg1";
	    target:  "fg2";
	    target:  "e.text.label";
	    transition: LINEAR 0.1;
	 }
	 program { name: "ask";
	    signal: "e,state,ask";
	    source: "e";
	    action: STATE_SET "ask" 0.0;
	    target: "dnd_action";
	 }
	 program { name: "move";
	    signal: "e,state,move";
	    source: "e";
	    action: STATE_SET "move" 0.0;
	    target: "dnd_action";
	 }
	 program { name: "copy";
	    signal: "e,state,copy";
	    source: "e";
	    action: STATE_SET "copy" 0.0;
	    target: "dnd_action";
	 }
	 program { name: "thumb_gen";
	    signal:  "e,action,thumb,gen";
	    source:  "e";
	    action:  STATE_SET "visible" 0.0;
	    target:  "icon_box_shadow";
	    target:  "icon_box";
	    target:  "icon_box_bg";
	    after:   "thumb_gen2";
	 }
	 program { name: "thumb_gen-";
	    signal:  "e,action,thumb,gen,alpha";
	    source:  "e";
	    action:  STATE_SET "default" 0.0;
	    target:  "icon_box_shadow";
	    target:  "icon_box";
	    target:  "icon_box_bg";
	    after:   "thumb_gen2";
	 }
	 program { name: "thumb_gen2";
	    action:  STATE_SET "min" 0.0;
	    target:  "icon";
	    after:   "thumb_gen3";
	 }
	 program { name: "thumb_gen3";
	    action:  STATE_SET "max" 0.0;
	    target:  "icon";
	    transition: DECELERATE 0.2;
	    after:   "thumb_gen4";
	 }
	 program { name: "thumb_gen4";
	    action:  STATE_SET "default" 0.0;
	    target:  "icon";
	    transition: SINUSOIDAL 0.1;
	    after:   "thumb_gen5";
	 }
	 program { name: "thumb_gen5";
	    action:  STATE_SET "max2" 0.0;
	    target:  "icon";
	    transition: SINUSOIDAL 0.2;
	    after:   "thumb_gen6";
	 }
	 program { name: "thumb_gen6";
	    action:  STATE_SET "default" 0.0;
	    target:  "icon";
	    transition: SINUSOIDAL 0.3;
	 }
      }
   }




More information about the community mailing list