• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.animation.ObjectAnimator;
20 import android.app.Activity;
21 import android.graphics.Color;
22 import android.graphics.HardwareRenderer;
23 import android.graphics.Paint;
24 import android.graphics.RecordingCanvas;
25 import android.graphics.RenderNode;
26 import android.os.Bundle;
27 import android.os.Handler;
28 import android.view.SurfaceHolder;
29 
30 public class CustomRenderer extends Activity {
31     private RenderNode mRootNode = new RenderNode("CustomRenderer");
32     private RenderNode mChildNode = new RenderNode("RedBox");
33     private HardwareRenderer mRenderer = new HardwareRenderer();
34     private ObjectAnimator mAnimator;
35     private Handler mRedrawHandler = new Handler(true);
36 
37     @Override
onCreate(Bundle savedInstanceState)38     protected void onCreate(Bundle savedInstanceState) {
39         super.onCreate(savedInstanceState);
40         getWindow().takeSurface(mSurfaceCallbacks);
41     }
42 
43     @Override
onStart()44     protected void onStart() {
45         super.onStart();
46         mAnimator = ObjectAnimator.ofFloat(mChildNode, "translationY", 0, 300);
47         mAnimator.setRepeatMode(ObjectAnimator.REVERSE);
48         mAnimator.setRepeatCount(ObjectAnimator.INFINITE);
49         final Runnable redraw = this::draw;
50         mAnimator.addUpdateListener(animation -> {
51             mRedrawHandler.post(redraw);
52         });
53     }
54 
55     @Override
onStop()56     protected void onStop() {
57         super.onStop();
58         mAnimator.end();
59         mAnimator = null;
60     }
61 
setupRoot(int width, int height)62     private void setupRoot(int width, int height) {
63         mRootNode.setPosition(0, 0, width, height);
64 
65         RecordingCanvas canvas = mRootNode.beginRecording();
66         canvas.drawColor(Color.WHITE);
67         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
68         paint.setColor(Color.BLACK);
69         paint.setTextAlign(Paint.Align.CENTER);
70         float textSize = Math.min(width, height) * .05f;
71         paint.setTextSize(textSize);
72         canvas.drawText("Hello custom renderer!", width / 2, textSize * 2, paint);
73 
74         canvas.translate(0, height / 4);
75         canvas.drawRenderNode(mChildNode);
76         canvas.translate(width / 2, 0);
77         canvas.drawRenderNode(mChildNode);
78         mRootNode.endRecording();
79 
80         setupChild(width / 2, height / 2);
81     }
82 
setupChild(int width, int height)83     private void setupChild(int width, int height) {
84         mChildNode.setPosition(0, 0, width, height);
85         mChildNode.setScaleX(.5f);
86         mChildNode.setScaleY(.5f);
87 
88         RecordingCanvas canvas = mChildNode.beginRecording();
89         canvas.drawColor(Color.RED);
90         mChildNode.endRecording();
91     }
92 
draw()93     private void draw() {
94         // Since we are constantly pumping frames between onStart & onStop we don't really
95         // care about any errors that may happen. They will self-correct.
96         mRenderer.createRenderRequest()
97                 .setVsyncTime(System.nanoTime())
98                 .syncAndDraw();
99     }
100 
101     private SurfaceHolder.Callback2 mSurfaceCallbacks = new SurfaceHolder.Callback2() {
102 
103         @Override
104         public void surfaceRedrawNeeded(SurfaceHolder holder) {
105         }
106 
107         @Override
108         public void surfaceCreated(SurfaceHolder holder) {
109         }
110 
111         @Override
112         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
113             setupRoot(width, height);
114 
115             mRenderer.setContentRoot(mRootNode);
116             mRenderer.setSurface(holder.getSurface());
117             draw();
118             if (!mAnimator.isStarted()) {
119                 mAnimator.start();
120             }
121         }
122 
123         @Override
124         public void surfaceDestroyed(SurfaceHolder holder) {
125             mRenderer.destroy();
126         }
127     };
128 }
129