Datagrid2 Form view slow down.
Mark Waddingham
mark at livecode.com
Tue Aug 27 06:45:21 EDT 2019
On 2019-08-23 17:11, Pi Digital via use-livecode wrote:
> Hi all
>
> I’ve been testing extensively all day and I’ve determined that
> acceleratedRendering has no effect on Form View DataGrids at all.
> Screen recordings and lining them up shows no difference in
> performance with zero, one , two, three or four fields populated with
> 200 or 2000 records of data. It is jerky and stutters even on an over
> the top 12 core Mac Pro.
What is the behavior script of your row template group?
The key thing to ensure acceleratedRendering has an effect on the
DataGrid
is that you only change properties of the group or its children *if*
they
need to change.
The performance advantage of acceleratedRendering is predicated on only
the previously invisible rows which are coming into view being
re-rendered
(and thus recached) when scrolling occurs. If existing visible rows
change
whilst scrolling occurs then it is no different to having accelerated
rendering is false.
Four things which are critically important:
1) The 'effective layerMode' of the datagrid group must be
'container'- it
sounds like you already managed to turn off any properties on your
datagrids
which were causing this not to be the case.
2) The 'minimal layout' option must be true - if this isn't true then
the
LayoutControl message will be sent for all rows whilst scrolling
which
typically ends up setting rects and related properties of child
controls
resulting in those already visible rows being re-rendered.
3) If there is a dgHilite setter in the behavior script then it must
not
change any control properites *unless* they have actually changed.
(Just like
the LayoutControl, the DG sends this to every row even if the value
hasn't
changed - however unlike the LayoutControl message I couldn't see a
backwards
compatible way of not making it do this :( )
4) The 'cache controls' property must be false - this might be okay
for small
numbers of rows, but as the number of rows increases the overhead
of manipulating
so many invisible/cached groups in the DataGrid vastly dominates
the value of
having it at all.
Another thing which is worth fiddling with is the compositor settings of
the stack. The
following is a reasonable heuristic for determining what reasonable
values should be:
/* Fetch the maximum pixel scale of all screens */
local tPixelScale
put the systemPixelScale into tPixelScale
/* Compute the pixel width and height of the stack (content) */
local tPixelWidth, tPixelHeight
put the width of pSelf["stack"] * tPixelScale into tPixelWidth
put the height of pSelf["stack"] * tPixelScale into tPixelHeight
/* Compute the tile size, based on pixel scale */
local tTileSize
if tPixelScale < 2 then
put 32 into tTileSize
else if tPixelScale < 4 then
put 64 into tTileSize
else
put 128 into tTileSize
end if
/* Compute the number of tiles covering across and down the window
*/
local tTilesAcross, tTilesDown
put (tPixelWidth + tTileSize - 1) div tTileSize into tTilesAcross
put (tPixelHeight + tTileSize - 1) div tTileSize into tTilesDown
/* Compute the total tile count */
local tTileCount
put tTilesAcross * tTilesDown into tTileCount
/* Make the cache limit big enough for twice the number of tiles
needed
* (note cachelimit is in bytes, with 4 bytes per pixel) */
local tCacheLimit
put (tTileCount * 2) * tTileSize * tTileSize * 4 into tCacheLimit
/* Configure the compositor properties */
set the compositorTileSize of pSelf["stack"] to tTileSize
set the compositorCacheLimit of pSelf["stack"] to tCacheLimit
The above is particularly important on Desktop and iPads as they tend to
have very many
more pixels being rendered (and thus needing cached) than any other
hardware (due to the
increasingly high density of displays).
> The good news to me is that it gets identical performance even running
> in a chrome browser standalone - which I find pleasantly impressive
> all things considered.
I remember being somewhat surprised at this fact when we started working
on the HTML5
port - however it is easy to rationalise why it is the case... Rendering
anything is
almost entirely dominated by the number of pixels being composited to
the screen in each
thing being drawn. The code which does this is generally done in very
tight loops - the
kind of thing which JavaScript JITs convert to asm very well. So, for
the most part,
there's probably not much difference in the machine instructions being
executed for
this specific task compared to ahead-of-time compiled code which you get
with the native
engines.
> I’m going to file a bug report for this on the understanding that this
> was intended to be a feature upgrade for DataGrid v2. Even if not,
> excuse the excessive sarcasm but, in 2019 where we have hover boards,
> self driving cars and rockets that can park themselves, it’s hard to
> believe that we still can’t get simple lines of data to scroll
> smoothly up and down a screen on computers literally 1000 times more
> powerful than we were all using 20 years ago (that somehow managed it
> far better!!).
Heh - so 20 years ago we drew a lot less stuff at much lower resolutions
and had to very carefully craft code to ensure that pixels were not
drawn
more than once with generally no alpha-blending or anti-aliasing. You
could
also very rapidly access the screen buffer and copy areas around with
API
calls - which was a common approach to scrolling areas windows.
These days, though, a good screen will require a buffer with 8-10x as
many bytes
and we tend to expect to be able to blend many thing together with
compositing
operations and anti-aliasing (indeed, raster fonts are almost
non-existent these
days, and we expect sub-pixel lcd-oriented smoothing). Also there is no
way to
access the screen buffer to copy stuff around (which, to be fair, is
much
less useful if you have alpha-blending as the trick no longer works).
So whilst computers have become significantly more powerful (I'd
actually
suggest 30-40x would be a more reasonable factor compared to 2000) - we
also
expect a great deal more from them.
In the case of LiveCode, scrolling is actually quite a tricky problem
for form-like
lists due to the fact we have to instantiate and manipulate controls
imperatively
through script which obviously allows you to do pretty much anything you
want - the
general rule is though if you want smooth scrolling then you need to
make sure you
do the absolute minimum work when scrolling.
Its important to remember that the DataGrid is a general and flexible
tool - so
it almost goes without saying that you'll probably get better
performance if you
roll your own specialized variant for your specific use cases. However,
you might
find that you only need to tweak a few things as outlined above and
you'll get
more than adequate smooth scrolling.
Warmest Regards,
Mark.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list