Complete
over 2 years ago

BUG: some newer devices clear the screen on every view update. Simulator behaves differently

Some users have reported issues with my app Maze (https://apps.garmin.com/en-US/apps/3a4436a8-1126-4539-a2f2-aefb319a0ef0) and Snake (https://apps.garmin.com/en-US/apps/e443b0cc-8046-4d76-830f-e87517cf14b6), where the screen will go black after starting to play the game.

For efficiency, the screen is drawn using Dc calls, the view's onUpdate does not call the parent, and only the changed parts of the screen are redrawn: during gameplay on Maze, the previous location of the ball is blanked out, and the new location is drawn.  The event loop is run by a timer that calls Ui.requestUpdate() every 100ms.  This method has worked since I originally developed the games for my Forerunner 235.  

However, with newer devices - specifically, the Venu and the Forerunner 55 - this does not work.  For some reason, the display gets blacked out on every call to View.onUpdate. This only happens on the physical watches, not in the simulator, so I have no way to test this behaviour!I can create the undesired behaviour in the simulator by adding a call to View.onUpdate(dc) at the top of the onUpdate method in my view class.

So, here are my requests:

* please correct the behaviour on these watches

* if this behaviour was a desired change, please update your documentation to make it clear that we can no longer perform incremental updates to the screen

* please fix the simulator so that it behaves the same as these watches

* in the meantime, please tell me if there is a workaround for this issue.  I believe my code is correct since it has behaved correctly for years, and there is no detail in the documentation that says that what I'm doing is no longer possible

More details available on request - for some reason I can't add an image here.

  • Yes.  The system font on the Fenix 5 series is antialiased so it won't draw on a palette bitmap.  I tested it both in the simulator and on the watch, and got an exception both times.  My code definitely works, and I took many steps along the way that didn't work - there's a reason for every line that's there. Slight smile

    Regarding our different experiences, I wonder how much of it is down to the fact that you're developing watch faces and my experience is all from apps.  My guess is that there are further differences in how the watches behave between the different app types, especially since watch faces have power consumption considerations and the fast/slow update frequency.

  • and one more thing, according your comment in code
    // fenix5 series can't draw antialiased fonts so need this kind of BufferedBitmap

    yesterday I tested drawing antialiased font on buffered bitmaps and it run well but bitmaps can have own palmette  (but system palmette increasing memory consumption unfortunately) .

    Are you sure that it doesn't run on fenix 5?

  • As I mentioned it doesn't work for all device because you check

    if (bufferedBitmap != null)
    instead
    if (ShouldAlwaysDrawAll)
    where ShouldAlwaysDrawAll is for venus, vivoactive4 etc

    In my case, I have also buffered bitmaps and got review some tieme ago:

    Nice watch face, but there's flash everything on my screen. Can't use whole watch face. Some watch you have resolved the problem, but isn't work on my watch vivoactive 4. Maybe new update?

  • I only ever said it was a workaround. ;)

    This should work well for people who want to draw incrementally - i.e. not clear the screen every time, but the draw logic only draws the differences.  The workaround lets you draw only the differences on to the BufferedBitmap then render the bitmap to the whole screen.

    The logic in my code also means that you don't need to care whether the device clears the screen every time or not - it doesn't matter.  As long as the device supports BufferedBitmap, the code will ensure that the screen is rendered correctly.

    I've solved my immediate problem, and as a result of my workaround, my code works.  This isn't how it should be, and I'm not guaranteeing that the code will work for all use cases, but even if it's not useful to you it will probably be useful for someone out there.  And hopefully this page will get into the search engines so that people find it when they hit this issue.

  • Your solution doesn't solve problem:

    1. For some devices buffered bitmaps not run well event they should support it (e.g. Venus SQ, maybe now is good but I don't want to test users).

    2. Buffered bitmap is not indicator that screen is cleared. It concerns not only venu but also  e.g. vivoactive4 so you should rather use jungle to specify different behaviour.