blob: 165316ca7b9ce1e5b5fba02bc2fc16a77c4641d1 [file] [log] [blame]
John Reckcec24ae2013-11-05 13:27:50 -08001/*
2 * Copyright (C) 2010 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
John Reck23b797a2014-01-03 18:08:34 -080017#define LOG_TAG "ThreadedRenderer"
John Reck5b02c622018-05-17 10:44:00 -070018#define ATRACE_TAG ATRACE_TAG_VIEW
John Reckcec24ae2013-11-05 13:27:50 -080019
John Recke45b1fd2014-04-15 09:50:16 -070020#include <algorithm>
Andres Morales11f02d72016-02-12 18:19:52 -080021#include <atomic>
John Reck5b02c622018-05-17 10:44:00 -070022#include <inttypes.h>
John Recke45b1fd2014-04-15 09:50:16 -070023
John Reckcec24ae2013-11-05 13:27:50 -080024#include "jni.h"
25#include <nativehelper/JNIHelp.h>
Andreas Gampeed6b9df2014-11-20 22:02:20 -080026#include "core_jni_helpers.h"
John Reck3731dc22015-04-13 15:20:29 -070027#include <GraphicsJNI.h>
Steven Moreland2279b252017-07-19 09:50:45 -070028#include <nativehelper/ScopedPrimitiveArray.h>
John Reckcec24ae2013-11-05 13:27:50 -080029
John Reck1fedd912017-05-23 14:45:22 -070030#include <gui/BufferItemConsumer.h>
31#include <gui/BufferQueue.h>
32#include <gui/Surface.h>
33
John Reck84a4c882014-05-30 14:34:03 -070034#include <EGL/egl.h>
35#include <EGL/eglext.h>
Mathias Agopian04d04612017-03-08 23:21:54 -080036#include <private/EGL/cache.h>
John Reck84a4c882014-05-30 14:34:03 -070037
Andres Morales06f5bc72015-12-15 15:21:31 -080038#include <utils/Looper.h>
39#include <utils/RefBase.h>
John Reck4f02bf42014-01-03 18:09:17 -080040#include <utils/StrongPointer.h>
Doris Liu67ce99b2016-05-17 16:50:31 -070041#include <utils/Timers.h>
John Reck5b02c622018-05-17 10:44:00 -070042#include <utils/TraceUtils.h>
John Reck4f02bf42014-01-03 18:09:17 -080043#include <android_runtime/android_view_Surface.h>
44#include <system/window.h>
45
Andres Morales06f5bc72015-12-15 15:21:31 -080046#include "android_os_MessageQueue.h"
John Reck66f0be62014-05-13 13:39:31 -070047
John Reck52244ff2014-05-01 21:27:37 -070048#include <Animator.h>
John Reck119907c2014-08-14 09:02:01 -070049#include <AnimationContext.h>
Andres Morales06f5bc72015-12-15 15:21:31 -080050#include <FrameInfo.h>
Andres Morales910beb82016-02-02 16:19:40 -080051#include <FrameMetricsObserver.h>
John Reck119907c2014-08-14 09:02:01 -070052#include <IContextFactory.h>
John Reck938e8842017-08-24 13:41:59 -070053#include <Properties.h>
Doris Liu67ce99b2016-05-17 16:50:31 -070054#include <PropertyValuesAnimatorSet.h>
John Recke45b1fd2014-04-15 09:50:16 -070055#include <RenderNode.h>
John Reck66f0be62014-05-13 13:39:31 -070056#include <renderthread/CanvasContext.h>
John Reck4f02bf42014-01-03 18:09:17 -080057#include <renderthread/RenderProxy.h>
John Reckcec24ae2013-11-05 13:27:50 -080058#include <renderthread/RenderTask.h>
59#include <renderthread/RenderThread.h>
Stan Ilievd495f432017-10-09 15:49:32 -040060#include <pipeline/skia/ShaderCache.h>
John Reckcec24ae2013-11-05 13:27:50 -080061
62namespace android {
63
John Reck4f02bf42014-01-03 18:09:17 -080064using namespace android::uirenderer;
65using namespace android::uirenderer::renderthread;
John Reckcec24ae2013-11-05 13:27:50 -080066
Andres Morales06f5bc72015-12-15 15:21:31 -080067struct {
Andres Morales910beb82016-02-02 16:19:40 -080068 jfieldID frameMetrics;
69 jfieldID timingDataBuffer;
Andres Morales06f5bc72015-12-15 15:21:31 -080070 jfieldID messageQueue;
Andres Morales910beb82016-02-02 16:19:40 -080071 jmethodID callback;
72} gFrameMetricsObserverClassInfo;
Andres Morales06f5bc72015-12-15 15:21:31 -080073
Mihai Popa95688002018-02-23 16:10:11 +000074struct {
75 jmethodID onFrameDraw;
76} gFrameDrawingCallback;
77
John Reck5b02c622018-05-17 10:44:00 -070078struct {
79 jmethodID onFrameComplete;
80} gFrameCompleteCallback;
81
John Reckc25e5062014-06-18 14:21:29 -070082static JNIEnv* getenv(JavaVM* vm) {
83 JNIEnv* env;
84 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
85 LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
86 }
87 return env;
88}
89
John Reck52244ff2014-05-01 21:27:37 -070090class OnFinishedEvent {
91public:
John Reckff941dc2014-05-14 16:34:14 -070092 OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
John Reck52244ff2014-05-01 21:27:37 -070093 : animator(animator), listener(listener) {}
John Reckff941dc2014-05-14 16:34:14 -070094 sp<BaseRenderNodeAnimator> animator;
John Reck52244ff2014-05-01 21:27:37 -070095 sp<AnimationListener> listener;
96};
97
John Recke45b1fd2014-04-15 09:50:16 -070098class InvokeAnimationListeners : public MessageHandler {
99public:
Chih-Hung Hsiehc6baf562016-04-27 11:29:23 -0700100 explicit InvokeAnimationListeners(std::vector<OnFinishedEvent>& events) {
John Reck52244ff2014-05-01 21:27:37 -0700101 mOnFinishedEvents.swap(events);
John Recke45b1fd2014-04-15 09:50:16 -0700102 }
103
John Reck52244ff2014-05-01 21:27:37 -0700104 static void callOnFinished(OnFinishedEvent& event) {
105 event.listener->onAnimationFinished(event.animator.get());
John Recke45b1fd2014-04-15 09:50:16 -0700106 }
107
108 virtual void handleMessage(const Message& message) {
John Reck52244ff2014-05-01 21:27:37 -0700109 std::for_each(mOnFinishedEvents.begin(), mOnFinishedEvents.end(), callOnFinished);
110 mOnFinishedEvents.clear();
John Recke45b1fd2014-04-15 09:50:16 -0700111 }
112
113private:
John Reck52244ff2014-05-01 21:27:37 -0700114 std::vector<OnFinishedEvent> mOnFinishedEvents;
John Recke45b1fd2014-04-15 09:50:16 -0700115};
116
Doris Liu67ce99b2016-05-17 16:50:31 -0700117class FinishAndInvokeListener : public MessageHandler {
118public:
119 explicit FinishAndInvokeListener(PropertyValuesAnimatorSet* anim)
120 : mAnimator(anim) {
121 mListener = anim->getOneShotListener();
122 mRequestId = anim->getRequestId();
123 }
124
125 virtual void handleMessage(const Message& message) {
126 if (mAnimator->getRequestId() == mRequestId) {
127 // Request Id has not changed, meaning there's no animation lifecyle change since the
128 // message is posted, so go ahead and call finish to make sure the PlayState is properly
129 // updated. This is needed because before the next frame comes in from UI thread to
130 // trigger an animation update, there could be reverse/cancel etc. So we need to update
131 // the playstate in time to ensure all the subsequent events get chained properly.
132 mAnimator->end();
133 }
134 mListener->onAnimationFinished(nullptr);
135 }
136private:
137 sp<PropertyValuesAnimatorSet> mAnimator;
138 sp<AnimationListener> mListener;
139 uint32_t mRequestId;
140};
141
John Reckc25e5062014-06-18 14:21:29 -0700142class RenderingException : public MessageHandler {
John Recke45b1fd2014-04-15 09:50:16 -0700143public:
John Reckc25e5062014-06-18 14:21:29 -0700144 RenderingException(JavaVM* vm, const std::string& message)
145 : mVm(vm)
146 , mMessage(message) {
147 }
148
149 virtual void handleMessage(const Message&) {
150 throwException(mVm, mMessage);
151 }
152
153 static void throwException(JavaVM* vm, const std::string& message) {
154 JNIEnv* env = getenv(vm);
155 jniThrowException(env, "java/lang/IllegalStateException", message.c_str());
156 }
157
158private:
159 JavaVM* mVm;
160 std::string mMessage;
161};
162
John Reck5b02c622018-05-17 10:44:00 -0700163class FrameCompleteWrapper : public MessageHandler {
164public:
165 FrameCompleteWrapper(JNIEnv* env, jobject jobject) {
166 mLooper = Looper::getForThread();
167 LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create runnable on a Looper thread!");
168 env->GetJavaVM(&mVm);
169 mObject = env->NewGlobalRef(jobject);
170 LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref");
171 }
172
173 virtual ~FrameCompleteWrapper() {
174 releaseObject();
175 }
176
177 void postFrameComplete(int64_t frameNr) {
178 if (mObject) {
179 mFrameNr = frameNr;
180 mLooper->sendMessage(this, 0);
181 }
182 }
183
184 virtual void handleMessage(const Message&) {
185 if (mObject) {
186 ATRACE_FORMAT("frameComplete %" PRId64, mFrameNr);
187 getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, mFrameNr);
188 releaseObject();
189 }
190 }
191
192private:
193 JavaVM* mVm;
194 jobject mObject;
195 sp<Looper> mLooper;
196 int64_t mFrameNr = -1;
197
198 void releaseObject() {
199 if (mObject) {
200 getenv(mVm)->DeleteGlobalRef(mObject);
201 mObject = nullptr;
202 }
203 }
204};
205
John Reck51f2d602016-04-06 07:50:47 -0700206class RootRenderNode : public RenderNode, ErrorHandler {
John Reckc25e5062014-06-18 14:21:29 -0700207public:
Chih-Hung Hsiehc6baf562016-04-27 11:29:23 -0700208 explicit RootRenderNode(JNIEnv* env) : RenderNode() {
John Recke45b1fd2014-04-15 09:50:16 -0700209 mLooper = Looper::getForThread();
210 LOG_ALWAYS_FATAL_IF(!mLooper.get(),
211 "Must create RootRenderNode on a thread with a looper!");
John Reckc25e5062014-06-18 14:21:29 -0700212 env->GetJavaVM(&mVm);
John Recke45b1fd2014-04-15 09:50:16 -0700213 }
214
215 virtual ~RootRenderNode() {}
216
John Reck44b49f02016-03-25 14:29:48 -0700217 virtual void onError(const std::string& message) override {
John Reckc25e5062014-06-18 14:21:29 -0700218 mLooper->sendMessage(new RenderingException(mVm, message), 0);
219 }
220
John Reck44b49f02016-03-25 14:29:48 -0700221 virtual void prepareTree(TreeInfo& info) override {
John Reckc25e5062014-06-18 14:21:29 -0700222 info.errorHandler = this;
Doris Liu67ce99b2016-05-17 16:50:31 -0700223
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700224 for (auto& anim : mRunningVDAnimators) {
Doris Liu67ce99b2016-05-17 16:50:31 -0700225 // Assume that the property change in VD from the animators will not be consumed. Mark
226 // otherwise if the VDs are found in the display list tree. For VDs that are not in
227 // the display list tree, we stop providing animation pulses by 1) removing them from
228 // the animation list, 2) post a delayed message to end them at end time so their
229 // listeners can receive the corresponding callbacks.
230 anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
Doris Liu7c7052d2016-07-25 17:19:24 -0700231 // Mark the VD dirty so it will damage itself during prepareTree.
232 anim->getVectorDrawable()->markDirty();
Doris Liu67ce99b2016-05-17 16:50:31 -0700233 }
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700234 if (info.mode == TreeInfo::MODE_FULL) {
235 for (auto &anim : mPausedVDAnimators) {
236 anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
Doris Liu7c7052d2016-07-25 17:19:24 -0700237 anim->getVectorDrawable()->markDirty();
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700238 }
239 }
John Reckf6481082016-02-02 15:18:23 -0800240 // TODO: This is hacky
John Reckf6481082016-02-02 15:18:23 -0800241 info.updateWindowPositions = true;
John Recke45b1fd2014-04-15 09:50:16 -0700242 RenderNode::prepareTree(info);
John Reckf6481082016-02-02 15:18:23 -0800243 info.updateWindowPositions = false;
John Reck44b49f02016-03-25 14:29:48 -0700244 info.errorHandler = nullptr;
John Reck119907c2014-08-14 09:02:01 -0700245 }
John Recke45b1fd2014-04-15 09:50:16 -0700246
John Reck119907c2014-08-14 09:02:01 -0700247 void sendMessage(const sp<MessageHandler>& handler) {
248 mLooper->sendMessage(handler, 0);
249 }
250
Doris Liu67ce99b2016-05-17 16:50:31 -0700251 void sendMessageDelayed(const sp<MessageHandler>& handler, nsecs_t delayInMs) {
252 mLooper->sendMessageDelayed(ms2ns(delayInMs), handler, 0);
253 }
254
John Reck119907c2014-08-14 09:02:01 -0700255 void attachAnimatingNode(RenderNode* animatingNode) {
256 mPendingAnimatingRenderNodes.push_back(animatingNode);
257 }
258
Doris Liu67ce99b2016-05-17 16:50:31 -0700259 void attachPendingVectorDrawableAnimators() {
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700260 mRunningVDAnimators.insert(mPendingVectorDrawableAnimators.begin(),
Doris Liu67ce99b2016-05-17 16:50:31 -0700261 mPendingVectorDrawableAnimators.end());
262 mPendingVectorDrawableAnimators.clear();
263 }
264
265 void detachAnimators() {
266 // Remove animators from the list and post a delayed message in future to end the animator
Doris Liu0bfce2c2017-05-30 18:52:26 -0700267 // For infinite animators, remove the listener so we no longer hold a global ref to the AVD
268 // java object, and therefore the AVD objects in both native and Java can be properly
269 // released.
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700270 for (auto& anim : mRunningVDAnimators) {
Doris Liu67ce99b2016-05-17 16:50:31 -0700271 detachVectorDrawableAnimator(anim.get());
Doris Liu0bfce2c2017-05-30 18:52:26 -0700272 anim->clearOneShotListener();
273 }
274 for (auto& anim : mPausedVDAnimators) {
275 anim->clearOneShotListener();
Doris Liu67ce99b2016-05-17 16:50:31 -0700276 }
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700277 mRunningVDAnimators.clear();
278 mPausedVDAnimators.clear();
Doris Liu67ce99b2016-05-17 16:50:31 -0700279 }
280
Doris Liuc82e8792016-07-29 16:45:24 -0700281 // Move all the animators to the paused list, and send a delayed message to notify the finished
282 // listener.
283 void pauseAnimators() {
284 mPausedVDAnimators.insert(mRunningVDAnimators.begin(), mRunningVDAnimators.end());
285 for (auto& anim : mRunningVDAnimators) {
286 detachVectorDrawableAnimator(anim.get());
287 }
288 mRunningVDAnimators.clear();
289 }
290
John Reck119907c2014-08-14 09:02:01 -0700291 void doAttachAnimatingNodes(AnimationContext* context) {
292 for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) {
293 RenderNode* node = mPendingAnimatingRenderNodes[i].get();
294 context->addAnimatingRenderNode(*node);
John Recke45b1fd2014-04-15 09:50:16 -0700295 }
John Reck119907c2014-08-14 09:02:01 -0700296 mPendingAnimatingRenderNodes.clear();
John Recke45b1fd2014-04-15 09:50:16 -0700297 }
298
Doris Liu7c7052d2016-07-25 17:19:24 -0700299 // Run VectorDrawable animators after prepareTree.
300 void runVectorDrawableAnimators(AnimationContext* context, TreeInfo& info) {
301 // Push staging.
302 if (info.mode == TreeInfo::MODE_FULL) {
303 pushStagingVectorDrawableAnimators(context);
304 }
305
306 // Run the animators in the running list.
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700307 for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
Doris Liu67ce99b2016-05-17 16:50:31 -0700308 if ((*it)->animate(*context)) {
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700309 it = mRunningVDAnimators.erase(it);
Doris Liu67ce99b2016-05-17 16:50:31 -0700310 } else {
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700311 it++;
312 }
313 }
314
Doris Liu7c7052d2016-07-25 17:19:24 -0700315 // Run the animators in paused list during full sync.
316 if (info.mode == TreeInfo::MODE_FULL) {
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700317 // During full sync we also need to pulse paused animators, in case their targets
318 // have been added back to the display list. All the animators that passed the
319 // scheduled finish time will be removed from the paused list.
320 for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
321 if ((*it)->animate(*context)) {
322 // Animator has finished, remove from the list.
323 it = mPausedVDAnimators.erase(it);
324 } else {
325 it++;
326 }
327 }
328 }
Doris Liu7c7052d2016-07-25 17:19:24 -0700329
330 // Move the animators with a target not in DisplayList to paused list.
331 for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
332 if (!(*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
333 // Vector Drawable is not in the display list, we should remove this animator from
334 // the list, put it in the paused list, and post a delayed message to end the
335 // animator.
336 detachVectorDrawableAnimator(it->get());
337 mPausedVDAnimators.insert(*it);
338 it = mRunningVDAnimators.erase(it);
339 } else {
340 it++;
341 }
342 }
343
344 // Move the animators with a target in DisplayList from paused list to running list, and
345 // trim paused list.
346 if (info.mode == TreeInfo::MODE_FULL) {
347 // Check whether any paused animator's target is back in Display List. If so, put the
348 // animator back in the running list.
349 for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
350 if ((*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
351 mRunningVDAnimators.insert(*it);
352 it = mPausedVDAnimators.erase(it);
353 } else {
354 it++;
355 }
356 }
357 // Trim paused VD animators at full sync, so that when Java loses reference to an
358 // animator, we know we won't be requested to animate it any more, then we remove such
359 // animators from the paused list so they can be properly freed. We also remove the
360 // animators from paused list when the time elapsed since start has exceeded duration.
361 trimPausedVDAnimators(context);
362 }
363
364 info.out.hasAnimations |= !mRunningVDAnimators.empty();
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700365 }
366
367 void trimPausedVDAnimators(AnimationContext* context) {
368 // Trim paused vector drawable animator list.
369 for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
370 // Remove paused VD animator if no one else is referencing it. Note that animators that
371 // have passed scheduled finish time are removed from list when they are being pulsed
372 // before prepare tree.
373 // TODO: this is a bit hacky, need to figure out a better way to track when the paused
374 // animators should be freed.
375 if ((*it)->getStrongCount() == 1) {
376 it = mPausedVDAnimators.erase(it);
377 } else {
378 it++;
Doris Liu67ce99b2016-05-17 16:50:31 -0700379 }
380 }
381 }
382
Doris Liu7f2bf462016-06-21 16:06:06 -0700383 void pushStagingVectorDrawableAnimators(AnimationContext* context) {
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700384 for (auto& anim : mRunningVDAnimators) {
Doris Liu7f2bf462016-06-21 16:06:06 -0700385 anim->pushStaging(*context);
386 }
387 }
388
Doris Liu350e6522016-02-19 14:20:37 -0800389 void destroy() {
390 for (auto& renderNode : mPendingAnimatingRenderNodes) {
391 renderNode->animators().endAllStagingAnimators();
392 }
393 mPendingAnimatingRenderNodes.clear();
Doris Liu67ce99b2016-05-17 16:50:31 -0700394 mPendingVectorDrawableAnimators.clear();
395 }
396
397 void addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
398 mPendingVectorDrawableAnimators.insert(anim);
Doris Liu350e6522016-02-19 14:20:37 -0800399 }
400
John Recke45b1fd2014-04-15 09:50:16 -0700401private:
402 sp<Looper> mLooper;
John Reckc25e5062014-06-18 14:21:29 -0700403 JavaVM* mVm;
John Reck119907c2014-08-14 09:02:01 -0700404 std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
Doris Liu67ce99b2016-05-17 16:50:31 -0700405 std::set< sp<PropertyValuesAnimatorSet> > mPendingVectorDrawableAnimators;
Doris Liu3bb5ddd2016-07-19 19:04:31 -0700406 std::set< sp<PropertyValuesAnimatorSet> > mRunningVDAnimators;
407 // mPausedVDAnimators stores a list of animators that have not yet passed the finish time, but
408 // their VectorDrawable targets are no longer in the DisplayList. We skip these animators when
409 // render thread runs animators independent of UI thread (i.e. RT_ONLY mode). These animators
410 // need to be re-activated once their VD target is added back into DisplayList. Since that could
411 // only happen when we do a full sync, we need to make sure to pulse these paused animators at
412 // full sync. If any animator's VD target is found in DisplayList during a full sync, we move
413 // the animator back to the running list.
414 std::set< sp<PropertyValuesAnimatorSet> > mPausedVDAnimators;
Doris Liu67ce99b2016-05-17 16:50:31 -0700415 void detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
416 if (anim->isInfinite() || !anim->isRunning()) {
417 // Do not need to post anything if the animation is infinite (i.e. no meaningful
418 // end listener action), or if the animation has already ended.
419 return;
420 }
421 nsecs_t remainingTimeInMs = anim->getRemainingPlayTime();
422 // Post a delayed onFinished event that is scheduled to be handled when the animator ends.
423 if (anim->getOneShotListener()) {
424 // VectorDrawable's oneshot listener is updated when there are user triggered animation
425 // lifecycle changes, such as start(), end(), etc. By using checking and clearing
426 // one shot listener, we ensure the same end listener event gets posted only once.
427 // Therefore no duplicates. Another benefit of using one shot listener is that no
428 // removal is necessary: the end time of animation will not change unless triggered by
429 // user events, in which case the already posted listener's id will become stale, and
430 // the onFinished callback will then be ignored.
431 sp<FinishAndInvokeListener> message
432 = new FinishAndInvokeListener(anim);
433 sendMessageDelayed(message, remainingTimeInMs);
434 anim->clearOneShotListener();
435 }
436 }
John Reck119907c2014-08-14 09:02:01 -0700437};
438
439class AnimationContextBridge : public AnimationContext {
440public:
441 AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode)
442 : AnimationContext(clock), mRootNode(rootNode) {
443 }
444
445 virtual ~AnimationContextBridge() {}
446
447 // Marks the start of a frame, which will update the frame time and move all
448 // next frame animations into the current frame
John Reckec845a22014-09-05 15:23:38 -0700449 virtual void startFrame(TreeInfo::TraversalMode mode) {
450 if (mode == TreeInfo::MODE_FULL) {
451 mRootNode->doAttachAnimatingNodes(this);
Doris Liu67ce99b2016-05-17 16:50:31 -0700452 mRootNode->attachPendingVectorDrawableAnimators();
John Reckec845a22014-09-05 15:23:38 -0700453 }
454 AnimationContext::startFrame(mode);
John Reck119907c2014-08-14 09:02:01 -0700455 }
456
457 // Runs any animations still left in mCurrentFrameAnimations
458 virtual void runRemainingAnimations(TreeInfo& info) {
459 AnimationContext::runRemainingAnimations(info);
Doris Liu7c7052d2016-07-25 17:19:24 -0700460 mRootNode->runVectorDrawableAnimators(this, info);
John Recke2478d42014-09-03 16:46:05 -0700461 postOnFinishedEvents();
John Reck119907c2014-08-14 09:02:01 -0700462 }
463
Doris Liuc82e8792016-07-29 16:45:24 -0700464 virtual void pauseAnimators() override {
465 mRootNode->pauseAnimators();
Doris Liu67ce99b2016-05-17 16:50:31 -0700466 }
467
John Reck119907c2014-08-14 09:02:01 -0700468 virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) {
469 OnFinishedEvent event(animator, listener);
470 mOnFinishedEvents.push_back(event);
471 }
472
John Recke2478d42014-09-03 16:46:05 -0700473 virtual void destroy() {
474 AnimationContext::destroy();
Doris Liuc82e8792016-07-29 16:45:24 -0700475 mRootNode->detachAnimators();
John Recke2478d42014-09-03 16:46:05 -0700476 postOnFinishedEvents();
477 }
478
John Reck119907c2014-08-14 09:02:01 -0700479private:
480 sp<RootRenderNode> mRootNode;
481 std::vector<OnFinishedEvent> mOnFinishedEvents;
John Recke2478d42014-09-03 16:46:05 -0700482
483 void postOnFinishedEvents() {
484 if (mOnFinishedEvents.size()) {
485 sp<InvokeAnimationListeners> message
486 = new InvokeAnimationListeners(mOnFinishedEvents);
487 mRootNode->sendMessage(message);
488 }
489 }
John Reck119907c2014-08-14 09:02:01 -0700490};
491
492class ContextFactoryImpl : public IContextFactory {
493public:
Chih-Hung Hsiehc6baf562016-04-27 11:29:23 -0700494 explicit ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {}
John Reck119907c2014-08-14 09:02:01 -0700495
496 virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
497 return new AnimationContextBridge(clock, mRootNode);
498 }
499
500private:
501 RootRenderNode* mRootNode;
John Recke45b1fd2014-04-15 09:50:16 -0700502};
503
Andres Morales06f5bc72015-12-15 15:21:31 -0800504class ObserverProxy;
505
506class NotifyHandler : public MessageHandler {
507public:
Andres Morales11f02d72016-02-12 18:19:52 -0800508 NotifyHandler(JavaVM* vm, ObserverProxy* observer) : mVm(vm), mObserver(observer) {}
Andres Morales910beb82016-02-02 16:19:40 -0800509
Andres Morales06f5bc72015-12-15 15:21:31 -0800510 virtual void handleMessage(const Message& message);
511
512private:
Andres Morales11f02d72016-02-12 18:19:52 -0800513 JavaVM* const mVm;
514 ObserverProxy* const mObserver;
Andres Morales06f5bc72015-12-15 15:21:31 -0800515};
516
Andres Morales910beb82016-02-02 16:19:40 -0800517static jlongArray get_metrics_buffer(JNIEnv* env, jobject observer) {
518 jobject frameMetrics = env->GetObjectField(
519 observer, gFrameMetricsObserverClassInfo.frameMetrics);
520 LOG_ALWAYS_FATAL_IF(frameMetrics == nullptr, "unable to retrieve data sink object");
521 jobject buffer = env->GetObjectField(
522 frameMetrics, gFrameMetricsObserverClassInfo.timingDataBuffer);
523 LOG_ALWAYS_FATAL_IF(buffer == nullptr, "unable to retrieve data sink buffer");
524 return reinterpret_cast<jlongArray>(buffer);
525}
526
Andres Morales11f02d72016-02-12 18:19:52 -0800527/*
528 * Implements JNI layer for hwui frame metrics reporting.
529 */
Andres Morales910beb82016-02-02 16:19:40 -0800530class ObserverProxy : public FrameMetricsObserver {
Andres Morales06f5bc72015-12-15 15:21:31 -0800531public:
Andres Morales910beb82016-02-02 16:19:40 -0800532 ObserverProxy(JavaVM *vm, jobject observer) : mVm(vm) {
Andres Morales06f5bc72015-12-15 15:21:31 -0800533 JNIEnv* env = getenv(mVm);
534
Andres Morales910beb82016-02-02 16:19:40 -0800535 mObserverWeak = env->NewWeakGlobalRef(observer);
536 LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr,
Andres Morales06f5bc72015-12-15 15:21:31 -0800537 "unable to create frame stats observer reference");
538
Andres Morales910beb82016-02-02 16:19:40 -0800539 jlongArray buffer = get_metrics_buffer(env, observer);
540 jsize bufferSize = env->GetArrayLength(reinterpret_cast<jarray>(buffer));
541 LOG_ALWAYS_FATAL_IF(bufferSize != kBufferSize,
542 "Mismatched Java/Native FrameMetrics data format.");
543
544 jobject messageQueueLocal = env->GetObjectField(
545 observer, gFrameMetricsObserverClassInfo.messageQueue);
Andres Morales06f5bc72015-12-15 15:21:31 -0800546 mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal);
547 LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available");
548
Andres Morales11f02d72016-02-12 18:19:52 -0800549 mMessageHandler = new NotifyHandler(mVm, this);
Andres Morales06f5bc72015-12-15 15:21:31 -0800550 LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr,
551 "OOM: unable to allocate NotifyHandler");
552 }
553
554 ~ObserverProxy() {
555 JNIEnv* env = getenv(mVm);
Andres Morales910beb82016-02-02 16:19:40 -0800556 env->DeleteWeakGlobalRef(mObserverWeak);
Andres Morales06f5bc72015-12-15 15:21:31 -0800557 }
558
Andres Morales910beb82016-02-02 16:19:40 -0800559 jweak getObserverReference() {
560 return mObserverWeak;
Andres Morales06f5bc72015-12-15 15:21:31 -0800561 }
562
Andres Morales11f02d72016-02-12 18:19:52 -0800563 bool getNextBuffer(JNIEnv* env, jlongArray sink, int* dropCount) {
564 FrameMetricsNotification& elem = mRingBuffer[mNextInQueue];
565
566 if (elem.hasData.load()) {
567 env->SetLongArrayRegion(sink, 0, kBufferSize, elem.buffer);
568 *dropCount = elem.dropCount;
569 mNextInQueue = (mNextInQueue + 1) % kRingSize;
570 elem.hasData = false;
571 return true;
572 }
573
574 return false;
575 }
576
577 virtual void notify(const int64_t* stats) {
578 FrameMetricsNotification& elem = mRingBuffer[mNextFree];
579
580 if (!elem.hasData.load()) {
581 memcpy(elem.buffer, stats, kBufferSize * sizeof(stats[0]));
582
583 elem.dropCount = mDroppedReports;
584 mDroppedReports = 0;
585
586 incStrong(nullptr);
587 mNextFree = (mNextFree + 1) % kRingSize;
588 elem.hasData = true;
589
590 mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
591 } else {
592 mDroppedReports++;
593 }
Andres Morales06f5bc72015-12-15 15:21:31 -0800594 }
595
596private:
597 static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes);
Andres Morales11f02d72016-02-12 18:19:52 -0800598 static constexpr int kRingSize = 3;
Andres Morales06f5bc72015-12-15 15:21:31 -0800599
Andres Morales11f02d72016-02-12 18:19:52 -0800600 class FrameMetricsNotification {
601 public:
602 FrameMetricsNotification() : hasData(false) {}
603
604 std::atomic_bool hasData;
605 int64_t buffer[kBufferSize];
606 int dropCount = 0;
607 };
608
609 JavaVM* const mVm;
Andres Morales910beb82016-02-02 16:19:40 -0800610 jweak mObserverWeak;
Andres Morales06f5bc72015-12-15 15:21:31 -0800611
612 sp<MessageQueue> mMessageQueue;
613 sp<NotifyHandler> mMessageHandler;
614 Message mMessage;
Andres Morales910beb82016-02-02 16:19:40 -0800615
Andres Morales11f02d72016-02-12 18:19:52 -0800616 int mNextFree = 0;
617 int mNextInQueue = 0;
618 FrameMetricsNotification mRingBuffer[kRingSize];
619
620 int mDroppedReports = 0;
Andres Morales06f5bc72015-12-15 15:21:31 -0800621};
622
623void NotifyHandler::handleMessage(const Message& message) {
624 JNIEnv* env = getenv(mVm);
625
Andres Morales11f02d72016-02-12 18:19:52 -0800626 jobject target = env->NewLocalRef(mObserver->getObserverReference());
Andres Morales06f5bc72015-12-15 15:21:31 -0800627
628 if (target != nullptr) {
Andres Morales910beb82016-02-02 16:19:40 -0800629 jlongArray javaBuffer = get_metrics_buffer(env, target);
Andres Morales11f02d72016-02-12 18:19:52 -0800630 int dropCount = 0;
631 while (mObserver->getNextBuffer(env, javaBuffer, &dropCount)) {
632 env->CallVoidMethod(target, gFrameMetricsObserverClassInfo.callback, dropCount);
633 }
Andres Morales910beb82016-02-02 16:19:40 -0800634 env->DeleteLocalRef(target);
Andres Morales06f5bc72015-12-15 15:21:31 -0800635 }
636
Andres Morales11f02d72016-02-12 18:19:52 -0800637 mObserver->decStrong(nullptr);
Andres Morales06f5bc72015-12-15 15:21:31 -0800638}
639
John Reckdf1742e2017-01-19 15:56:21 -0800640static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
641 RenderProxy::rotateProcessStatsBuffer();
642}
643
John Reckedc524c2015-03-18 15:24:33 -0700644static void android_view_ThreadedRenderer_setProcessStatsBuffer(JNIEnv* env, jobject clazz,
John Reckdf1742e2017-01-19 15:56:21 -0800645 jint fd) {
646 RenderProxy::setProcessStatsBuffer(fd);
John Reckedc524c2015-03-18 15:24:33 -0700647}
648
Tim Murray33eb07f2016-06-10 10:03:20 -0700649static jint android_view_ThreadedRenderer_getRenderThreadTid(JNIEnv* env, jobject clazz,
650 jlong proxyPtr) {
651 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
652 return proxy->getRenderThreadTid();
653}
654
John Recke45b1fd2014-04-15 09:50:16 -0700655static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
John Reckc25e5062014-06-18 14:21:29 -0700656 RootRenderNode* node = new RootRenderNode(env);
John Recke45b1fd2014-04-15 09:50:16 -0700657 node->incStrong(0);
658 node->setName("RootRenderNode");
659 return reinterpret_cast<jlong>(node);
660}
661
John Reck4f02bf42014-01-03 18:09:17 -0800662static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
John Recke45b1fd2014-04-15 09:50:16 -0700663 jboolean translucent, jlong rootRenderNodePtr) {
John Reck119907c2014-08-14 09:02:01 -0700664 RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
665 ContextFactoryImpl factory(rootRenderNode);
666 return (jlong) new RenderProxy(translucent, rootRenderNode, &factory);
John Reck4f02bf42014-01-03 18:09:17 -0800667}
668
669static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz,
670 jlong proxyPtr) {
John Reck19b6bcf2014-02-14 20:03:38 -0800671 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reck4f02bf42014-01-03 18:09:17 -0800672 delete proxy;
673}
674
John Recke4280ba2014-05-05 16:39:37 -0700675static jboolean android_view_ThreadedRenderer_loadSystemProperties(JNIEnv* env, jobject clazz,
676 jlong proxyPtr) {
677 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
678 return proxy->loadSystemProperties();
679}
680
John Reckb36016c2015-03-11 08:50:53 -0700681static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz,
682 jlong proxyPtr, jstring jname) {
683 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
684 const char* name = env->GetStringUTFChars(jname, NULL);
685 proxy->setName(name);
686 env->ReleaseStringUTFChars(jname, name);
687}
688
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100689static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
John Reck4f02bf42014-01-03 18:09:17 -0800690 jlong proxyPtr, jobject jsurface) {
John Reck19b6bcf2014-02-14 20:03:38 -0800691 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reckf6481082016-02-02 15:18:23 -0800692 sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
693 proxy->initialize(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800694}
695
696static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
697 jlong proxyPtr, jobject jsurface) {
John Reck19b6bcf2014-02-14 20:03:38 -0800698 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reckf6481082016-02-02 15:18:23 -0800699 sp<Surface> surface;
John Reck4f02bf42014-01-03 18:09:17 -0800700 if (jsurface) {
John Reckf6481082016-02-02 15:18:23 -0800701 surface = android_view_Surface_getSurface(env, jsurface);
John Reck4f02bf42014-01-03 18:09:17 -0800702 }
John Reckf6481082016-02-02 15:18:23 -0800703 proxy->updateSurface(surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700704}
705
John Reck01a5ea32014-12-03 13:01:07 -0800706static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
John Reckf7d9c1d2014-04-09 10:01:03 -0700707 jlong proxyPtr, jobject jsurface) {
708 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reckf6481082016-02-02 15:18:23 -0800709 sp<Surface> surface;
John Reckf7d9c1d2014-04-09 10:01:03 -0700710 if (jsurface) {
John Reckf6481082016-02-02 15:18:23 -0800711 surface = android_view_Surface_getSurface(env, jsurface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700712 }
John Reckf6481082016-02-02 15:18:23 -0800713 return proxy->pauseSurface(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800714}
715
John Reck8afcc762016-04-13 10:24:06 -0700716static void android_view_ThreadedRenderer_setStopped(JNIEnv* env, jobject clazz,
717 jlong proxyPtr, jboolean stopped) {
718 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
719 proxy->setStopped(stopped);
720}
721
Chris Craik797b95b2014-05-20 18:10:25 -0700722static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
John Reckab1080c2016-06-21 16:24:20 -0700723 jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) {
John Reck19b6bcf2014-02-14 20:03:38 -0800724 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reckab1080c2016-06-21 16:24:20 -0700725 proxy->setup(lightRadius, ambientShadowAlpha, spotShadowAlpha);
Alan Viverette50210d92015-05-14 18:05:36 -0700726}
727
728static void android_view_ThreadedRenderer_setLightCenter(JNIEnv* env, jobject clazz,
729 jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ) {
730 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
731 proxy->setLightCenter((Vector3){lightX, lightY, lightZ});
John Reck4f02bf42014-01-03 18:09:17 -0800732}
733
John Reck63a06672014-05-07 13:45:54 -0700734static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
735 jlong proxyPtr, jboolean opaque) {
736 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
737 proxy->setOpaque(opaque);
738}
739
Romain Guy26a2b972017-04-17 09:39:51 -0700740static void android_view_ThreadedRenderer_setWideGamut(JNIEnv* env, jobject clazz,
741 jlong proxyPtr, jboolean wideGamut) {
742 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
743 proxy->setWideGamut(wideGamut);
744}
745
John Reckf9be7792014-05-02 18:21:16 -0700746static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
John Reck51f2d602016-04-06 07:50:47 -0700747 jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
John Reckba6adf62015-02-19 14:36:50 -0800748 LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
749 "Mismatched size expectations, given %d expected %d",
750 frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
John Reck19b6bcf2014-02-14 20:03:38 -0800751 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reckba6adf62015-02-19 14:36:50 -0800752 env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
John Reck2de950d2017-01-25 10:58:30 -0800753 return proxy->syncAndDrawFrame();
John Reck4f02bf42014-01-03 18:09:17 -0800754}
755
John Reck17035b02014-09-03 07:39:53 -0700756static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
Doris Liu350e6522016-02-19 14:20:37 -0800757 jlong proxyPtr, jlong rootNodePtr) {
758 RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
759 rootRenderNode->destroy();
John Reck19b6bcf2014-02-14 20:03:38 -0800760 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reck2de950d2017-01-25 10:58:30 -0800761 proxy->destroy();
John Reck4f02bf42014-01-03 18:09:17 -0800762}
763
John Reck119907c2014-08-14 09:02:01 -0700764static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
765 jlong rootNodePtr, jlong animatingNodePtr) {
766 RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
767 RenderNode* animatingNode = reinterpret_cast<RenderNode*>(animatingNodePtr);
768 rootRenderNode->attachAnimatingNode(animatingNode);
769}
770
Doris Liu67ce99b2016-05-17 16:50:31 -0700771static void android_view_ThreadedRenderer_registerVectorDrawableAnimator(JNIEnv* env, jobject clazz,
772 jlong rootNodePtr, jlong animatorPtr) {
773 RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
774 PropertyValuesAnimatorSet* animator = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorPtr);
775 rootRenderNode->addVectorDrawableAnimator(animator);
776}
777
John Reck0d1f6342014-03-28 20:30:27 -0700778static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
John Reck3b202512014-06-23 13:13:08 -0700779 jlong functorPtr, jboolean waitForCompletion) {
John Reck0d1f6342014-03-28 20:30:27 -0700780 Functor* functor = reinterpret_cast<Functor*>(functorPtr);
John Reck3b202512014-06-23 13:13:08 -0700781 RenderProxy::invokeFunctor(functor, waitForCompletion);
John Reck0d1f6342014-03-28 20:30:27 -0700782}
783
John Reck19b6bcf2014-02-14 20:03:38 -0800784static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz,
785 jlong proxyPtr) {
786 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
787 DeferredLayerUpdater* layer = proxy->createTextureLayer();
788 return reinterpret_cast<jlong>(layer);
789}
790
John Reck3e824952014-08-20 10:08:39 -0700791static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
792 jlong proxyPtr, jlong nodePtr) {
793 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
794 RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
John Reck2de950d2017-01-25 10:58:30 -0800795 proxy->buildLayer(node);
John Reck3e824952014-08-20 10:08:39 -0700796}
797
John Reck19b6bcf2014-02-14 20:03:38 -0800798static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
John Reck3731dc22015-04-13 15:20:29 -0700799 jlong proxyPtr, jlong layerPtr, jobject jbitmap) {
John Reck19b6bcf2014-02-14 20:03:38 -0800800 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
801 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
John Reck3731dc22015-04-13 15:20:29 -0700802 SkBitmap bitmap;
803 GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
John Reck19b6bcf2014-02-14 20:03:38 -0800804 return proxy->copyLayerInto(layer, bitmap);
805}
806
John Reckd72e0a32014-05-29 18:56:11 -0700807static void android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv* env, jobject clazz,
John Reck19b6bcf2014-02-14 20:03:38 -0800808 jlong proxyPtr, jlong layerPtr) {
809 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
810 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
John Reckd72e0a32014-05-29 18:56:11 -0700811 proxy->pushLayerUpdate(layer);
812}
813
814static void android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv* env, jobject clazz,
815 jlong proxyPtr, jlong layerPtr) {
816 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
817 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
818 proxy->cancelLayerUpdate(layer);
John Reck19b6bcf2014-02-14 20:03:38 -0800819}
820
John Reck918ad522014-06-27 14:45:25 -0700821static void android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv* env, jobject clazz,
822 jlong proxyPtr, jlong layerPtr) {
823 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
824 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
825 proxy->detachSurfaceTexture(layer);
826}
827
John Reckf47a5942014-06-30 16:20:04 -0700828static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
829 jlong proxyPtr) {
John Recke1628b72014-05-23 15:11:19 -0700830 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
John Reck2de950d2017-01-25 10:58:30 -0800831 proxy->destroyHardwareResources();
John Reckf47a5942014-06-30 16:20:04 -0700832}
833
834static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
835 jint level) {
836 RenderProxy::trimMemory(level);
John Recke1628b72014-05-23 15:11:19 -0700837}
838
Chris Craik2507c342015-05-04 14:36:49 -0700839static void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz,
840 jstring name, jstring value) {
841 const char* nameCharArray = env->GetStringUTFChars(name, NULL);
842 const char* valueCharArray = env->GetStringUTFChars(value, NULL);
843 RenderProxy::overrideProperty(nameCharArray, valueCharArray);
844 env->ReleaseStringUTFChars(name, nameCharArray);
845 env->ReleaseStringUTFChars(name, valueCharArray);
846}
847
John Reck28ad7b52014-04-07 16:59:25 -0700848static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
849 jlong proxyPtr) {
850 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
851 proxy->fence();
852}
853
John Reckf47a5942014-06-30 16:20:04 -0700854static void android_view_ThreadedRenderer_stopDrawing(JNIEnv* env, jobject clazz,
855 jlong proxyPtr) {
856 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
857 proxy->stopDrawing();
858}
859
John Recka5dda642014-05-22 15:43:54 -0700860static void android_view_ThreadedRenderer_notifyFramePending(JNIEnv* env, jobject clazz,
861 jlong proxyPtr) {
862 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
863 proxy->notifyFramePending();
864}
865
John Recke248bd12015-08-05 13:53:53 -0700866static void android_view_ThreadedRenderer_serializeDisplayListTree(JNIEnv* env, jobject clazz,
867 jlong proxyPtr) {
868 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
869 proxy->serializeDisplayListTree();
870}
871
John Reckfe5e7b72014-05-23 17:42:28 -0700872static void android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv* env, jobject clazz,
John Reckba6adf62015-02-19 14:36:50 -0800873 jlong proxyPtr, jobject javaFileDescriptor, jint dumpFlags) {
John Reckfe5e7b72014-05-23 17:42:28 -0700874 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
875 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
John Reckba6adf62015-02-19 14:36:50 -0800876 proxy->dumpProfileInfo(fd, dumpFlags);
John Reckfe5e7b72014-05-23 17:42:28 -0700877}
878
Skuhneea7a7fb2015-08-28 07:10:31 -0700879static void android_view_ThreadedRenderer_addRenderNode(JNIEnv* env, jobject clazz,
880 jlong proxyPtr, jlong renderNodePtr, jboolean placeFront) {
881 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
882 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
883 proxy->addRenderNode(renderNode, placeFront);
884}
885
886static void android_view_ThreadedRenderer_removeRenderNode(JNIEnv* env, jobject clazz,
887 jlong proxyPtr, jlong renderNodePtr) {
888 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
889 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
890 proxy->removeRenderNode(renderNode);
891}
892
893static void android_view_ThreadedRendererd_drawRenderNode(JNIEnv* env, jobject clazz,
894 jlong proxyPtr, jlong renderNodePtr) {
895 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
896 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
897 proxy->drawRenderNode(renderNode);
898}
899
Skuhneb8160872015-09-22 09:51:39 -0700900static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env,
Skuhneea7a7fb2015-08-28 07:10:31 -0700901 jobject clazz, jlong proxyPtr, jint left, jint top, jint right, jint bottom) {
902 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
Skuhneb8160872015-09-22 09:51:39 -0700903 proxy->setContentDrawBounds(left, top, right, bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700904}
John Reckedc524c2015-03-18 15:24:33 -0700905
Mihai Popa95688002018-02-23 16:10:11 +0000906class JGlobalRefHolder {
907public:
908 JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
909
910 virtual ~JGlobalRefHolder() {
911 getenv(mVm)->DeleteGlobalRef(mObject);
912 mObject = nullptr;
913 }
914
915 jobject object() { return mObject; }
916 JavaVM* vm() { return mVm; }
917
918private:
919 JGlobalRefHolder(const JGlobalRefHolder&) = delete;
920 void operator=(const JGlobalRefHolder&) = delete;
921
922 JavaVM* mVm;
923 jobject mObject;
924};
925
926static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
927 jobject clazz, jlong proxyPtr, jobject frameCallback) {
928 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
929 if (!frameCallback) {
930 proxy->setFrameCallback(nullptr);
931 } else {
932 JavaVM* vm = nullptr;
933 LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
934 auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm,
935 env->NewGlobalRef(frameCallback));
936 proxy->setFrameCallback([globalCallbackRef](int64_t frameNr) {
937 JNIEnv* env = getenv(globalCallbackRef->vm());
938 env->CallVoidMethod(globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw,
939 static_cast<jlong>(frameNr));
940 });
941 }
942}
943
John Reck5b02c622018-05-17 10:44:00 -0700944static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env,
945 jobject clazz, jlong proxyPtr, jobject callback) {
946 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
947 if (!callback) {
948 proxy->setFrameCompleteCallback(nullptr);
949 } else {
950 sp<FrameCompleteWrapper> wrapper = new FrameCompleteWrapper{env, callback};
951 proxy->setFrameCompleteCallback([wrapper](int64_t frameNr) {
952 wrapper->postFrameComplete(frameNr);
953 });
954 }
955}
956
John Recke94cbc72016-04-25 13:03:44 -0700957static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
John Reck95801462016-09-01 09:44:09 -0700958 jobject clazz, jobject jsurface, jint left, jint top,
959 jint right, jint bottom, jobject jbitmap) {
John Reck10dd0582016-03-31 16:36:16 -0700960 SkBitmap bitmap;
961 GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
962 sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
John Reck95801462016-09-01 09:44:09 -0700963 return RenderProxy::copySurfaceInto(surface, left, top, right, bottom, &bitmap);
John Reck10dd0582016-03-31 16:36:16 -0700964}
965
John Reck1fedd912017-05-23 14:45:22 -0700966class ContextFactory : public IContextFactory {
967public:
968 virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
969 return new AnimationContext(clock);
970 }
971};
972
973static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(JNIEnv* env,
974 jobject clazz, jlong renderNodePtr, jint jwidth, jint jheight) {
975 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
976 if (jwidth <= 0 || jheight <= 0) {
977 ALOGW("Invalid width %d or height %d", jwidth, jheight);
978 return nullptr;
979 }
980
981 uint32_t width = jwidth;
982 uint32_t height = jheight;
983
984 // Create a Surface wired up to a BufferItemConsumer
985 sp<IGraphicBufferProducer> producer;
986 sp<IGraphicBufferConsumer> rawConsumer;
987 BufferQueue::createBufferQueue(&producer, &rawConsumer);
John Recka67b62e2017-06-01 12:44:58 -0700988 // We only need 1 buffer but some drivers have bugs so workaround it by setting max count to 2
989 rawConsumer->setMaxBufferCount(2);
John Reck1fedd912017-05-23 14:45:22 -0700990 sp<BufferItemConsumer> consumer = new BufferItemConsumer(rawConsumer,
991 GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER);
992 consumer->setDefaultBufferSize(width, height);
993 sp<Surface> surface = new Surface(producer);
994
995 // Render into the surface
996 {
997 ContextFactory factory;
John Reck226fcca2017-09-05 11:24:59 -0700998 RenderProxy proxy{true, renderNode, &factory};
John Reck1fedd912017-05-23 14:45:22 -0700999 proxy.loadSystemProperties();
1000 proxy.setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
1001 proxy.initialize(surface);
1002 // Shadows can't be used via this interface, so just set the light source
1003 // to all 0s.
1004 proxy.setup(0, 0, 0);
1005 proxy.setLightCenter((Vector3){0, 0, 0});
1006 nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
1007 UiFrameInfoBuilder(proxy.frameInfo())
1008 .setVsync(vsync, vsync)
1009 .addFlag(FrameInfoFlags::SurfaceCanvas);
1010 proxy.syncAndDrawFrame();
1011 }
1012
1013 // Yank out the GraphicBuffer
1014 BufferItem bufferItem;
1015 status_t err;
1016 if ((err = consumer->acquireBuffer(&bufferItem, 0, true)) != OK) {
1017 ALOGW("Failed to acquireBuffer, error %d (%s)", err, strerror(-err));
1018 return nullptr;
1019 }
1020 sp<GraphicBuffer> buffer = bufferItem.mGraphicBuffer;
1021 // We don't really care if this fails or not since we're just going to destroy this anyway
1022 consumer->releaseBuffer(bufferItem);
1023 if (!buffer.get()) {
1024 ALOGW("GraphicBuffer is null?");
1025 return nullptr;
1026 }
1027 if (buffer->getWidth() != width || buffer->getHeight() != height) {
1028 ALOGW("GraphicBuffer size mismatch, got %dx%d expected %dx%d",
1029 buffer->getWidth(), buffer->getHeight(), width, height);
1030 // Continue I guess?
1031 }
1032 sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer);
Stan Ilievc2311822017-08-23 16:25:33 -04001033 return bitmap::createBitmap(env, bitmap.release(),
1034 android::bitmap::kBitmapCreateFlag_Premultiplied);
John Reck1fedd912017-05-23 14:45:22 -07001035}
1036
John Recka8963062017-06-14 10:47:50 -07001037static void android_view_ThreadedRenderer_disableVsync(JNIEnv*, jclass) {
1038 RenderProxy::disableVsync();
1039}
1040
John Reck938e8842017-08-24 13:41:59 -07001041static void android_view_ThreadedRenderer_setHighContrastText(JNIEnv*, jclass, jboolean enable) {
1042 Properties::enableHighContrastText = enable;
1043}
1044
John Reck9f516442017-09-25 10:27:21 -07001045static void android_view_ThreadedRenderer_hackySetRTAnimationsEnabled(JNIEnv*, jclass,
1046 jboolean enable) {
1047 Properties::enableRTAnimations = enable;
1048}
1049
John Reck6afa0092018-03-01 17:28:35 -08001050static void android_view_ThreadedRenderer_setDebuggingEnabled(JNIEnv*, jclass, jboolean enable) {
1051 Properties::debuggingEnabled = enable;
1052}
1053
John Reck56428472018-03-16 17:27:17 -07001054static void android_view_ThreadedRenderer_setIsolatedProcess(JNIEnv*, jclass, jboolean isolated) {
1055 Properties::isolatedProcess = isolated;
1056}
1057
Jorim Jaggi767e25e2018-04-04 23:07:35 +02001058static void android_view_ThreadedRenderer_setContextPriority(JNIEnv*, jclass,
1059 jint contextPriority) {
1060 Properties::contextPriority = contextPriority;
1061}
John Reck56428472018-03-16 17:27:17 -07001062
Jorim Jaggi7823ee72018-07-17 15:24:16 +02001063static void android_view_ThreadedRenderer_allocateBuffers(JNIEnv* env, jobject clazz,
1064 jlong proxyPtr, jobject jsurface) {
1065 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
1066 sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
1067 proxy->allocateBuffers(surface);
1068}
1069
John Reckcec24ae2013-11-05 13:27:50 -08001070// ----------------------------------------------------------------------------
Andres Morales910beb82016-02-02 16:19:40 -08001071// FrameMetricsObserver
Andres Morales06f5bc72015-12-15 15:21:31 -08001072// ----------------------------------------------------------------------------
1073
Andres Morales910beb82016-02-02 16:19:40 -08001074static jlong android_view_ThreadedRenderer_addFrameMetricsObserver(JNIEnv* env,
Andres Morales06f5bc72015-12-15 15:21:31 -08001075 jclass clazz, jlong proxyPtr, jobject fso) {
1076 JavaVM* vm = nullptr;
1077 if (env->GetJavaVM(&vm) != JNI_OK) {
1078 LOG_ALWAYS_FATAL("Unable to get Java VM");
1079 return 0;
1080 }
1081
1082 renderthread::RenderProxy* renderProxy =
1083 reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
1084
Andres Morales910beb82016-02-02 16:19:40 -08001085 FrameMetricsObserver* observer = new ObserverProxy(vm, fso);
1086 renderProxy->addFrameMetricsObserver(observer);
Andres Morales06f5bc72015-12-15 15:21:31 -08001087 return reinterpret_cast<jlong>(observer);
1088}
1089
Andres Morales910beb82016-02-02 16:19:40 -08001090static void android_view_ThreadedRenderer_removeFrameMetricsObserver(JNIEnv* env, jclass clazz,
Andres Morales06f5bc72015-12-15 15:21:31 -08001091 jlong proxyPtr, jlong observerPtr) {
Andres Morales910beb82016-02-02 16:19:40 -08001092 FrameMetricsObserver* observer = reinterpret_cast<FrameMetricsObserver*>(observerPtr);
Andres Morales06f5bc72015-12-15 15:21:31 -08001093 renderthread::RenderProxy* renderProxy =
1094 reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
1095
Andres Morales910beb82016-02-02 16:19:40 -08001096 renderProxy->removeFrameMetricsObserver(observer);
Andres Morales06f5bc72015-12-15 15:21:31 -08001097}
1098
1099// ----------------------------------------------------------------------------
John Reck84a4c882014-05-30 14:34:03 -07001100// Shaders
1101// ----------------------------------------------------------------------------
1102
1103static void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
Stan Ilievd495f432017-10-09 15:49:32 -04001104 jstring diskCachePath, jstring skiaDiskCachePath) {
John Reck84a4c882014-05-30 14:34:03 -07001105 const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
Mathias Agopian04d04612017-03-08 23:21:54 -08001106 android::egl_set_cache_filename(cacheArray);
John Reck84a4c882014-05-30 14:34:03 -07001107 env->ReleaseStringUTFChars(diskCachePath, cacheArray);
Stan Ilievd495f432017-10-09 15:49:32 -04001108
1109 const char* skiaCacheArray = env->GetStringUTFChars(skiaDiskCachePath, NULL);
1110 uirenderer::skiapipeline::ShaderCache::get().setFilename(skiaCacheArray);
1111 env->ReleaseStringUTFChars(skiaDiskCachePath, skiaCacheArray);
John Reck84a4c882014-05-30 14:34:03 -07001112}
1113
1114// ----------------------------------------------------------------------------
John Reckcec24ae2013-11-05 13:27:50 -08001115// JNI Glue
1116// ----------------------------------------------------------------------------
1117
1118const char* const kClassPathName = "android/view/ThreadedRenderer";
1119
Daniel Micay76f6a862015-09-19 17:31:01 -04001120static const JNINativeMethod gMethods[] = {
John Reckdf1742e2017-01-19 15:56:21 -08001121 { "nRotateProcessStatsBuffer", "()V", (void*) android_view_ThreadedRenderer_rotateProcessStatsBuffer },
1122 { "nSetProcessStatsBuffer", "(I)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer },
Tim Murray33eb07f2016-06-10 10:03:20 -07001123 { "nGetRenderThreadTid", "(J)I", (void*) android_view_ThreadedRenderer_getRenderThreadTid },
John Recke45b1fd2014-04-15 09:50:16 -07001124 { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode },
1125 { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy },
John Reck4f02bf42014-01-03 18:09:17 -08001126 { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
John Recke4280ba2014-05-05 16:39:37 -07001127 { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties },
John Reckb36016c2015-03-11 08:50:53 -07001128 { "nSetName", "(JLjava/lang/String;)V", (void*) android_view_ThreadedRenderer_setName },
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +01001129 { "nInitialize", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_initialize },
John Reck4f02bf42014-01-03 18:09:17 -08001130 { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
John Reck01a5ea32014-12-03 13:01:07 -08001131 { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
John Reck8afcc762016-04-13 10:24:06 -07001132 { "nSetStopped", "(JZ)V", (void*) android_view_ThreadedRenderer_setStopped },
John Reckab1080c2016-06-21 16:24:20 -07001133 { "nSetup", "(JFII)V", (void*) android_view_ThreadedRenderer_setup },
Alan Viverette50210d92015-05-14 18:05:36 -07001134 { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
John Reck63a06672014-05-07 13:45:54 -07001135 { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
Romain Guy26a2b972017-04-17 09:39:51 -07001136 { "nSetWideGamut", "(JZ)V", (void*) android_view_ThreadedRenderer_setWideGamut },
John Reck51f2d602016-04-06 07:50:47 -07001137 { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
Doris Liu350e6522016-02-19 14:20:37 -08001138 { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
John Reck119907c2014-08-14 09:02:01 -07001139 { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
Doris Liu67ce99b2016-05-17 16:50:31 -07001140 { "nRegisterVectorDrawableAnimator", "(JJ)V", (void*) android_view_ThreadedRenderer_registerVectorDrawableAnimator },
John Reck3b202512014-06-23 13:13:08 -07001141 { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
John Reck19b6bcf2014-02-14 20:03:38 -08001142 { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
John Reck3e824952014-08-20 10:08:39 -07001143 { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
John Reck3731dc22015-04-13 15:20:29 -07001144 { "nCopyLayerInto", "(JJLandroid/graphics/Bitmap;)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
John Reckd72e0a32014-05-29 18:56:11 -07001145 { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
1146 { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
John Reck918ad522014-06-27 14:45:25 -07001147 { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
John Reckf47a5942014-06-30 16:20:04 -07001148 { "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources },
1149 { "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory },
Chris Craik2507c342015-05-04 14:36:49 -07001150 { "nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V", (void*) android_view_ThreadedRenderer_overrideProperty },
John Reck28ad7b52014-04-07 16:59:25 -07001151 { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
John Reckf47a5942014-06-30 16:20:04 -07001152 { "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing },
John Recka5dda642014-05-22 15:43:54 -07001153 { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
John Recke248bd12015-08-05 13:53:53 -07001154 { "nSerializeDisplayListTree", "(J)V", (void*) android_view_ThreadedRenderer_serializeDisplayListTree },
John Reckba6adf62015-02-19 14:36:50 -08001155 { "nDumpProfileInfo", "(JLjava/io/FileDescriptor;I)V", (void*) android_view_ThreadedRenderer_dumpProfileInfo },
Stan Ilievd495f432017-10-09 15:49:32 -04001156 { "setupShadersDiskCache", "(Ljava/lang/String;Ljava/lang/String;)V",
John Reck84a4c882014-05-30 14:34:03 -07001157 (void*) android_view_ThreadedRenderer_setupShadersDiskCache },
Skuhneea7a7fb2015-08-28 07:10:31 -07001158 { "nAddRenderNode", "(JJZ)V", (void*) android_view_ThreadedRenderer_addRenderNode},
1159 { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
1160 { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
Skuhneb8160872015-09-22 09:51:39 -07001161 { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
Mihai Popa95688002018-02-23 16:10:11 +00001162 { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V",
1163 (void*)android_view_ThreadedRenderer_setFrameCallback},
John Reck5b02c622018-05-17 10:44:00 -07001164 { "nSetFrameCompleteCallback", "(JLandroid/view/ThreadedRenderer$FrameCompleteCallback;)V",
1165 (void*)android_view_ThreadedRenderer_setFrameCompleteCallback },
Andres Morales910beb82016-02-02 16:19:40 -08001166 { "nAddFrameMetricsObserver",
1167 "(JLandroid/view/FrameMetricsObserver;)J",
1168 (void*)android_view_ThreadedRenderer_addFrameMetricsObserver },
1169 { "nRemoveFrameMetricsObserver",
Andres Morales06f5bc72015-12-15 15:21:31 -08001170 "(JJ)V",
Andres Morales910beb82016-02-02 16:19:40 -08001171 (void*)android_view_ThreadedRenderer_removeFrameMetricsObserver },
John Reck95801462016-09-01 09:44:09 -07001172 { "nCopySurfaceInto", "(Landroid/view/Surface;IIIILandroid/graphics/Bitmap;)I",
John Reck10dd0582016-03-31 16:36:16 -07001173 (void*)android_view_ThreadedRenderer_copySurfaceInto },
John Reck1fedd912017-05-23 14:45:22 -07001174 { "nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;",
1175 (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode },
John Recka8963062017-06-14 10:47:50 -07001176 { "disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync },
John Reck938e8842017-08-24 13:41:59 -07001177 { "nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText },
John Reck9f516442017-09-25 10:27:21 -07001178 { "nHackySetRTAnimationsEnabled", "(Z)V",
1179 (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled },
John Reck6afa0092018-03-01 17:28:35 -08001180 { "nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled },
John Reck56428472018-03-16 17:27:17 -07001181 { "nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess },
Jorim Jaggi767e25e2018-04-04 23:07:35 +02001182 { "nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority },
Jorim Jaggi7823ee72018-07-17 15:24:16 +02001183 { "nAllocateBuffers", "(JLandroid/view/Surface;)V", (void*)android_view_ThreadedRenderer_allocateBuffers },
John Reckcec24ae2013-11-05 13:27:50 -08001184};
1185
John Reck259b25a2017-12-01 16:18:53 -08001186static JavaVM* mJvm = nullptr;
1187
1188static void attachRenderThreadToJvm() {
1189 LOG_ALWAYS_FATAL_IF(!mJvm, "No jvm but we set the hook??");
1190
1191 JavaVMAttachArgs args;
1192 args.version = JNI_VERSION_1_4;
1193 args.name = (char*) "RenderThread";
1194 args.group = NULL;
1195 JNIEnv* env;
1196 mJvm->AttachCurrentThreadAsDaemon(&env, (void*) &args);
1197}
1198
John Reckcec24ae2013-11-05 13:27:50 -08001199int register_android_view_ThreadedRenderer(JNIEnv* env) {
John Reck259b25a2017-12-01 16:18:53 -08001200 env->GetJavaVM(&mJvm);
1201 RenderThread::setOnStartHook(&attachRenderThreadToJvm);
Andres Morales910beb82016-02-02 16:19:40 -08001202 jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver");
1203 gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie(
1204 env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;");
1205 gFrameMetricsObserverClassInfo.messageQueue = GetFieldIDOrDie(
1206 env, observerClass, "mMessageQueue", "Landroid/os/MessageQueue;");
1207 gFrameMetricsObserverClassInfo.callback = GetMethodIDOrDie(
1208 env, observerClass, "notifyDataAvailable", "(I)V");
1209
1210 jclass metricsClass = FindClassOrDie(env, "android/view/FrameMetrics");
1211 gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
1212 env, metricsClass, "mTimingData", "[J");
Andres Morales06f5bc72015-12-15 15:21:31 -08001213
Mihai Popa95688002018-02-23 16:10:11 +00001214 jclass frameCallbackClass = FindClassOrDie(env,
1215 "android/view/ThreadedRenderer$FrameDrawingCallback");
1216 gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
1217 "onFrameDraw", "(J)V");
1218
John Reck5b02c622018-05-17 10:44:00 -07001219 jclass frameCompleteClass = FindClassOrDie(env,
1220 "android/view/ThreadedRenderer$FrameCompleteCallback");
1221 gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass,
1222 "onFrameComplete", "(J)V");
1223
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001224 return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
John Reckcec24ae2013-11-05 13:27:50 -08001225}
1226
1227}; // namespace android