Home | History | Annotate | Download | only in view
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.view;
     18 
     19 import android.content.Context;
     20 import android.graphics.Canvas;
     21 import android.view.SurfaceHolder;
     22 import android.view.SurfaceView;
     23 
     24 /**
     25  * A {@link SurfaceView} that manages its own rendering thread and uses a {@link SurfaceRenderer} to
     26  * dictate what should be drawn for each frame.
     27  */
     28 public class RenderedSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
     29 
     30     private static final int JOIN_TIME_OUT_MS = 1000;
     31 
     32     private SurfaceRenderer mRenderer;
     33     private volatile boolean mRunning;
     34     private Thread mRenderThread;
     35 
     36     public RenderedSurfaceView(Context context) {
     37         super(context);
     38 
     39         mRenderer = null;
     40         mRunning = false;
     41         getHolder().addCallback(this);
     42     }
     43 
     44     /**
     45      * Sets the renderer to be used.
     46      *
     47      * <i>Must</i> be called after instantiation.
     48      */
     49     public void setRenderer(SurfaceRenderer renderer) {
     50         mRenderer = renderer;
     51     }
     52 
     53     @Override
     54     public void surfaceCreated(SurfaceHolder surfaceHolder) {
     55         mRenderThread = new RenderThread();
     56         mRunning = true;
     57         mRenderThread.start();
     58     }
     59 
     60     @Override
     61     public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
     62         // Configuration changes are disabled so surface changes can be ignored.
     63     }
     64 
     65     @Override
     66     public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
     67         mRunning = false;
     68         // Wait for rendering thread to halt after it has observed that it should no longer render
     69         while (true) {
     70             try {
     71                 mRenderThread.join(JOIN_TIME_OUT_MS);
     72                 break;
     73             } catch (InterruptedException e) {
     74                 // Ignore spurious wakeup
     75             }
     76         }
     77         mRenderThread = null;
     78     }
     79 
     80     /**
     81      * Thread to run the rendering loop for this SurfaceView.
     82      */
     83     private final class RenderThread extends Thread {
     84         private static final int SLEEP_TIME_MS = 16;
     85 
     86         @Override
     87         public void run() {
     88             while (mRunning) {
     89                 SurfaceHolder holder = getHolder();
     90                 Canvas surfaceCanvas = holder.lockCanvas();
     91                 // Draw onto canvas if valid
     92                 if (surfaceCanvas != null && mRenderer != null) {
     93                     mRenderer.onDrawFrame(surfaceCanvas);
     94                     holder.unlockCanvasAndPost(surfaceCanvas);
     95                 }
     96                 try {
     97                     sleep(SLEEP_TIME_MS);
     98                 } catch (InterruptedException e) {
     99                     // Stop rendering if interrupted
    100                     break;
    101                 }
    102             }
    103         }
    104     }
    105 }
    106