blob: 1fd7109736b2f928d221384df482d04e03084446 [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 Reckba6adf62015-02-19 14:36:50 -080019import android.annotation.IntDef;
Chris Craik2507c342015-05-04 14:36:49 -070020import android.annotation.NonNull;
John Reckb8802b12014-06-16 15:28:50 -070021import android.content.Context;
22import android.content.res.Resources;
Alan Viverette58c42c32014-07-12 20:33:45 -070023import android.content.res.TypedArray;
John Reck04fc5832014-02-05 16:38:25 -080024import android.graphics.Bitmap;
Alan Viveretteccb11e12014-07-08 16:04:02 -070025import android.graphics.Rect;
John Reckb8802b12014-06-16 15:28:50 -070026import android.graphics.drawable.Drawable;
John Reckedc524c2015-03-18 15:24:33 -070027import android.os.Binder;
John Reck66f0be62014-05-13 13:39:31 -070028import android.os.IBinder;
John Reckedc524c2015-03-18 15:24:33 -070029import android.os.ParcelFileDescriptor;
John Reck66f0be62014-05-13 13:39:31 -070030import android.os.RemoteException;
31import android.os.ServiceManager;
John Reckcec24ae2013-11-05 13:27:50 -080032import android.os.Trace;
John Reck66f0be62014-05-13 13:39:31 -070033import android.util.Log;
John Reckb8802b12014-06-16 15:28:50 -070034import android.util.LongSparseArray;
John Reckcec24ae2013-11-05 13:27:50 -080035import android.view.Surface.OutOfResourcesException;
36import android.view.View.AttachInfo;
37
John Reckba6adf62015-02-19 14:36:50 -080038import com.android.internal.R;
39
John Reckfe5e7b72014-05-23 17:42:28 -070040import java.io.FileDescriptor;
John Reckcec24ae2013-11-05 13:27:50 -080041import java.io.PrintWriter;
John Reckba6adf62015-02-19 14:36:50 -080042import java.lang.annotation.Retention;
43import java.lang.annotation.RetentionPolicy;
John Reckdad7d84c2014-12-09 12:33:26 -080044import java.util.ArrayList;
John Reckb8802b12014-06-16 15:28:50 -070045import java.util.HashSet;
John Reckcec24ae2013-11-05 13:27:50 -080046
47/**
48 * Hardware renderer that proxies the rendering to a render thread. Most calls
John Reck4f02bf42014-01-03 18:09:17 -080049 * are currently synchronous.
John Reckcec24ae2013-11-05 13:27:50 -080050 *
51 * The UI thread can block on the RenderThread, but RenderThread must never
52 * block on the UI thread.
53 *
John Reck4f02bf42014-01-03 18:09:17 -080054 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
55 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
56 * by the lifecycle of the RenderProxy.
57 *
John Reckcec24ae2013-11-05 13:27:50 -080058 * Note that although currently the EGL context & surfaces are created & managed
59 * by the render thread, the goal is to move that into a shared structure that can
60 * be managed by both threads. EGLSurface creation & deletion should ideally be
61 * done on the UI thread and not the RenderThread to avoid stalling the
62 * RenderThread with surface buffer allocation.
63 *
64 * @hide
65 */
66public class ThreadedRenderer extends HardwareRenderer {
67 private static final String LOGTAG = "ThreadedRenderer";
68
John Reckf9be7792014-05-02 18:21:16 -070069 // Keep in sync with DrawFrameTask.h SYNC_* flags
70 // Nothing interesting to report
John Reckcd028f32014-06-24 08:44:29 -070071 private static final int SYNC_OK = 0;
John Reckf9be7792014-05-02 18:21:16 -070072 // Needs a ViewRoot invalidate
John Reckcd028f32014-06-24 08:44:29 -070073 private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
John Reckaa95a882014-11-07 11:02:07 -080074 // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
75 private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
John Reckf9be7792014-05-02 18:21:16 -070076
John Reckfe5e7b72014-05-23 17:42:28 -070077 private static final String[] VISUALIZERS = {
78 PROFILE_PROPERTY_VISUALIZE_BARS,
79 };
80
John Reckba6adf62015-02-19 14:36:50 -080081 private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
82 private static final int FLAG_DUMP_RESET = 1 << 1;
83
84 @IntDef(flag = true, value = {
85 FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
86 @Retention(RetentionPolicy.SOURCE)
87 public @interface DumpFlags {}
88
Alan Viveretteccb11e12014-07-08 16:04:02 -070089 // Size of the rendered content.
John Reckcec24ae2013-11-05 13:27:50 -080090 private int mWidth, mHeight;
Alan Viveretteccb11e12014-07-08 16:04:02 -070091
92 // Actual size of the drawing surface.
93 private int mSurfaceWidth, mSurfaceHeight;
94
95 // Insets between the drawing surface and rendered content. These are
96 // applied as translation when updating the root render node.
97 private int mInsetTop, mInsetLeft;
98
Alan Viverette57774a82014-07-15 15:49:55 -070099 // Whether the surface has insets. Used to protect opacity.
100 private boolean mHasInsets;
101
Alan Viverette58c42c32014-07-12 20:33:45 -0700102 // Light and shadow properties specified by the theme.
103 private final float mLightY;
104 private final float mLightZ;
105 private final float mLightRadius;
Chris Craik058fc642014-07-23 18:19:28 -0700106 private final int mAmbientShadowAlpha;
107 private final int mSpotShadowAlpha;
Alan Viverette58c42c32014-07-12 20:33:45 -0700108
John Reck4f02bf42014-01-03 18:09:17 -0800109 private long mNativeProxy;
John Reckf7d9c1d2014-04-09 10:01:03 -0700110 private boolean mInitialized = false;
John Reckbc0cc022014-04-11 16:08:14 -0700111 private RenderNode mRootNode;
John Reck18f16e62014-05-02 16:46:41 -0700112 private Choreographer mChoreographer;
John Reck0a973302014-07-16 13:29:45 -0700113 private boolean mRootNodeNeedsUpdate;
John Reckcec24ae2013-11-05 13:27:50 -0800114
John Reckb8802b12014-06-16 15:28:50 -0700115 ThreadedRenderer(Context context, boolean translucent) {
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700116 final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
Alan Viverette58c42c32014-07-12 20:33:45 -0700117 mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
118 mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
119 mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700120 mAmbientShadowAlpha =
121 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
122 mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
Alan Viverette58c42c32014-07-12 20:33:45 -0700123 a.recycle();
124
John Recke45b1fd2014-04-15 09:50:16 -0700125 long rootNodePtr = nCreateRootRenderNode();
126 mRootNode = RenderNode.adopt(rootNodePtr);
John Reckbc0cc022014-04-11 16:08:14 -0700127 mRootNode.setClipToBounds(false);
John Recke45b1fd2014-04-15 09:50:16 -0700128 mNativeProxy = nCreateProxy(translucent, rootNodePtr);
John Reck18f16e62014-05-02 16:46:41 -0700129
John Reckedc524c2015-03-18 15:24:33 -0700130 ProcessInitializer.sInstance.init(context, mNativeProxy);
John Reck3b202512014-06-23 13:13:08 -0700131
John Reckfe5e7b72014-05-23 17:42:28 -0700132 loadSystemProperties();
John Reckcec24ae2013-11-05 13:27:50 -0800133 }
134
135 @Override
John Reckf47a5942014-06-30 16:20:04 -0700136 void destroy() {
John Reckf7d9c1d2014-04-09 10:01:03 -0700137 mInitialized = false;
138 updateEnabledState(null);
John Reck17035b02014-09-03 07:39:53 -0700139 nDestroy(mNativeProxy);
John Reckcec24ae2013-11-05 13:27:50 -0800140 }
141
John Reckf7d9c1d2014-04-09 10:01:03 -0700142 private void updateEnabledState(Surface surface) {
143 if (surface == null || !surface.isValid()) {
144 setEnabled(false);
145 } else {
146 setEnabled(mInitialized);
147 }
148 }
149
John Reckcec24ae2013-11-05 13:27:50 -0800150 @Override
151 boolean initialize(Surface surface) throws OutOfResourcesException {
John Reckf7d9c1d2014-04-09 10:01:03 -0700152 mInitialized = true;
153 updateEnabledState(surface);
Dan Stoza5795d642014-06-20 13:01:36 -0700154 boolean status = nInitialize(mNativeProxy, surface);
155 surface.allocateBuffers();
156 return status;
John Reckcec24ae2013-11-05 13:27:50 -0800157 }
158
159 @Override
160 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reckf7d9c1d2014-04-09 10:01:03 -0700161 updateEnabledState(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800162 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -0800163 }
164
165 @Override
John Reck01a5ea32014-12-03 13:01:07 -0800166 boolean pauseSurface(Surface surface) {
167 return nPauseSurface(mNativeProxy, surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700168 }
169
170 @Override
John Reckcec24ae2013-11-05 13:27:50 -0800171 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -0800172 destroyResources(view);
John Reckf47a5942014-06-30 16:20:04 -0700173 nDestroyHardwareResources(mNativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -0800174 }
175
176 private static void destroyResources(View view) {
177 view.destroyHardwareResources();
178
179 if (view instanceof ViewGroup) {
180 ViewGroup group = (ViewGroup) view;
181
182 int count = group.getChildCount();
183 for (int i = 0; i < count; i++) {
184 destroyResources(group.getChildAt(i));
185 }
186 }
John Reckcec24ae2013-11-05 13:27:50 -0800187 }
188
189 @Override
190 void invalidate(Surface surface) {
John Reck4f02bf42014-01-03 18:09:17 -0800191 updateSurface(surface);
John Reckcec24ae2013-11-05 13:27:50 -0800192 }
193
194 @Override
John Reck918ad522014-06-27 14:45:25 -0700195 void detachSurfaceTexture(long hardwareLayer) {
196 nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
John Reckcec24ae2013-11-05 13:27:50 -0800197 }
198
199 @Override
Alan Viverette58c42c32014-07-12 20:33:45 -0700200 void setup(int width, int height, Rect surfaceInsets) {
201 final float lightX = width / 2.0f;
John Reckcec24ae2013-11-05 13:27:50 -0800202 mWidth = width;
203 mHeight = height;
Alan Viverette3aa1ffb2014-10-30 12:22:08 -0700204 if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
205 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
Alan Viverette57774a82014-07-15 15:49:55 -0700206 mHasInsets = true;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700207 mInsetLeft = surfaceInsets.left;
208 mInsetTop = surfaceInsets.top;
209 mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
210 mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
Alan Viverette57774a82014-07-15 15:49:55 -0700211
212 // If the surface has insets, it can't be opaque.
213 setOpaque(false);
Alan Viveretteccb11e12014-07-08 16:04:02 -0700214 } else {
Alan Viverette57774a82014-07-15 15:49:55 -0700215 mHasInsets = false;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700216 mInsetLeft = 0;
217 mInsetTop = 0;
218 mSurfaceWidth = width;
219 mSurfaceHeight = height;
220 }
221 mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
Chris Craik058fc642014-07-23 18:19:28 -0700222 nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight,
223 lightX, mLightY, mLightZ, mLightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700224 mAmbientShadowAlpha, mSpotShadowAlpha);
John Reckcec24ae2013-11-05 13:27:50 -0800225 }
226
227 @Override
John Reck63a06672014-05-07 13:45:54 -0700228 void setOpaque(boolean opaque) {
Alan Viverette57774a82014-07-15 15:49:55 -0700229 nSetOpaque(mNativeProxy, opaque && !mHasInsets);
John Reck63a06672014-05-07 13:45:54 -0700230 }
231
232 @Override
John Reckcec24ae2013-11-05 13:27:50 -0800233 int getWidth() {
234 return mWidth;
235 }
236
237 @Override
238 int getHeight() {
239 return mHeight;
240 }
241
242 @Override
John Reckba6adf62015-02-19 14:36:50 -0800243 void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
John Reckfe5e7b72014-05-23 17:42:28 -0700244 pw.flush();
John Reckba6adf62015-02-19 14:36:50 -0800245 int flags = 0;
246 for (int i = 0; i < args.length; i++) {
247 switch (args[i]) {
248 case "framestats":
249 flags |= FLAG_DUMP_FRAMESTATS;
250 break;
251 case "reset":
252 flags |= FLAG_DUMP_RESET;
253 break;
254 }
John Reckfe5e7b72014-05-23 17:42:28 -0700255 }
John Reckba6adf62015-02-19 14:36:50 -0800256 nDumpProfileInfo(mNativeProxy, fd, flags);
John Reckcec24ae2013-11-05 13:27:50 -0800257 }
258
259 @Override
260 boolean loadSystemProperties() {
John Reckfe5e7b72014-05-23 17:42:28 -0700261 boolean changed = nLoadSystemProperties(mNativeProxy);
John Reck23d307c2014-10-27 12:38:48 -0700262 if (changed) {
263 invalidateRoot();
264 }
John Reckfe5e7b72014-05-23 17:42:28 -0700265 return changed;
John Reckcec24ae2013-11-05 13:27:50 -0800266 }
267
John Reck0a973302014-07-16 13:29:45 -0700268 private void updateViewTreeDisplayList(View view) {
John Reckcec24ae2013-11-05 13:27:50 -0800269 view.mPrivateFlags |= View.PFLAG_DRAWN;
John Reckcec24ae2013-11-05 13:27:50 -0800270 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
271 == View.PFLAG_INVALIDATED;
272 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
Chris Craik31a2d062015-05-01 14:22:47 -0700273 view.updateDisplayListIfDirty();
John Reckcec24ae2013-11-05 13:27:50 -0800274 view.mRecreateDisplayList = false;
John Reckbc0cc022014-04-11 16:08:14 -0700275 }
276
John Reck61375a82014-09-18 19:27:48 +0000277 private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
Chris Craik70850ea2014-11-18 10:49:23 -0800278 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
John Reck0a973302014-07-16 13:29:45 -0700279 updateViewTreeDisplayList(view);
280
281 if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
Chris Craikf6829a02015-03-10 10:28:59 -0700282 DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
John Reck0a973302014-07-16 13:29:45 -0700283 try {
Alan Viverettedbed8932014-08-06 17:54:52 -0700284 final int saveCount = canvas.save();
John Reck0a973302014-07-16 13:29:45 -0700285 canvas.translate(mInsetLeft, mInsetTop);
286 callbacks.onHardwarePreDraw(canvas);
Chris Craikabedca32014-08-28 15:03:55 -0700287
288 canvas.insertReorderBarrier();
Chris Craik31a2d062015-05-01 14:22:47 -0700289 canvas.drawRenderNode(view.updateDisplayListIfDirty());
Chris Craikabedca32014-08-28 15:03:55 -0700290 canvas.insertInorderBarrier();
291
John Reck0a973302014-07-16 13:29:45 -0700292 callbacks.onHardwarePostDraw(canvas);
Alan Viverettedbed8932014-08-06 17:54:52 -0700293 canvas.restoreToCount(saveCount);
John Reck0a973302014-07-16 13:29:45 -0700294 mRootNodeNeedsUpdate = false;
295 } finally {
296 mRootNode.end(canvas);
297 }
298 }
299 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
300 }
301
302 @Override
303 void invalidateRoot() {
304 mRootNodeNeedsUpdate = true;
305 }
306
John Reckbc0cc022014-04-11 16:08:14 -0700307 @Override
John Reck61375a82014-09-18 19:27:48 +0000308 void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
John Reckbc0cc022014-04-11 16:08:14 -0700309 attachInfo.mIgnoreDirtyState = true;
John Reckbc0cc022014-04-11 16:08:14 -0700310
John Reckba6adf62015-02-19 14:36:50 -0800311 final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
312 choreographer.mFrameInfo.markDrawStart();
John Reckfe5e7b72014-05-23 17:42:28 -0700313
John Reck61375a82014-09-18 19:27:48 +0000314 updateRootDisplayList(view, callbacks);
John Reckcec24ae2013-11-05 13:27:50 -0800315
John Reck6313b922014-04-16 18:59:21 -0700316 attachInfo.mIgnoreDirtyState = false;
317
John Reck119907c2014-08-14 09:02:01 -0700318 // register animating rendernodes which started animating prior to renderer
319 // creation, which is typical for animators started prior to first draw
320 if (attachInfo.mPendingAnimatingRenderNodes != null) {
321 final int count = attachInfo.mPendingAnimatingRenderNodes.size();
322 for (int i = 0; i < count; i++) {
323 registerAnimatingRenderNode(
324 attachInfo.mPendingAnimatingRenderNodes.get(i));
325 }
326 attachInfo.mPendingAnimatingRenderNodes.clear();
327 // We don't need this anymore as subsequent calls to
328 // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
329 attachInfo.mPendingAnimatingRenderNodes = null;
330 }
331
John Reckba6adf62015-02-19 14:36:50 -0800332 final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
333 int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
John Reckaa95a882014-11-07 11:02:07 -0800334 if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
335 setEnabled(false);
John Reckb13de072014-11-19 16:33:47 -0800336 attachInfo.mViewRootImpl.mSurface.release();
John Reckaa95a882014-11-07 11:02:07 -0800337 // Invalidate since we failed to draw. This should fetch a Surface
338 // if it is still needed or do nothing if we are no longer drawing
339 attachInfo.mViewRootImpl.invalidate();
340 }
John Reckf9be7792014-05-02 18:21:16 -0700341 if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
342 attachInfo.mViewRootImpl.invalidate();
343 }
John Reckcec24ae2013-11-05 13:27:50 -0800344 }
345
John Reck3b202512014-06-23 13:13:08 -0700346 static void invokeFunctor(long functor, boolean waitForCompletion) {
347 nInvokeFunctor(functor, waitForCompletion);
John Reck0d1f6342014-03-28 20:30:27 -0700348 }
349
350 @Override
John Reck19b6bcf2014-02-14 20:03:38 -0800351 HardwareLayer createTextureLayer() {
352 long layer = nCreateTextureLayer(mNativeProxy);
353 return HardwareLayer.adoptTextureLayer(this, layer);
354 }
355
356 @Override
John Reck3e824952014-08-20 10:08:39 -0700357 void buildLayer(RenderNode node) {
358 nBuildLayer(mNativeProxy, node.getNativeDisplayList());
359 }
360
361 @Override
John Reck19b6bcf2014-02-14 20:03:38 -0800362 boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
363 return nCopyLayerInto(mNativeProxy,
John Reck3731dc22015-04-13 15:20:29 -0700364 layer.getDeferredLayerUpdater(), bitmap);
John Reck19b6bcf2014-02-14 20:03:38 -0800365 }
366
367 @Override
368 void pushLayerUpdate(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700369 nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800370 }
371
372 @Override
John Reck19b6bcf2014-02-14 20:03:38 -0800373 void onLayerDestroyed(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700374 nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800375 }
376
377 @Override
John Reckcec24ae2013-11-05 13:27:50 -0800378 void setName(String name) {
John Reckb36016c2015-03-11 08:50:53 -0700379 nSetName(mNativeProxy, name);
John Reckcec24ae2013-11-05 13:27:50 -0800380 }
381
John Reck4f02bf42014-01-03 18:09:17 -0800382 @Override
John Reck28ad7b52014-04-07 16:59:25 -0700383 void fence() {
384 nFence(mNativeProxy);
385 }
386
387 @Override
John Reckf47a5942014-06-30 16:20:04 -0700388 void stopDrawing() {
389 nStopDrawing(mNativeProxy);
390 }
391
392 @Override
John Recka5dda642014-05-22 15:43:54 -0700393 public void notifyFramePending() {
394 nNotifyFramePending(mNativeProxy);
395 }
396
397 @Override
John Reck119907c2014-08-14 09:02:01 -0700398 void registerAnimatingRenderNode(RenderNode animator) {
399 nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
400 }
401
402 @Override
John Reck4f02bf42014-01-03 18:09:17 -0800403 protected void finalize() throws Throwable {
404 try {
405 nDeleteProxy(mNativeProxy);
John Reck0ed751d2014-04-08 14:10:17 -0700406 mNativeProxy = 0;
John Reck4f02bf42014-01-03 18:09:17 -0800407 } finally {
408 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800409 }
410 }
411
John Reckf47a5942014-06-30 16:20:04 -0700412 static void trimMemory(int level) {
413 nTrimMemory(level);
John Reck84a4c882014-05-30 14:34:03 -0700414 }
415
Chris Craik2507c342015-05-04 14:36:49 -0700416 public static void overrideProperty(@NonNull String name, @NonNull String value) {
417 if (name == null || value == null) {
418 throw new IllegalArgumentException("name and value must be non-null");
419 }
420 nOverrideProperty(name, value);
421 }
422
John Reckedc524c2015-03-18 15:24:33 -0700423 public static void dumpProfileData(byte[] data, FileDescriptor fd) {
424 nDumpProfileData(data, fd);
425 }
426
427 private static class ProcessInitializer {
428 static ProcessInitializer sInstance = new ProcessInitializer();
429 static IGraphicsStats sGraphicsStatsService;
430 private static IBinder sProcToken;
John Reck66f0be62014-05-13 13:39:31 -0700431
432 private boolean mInitialized = false;
433
John Reckedc524c2015-03-18 15:24:33 -0700434 private ProcessInitializer() {}
John Reck66f0be62014-05-13 13:39:31 -0700435
John Reck3b202512014-06-23 13:13:08 -0700436 synchronized void init(Context context, long renderProxy) {
John Reck66f0be62014-05-13 13:39:31 -0700437 if (mInitialized) return;
John Reckedc524c2015-03-18 15:24:33 -0700438 mInitialized = true;
439 initGraphicsStats(context, renderProxy);
440 initAssetAtlas(context, renderProxy);
441 }
442
443 private static void initGraphicsStats(Context context, long renderProxy) {
444 IBinder binder = ServiceManager.getService("graphicsstats");
445 if (binder == null) return;
446
447 sGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
448 sProcToken = new Binder();
449 try {
450 final String pkg = context.getApplicationInfo().packageName;
451 ParcelFileDescriptor pfd = sGraphicsStatsService.
452 requestBufferForProcess(pkg, sProcToken);
453 nSetProcessStatsBuffer(renderProxy, pfd.getFd());
454 pfd.close();
455 } catch (Exception e) {
456 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", e);
457 }
458 }
459
460 private static void initAssetAtlas(Context context, long renderProxy) {
John Reck66f0be62014-05-13 13:39:31 -0700461 IBinder binder = ServiceManager.getService("assetatlas");
462 if (binder == null) return;
463
464 IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
465 try {
466 if (atlas.isCompatible(android.os.Process.myPpid())) {
467 GraphicBuffer buffer = atlas.getBuffer();
468 if (buffer != null) {
469 long[] map = atlas.getMap();
470 if (map != null) {
John Reck3b202512014-06-23 13:13:08 -0700471 nSetAtlas(renderProxy, buffer, map);
John Reck66f0be62014-05-13 13:39:31 -0700472 }
473 // If IAssetAtlas is not the same class as the IBinder
474 // we are using a remote service and we can safely
475 // destroy the graphic buffer
476 if (atlas.getClass() != binder.getClass()) {
477 buffer.destroy();
478 }
479 }
480 }
481 } catch (RemoteException e) {
482 Log.w(LOG_TAG, "Could not acquire atlas", e);
483 }
484 }
485 }
486
John Reck84a4c882014-05-30 14:34:03 -0700487 static native void setupShadersDiskCache(String cacheFile);
488
John Reck3b202512014-06-23 13:13:08 -0700489 private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
John Reckedc524c2015-03-18 15:24:33 -0700490 private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
John Reck4f02bf42014-01-03 18:09:17 -0800491
John Recke45b1fd2014-04-15 09:50:16 -0700492 private static native long nCreateRootRenderNode();
493 private static native long nCreateProxy(boolean translucent, long rootRenderNode);
John Reck4f02bf42014-01-03 18:09:17 -0800494 private static native void nDeleteProxy(long nativeProxy);
495
John Recke4280ba2014-05-05 16:39:37 -0700496 private static native boolean nLoadSystemProperties(long nativeProxy);
John Reckb36016c2015-03-11 08:50:53 -0700497 private static native void nSetName(long nativeProxy, String name);
John Reck18f16e62014-05-02 16:46:41 -0700498
John Reck4f02bf42014-01-03 18:09:17 -0800499 private static native boolean nInitialize(long nativeProxy, Surface window);
500 private static native void nUpdateSurface(long nativeProxy, Surface window);
John Reck01a5ea32014-12-03 13:01:07 -0800501 private static native boolean nPauseSurface(long nativeProxy, Surface window);
Chris Craik797b95b2014-05-20 18:10:25 -0700502 private static native void nSetup(long nativeProxy, int width, int height,
Chris Craik058fc642014-07-23 18:19:28 -0700503 float lightX, float lightY, float lightZ, float lightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700504 int ambientShadowAlpha, int spotShadowAlpha);
John Reck63a06672014-05-07 13:45:54 -0700505 private static native void nSetOpaque(long nativeProxy, boolean opaque);
John Reckba6adf62015-02-19 14:36:50 -0800506 private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
John Reck17035b02014-09-03 07:39:53 -0700507 private static native void nDestroy(long nativeProxy);
John Reck119907c2014-08-14 09:02:01 -0700508 private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
John Reck4f02bf42014-01-03 18:09:17 -0800509
John Reck3b202512014-06-23 13:13:08 -0700510 private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
John Reck19b6bcf2014-02-14 20:03:38 -0800511
John Reck19b6bcf2014-02-14 20:03:38 -0800512 private static native long nCreateTextureLayer(long nativeProxy);
John Reck3e824952014-08-20 10:08:39 -0700513 private static native void nBuildLayer(long nativeProxy, long node);
John Reck3731dc22015-04-13 15:20:29 -0700514 private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
John Reckd72e0a32014-05-29 18:56:11 -0700515 private static native void nPushLayerUpdate(long nativeProxy, long layer);
516 private static native void nCancelLayerUpdate(long nativeProxy, long layer);
John Reck918ad522014-06-27 14:45:25 -0700517 private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
John Reck28ad7b52014-04-07 16:59:25 -0700518
John Reckf47a5942014-06-30 16:20:04 -0700519 private static native void nDestroyHardwareResources(long nativeProxy);
520 private static native void nTrimMemory(int level);
Chris Craik2507c342015-05-04 14:36:49 -0700521 private static native void nOverrideProperty(String name, String value);
John Recke1628b72014-05-23 15:11:19 -0700522
John Reck28ad7b52014-04-07 16:59:25 -0700523 private static native void nFence(long nativeProxy);
John Reckf47a5942014-06-30 16:20:04 -0700524 private static native void nStopDrawing(long nativeProxy);
John Recka5dda642014-05-22 15:43:54 -0700525 private static native void nNotifyFramePending(long nativeProxy);
John Reckfe5e7b72014-05-23 17:42:28 -0700526
John Reckba6adf62015-02-19 14:36:50 -0800527 private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
528 @DumpFlags int dumpFlags);
John Reckedc524c2015-03-18 15:24:33 -0700529 private static native void nDumpProfileData(byte[] data, FileDescriptor fd);
John Reckcec24ae2013-11-05 13:27:50 -0800530}