• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.test.hwui;
18 
19 import android.app.Activity;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.Paint;
23 import android.graphics.PorterDuff;
24 import android.os.Bundle;
25 import android.os.Environment;
26 import android.view.PixelCopy;
27 import android.view.Surface;
28 import android.view.SurfaceHolder;
29 import android.view.SurfaceHolder.Callback;
30 import android.view.SurfaceView;
31 import android.view.View;
32 import android.widget.Button;
33 import android.widget.FrameLayout;
34 import android.widget.LinearLayout;
35 import android.widget.Toast;
36 
37 import java.io.FileOutputStream;
38 
39 public class HardwareCanvasSurfaceViewActivity extends Activity implements Callback {
40     private SurfaceView mSurfaceView;
41     private HardwareCanvasSurfaceViewActivity.RenderingThread mThread;
42 
43     @Override
onCreate(Bundle savedInstanceState)44     protected void onCreate(Bundle savedInstanceState) {
45         super.onCreate(savedInstanceState);
46 
47         FrameLayout content = new FrameLayout(this);
48 
49         mSurfaceView = new SurfaceView(this);
50         mSurfaceView.getHolder().addCallback(this);
51 
52         Button button = new Button(this);
53         button.setText("Copy bitmap to /sdcard/surfaceview.png");
54         button.setOnClickListener((View v) -> {
55             final Bitmap b = Bitmap.createBitmap(
56                     mSurfaceView.getWidth(), mSurfaceView.getHeight(),
57                     Bitmap.Config.ARGB_8888);
58             PixelCopy.request(mSurfaceView, b,
59                     (int result) -> {
60                         if (result != PixelCopy.SUCCESS) {
61                             Toast.makeText(HardwareCanvasSurfaceViewActivity.this,
62                                     "Failed to copy", Toast.LENGTH_SHORT).show();
63                             return;
64                         }
65                         try {
66                             try (FileOutputStream out = new FileOutputStream(
67                                     Environment.getExternalStorageDirectory() + "/surfaceview.png");) {
68                                 b.compress(Bitmap.CompressFormat.PNG, 100, out);
69                             }
70                         } catch (Exception e) {
71                             // Ignore
72                         }
73                     }, mSurfaceView.getHandler());
74         });
75 
76         LinearLayout layout = new LinearLayout(this);
77         layout.setOrientation(LinearLayout.VERTICAL);
78         layout.addView(button, LinearLayout.LayoutParams.MATCH_PARENT,
79                 LinearLayout.LayoutParams.WRAP_CONTENT);
80         layout.addView(mSurfaceView, LinearLayout.LayoutParams.MATCH_PARENT,
81                 LinearLayout.LayoutParams.MATCH_PARENT);
82 
83         content.addView(layout, new FrameLayout.LayoutParams(
84                 FrameLayout.LayoutParams.MATCH_PARENT,
85                 FrameLayout.LayoutParams.MATCH_PARENT));
86         setContentView(content);
87     }
88 
89     @Override
surfaceCreated(SurfaceHolder holder)90     public void surfaceCreated(SurfaceHolder holder) {
91         mThread = new RenderingThread(holder);
92         mThread.start();
93     }
94 
95     @Override
surfaceChanged(SurfaceHolder holder, int format, int width, int height)96     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
97         mThread.setSize(width, height);
98     }
99 
100     @Override
surfaceDestroyed(SurfaceHolder holder)101     public void surfaceDestroyed(SurfaceHolder holder) {
102         if (mThread != null) mThread.stopRendering();
103     }
104 
105     private static class RenderingThread extends Thread {
106         private final SurfaceHolder mSurface;
107         private volatile boolean mRunning = true;
108         private int mWidth, mHeight;
109 
RenderingThread(SurfaceHolder surface)110         public RenderingThread(SurfaceHolder surface) {
111             mSurface = surface;
112         }
113 
setSize(int width, int height)114         void setSize(int width, int height) {
115             mWidth = width;
116             mHeight = height;
117         }
118 
119         @Override
run()120         public void run() {
121             float x = 0.0f;
122             float y = 0.0f;
123             float speedX = 5.0f;
124             float speedY = 3.0f;
125 
126             Paint paint = new Paint();
127             paint.setColor(0xff00ff00);
128 
129             while (mRunning && !Thread.interrupted()) {
130                 final Canvas canvas = mSurface.lockHardwareCanvas();
131                 try {
132                     canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
133                     canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint);
134                 } finally {
135                     mSurface.unlockCanvasAndPost(canvas);
136                 }
137 
138                 if (x + 20.0f + speedX >= mWidth || x + speedX <= 0.0f) {
139                     speedX = -speedX;
140                 }
141                 if (y + 20.0f + speedY >= mHeight || y + speedY <= 0.0f) {
142                     speedY = -speedY;
143                 }
144 
145                 x += speedX;
146                 y += speedY;
147 
148                 try {
149                     Thread.sleep(15);
150                 } catch (InterruptedException e) {
151                     // Interrupted
152                 }
153             }
154         }
155 
stopRendering()156         void stopRendering() {
157             interrupt();
158             mRunning = false;
159         }
160     }
161 }
162