blob: a747ab601eabb7c106a6eff25ea5ba986173afef [file] [log] [blame]
John Reckcec24ae2013-11-05 13:27:50 -08001/*
2 * Copyright (C) 2013 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
17package android.view;
18
John Reck04fc5832014-02-05 16:38:25 -080019import android.graphics.Bitmap;
John Reckcec24ae2013-11-05 13:27:50 -080020import android.graphics.Rect;
21import android.graphics.SurfaceTexture;
John Reckcec24ae2013-11-05 13:27:50 -080022import android.os.SystemClock;
23import android.os.Trace;
John Reckcec24ae2013-11-05 13:27:50 -080024import android.view.Surface.OutOfResourcesException;
25import android.view.View.AttachInfo;
26
27import java.io.PrintWriter;
John Reckcec24ae2013-11-05 13:27:50 -080028
29/**
30 * Hardware renderer that proxies the rendering to a render thread. Most calls
John Reck4f02bf42014-01-03 18:09:17 -080031 * are currently synchronous.
32 * TODO: Make draw() async.
33 * TODO: Figure out how to share the DisplayList between two threads (global lock?)
John Reckcec24ae2013-11-05 13:27:50 -080034 *
35 * The UI thread can block on the RenderThread, but RenderThread must never
36 * block on the UI thread.
37 *
John Reck4f02bf42014-01-03 18:09:17 -080038 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
39 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
40 * by the lifecycle of the RenderProxy.
41 *
John Reckcec24ae2013-11-05 13:27:50 -080042 * Note that although currently the EGL context & surfaces are created & managed
43 * by the render thread, the goal is to move that into a shared structure that can
44 * be managed by both threads. EGLSurface creation & deletion should ideally be
45 * done on the UI thread and not the RenderThread to avoid stalling the
46 * RenderThread with surface buffer allocation.
47 *
48 * @hide
49 */
50public class ThreadedRenderer extends HardwareRenderer {
51 private static final String LOGTAG = "ThreadedRenderer";
52
John Reck4f02bf42014-01-03 18:09:17 -080053 private static final Rect NULL_RECT = new Rect(-1, -1, -1, -1);
John Reckcec24ae2013-11-05 13:27:50 -080054
John Reckcec24ae2013-11-05 13:27:50 -080055 private int mWidth, mHeight;
John Reck4f02bf42014-01-03 18:09:17 -080056 private long mNativeProxy;
John Reckcec24ae2013-11-05 13:27:50 -080057
John Reck3dfe19f2013-12-13 14:25:19 -080058 ThreadedRenderer(boolean translucent) {
John Reck4f02bf42014-01-03 18:09:17 -080059 mNativeProxy = nCreateProxy(translucent);
60 setEnabled(mNativeProxy != 0);
John Reckcec24ae2013-11-05 13:27:50 -080061 }
62
63 @Override
64 void destroy(boolean full) {
John Reck4f02bf42014-01-03 18:09:17 -080065 nDestroyCanvas(mNativeProxy);
John Reckcec24ae2013-11-05 13:27:50 -080066 }
67
68 @Override
69 boolean initialize(Surface surface) throws OutOfResourcesException {
John Reck4f02bf42014-01-03 18:09:17 -080070 return nInitialize(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -080071 }
72
73 @Override
74 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reck4f02bf42014-01-03 18:09:17 -080075 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -080076 }
77
78 @Override
John Reckcec24ae2013-11-05 13:27:50 -080079 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -080080 destroyResources(view);
81 // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
82 }
83
84 private static void destroyResources(View view) {
85 view.destroyHardwareResources();
86
87 if (view instanceof ViewGroup) {
88 ViewGroup group = (ViewGroup) view;
89
90 int count = group.getChildCount();
91 for (int i = 0; i < count; i++) {
92 destroyResources(group.getChildAt(i));
93 }
94 }
John Reckcec24ae2013-11-05 13:27:50 -080095 }
96
97 @Override
98 void invalidate(Surface surface) {
John Reck4f02bf42014-01-03 18:09:17 -080099 updateSurface(surface);
John Reckcec24ae2013-11-05 13:27:50 -0800100 }
101
102 @Override
John Reckcec24ae2013-11-05 13:27:50 -0800103 boolean safelyRun(Runnable action) {
John Reckfc53ef272014-02-11 10:40:25 -0800104 nRunWithGlContext(mNativeProxy, action);
105 return true;
John Reckcec24ae2013-11-05 13:27:50 -0800106 }
107
108 @Override
109 void setup(int width, int height) {
110 mWidth = width;
111 mHeight = height;
John Reck4f02bf42014-01-03 18:09:17 -0800112 nSetup(mNativeProxy, width, height);
John Reckcec24ae2013-11-05 13:27:50 -0800113 }
114
115 @Override
116 int getWidth() {
117 return mWidth;
118 }
119
120 @Override
121 int getHeight() {
122 return mHeight;
123 }
124
125 @Override
126 void dumpGfxInfo(PrintWriter pw) {
127 // TODO Auto-generated method stub
128 }
129
130 @Override
131 long getFrameCount() {
132 // TODO Auto-generated method stub
133 return 0;
134 }
135
136 @Override
137 boolean loadSystemProperties() {
John Reck4f02bf42014-01-03 18:09:17 -0800138 return false;
John Reckcec24ae2013-11-05 13:27:50 -0800139 }
140
John Reckcec24ae2013-11-05 13:27:50 -0800141 /**
142 * TODO: Remove
143 * Temporary hack to allow RenderThreadTest prototype app to trigger
144 * replaying a DisplayList after modifying the displaylist properties
145 *
146 * @hide */
147 public void repeatLastDraw() {
John Reckcec24ae2013-11-05 13:27:50 -0800148 }
149
150 @Override
John Reckbe34f2f2014-03-10 08:58:44 -0700151 void setDisplayListData(long displayList, long newData) {
152 nSetDisplayListData(mNativeProxy, displayList, newData);
John Reck44fd8d22014-02-26 11:00:11 -0800153 }
154
155 @Override
John Reckcec24ae2013-11-05 13:27:50 -0800156 void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
John Reckcec24ae2013-11-05 13:27:50 -0800157 attachInfo.mIgnoreDirtyState = true;
158 attachInfo.mDrawingTime = SystemClock.uptimeMillis();
159 view.mPrivateFlags |= View.PFLAG_DRAWN;
160
161 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
162 == View.PFLAG_INVALIDATED;
163 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
164
165 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
John Reckf666ad72014-03-14 16:24:57 -0700166 RenderNode displayList = view.getDisplayList();
John Reckcec24ae2013-11-05 13:27:50 -0800167 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
168
169 view.mRecreateDisplayList = false;
170
John Reck4f02bf42014-01-03 18:09:17 -0800171 if (dirty == null) {
172 dirty = NULL_RECT;
173 }
174 nDrawDisplayList(mNativeProxy, displayList.getNativeDisplayList(),
175 dirty.left, dirty.top, dirty.right, dirty.bottom);
John Reckcec24ae2013-11-05 13:27:50 -0800176 }
177
178 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000179 void detachFunctor(long functor) {
John Reck4f02bf42014-01-03 18:09:17 -0800180 nDetachFunctor(mNativeProxy, functor);
John Reckcec24ae2013-11-05 13:27:50 -0800181 }
182
183 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000184 void attachFunctor(AttachInfo attachInfo, long functor) {
John Reck4f02bf42014-01-03 18:09:17 -0800185 nAttachFunctor(mNativeProxy, functor);
John Reckcec24ae2013-11-05 13:27:50 -0800186 }
187
188 @Override
John Reck0d1f6342014-03-28 20:30:27 -0700189 public void invokeFunctor(long functor, boolean waitForCompletion) {
190 nInvokeFunctor(mNativeProxy, functor, waitForCompletion);
191 }
192
193 @Override
John Reck19b6bcf2014-02-14 20:03:38 -0800194 HardwareLayer createDisplayListLayer(int width, int height) {
195 long layer = nCreateDisplayListLayer(mNativeProxy, width, height);
196 return HardwareLayer.adoptDisplayListLayer(this, layer);
197 }
198
199 @Override
200 HardwareLayer createTextureLayer() {
201 long layer = nCreateTextureLayer(mNativeProxy);
202 return HardwareLayer.adoptTextureLayer(this, layer);
203 }
204
205 @Override
206 SurfaceTexture createSurfaceTexture(final HardwareLayer layer) {
207 final SurfaceTexture[] ret = new SurfaceTexture[1];
208 nRunWithGlContext(mNativeProxy, new Runnable() {
209 @Override
210 public void run() {
211 ret[0] = layer.createSurfaceTexture();
212 }
213 });
214 return ret[0];
215 }
216
217 @Override
218 boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
219 return nCopyLayerInto(mNativeProxy,
220 layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap);
221 }
222
223 @Override
224 void pushLayerUpdate(HardwareLayer layer) {
225 // TODO: Remove this, it's not needed outside of GLRenderer
226 }
227
228 @Override
229 void onLayerCreated(HardwareLayer layer) {
230 // TODO: Is this actually useful?
231 }
232
233 @Override
234 void flushLayerUpdates() {
235 // TODO: Figure out what this should do or remove it
236 }
237
238 @Override
239 void onLayerDestroyed(HardwareLayer layer) {
240 nDestroyLayer(mNativeProxy, layer.getDeferredLayerUpdater());
241 }
242
243 @Override
John Reckcec24ae2013-11-05 13:27:50 -0800244 void setName(String name) {
John Reckcec24ae2013-11-05 13:27:50 -0800245 }
246
John Reck4f02bf42014-01-03 18:09:17 -0800247 @Override
John Reck28ad7b52014-04-07 16:59:25 -0700248 void fence() {
249 nFence(mNativeProxy);
250 }
251
252 @Override
John Reck4f02bf42014-01-03 18:09:17 -0800253 protected void finalize() throws Throwable {
254 try {
255 nDeleteProxy(mNativeProxy);
John Reck0ed751d2014-04-08 14:10:17 -0700256 mNativeProxy = 0;
John Reck4f02bf42014-01-03 18:09:17 -0800257 } finally {
258 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800259 }
260 }
261
262 /** @hide */
263 public static native void postToRenderThread(Runnable runnable);
John Reck4f02bf42014-01-03 18:09:17 -0800264
265 private static native long nCreateProxy(boolean translucent);
266 private static native void nDeleteProxy(long nativeProxy);
267
268 private static native boolean nInitialize(long nativeProxy, Surface window);
269 private static native void nUpdateSurface(long nativeProxy, Surface window);
270 private static native void nSetup(long nativeProxy, int width, int height);
John Reckbe34f2f2014-03-10 08:58:44 -0700271 private static native void nSetDisplayListData(long nativeProxy, long displayList,
John Reck44fd8d22014-02-26 11:00:11 -0800272 long newData);
John Reck4f02bf42014-01-03 18:09:17 -0800273 private static native void nDrawDisplayList(long nativeProxy, long displayList,
274 int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
John Reckfc53ef272014-02-11 10:40:25 -0800275 private static native void nRunWithGlContext(long nativeProxy, Runnable runnable);
John Reck4f02bf42014-01-03 18:09:17 -0800276 private static native void nDestroyCanvas(long nativeProxy);
277
278 private static native void nAttachFunctor(long nativeProxy, long functor);
279 private static native void nDetachFunctor(long nativeProxy, long functor);
John Reck0d1f6342014-03-28 20:30:27 -0700280 private static native void nInvokeFunctor(long nativeProxy, long functor, boolean waitForCompletion);
John Reck19b6bcf2014-02-14 20:03:38 -0800281
282 private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
283 private static native long nCreateTextureLayer(long nativeProxy);
284 private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
285 private static native void nDestroyLayer(long nativeProxy, long layer);
John Reck28ad7b52014-04-07 16:59:25 -0700286
287 private static native void nFence(long nativeProxy);
John Reckcec24ae2013-11-05 13:27:50 -0800288}