Scaling up the details

by Ian Macphail on April 8, 2014 1 comment

In the previous post, I covered the update to the graphics layer. Updating the graphics library means we can now draw stacks at any scale, which allows us to add a whole slew of new and useful features. One of which is the ability to transparently support high-density displays.

Hi-DPI support

The introduction of the Retina display to iPhone/iPad created something of a problem for apps developed for the previous generation of devices. Apps created at the fixed size of these devices suddenly had four times the number of pixels to fit into (2x width and 2x height), and although they could still display at the same size, on the higher density displays it was apparent that they were not taking advantage of the available high resolution. The reason being that the apps were drawing at the old size, and then being scaled up – giving a stretched, pixelated appearance.

Rather than create a smaller image and scale it up, in order to draw cleanly and crisp on higher density displays you need to create an image with the same number of pixels as the display. This is a problem when your app is 320 x 480 in size, and the area into which you need to draw is now 640 x 960. Without scaled drawing support in the engine you would need to manually adjust everything on the stack to appear twice as big – from the size & position of each control, to the line width of any graphics, to the font size of any text appearing in the app.

To overcome these issues we could now use the new graphics library features to implement scaled drawing within the LiveCode engine. This automatic scaling is now included as of LiveCode 6.6 and is enabled by setting the "usePixelScaling" property. On mobile devices the degree of scaling can also be controlled by changing the "pixelScale" property.

The pixelScale controls the relationship between the logical size of the screen and the number of physical pixels in the display. This is quite straightforward on mobile devices, where there is only a single display. The old pre-Retina Apple devices have a 1:1 ratio of logical coordinates to pixels, retina devices have a 1:2 ratio. For a 320×480 stack to appear at the same size on both devices it should have a pixelScale of 1 on the non-Retina device, and a pixelScale of 2 on the Retina device. This happens automatically in the LiveCode engine – the pixelScale is set on startup to the appropriate value for the density of the display.

Getting it all to work

Implementing this within the engine was pretty challenging. If everything can be scaled, then there is no longer necessarily a 1:1 relationship between the size and location of objects on the stack, and their position on the screen as understood by the operating system. Unfortunately this was an assumption made in many different areas, such as the size and location of windows, to the position of mouse movements and clicks, to the apparent size of the screen itself. The situation is further complicated by the fact that some platforms expect coordinates in terms of screen pixels (Windows, Android), and others in terms of logical screen coordinates distinct from physical pixel sizes (iOS, OSX) so we end up having to think in terms of three separate coordinate systems: logical sizes within the engine, physical pixels, and logical (or not) coordinates used by the OS.

All this means that where code could previously use the same coordinates when referring to objects on a stack, or the position of the mouse cursor within a window, now that code had to be adapted to translate back & forth from one coordinate system to another. This was made somewhat easier by the progress of ongoing refactoring work to separate out window-related functionality from the tangle of stack code that made no distinction between a stack and the window that contains it. Now it was possible to define a scale factor between one and the other, and convert coordinates at the point of passing through from one to the other.

I think this really highlights the value of the work we’ve done to split apart the engine code into clearly defined areas based on a consistent and logical identification of distinct concepts that helps collect related code together and removes the implementation details from areas that are not directly related.

LiveCode 6.6.1 is now available. This is a stable release.

Getting this release
To upgrade to this release please select "check for updates" from the help menu in LiveCode or download the installers directly at: http://downloads.livecode.com/livecode/

read more
Ian MacphailScaling up the details

LiveCode 6.6 Released

by Ben Beaumont on March 26, 2014 9 comments

This release brings automatic scaling and handling of Retina screens to the desktop platforms, in line with the existing iOS and Android support. Also in this release open SSL and encryption support have been added for the mobile platforms. LiveCode continues to increase the feature parity available on all six supported platforms it offers. 

We recognize that whilst the mobile platforms are continuing to grow and mature in terms of apps and development, the desktop platforms are vitally important to developers and end users alike. We are proud to offer seamless support for a huge variety of screen sizes, shapes and densities with LiveCode 6.6. Now you can write the same single line of code to handle scaling for your app on the smallest Android device and the largest Mac Retina screens.

Here is everything that is new in LiveCode 6.6

Assert Command (Experimental)

A new assert command has been added to help people who wish to write tests. It was primarily written to support in-house testing of LiveCode but has been documented in the release notes so LiveCode developers can also make use of it with their projects.

High DPI support

High DPI support on windows and OSX has been added meaning LiveCode applications will now run at the native screen resolution on computers with high density screens. For example, the MacBook Pro now comes with a ‘retina’ screen which has 4x the number of pixels than a standard laptop screen. The extra pixels are there to make the apps on screen crisper, rather than provide more screen real estate. By default, the OS up scales applications implemented without High DPI support to the high density screens, resulting in some pixilation. LiveCode 6.6 now creates apps in the new format allowing the OS to render them at the true screen density. The result, your app looks beautiful!

LiveCode CTO Mark Waddingham talks about the High DPI in his blog post titled – Hi-speed HiDPI

ShowAll fullscreen mode

When running a stack in fullscreen mode you can tell LiveCode how you want your app to be scaled. In LiveCode 6.5 we added a number of scaling options and in 6.6 we added an additional one. ShowAll scales the stack preserving aspect ratio so all content within the stack rect is visible. Portions of the stack outside the stack rect will be visible if the scaled stack does not fit the screen exactly.

HTTPS through proxy

The desktop version of LibURL has been updated to support fetching HTTPS URLs through a proxy server. Anyone writing an app that was deployed to a network secured by proxy could not access internet based URLs. LiveCode now supports auto-detection of proxy server settings so that developer apps will automatically tunnel outside of a network with zero configuration. 

Image Filtering Updates

Due to a degrade in the image resizing quality in 6.5, the image filtering algorithms have been updated for 6.6.

For LiveCode versions prior to 6.5, the image filtering algorithms were not universal across all platforms. "Good" resize quality used bilinear filtering and "best" used bicubic filtering for all platforms. However, "normal" differed. On Mac, box filtering was used. All other platforms applied no filtering.

For LiveCode versions prior to 6.5, all resize operations were cached (i.e. moving a resized image around did not cause the resize to be recalculated).

For LiveCode 6.5, the image filtering was united across all platforms, with no filtering being applied in "normal" mode, bilinear filtering being used in "good" mode and bicubic filtering being used in "best" mode.

For LiveCode 6.5, only "best" resize operations were cached (the acceleratedRendering mode should be used for caching in other modes). All others were calculated on the fly.

The bilinear filter used in 6.5 was of poorer quality when compared to pre 6.5. Additionally, the "normal" mode on Mac was poorer (due to the loss of the box filter). We’ve addressed this in LiveCode 6.6 by improving the image filtering algorithms across all platforms. "Normal" and "good" mode now use updated algorithms. "Best" mode remains as before.

It should be noted that the improvements to the filters used may cause a slight drop in performance. The final image filters and resize modes used has not been finalized and is open to user input.

iOS 7.1 Support

Support has been added for iOS 7.1. For OS 10.8 and 10.9, LiveCode now uses the iOS 7.1 SDK to produce device builds. As such, OS 10.8 and 10.9 users must have the iOS 7.1 SDK installed (which comes with Xcode 5.1) and configured in their mobile preferences in order to produce iOS device builds.

Open SSL & encryption

Open SSL & encryption support has been added to the iOS and Android engines (using LibOpenSSL version 1.0.1e). This allows developers to use the encrypt and decrypt commands on the mobile platforms in exactly the same way they would on desktop. In order to include the SSL and encryption libraries, developers must tick the "SSL & Encryption" checkbox in the iOS/Android pane of the standalone builder.

SQLite update

The version of SQLite has been updated to 3.8.3. We have also cleaned up the way you connect to the database making it simpler, as well as improving binary data support.

Binary data can now be placed into SQLite databases verbatim (without the encoding that used to occur) – this means databases can be made to contain binary data which is compatible with other applications. To utilize this functionality, the ‘binary’ option must be passed to the revOpenDatabase() call when creating the database connection (see below).

Stack Scale Factor

The new scaleFactor stack property allows you to set a custom scale factor for a stack. If you are working on a stack that is larger than your screen, you can ’zoom out’ by reducing the stack size via the scaleFactor property. The stack appears smaller and all assets are scaled, however, the stack still reports to be its native size.

Hashbangs recognized

Hashbangs ‘#!’ is now recognized by LiveCode Server – this brings the LC Server engine more in line with expected behaviors in the Unix/server scripting world.

55 bug fixes

55 bugs have been fixed in this release making it more stable than previous releases.

Get LiveCode 6.6

Your LiveCode install should prompt you to download this latest release. Alternatively you can download the latest release from the LiveCode Download area

read more
Ben BeaumontLiveCode 6.6 Released

Hi-speed HiDPI

by Mark Waddingham on March 18, 2014 2 comments

With 6.6 almost out of the door (we released 6.6. RC 2 today, for those yet to check) we’ve finally added support for new Retina displays to Mac Desktop. This support means that LiveCode apps will look as crisp as other Mac apps on modern Mac laptops with virtually no work at all (you might need to add some @2x images, but that’s about it). However, this crispness does come at a cost…

 

LiveCode’s graphics rendering is inherently CPU-bound (for the moment at least). This means that every pixel you see in a window is being generated by operations performed on the machine’s CPU with the GPU only being involved at the Window Server end when its compositing the display. Whilst this approach means that we can deliver a much richer set of graphics primitives and effects than the host OS can manage, it does mean that Retina has a huge cost – a four-fold cost in fact (Retina displays are double the density in both directions, so that means for every single pixel rendered on a non-Retina display, there will be four pixels rendered on a Retina display).

 

Now, whilst CPU speed hasn’t suddenly jumped 4 four-fold in the same time as pixel counts have, one thing has jumped considerably – the number of cores our CPUs have. Indeed, all Retina MacBook’s have at two cores with each core able to run two threads concurrently. Within this fact lies a potential short-term solution to speeding up display on Retina systems…

 

The solution I’ve been experimenting with is to split the rendering of a stack up into 4 tiles with a separate thread responsible for rendering each tile. The engine keeps a pool of four threads around on which it schedules this work – as soon as one thread is complete, the main thread takes its work and sends it to the appropriate quadrant of the window buffer (ideally the individual threads would do this last part as well to eliminate the inherent bottleneck this creates, however for the APIs the engine currently uses for window updates this isn’t possible).

 

In an ideal world you’d hope to get a 4x speed up to rendering but due to the reality of overhead in the approach this is purely a theoretical limit. However, that being said, my current experiments indicate that around a two-fold increase in rendering speed should be attainable for large and reasonably graphically complex stacks (lots of bitmap effects and gradients) which should certainly help to mitigate jump from normal to Retina resolution.

 

Of course, this approach isn’t limited to Retina displays, the same idea can be applied to any computer with a multi-core CPU – there you could see up to a two-fold increase in rendering speed which is nothing to be sniffed at!

For C-source-level-interested parties, the code for the experiments I’ve been running can be found on the feature-threaded_rendering in my github repo (https://github.com/runrevmark/livecode.git). The code is Mac-only for now (search for MacStackTile in osxstack.cpp), and there’s a few hacks here and there to ensure thread-safety (patterns are disabled and there’s a global lock around text rendering) but it’s certainly showing promise…

read more
Mark WaddinghamHi-speed HiDPI