Search code examples
androidcanvaswear-os

How to get hardware accelerated Canvas in onDraw() of CanvasWatchFaceService?


I am developing a Watch Face for android wear. I want to make the Canvas hardware accelerated.

In manifest I declared it like bellow

     <application
         android:hardwareAccelerated="true"
         ..>
            <service
            android:name=".WatchFaceMain"
            android:hardwareAccelerated="true"
            ..>
    </application>

But when I checked it from inside of My onDraw(Canvas canvas, Rect bounds) method canvas.isHardwareAccelerated() returns false. which clearly means my canvas is not hardware accelerated.

 @Override
 public void onDraw(Canvas canvas, Rect bounds) {
       ...
       boolean isAccelarated = canvas.isHardwareAccelerated();
       .......
 }

How do I make this canvas Hardware Accelerated?


Solution

  • Finally found a solution for this issue. Though it wasn't a straight forward or easy solution.

    First I got to copy the whole android.support.wearable.watchface.CanvasWatchFaceService class from librar, which my WatchFaceMain class extended.

    Then I had to edit the draw() Method inside Engine Class like bellow

    public abstract class CanvasWatchFaceService extends WatchFaceService {
        .....
    
            public class Engine extends android.support.wearable.watchface.WatchFaceService.Engine {
              ...
                private void draw(SurfaceHolder holder) {
                    this.mDrawRequested = false;
                    Canvas canvas = holder.getSurface().lockHardwareCanvas();
                    if(canvas != null) {
                        try {
                            this.onDraw(canvas, holder.getSurfaceFrame());
                        } finally {
                            holder.getSurface().unlockCanvasAndPost(canvas);
                        }
    
                    }
                }
            }
        }
    

    I edited two lines inside onDraw like bellow.

    from
     Canvas canvas = holder.lockCanvas();
    To
     Canvas canvas = holder.getSurface().lockHardwareCanvas();
    
    And From
     holder.unlockCanvasAndPost(canvas);
    To
     holder.getSurface().unlockCanvasAndPost(canvas);
    

    I still wonder why did CanvasWatchFaceService didn't offer any easier way to request for a hardware accelerated canvas!

    More detail solution is available here in this Article.

    Hopefully this answer helps someone else too.