android_view_ThreadedRenderer.cpp revision 03d8f76836c5950374bc9030a78706d25ac233e9
1/* 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 17#define LOG_TAG "ThreadedRenderer" 18 19#include <algorithm> 20 21#include "jni.h" 22#include <nativehelper/JNIHelp.h> 23#include "core_jni_helpers.h" 24#include <GraphicsJNI.h> 25#include <ScopedPrimitiveArray.h> 26 27#include <EGL/egl.h> 28#include <EGL/eglext.h> 29#include <EGL/egl_cache.h> 30#include <vulkan/vulkan_loader_data.h> 31 32#include <utils/Looper.h> 33#include <utils/RefBase.h> 34#include <utils/StrongPointer.h> 35#include <android_runtime/android_view_Surface.h> 36#include <system/window.h> 37 38#include "android_view_GraphicBuffer.h" 39#include "android_os_MessageQueue.h" 40 41#include <Animator.h> 42#include <AnimationContext.h> 43#include <FrameInfo.h> 44#include <IContextFactory.h> 45#include <JankTracker.h> 46#include <RenderNode.h> 47#include <renderthread/CanvasContext.h> 48#include <renderthread/RenderProxy.h> 49#include <renderthread/RenderTask.h> 50#include <renderthread/RenderThread.h> 51#include <Vector.h> 52 53namespace android { 54 55using namespace android::uirenderer; 56using namespace android::uirenderer::renderthread; 57 58struct { 59 jfieldID buffer; 60 jfieldID messageQueue; 61 jmethodID notifyData; 62} gFrameStatsObserverClassInfo; 63 64static JNIEnv* getenv(JavaVM* vm) { 65 JNIEnv* env; 66 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { 67 LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm); 68 } 69 return env; 70} 71 72class OnFinishedEvent { 73public: 74 OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener) 75 : animator(animator), listener(listener) {} 76 sp<BaseRenderNodeAnimator> animator; 77 sp<AnimationListener> listener; 78}; 79 80class InvokeAnimationListeners : public MessageHandler { 81public: 82 InvokeAnimationListeners(std::vector<OnFinishedEvent>& events) { 83 mOnFinishedEvents.swap(events); 84 } 85 86 static void callOnFinished(OnFinishedEvent& event) { 87 event.listener->onAnimationFinished(event.animator.get()); 88 } 89 90 virtual void handleMessage(const Message& message) { 91 std::for_each(mOnFinishedEvents.begin(), mOnFinishedEvents.end(), callOnFinished); 92 mOnFinishedEvents.clear(); 93 } 94 95private: 96 std::vector<OnFinishedEvent> mOnFinishedEvents; 97}; 98 99class RenderingException : public MessageHandler { 100public: 101 RenderingException(JavaVM* vm, const std::string& message) 102 : mVm(vm) 103 , mMessage(message) { 104 } 105 106 virtual void handleMessage(const Message&) { 107 throwException(mVm, mMessage); 108 } 109 110 static void throwException(JavaVM* vm, const std::string& message) { 111 JNIEnv* env = getenv(vm); 112 jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); 113 } 114 115private: 116 JavaVM* mVm; 117 std::string mMessage; 118}; 119 120class RootRenderNode : public RenderNode, ErrorHandler { 121public: 122 RootRenderNode(JNIEnv* env) : RenderNode() { 123 mLooper = Looper::getForThread(); 124 LOG_ALWAYS_FATAL_IF(!mLooper.get(), 125 "Must create RootRenderNode on a thread with a looper!"); 126 env->GetJavaVM(&mVm); 127 } 128 129 virtual ~RootRenderNode() {} 130 131 virtual void onError(const std::string& message) { 132 mLooper->sendMessage(new RenderingException(mVm, message), 0); 133 } 134 135 virtual void prepareTree(TreeInfo& info) { 136 info.errorHandler = this; 137 RenderNode::prepareTree(info); 138 info.errorHandler = NULL; 139 } 140 141 void sendMessage(const sp<MessageHandler>& handler) { 142 mLooper->sendMessage(handler, 0); 143 } 144 145 void attachAnimatingNode(RenderNode* animatingNode) { 146 mPendingAnimatingRenderNodes.push_back(animatingNode); 147 } 148 149 void doAttachAnimatingNodes(AnimationContext* context) { 150 for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) { 151 RenderNode* node = mPendingAnimatingRenderNodes[i].get(); 152 context->addAnimatingRenderNode(*node); 153 } 154 mPendingAnimatingRenderNodes.clear(); 155 } 156 157private: 158 sp<Looper> mLooper; 159 JavaVM* mVm; 160 std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes; 161}; 162 163class AnimationContextBridge : public AnimationContext { 164public: 165 AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode) 166 : AnimationContext(clock), mRootNode(rootNode) { 167 } 168 169 virtual ~AnimationContextBridge() {} 170 171 // Marks the start of a frame, which will update the frame time and move all 172 // next frame animations into the current frame 173 virtual void startFrame(TreeInfo::TraversalMode mode) { 174 if (mode == TreeInfo::MODE_FULL) { 175 mRootNode->doAttachAnimatingNodes(this); 176 } 177 AnimationContext::startFrame(mode); 178 } 179 180 // Runs any animations still left in mCurrentFrameAnimations 181 virtual void runRemainingAnimations(TreeInfo& info) { 182 AnimationContext::runRemainingAnimations(info); 183 postOnFinishedEvents(); 184 } 185 186 virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) { 187 OnFinishedEvent event(animator, listener); 188 mOnFinishedEvents.push_back(event); 189 } 190 191 virtual void destroy() { 192 AnimationContext::destroy(); 193 postOnFinishedEvents(); 194 } 195 196private: 197 sp<RootRenderNode> mRootNode; 198 std::vector<OnFinishedEvent> mOnFinishedEvents; 199 200 void postOnFinishedEvents() { 201 if (mOnFinishedEvents.size()) { 202 sp<InvokeAnimationListeners> message 203 = new InvokeAnimationListeners(mOnFinishedEvents); 204 mRootNode->sendMessage(message); 205 } 206 } 207}; 208 209class ContextFactoryImpl : public IContextFactory { 210public: 211 ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {} 212 213 virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { 214 return new AnimationContextBridge(clock, mRootNode); 215 } 216 217private: 218 RootRenderNode* mRootNode; 219}; 220 221class ObserverProxy; 222 223class NotifyHandler : public MessageHandler { 224public: 225 NotifyHandler(JavaVM* vm) : mVm(vm) {} 226 227 void setObserver(ObserverProxy* observer) { 228 mObserver = observer; 229 } 230 231 void setBuffer(BufferPool::Buffer* buffer) { 232 mBuffer = buffer; 233 } 234 235 virtual void handleMessage(const Message& message); 236 237private: 238 JavaVM* mVm; 239 240 sp<ObserverProxy> mObserver; 241 BufferPool::Buffer* mBuffer; 242}; 243 244class ObserverProxy : public FrameStatsObserver { 245public: 246 ObserverProxy(JavaVM *vm, jobject fso) : mVm(vm) { 247 JNIEnv* env = getenv(mVm); 248 249 jlongArray longArrayLocal = env->NewLongArray(kBufferSize); 250 LOG_ALWAYS_FATAL_IF(longArrayLocal == nullptr, 251 "OOM: can't allocate frame stats buffer"); 252 env->SetObjectField(fso, gFrameStatsObserverClassInfo.buffer, longArrayLocal); 253 254 mFsoWeak = env->NewWeakGlobalRef(fso); 255 LOG_ALWAYS_FATAL_IF(mFsoWeak == nullptr, 256 "unable to create frame stats observer reference"); 257 258 jobject messageQueueLocal = 259 env->GetObjectField(fso, gFrameStatsObserverClassInfo.messageQueue); 260 mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal); 261 LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available"); 262 263 mMessageHandler = new NotifyHandler(mVm); 264 LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr, 265 "OOM: unable to allocate NotifyHandler"); 266 } 267 268 ~ObserverProxy() { 269 JNIEnv* env = getenv(mVm); 270 env->DeleteWeakGlobalRef(mFsoWeak); 271 } 272 273 jweak getJavaObjectRef() { 274 return mFsoWeak; 275 } 276 277 virtual void notify(BufferPool::Buffer* buffer) { 278 buffer->incRef(); 279 mMessageHandler->setBuffer(buffer); 280 mMessageHandler->setObserver(this); 281 mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage); 282 } 283 284private: 285 static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes); 286 287 JavaVM* mVm; 288 jweak mFsoWeak; 289 290 sp<MessageQueue> mMessageQueue; 291 sp<NotifyHandler> mMessageHandler; 292 Message mMessage; 293}; 294 295void NotifyHandler::handleMessage(const Message& message) { 296 JNIEnv* env = getenv(mVm); 297 298 jobject target = env->NewLocalRef(mObserver->getJavaObjectRef()); 299 300 if (target != nullptr) { 301 jobject javaBuffer = env->GetObjectField(target, gFrameStatsObserverClassInfo.buffer); 302 if (javaBuffer != nullptr) { 303 env->SetLongArrayRegion(reinterpret_cast<jlongArray>(javaBuffer), 304 0, mBuffer->getSize(), mBuffer->getBuffer()); 305 env->CallVoidMethod(target, gFrameStatsObserverClassInfo.notifyData); 306 env->DeleteLocalRef(target); 307 } 308 } 309 310 mBuffer->release(); 311 mObserver.clear(); 312} 313 314static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, 315 jlong proxyPtr, jobject graphicBuffer, jlongArray atlasMapArray) { 316 sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer); 317 jsize len = env->GetArrayLength(atlasMapArray); 318 if (len <= 0) { 319 ALOGW("Failed to initialize atlas, invalid map length: %d", len); 320 return; 321 } 322 int64_t* map = new int64_t[len]; 323 env->GetLongArrayRegion(atlasMapArray, 0, len, map); 324 325 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 326 proxy->setTextureAtlas(buffer, map, len); 327} 328 329static void android_view_ThreadedRenderer_setProcessStatsBuffer(JNIEnv* env, jobject clazz, 330 jlong proxyPtr, jint fd) { 331 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 332 proxy->setProcessStatsBuffer(fd); 333} 334 335static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) { 336 RootRenderNode* node = new RootRenderNode(env); 337 node->incStrong(0); 338 node->setName("RootRenderNode"); 339 return reinterpret_cast<jlong>(node); 340} 341 342static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz, 343 jboolean translucent, jlong rootRenderNodePtr) { 344 RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr); 345 ContextFactoryImpl factory(rootRenderNode); 346 return (jlong) new RenderProxy(translucent, rootRenderNode, &factory); 347} 348 349static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz, 350 jlong proxyPtr) { 351 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 352 delete proxy; 353} 354 355static jboolean android_view_ThreadedRenderer_loadSystemProperties(JNIEnv* env, jobject clazz, 356 jlong proxyPtr) { 357 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 358 return proxy->loadSystemProperties(); 359} 360 361static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz, 362 jlong proxyPtr, jstring jname) { 363 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 364 const char* name = env->GetStringUTFChars(jname, NULL); 365 proxy->setName(name); 366 env->ReleaseStringUTFChars(jname, name); 367} 368 369static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz, 370 jlong proxyPtr, jobject jsurface) { 371 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 372 sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface); 373 proxy->initialize(window); 374} 375 376static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz, 377 jlong proxyPtr, jobject jsurface) { 378 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 379 sp<ANativeWindow> window; 380 if (jsurface) { 381 window = android_view_Surface_getNativeWindow(env, jsurface); 382 } 383 proxy->updateSurface(window); 384} 385 386static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, 387 jlong proxyPtr, jobject jsurface) { 388 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 389 sp<ANativeWindow> window; 390 if (jsurface) { 391 window = android_view_Surface_getNativeWindow(env, jsurface); 392 } 393 return proxy->pauseSurface(window); 394} 395 396static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr, 397 jint width, jint height, jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) { 398 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 399 proxy->setup(width, height, lightRadius, ambientShadowAlpha, spotShadowAlpha); 400} 401 402static void android_view_ThreadedRenderer_setLightCenter(JNIEnv* env, jobject clazz, 403 jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ) { 404 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 405 proxy->setLightCenter((Vector3){lightX, lightY, lightZ}); 406} 407 408static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz, 409 jlong proxyPtr, jboolean opaque) { 410 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 411 proxy->setOpaque(opaque); 412} 413 414static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz, 415 jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) { 416 LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE, 417 "Mismatched size expectations, given %d expected %d", 418 frameInfoSize, UI_THREAD_FRAME_INFO_SIZE); 419 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 420 env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo()); 421 return proxy->syncAndDrawFrame(); 422} 423 424static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz, 425 jlong proxyPtr) { 426 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 427 proxy->destroy(); 428} 429 430static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz, 431 jlong rootNodePtr, jlong animatingNodePtr) { 432 RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr); 433 RenderNode* animatingNode = reinterpret_cast<RenderNode*>(animatingNodePtr); 434 rootRenderNode->attachAnimatingNode(animatingNode); 435} 436 437static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz, 438 jlong functorPtr, jboolean waitForCompletion) { 439 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 440 RenderProxy::invokeFunctor(functor, waitForCompletion); 441} 442 443static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz, 444 jlong proxyPtr) { 445 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 446 DeferredLayerUpdater* layer = proxy->createTextureLayer(); 447 return reinterpret_cast<jlong>(layer); 448} 449 450static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz, 451 jlong proxyPtr, jlong nodePtr) { 452 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 453 RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr); 454 proxy->buildLayer(node); 455} 456 457static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz, 458 jlong proxyPtr, jlong layerPtr, jobject jbitmap) { 459 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 460 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 461 SkBitmap bitmap; 462 GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); 463 return proxy->copyLayerInto(layer, bitmap); 464} 465 466static void android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv* env, jobject clazz, 467 jlong proxyPtr, jlong layerPtr) { 468 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 469 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 470 proxy->pushLayerUpdate(layer); 471} 472 473static void android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv* env, jobject clazz, 474 jlong proxyPtr, jlong layerPtr) { 475 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 476 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 477 proxy->cancelLayerUpdate(layer); 478} 479 480static void android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv* env, jobject clazz, 481 jlong proxyPtr, jlong layerPtr) { 482 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 483 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 484 proxy->detachSurfaceTexture(layer); 485} 486 487static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz, 488 jlong proxyPtr) { 489 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 490 proxy->destroyHardwareResources(); 491} 492 493static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz, 494 jint level) { 495 RenderProxy::trimMemory(level); 496} 497 498static void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz, 499 jstring name, jstring value) { 500 const char* nameCharArray = env->GetStringUTFChars(name, NULL); 501 const char* valueCharArray = env->GetStringUTFChars(value, NULL); 502 RenderProxy::overrideProperty(nameCharArray, valueCharArray); 503 env->ReleaseStringUTFChars(name, nameCharArray); 504 env->ReleaseStringUTFChars(name, valueCharArray); 505} 506 507static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz, 508 jlong proxyPtr) { 509 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 510 proxy->fence(); 511} 512 513static void android_view_ThreadedRenderer_stopDrawing(JNIEnv* env, jobject clazz, 514 jlong proxyPtr) { 515 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 516 proxy->stopDrawing(); 517} 518 519static void android_view_ThreadedRenderer_notifyFramePending(JNIEnv* env, jobject clazz, 520 jlong proxyPtr) { 521 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 522 proxy->notifyFramePending(); 523} 524 525static void android_view_ThreadedRenderer_serializeDisplayListTree(JNIEnv* env, jobject clazz, 526 jlong proxyPtr) { 527 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 528 proxy->serializeDisplayListTree(); 529} 530 531static void android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv* env, jobject clazz, 532 jlong proxyPtr, jobject javaFileDescriptor, jint dumpFlags) { 533 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 534 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); 535 proxy->dumpProfileInfo(fd, dumpFlags); 536} 537 538static void android_view_ThreadedRenderer_dumpProfileData(JNIEnv* env, jobject clazz, 539 jbyteArray jdata, jobject javaFileDescriptor) { 540 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); 541 ScopedByteArrayRO buffer(env, jdata); 542 if (buffer.get()) { 543 JankTracker::dumpBuffer(buffer.get(), buffer.size(), fd); 544 } 545} 546 547static void android_view_ThreadedRenderer_addRenderNode(JNIEnv* env, jobject clazz, 548 jlong proxyPtr, jlong renderNodePtr, jboolean placeFront) { 549 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 550 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); 551 proxy->addRenderNode(renderNode, placeFront); 552} 553 554static void android_view_ThreadedRenderer_removeRenderNode(JNIEnv* env, jobject clazz, 555 jlong proxyPtr, jlong renderNodePtr) { 556 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 557 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); 558 proxy->removeRenderNode(renderNode); 559} 560 561static void android_view_ThreadedRendererd_drawRenderNode(JNIEnv* env, jobject clazz, 562 jlong proxyPtr, jlong renderNodePtr) { 563 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 564 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); 565 proxy->drawRenderNode(renderNode); 566} 567 568static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env, 569 jobject clazz, jlong proxyPtr, jint left, jint top, jint right, jint bottom) { 570 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 571 proxy->setContentDrawBounds(left, top, right, bottom); 572} 573 574// ---------------------------------------------------------------------------- 575// FrameStatsObserver 576// ---------------------------------------------------------------------------- 577 578static jlong android_view_ThreadedRenderer_addFrameStatsObserver(JNIEnv* env, 579 jclass clazz, jlong proxyPtr, jobject fso) { 580 JavaVM* vm = nullptr; 581 if (env->GetJavaVM(&vm) != JNI_OK) { 582 LOG_ALWAYS_FATAL("Unable to get Java VM"); 583 return 0; 584 } 585 586 renderthread::RenderProxy* renderProxy = 587 reinterpret_cast<renderthread::RenderProxy*>(proxyPtr); 588 589 FrameStatsObserver* observer = new ObserverProxy(vm, fso); 590 renderProxy->addFrameStatsObserver(observer); 591 return reinterpret_cast<jlong>(observer); 592} 593 594static void android_view_ThreadedRenderer_removeFrameStatsObserver(JNIEnv* env, jclass clazz, 595 jlong proxyPtr, jlong observerPtr) { 596 FrameStatsObserver* observer = reinterpret_cast<FrameStatsObserver*>(observerPtr); 597 renderthread::RenderProxy* renderProxy = 598 reinterpret_cast<renderthread::RenderProxy*>(proxyPtr); 599 600 renderProxy->removeFrameStatsObserver(observer); 601} 602 603static jint android_view_ThreadedRenderer_getDroppedFrameReportCount(JNIEnv* env, jclass clazz, 604 jlong proxyPtr) { 605 renderthread::RenderProxy* renderProxy = 606 reinterpret_cast<renderthread::RenderProxy*>(proxyPtr); 607 return renderProxy->getDroppedFrameReportCount(); 608} 609 610// ---------------------------------------------------------------------------- 611// Shaders 612// ---------------------------------------------------------------------------- 613 614static void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz, 615 jstring diskCachePath) { 616 const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL); 617 egl_cache_t::get()->setCacheFilename(cacheArray); 618 env->ReleaseStringUTFChars(diskCachePath, cacheArray); 619} 620 621// ---------------------------------------------------------------------------- 622// Layers 623// ---------------------------------------------------------------------------- 624 625static void android_view_ThreadedRenderer_setupVulkanLayerPath(JNIEnv* env, jobject clazz, 626 jstring layerPath) { 627 628 const char* layerArray = env->GetStringUTFChars(layerPath, NULL); 629 vulkan::LoaderData::GetInstance().layer_path = layerArray; 630 env->ReleaseStringUTFChars(layerPath, layerArray); 631} 632 633// ---------------------------------------------------------------------------- 634// JNI Glue 635// ---------------------------------------------------------------------------- 636 637const char* const kClassPathName = "android/view/ThreadedRenderer"; 638 639static const JNINativeMethod gMethods[] = { 640 { "nSetAtlas", "(JLandroid/view/GraphicBuffer;[J)V", (void*) android_view_ThreadedRenderer_setAtlas }, 641 { "nSetProcessStatsBuffer", "(JI)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer }, 642 { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode }, 643 { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy }, 644 { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy }, 645 { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties }, 646 { "nSetName", "(JLjava/lang/String;)V", (void*) android_view_ThreadedRenderer_setName }, 647 { "nInitialize", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_initialize }, 648 { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, 649 { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface }, 650 { "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup }, 651 { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter }, 652 { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque }, 653 { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, 654 { "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy }, 655 { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode }, 656 { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor }, 657 { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer }, 658 { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer }, 659 { "nCopyLayerInto", "(JJLandroid/graphics/Bitmap;)Z", (void*) android_view_ThreadedRenderer_copyLayerInto }, 660 { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate }, 661 { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate }, 662 { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture }, 663 { "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources }, 664 { "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory }, 665 { "nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V", (void*) android_view_ThreadedRenderer_overrideProperty }, 666 { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence }, 667 { "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing }, 668 { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending }, 669 { "nSerializeDisplayListTree", "(J)V", (void*) android_view_ThreadedRenderer_serializeDisplayListTree }, 670 { "nDumpProfileInfo", "(JLjava/io/FileDescriptor;I)V", (void*) android_view_ThreadedRenderer_dumpProfileInfo }, 671 { "nDumpProfileData", "([BLjava/io/FileDescriptor;)V", (void*) android_view_ThreadedRenderer_dumpProfileData }, 672 { "setupShadersDiskCache", "(Ljava/lang/String;)V", 673 (void*) android_view_ThreadedRenderer_setupShadersDiskCache }, 674 { "setupVulkanLayerPath", "(Ljava/lang/String;)V", 675 (void*) android_view_ThreadedRenderer_setupVulkanLayerPath }, 676 { "nAddRenderNode", "(JJZ)V", (void*) android_view_ThreadedRenderer_addRenderNode}, 677 { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode}, 678 { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode}, 679 { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, 680 { "nAddFrameStatsObserver", 681 "(JLandroid/view/FrameStatsObserver;)J", 682 (void*)android_view_ThreadedRenderer_addFrameStatsObserver }, 683 { "nRemoveFrameStatsObserver", 684 "(JJ)V", 685 (void*)android_view_ThreadedRenderer_removeFrameStatsObserver }, 686 { "nGetDroppedFrameReportCount", 687 "(J)J", 688 (void*)android_view_ThreadedRenderer_getDroppedFrameReportCount }, 689}; 690 691int register_android_view_ThreadedRenderer(JNIEnv* env) { 692 jclass clazz = FindClassOrDie(env, "android/view/FrameStatsObserver"); 693 gFrameStatsObserverClassInfo.messageQueue = 694 GetFieldIDOrDie(env, clazz, "mMessageQueue", "Landroid/os/MessageQueue;"); 695 gFrameStatsObserverClassInfo.buffer = 696 GetFieldIDOrDie(env, clazz, "mBuffer", "[J"); 697 gFrameStatsObserverClassInfo.notifyData = 698 GetMethodIDOrDie(env, clazz, "notifyDataAvailable", "()V"); 699 700 return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); 701} 702 703}; // namespace android 704