BlockFrameCallback() { try { //获取系统属性:丢失的帧数阈值 int skipFrame = (int) MethodUtils .invokeStaticMethod(Class.forName("android.os.SystemProperties"), "getInt", "debug.choreographer.skipwarning", DEFAULT_FRAME_SKIP_WARNING); //获取设备每帧的时间间隔,单位ns long frameIntervalNs = (long) FieldUtils.readField(Choreographer.getInstance(), "mFrameIntervalNanos"); warningFrameMs = (int) (frameIntervalNs * skipFrame) / 1000000; } catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException | InvocationTargetException e) { e.printStackTrace(); warningFrameMs = 17 * DEFAULT_FRAME_SKIP_WARNING; } startWallClockTimeMs = System.currentTimeMillis(); startCpuTimeMs = SystemClock.currentThreadTimeMillis(); }
private void installLooperListener() { //TODO 注意Looper的选择,是否考虑其他线程的looper Looper.getMainLooper().setMessageLogging(looperListener); try { //获取系统属性:丢失的帧数阈值 int skipFrame = (int) MethodUtils .invokeStaticMethod(Class.forName("android.os.SystemProperties"), "getInt", "debug.choreographer.skipwarning", DEFAULT_FRAME_SKIP_WARNING); //获取设备每帧的时间间隔,单位ns long frameIntervalNs = (long) FieldUtils.readField(Choreographer.getInstance(), "mFrameIntervalNanos"); warningFrameMs = (int) (frameIntervalNs * skipFrame / 1000000); } catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException | InvocationTargetException e) { e.printStackTrace(); warningFrameMs = 16 * DEFAULT_FRAME_SKIP_WARNING; } }
@Override public void run() { setName("ChorRenderThread"); Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { Log.d(TAG, "got message, quitting"); Looper.myLooper().quit(); } }; Choreographer.getInstance().postFrameCallback(this); Looper.loop(); Log.d(TAG, "looper quit"); Choreographer.getInstance().removeFrameCallback(this); }
@Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "surfaceCreated holder=" + holder); // If we already have a Surface, we just need to resume the frame notifications. SurfaceView sv = (SurfaceView) findViewById(R.id.scheduledSwap_surfaceView); mRenderThread = new RenderThread(sv.getHolder(), this); mRenderThread.setName("ScheduledSwap GL render"); mRenderThread.start(); mRenderThread.waitUntilReady(); RenderHandler rh = mRenderThread.getHandler(); if (rh != null) { rh.sendSetParameters(mUpdatePatternIndex, mFramesAheadIndex); rh.sendSurfaceCreated(); } // start the draw events Choreographer.getInstance().postFrameCallback(this); }
@Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "surfaceCreated holder=" + holder); File outputFile = new File(getFilesDir(), "fbo-gl-recording.mp4"); SurfaceView sv = (SurfaceView) findViewById(R.id.fboActivity_surfaceView); mRenderThread = new RenderThread(sv.getHolder(), new ActivityHandler(this), outputFile, MiscUtils.getDisplayRefreshNsec(this)); mRenderThread.setName("RecordFBO GL render"); mRenderThread.start(); mRenderThread.waitUntilReady(); mRenderThread.setRecordMethod(mSelectedRecordMethod); RenderHandler rh = mRenderThread.getHandler(); if (rh != null) { rh.sendSurfaceCreated(); } // start the draw events Choreographer.getInstance().postFrameCallback(this); }
@ReactMethod public void startRecordingFps() { if (mCatalystSettings == null || !mCatalystSettings.isAnimationFpsDebugEnabled()) { return; } if (mFrameCallback != null) { throw new JSApplicationCausedNativeException("Already recording FPS!"); } checkAPILevel(); mFrameCallback = new FpsDebugFrameCallback( Choreographer.getInstance(), getReactApplicationContext()); mFrameCallback.startAndRecordFpsAtEachFrame(); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public void start(Activity activity) { this.mActivity = activity; threadStackSampler.start(); cpuSampler.start(); float refreshRate = mActivity.getWindowManager().getDefaultDisplay().getRefreshRate(); mFrameIntervalNanos = (long) (1000000000 / refreshRate); if (this.monitor == null) { this.monitor = new FrameMonitor(); } isStop = false; if (this.mActivity != null) { this.mActivity.runOnUiThread(new Runnable() { public void run() { Choreographer.getInstance().postFrameCallback(ChoreographerAnalysis.this.monitor); } }); } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = (Button) findViewById(R.id.button1); Button button2 = (Button) findViewById(R.id.button2); Button button3 = (Button) findViewById(R.id.button3); button1.setOnClickListener(this); button2.setOnClickListener(this); button3.setOnClickListener(this); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { Choreographer.getInstance().postFrameCallback(this); } startActivity(new Intent(this, SecondActivity.class)); }
@Override public void doFrame(long frameTimeNanos) { // Log.d(TAG, "frameTimeNanos = " + frameTimeNanos); if (lastFrameTimeNanos == 0) { lastFrameTimeNanos = frameTimeNanos; Choreographer.getInstance().postFrameCallback(this); return; } currentFrameTimeNanos = frameTimeNanos; long value = (currentFrameTimeNanos - lastFrameTimeNanos) / 1000000; // 大于16ms表示发生卡顿 if (value > 16) { Log.d(TAG, "currentFrameTimeNanos - lastFrameTimeNanos = " + (currentFrameTimeNanos - lastFrameTimeNanos) / 1000000); } lastFrameTimeNanos = currentFrameTimeNanos; Choreographer.getInstance().postFrameCallback(this); }
public WallpaperOffsetInterpolator(Workspace workspace) { mChoreographer = Choreographer.getInstance(); mInterpolator = new DecelerateInterpolator(1.5f); mWorkspace = workspace; mWallpaperManager = WallpaperManager.getInstance(workspace.getContext()); mIsRtl = Utilities.isRtl(workspace.getResources()); }
@Override protected void onPause() { super.onPause(); // If the callback was posted, remove it. This stops the notifications. Ideally we // would send a message to the thread letting it know, so when it wakes up it can // reset its notion of when the previous Choreographer event arrived. Log.d(TAG, "onPause unhooking choreographer"); Choreographer.getInstance().removeFrameCallback(this); }
@Override protected void onResume() { super.onResume(); // If we already have a Surface, we just need to resume the frame notifications. if (mRenderThread != null) { Log.d(TAG, "onResume re-hooking choreographer"); Choreographer.getInstance().postFrameCallback(this); } }
@Override public void doFrame(long frameTimeNanos) { RenderHandler rh = mRenderThread.getHandler(); if (rh != null) { Choreographer.getInstance().postFrameCallback(this); rh.sendDoFrame(frameTimeNanos); } }
/** * Choreographer callback, called near vsync. */ @Override public void doFrame(long frameTimeNanos) { // The events should not start until the RenderThread is created, and should stop // before it's nulled out. RenderHandler rh = mRenderThread.getHandler(); if (rh != null) { Choreographer.getInstance().postFrameCallback(this); rh.sendDoFrame(frameTimeNanos); } }
@Override protected void onPause() { super.onPause(); // TODO: we might want to stop recording here. As it is, we continue "recording", // which is pretty boring since we're not outputting any frames (test this // by blanking the screen with the power button). // If the callback was posted, remove it. This stops the notifications. Ideally we // would send a message to the thread letting it know, so when it wakes up it can // reset its notion of when the previous Choreographer event arrived. Log.d(TAG, "onPause unhooking choreographer"); Choreographer.getInstance().removeFrameCallback(this); }
@Override protected void onResume() { super.onResume(); // If we already have a Surface, we just need to resume the frame notifications. if (mRenderThread != null) { Log.d(TAG, "onResume re-hooking choreographer"); Choreographer.getInstance().postFrameCallback(this); } updateControls(); }
@Override public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "surfaceDestroyed holder=" + holder); // We need to wait for the render thread to shut down before continuing because we // don't want the Surface to disappear out from under it mid-render. The frame // notifications will have been stopped back in onPause(), but there might have // been one in progress. // // TODO: the RenderThread doesn't currently wait for the encoder / muxer to stop, // so we can't use this as an indication that the .mp4 file is complete. RenderHandler rh = mRenderThread.getHandler(); if (rh != null) { rh.sendShutdown(); try { mRenderThread.join(); } catch (InterruptedException ie) { // not expected throw new RuntimeException("join was interrupted", ie); } } mRenderThread = null; mRecordingEnabled = false; // If the callback was posted, remove it. Without this, we could get one more // call on doFrame(). Choreographer.getInstance().removeFrameCallback(this); Log.d(TAG, "surfaceDestroyed complete"); }
public ChoreographerAndroidSpringLooper(Choreographer choreographer) { mChoreographer = choreographer; mFrameCallback = new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { if (!mStarted || mSpringSystem == null) { return; } long currentTime = SystemClock.uptimeMillis(); mSpringSystem.loop(currentTime - mLastTime); mLastTime = currentTime; mChoreographer.postFrameCallback(mFrameCallback); } }; }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void doFrame(long frameTimeNanos) { if (!mRunning) { return; } Choreographer.getInstance().postFrameCallback(frameCallback); atom.incrementAndGet(); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public void start() { Log.d(TAG, "start vsync detect"); if (mRunning) { return; } mRunning = true; syncCheckThread = new Thread(new Runnable() { @Override public void run() { for (;;) { if (!mRunning) { break; } syncCheckThread(); } } }); syncCheckThread.start(); Choreographer chor = Choreographer.getInstance(); Field field; try { field = chor.getClass().getDeclaredField("mFrameIntervalNanos"); field.setAccessible(true); mFrameIntervalNanos = field.getLong(chor); Log.d(TAG, "mFrameIntervalNanos " + mFrameIntervalNanos); } catch (Exception e) { Log.e(TAG, "error: " + e.getMessage()); } chor.postFrameCallback(frameCallback); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) Choreographer.FrameCallback getFrameCallback() { if (mFrameCallback == null) { mFrameCallback = new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { FrameCallback.this.doFrame(frameTimeNanos); } }; } return mFrameCallback; }
@TargetApi(16) android.view.Choreographer.FrameCallback getFrameCallback() { if (this.mFrameCallback == null) { this.mFrameCallback = new android.view.Choreographer.FrameCallback() { public void doFrame(long frameTimeNanos) { FrameCallback.this.doFrame(frameTimeNanos); } }; } return this.mFrameCallback; }
@Override protected void onLooperPrepared() { mSampleChoreographer = Choreographer.getInstance(); mSampleCallback = new Choreographer.FrameCallback() { @Override public void doFrame(final long frameTimeNanos) { final long delta = (frameTimeNanos - lastSampleTime) / 1000000; if (lastSampleTime != 0 && delta > delay) { //采样周期不准了,目前丢弃吧 //LogUtils.w("monitor", "sample doFrame " + delta); // mCheckerHandler.post(new Runnable() { // @Override // public void run() { // processInfo(lastSampleTime / 1000000,frameTimeNanos / 1000000); // } // }); } else { mCheckerHandler.post(new Runnable() { @Override public void run() { statisticsStack(frameTimeNanos / 1000000, delta, StackInfo.TYPE_SAMPLE); } }); } lastSampleTime = frameTimeNanos; if (mLoopFlag) { mSampleChoreographer.postFrameCallback(mSampleCallback); } } }; lock[0] = true; }
@Override public void doFrame(long frameTimeNanos) { if (glThread.getRenderMode() == RENDERMODE_CONTINUOUSLY) { canSwap = true; glThread.requestRender(frameTimeNanos); Choreographer.getInstance().postFrameCallback(this); } }
public FpsView(ReactContext reactContext) { super(reactContext); inflate(reactContext, R.layout.fps_view, this); mTextView = (TextView) findViewById(R.id.fps_text); mFrameCallback = new FpsDebugFrameCallback(Choreographer.getInstance(), reactContext); mFPSMonitorRunnable = new FPSMonitorRunnable(); setCurrentFPS(0, 0, 0, 0); }
private ReactChoreographer() { mChoreographer = Choreographer.getInstance(); mReactChoreographerDispatcher = new ReactChoreographerDispatcher(); mCallbackQueues = new ArrayDeque[CallbackType.values().length]; for (int i = 0; i < mCallbackQueues.length; i++) { mCallbackQueues[i] = new ArrayDeque<>(); } }