android_view_ThreadedRenderer.cpp revision 11f02d7e522ec8742f7ef533c252e04e24b93f6b
1cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/*
2cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Copyright (C) 2010 The Android Open Source Project
3cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
4cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * you may not use this file except in compliance with the License.
6cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * You may obtain a copy of the License at
7cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
8cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
10cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Unless required by applicable law or agreed to in writing, software
11cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * See the License for the specific language governing permissions and
14cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * limitations under the License.
15cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
16cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#define LOG_TAG "ThreadedRenderer"
18cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
19e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <algorithm>
2011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales#include <atomic>
21e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
22cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include "jni.h"
23cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <nativehelper/JNIHelp.h>
24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
253731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck#include <GraphicsJNI.h>
26edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck#include <ScopedPrimitiveArray.h>
27cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2884a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck#include <EGL/egl.h>
2984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck#include <EGL/eglext.h>
3084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck#include <EGL/egl_cache.h>
3103d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine#include <vulkan/vulkan_loader_data.h>
3284a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
3306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales#include <utils/Looper.h>
3406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales#include <utils/RefBase.h>
354f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <utils/StrongPointer.h>
364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <android_runtime/android_view_Surface.h>
374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <system/window.h>
384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
3966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck#include "android_view_GraphicBuffer.h"
4006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales#include "android_os_MessageQueue.h"
4166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
4252244fff29042926e21fa897ef5ab11148e35299John Reck#include <Animator.h>
43119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include <AnimationContext.h>
4406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales#include <FrameInfo.h>
45910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales#include <FrameMetricsObserver.h>
46119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include <IContextFactory.h>
47edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck#include <JankTracker.h>
48e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <RenderNode.h>
4966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck#include <renderthread/CanvasContext.h>
504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <renderthread/RenderProxy.h>
51cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <renderthread/RenderTask.h>
52cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <renderthread/RenderThread.h>
53797b95b26bbb7557678af78b9a2a61830158920fChris Craik#include <Vector.h>
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace android {
56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckusing namespace android::uirenderer;
584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckusing namespace android::uirenderer::renderthread;
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
6006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesstruct {
61910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jfieldID frameMetrics;
62910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jfieldID timingDataBuffer;
6306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    jfieldID messageQueue;
64910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jmethodID callback;
65910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales} gFrameMetricsObserverClassInfo;
6606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
67c25e506f7fc08790c0532f927f31310a2ca778b7John Reckstatic JNIEnv* getenv(JavaVM* vm) {
68c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    JNIEnv* env;
69c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
70c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
71c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    }
72c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    return env;
73c25e506f7fc08790c0532f927f31310a2ca778b7John Reck}
74c25e506f7fc08790c0532f927f31310a2ca778b7John Reck
7552244fff29042926e21fa897ef5ab11148e35299John Reckclass OnFinishedEvent {
7652244fff29042926e21fa897ef5ab11148e35299John Reckpublic:
77ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
7852244fff29042926e21fa897ef5ab11148e35299John Reck            : animator(animator), listener(listener) {}
79ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    sp<BaseRenderNodeAnimator> animator;
8052244fff29042926e21fa897ef5ab11148e35299John Reck    sp<AnimationListener> listener;
8152244fff29042926e21fa897ef5ab11148e35299John Reck};
8252244fff29042926e21fa897ef5ab11148e35299John Reck
83e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckclass InvokeAnimationListeners : public MessageHandler {
84e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckpublic:
8552244fff29042926e21fa897ef5ab11148e35299John Reck    InvokeAnimationListeners(std::vector<OnFinishedEvent>& events) {
8652244fff29042926e21fa897ef5ab11148e35299John Reck        mOnFinishedEvents.swap(events);
87e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
88e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
8952244fff29042926e21fa897ef5ab11148e35299John Reck    static void callOnFinished(OnFinishedEvent& event) {
9052244fff29042926e21fa897ef5ab11148e35299John Reck        event.listener->onAnimationFinished(event.animator.get());
91e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
92e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
93e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    virtual void handleMessage(const Message& message) {
9452244fff29042926e21fa897ef5ab11148e35299John Reck        std::for_each(mOnFinishedEvents.begin(), mOnFinishedEvents.end(), callOnFinished);
9552244fff29042926e21fa897ef5ab11148e35299John Reck        mOnFinishedEvents.clear();
96e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
97e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
98e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckprivate:
9952244fff29042926e21fa897ef5ab11148e35299John Reck    std::vector<OnFinishedEvent> mOnFinishedEvents;
100e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck};
101e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
102c25e506f7fc08790c0532f927f31310a2ca778b7John Reckclass RenderingException : public MessageHandler {
103e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckpublic:
104c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    RenderingException(JavaVM* vm, const std::string& message)
105c25e506f7fc08790c0532f927f31310a2ca778b7John Reck            : mVm(vm)
106c25e506f7fc08790c0532f927f31310a2ca778b7John Reck            , mMessage(message) {
107c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    }
108c25e506f7fc08790c0532f927f31310a2ca778b7John Reck
109c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    virtual void handleMessage(const Message&) {
110c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        throwException(mVm, mMessage);
111c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    }
112c25e506f7fc08790c0532f927f31310a2ca778b7John Reck
113c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    static void throwException(JavaVM* vm, const std::string& message) {
114c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        JNIEnv* env = getenv(vm);
115c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        jniThrowException(env, "java/lang/IllegalStateException", message.c_str());
116c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    }
117c25e506f7fc08790c0532f927f31310a2ca778b7John Reck
118c25e506f7fc08790c0532f927f31310a2ca778b7John Reckprivate:
119c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    JavaVM* mVm;
120c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    std::string mMessage;
121c25e506f7fc08790c0532f927f31310a2ca778b7John Reck};
122c25e506f7fc08790c0532f927f31310a2ca778b7John Reck
123119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckclass RootRenderNode : public RenderNode, ErrorHandler {
124c25e506f7fc08790c0532f927f31310a2ca778b7John Reckpublic:
125c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    RootRenderNode(JNIEnv* env) : RenderNode() {
126e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mLooper = Looper::getForThread();
127e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        LOG_ALWAYS_FATAL_IF(!mLooper.get(),
128e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck                "Must create RootRenderNode on a thread with a looper!");
129c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        env->GetJavaVM(&mVm);
130e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
131e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
132e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    virtual ~RootRenderNode() {}
133e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
134c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    virtual void onError(const std::string& message) {
135c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        mLooper->sendMessage(new RenderingException(mVm, message), 0);
136c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    }
137c25e506f7fc08790c0532f927f31310a2ca778b7John Reck
138e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    virtual void prepareTree(TreeInfo& info) {
139c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        info.errorHandler = this;
140f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        // TODO: This is hacky
141f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        info.windowInsetLeft = -stagingProperties().getLeft();
142f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        info.windowInsetTop = -stagingProperties().getTop();
143f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        info.updateWindowPositions = true;
144e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        RenderNode::prepareTree(info);
145f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        info.updateWindowPositions = false;
146f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        info.windowInsetLeft = 0;
147f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        info.windowInsetTop = 0;
148c25e506f7fc08790c0532f927f31310a2ca778b7John Reck        info.errorHandler = NULL;
149119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
150119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
151119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void sendMessage(const sp<MessageHandler>& handler) {
152119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mLooper->sendMessage(handler, 0);
153119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
154119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
155119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void attachAnimatingNode(RenderNode* animatingNode) {
156119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mPendingAnimatingRenderNodes.push_back(animatingNode);
157119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
158119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
159119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void doAttachAnimatingNodes(AnimationContext* context) {
160119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) {
161119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            RenderNode* node = mPendingAnimatingRenderNodes[i].get();
162119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            context->addAnimatingRenderNode(*node);
163119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
164119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mPendingAnimatingRenderNodes.clear();
165119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
166119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
167119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckprivate:
168119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    sp<Looper> mLooper;
169119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    JavaVM* mVm;
170119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
171119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck};
172119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
173119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckclass AnimationContextBridge : public AnimationContext {
174119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckpublic:
175119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode)
176119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            : AnimationContext(clock), mRootNode(rootNode) {
177119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
178119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
179119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    virtual ~AnimationContextBridge() {}
180e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
181119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    // Marks the start of a frame, which will update the frame time and move all
182119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    // next frame animations into the current frame
183ec845a215e343cdb3b2e4c7b6aff7b24beb0236bJohn Reck    virtual void startFrame(TreeInfo::TraversalMode mode) {
184ec845a215e343cdb3b2e4c7b6aff7b24beb0236bJohn Reck        if (mode == TreeInfo::MODE_FULL) {
185ec845a215e343cdb3b2e4c7b6aff7b24beb0236bJohn Reck            mRootNode->doAttachAnimatingNodes(this);
186ec845a215e343cdb3b2e4c7b6aff7b24beb0236bJohn Reck        }
187ec845a215e343cdb3b2e4c7b6aff7b24beb0236bJohn Reck        AnimationContext::startFrame(mode);
188119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
189119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
190119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    // Runs any animations still left in mCurrentFrameAnimations
191119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    virtual void runRemainingAnimations(TreeInfo& info) {
192119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationContext::runRemainingAnimations(info);
193e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        postOnFinishedEvents();
194e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
195e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
196119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) {
197119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        OnFinishedEvent event(animator, listener);
198119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mOnFinishedEvents.push_back(event);
199119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
200119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
201e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck    virtual void destroy() {
202e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        AnimationContext::destroy();
203e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        postOnFinishedEvents();
204e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck    }
205e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck
206e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckprivate:
207119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    sp<RootRenderNode> mRootNode;
20852244fff29042926e21fa897ef5ab11148e35299John Reck    std::vector<OnFinishedEvent> mOnFinishedEvents;
209e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck
210e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck    void postOnFinishedEvents() {
211e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        if (mOnFinishedEvents.size()) {
212e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck            sp<InvokeAnimationListeners> message
213e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck                    = new InvokeAnimationListeners(mOnFinishedEvents);
214e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck            mRootNode->sendMessage(message);
215e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        }
216e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck    }
217119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck};
218119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
219119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckclass ContextFactoryImpl : public IContextFactory {
220119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckpublic:
221119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {}
222119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
223119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
224119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        return new AnimationContextBridge(clock, mRootNode);
225119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
226119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
227119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckprivate:
228119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    RootRenderNode* mRootNode;
229e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck};
230e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
23106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesclass ObserverProxy;
23206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
23306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesclass NotifyHandler : public MessageHandler {
23406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralespublic:
23511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    NotifyHandler(JavaVM* vm, ObserverProxy* observer) : mVm(vm), mObserver(observer) {}
236910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales
23706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    virtual void handleMessage(const Message& message);
23806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
23906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesprivate:
24011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    JavaVM* const mVm;
24111f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    ObserverProxy* const mObserver;
24206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales};
24306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
244910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Moralesstatic jlongArray get_metrics_buffer(JNIEnv* env, jobject observer) {
245910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jobject frameMetrics = env->GetObjectField(
246910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            observer, gFrameMetricsObserverClassInfo.frameMetrics);
247910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    LOG_ALWAYS_FATAL_IF(frameMetrics == nullptr, "unable to retrieve data sink object");
248910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jobject buffer = env->GetObjectField(
249910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            frameMetrics, gFrameMetricsObserverClassInfo.timingDataBuffer);
250910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    LOG_ALWAYS_FATAL_IF(buffer == nullptr, "unable to retrieve data sink buffer");
251910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    return reinterpret_cast<jlongArray>(buffer);
252910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales}
253910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales
25411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales/*
25511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales * Implements JNI layer for hwui frame metrics reporting.
25611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales */
257910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Moralesclass ObserverProxy : public FrameMetricsObserver {
25806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralespublic:
259910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    ObserverProxy(JavaVM *vm, jobject observer) : mVm(vm) {
26006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        JNIEnv* env = getenv(mVm);
26106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
262910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        mObserverWeak = env->NewWeakGlobalRef(observer);
263910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr,
26406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales                "unable to create frame stats observer reference");
26506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
266910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        jlongArray buffer = get_metrics_buffer(env, observer);
267910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        jsize bufferSize = env->GetArrayLength(reinterpret_cast<jarray>(buffer));
268910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        LOG_ALWAYS_FATAL_IF(bufferSize != kBufferSize,
269910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales                "Mismatched Java/Native FrameMetrics data format.");
270910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales
271910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        jobject messageQueueLocal = env->GetObjectField(
272910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales                observer, gFrameMetricsObserverClassInfo.messageQueue);
27306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal);
27406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available");
27506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
27611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        mMessageHandler = new NotifyHandler(mVm, this);
27706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr,
27806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales                "OOM: unable to allocate NotifyHandler");
27906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
28006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
28106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    ~ObserverProxy() {
28206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        JNIEnv* env = getenv(mVm);
283910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        env->DeleteWeakGlobalRef(mObserverWeak);
28406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
28506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
286910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jweak getObserverReference() {
287910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        return mObserverWeak;
28806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
28906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
29011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    bool getNextBuffer(JNIEnv* env, jlongArray sink, int* dropCount) {
29111f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        FrameMetricsNotification& elem = mRingBuffer[mNextInQueue];
29211f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
29311f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        if (elem.hasData.load()) {
29411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            env->SetLongArrayRegion(sink, 0, kBufferSize, elem.buffer);
29511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            *dropCount = elem.dropCount;
29611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            mNextInQueue = (mNextInQueue + 1) % kRingSize;
29711f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            elem.hasData = false;
29811f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            return true;
29911f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        }
30011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
30111f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        return false;
30211f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    }
30311f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
30411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    virtual void notify(const int64_t* stats) {
30511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        FrameMetricsNotification& elem = mRingBuffer[mNextFree];
30611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
30711f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        if (!elem.hasData.load()) {
30811f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            memcpy(elem.buffer, stats, kBufferSize * sizeof(stats[0]));
30911f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
31011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            elem.dropCount = mDroppedReports;
31111f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            mDroppedReports = 0;
31211f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
31311f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            incStrong(nullptr);
31411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            mNextFree = (mNextFree + 1) % kRingSize;
31511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            elem.hasData = true;
31611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
31711f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
31811f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        } else {
31911f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            mDroppedReports++;
32011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        }
32106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
32206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
32306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesprivate:
32406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes);
32511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    static constexpr int kRingSize = 3;
32606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
32711f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    class FrameMetricsNotification {
32811f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    public:
32911f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        FrameMetricsNotification() : hasData(false) {}
33011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
33111f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        std::atomic_bool hasData;
33211f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        int64_t buffer[kBufferSize];
33311f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        int dropCount = 0;
33411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    };
33511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
33611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    JavaVM* const mVm;
337910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jweak mObserverWeak;
338910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jobject mJavaBufferGlobal;
33906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
34006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    sp<MessageQueue> mMessageQueue;
34106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    sp<NotifyHandler> mMessageHandler;
34206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    Message mMessage;
343910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales
34411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    int mNextFree = 0;
34511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    int mNextInQueue = 0;
34611f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    FrameMetricsNotification mRingBuffer[kRingSize];
34711f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales
34811f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    int mDroppedReports = 0;
34906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales};
35006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
35106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesvoid NotifyHandler::handleMessage(const Message& message) {
35206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    JNIEnv* env = getenv(mVm);
35306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
35411f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    jobject target = env->NewLocalRef(mObserver->getObserverReference());
35506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
35606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    if (target != nullptr) {
357910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        jlongArray javaBuffer = get_metrics_buffer(env, target);
35811f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        int dropCount = 0;
35911f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        while (mObserver->getNextBuffer(env, javaBuffer, &dropCount)) {
36011f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales            env->CallVoidMethod(target, gFrameMetricsObserverClassInfo.callback, dropCount);
36111f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales        }
362910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        env->DeleteLocalRef(target);
36306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
36406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
36511f02d7e522ec8742f7ef533c252e04e24b93f6bAndres Morales    mObserver->decStrong(nullptr);
36606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales}
36706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
36866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckstatic void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz,
3693b20251a355c88193c439f928a84ae69483fb488John Reck        jlong proxyPtr, jobject graphicBuffer, jlongArray atlasMapArray) {
37066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
37166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    jsize len = env->GetArrayLength(atlasMapArray);
37266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    if (len <= 0) {
37366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        ALOGW("Failed to initialize atlas, invalid map length: %d", len);
37466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        return;
37566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
37666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    int64_t* map = new int64_t[len];
37766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    env->GetLongArrayRegion(atlasMapArray, 0, len, map);
37866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
3793b20251a355c88193c439f928a84ae69483fb488John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
3803b20251a355c88193c439f928a84ae69483fb488John Reck    proxy->setTextureAtlas(buffer, map, len);
3814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
3824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
383edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckstatic void android_view_ThreadedRenderer_setProcessStatsBuffer(JNIEnv* env, jobject clazz,
384edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        jlong proxyPtr, jint fd) {
385edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
386edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    proxy->setProcessStatsBuffer(fd);
387edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck}
388edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
389e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
390c25e506f7fc08790c0532f927f31310a2ca778b7John Reck    RootRenderNode* node = new RootRenderNode(env);
391e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    node->incStrong(0);
392e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    node->setName("RootRenderNode");
393e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    return reinterpret_cast<jlong>(node);
394e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
395e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
3964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckstatic jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
397e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        jboolean translucent, jlong rootRenderNodePtr) {
398119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
399119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    ContextFactoryImpl factory(rootRenderNode);
400119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    return (jlong) new RenderProxy(translucent, rootRenderNode, &factory);
4014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
4034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckstatic void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz,
4044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        jlong proxyPtr) {
40519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
4064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    delete proxy;
4074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
409e4280baaa709c74d86cf6a389a4674ca665f5af6John Reckstatic jboolean android_view_ThreadedRenderer_loadSystemProperties(JNIEnv* env, jobject clazz,
410e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck        jlong proxyPtr) {
411e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
412e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    return proxy->loadSystemProperties();
413e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck}
414e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck
415b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reckstatic void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz,
416b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck        jlong proxyPtr, jstring jname) {
417b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
418b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    const char* name = env->GetStringUTFChars(jname, NULL);
419b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    proxy->setName(name);
420b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    env->ReleaseStringUTFChars(jname, name);
421b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck}
422b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck
4230bcd0cb6b1193168fa2840855195347488daab9eThomas Buhotstatic void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
4244f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        jlong proxyPtr, jobject jsurface) {
42519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
426f648108f83d4e74811919e9811efb8fcc184b8a3John Reck    sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
427f648108f83d4e74811919e9811efb8fcc184b8a3John Reck    proxy->initialize(surface);
4284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
4304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckstatic void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
4314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        jlong proxyPtr, jobject jsurface) {
43219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
433f648108f83d4e74811919e9811efb8fcc184b8a3John Reck    sp<Surface> surface;
4344f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    if (jsurface) {
435f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        surface = android_view_Surface_getSurface(env, jsurface);
4364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
437f648108f83d4e74811919e9811efb8fcc184b8a3John Reck    proxy->updateSurface(surface);
438f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck}
439f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
44001a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reckstatic jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
441f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        jlong proxyPtr, jobject jsurface) {
442f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
443f648108f83d4e74811919e9811efb8fcc184b8a3John Reck    sp<Surface> surface;
444f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    if (jsurface) {
445f648108f83d4e74811919e9811efb8fcc184b8a3John Reck        surface = android_view_Surface_getSurface(env, jsurface);
446f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
447f648108f83d4e74811919e9811efb8fcc184b8a3John Reck    return proxy->pauseSurface(surface);
4484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
450797b95b26bbb7557678af78b9a2a61830158920fChris Craikstatic void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
45150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        jint width, jint height, jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) {
45219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
45350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    proxy->setup(width, height, lightRadius, ambientShadowAlpha, spotShadowAlpha);
45450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette}
45550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
45650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverettestatic void android_view_ThreadedRenderer_setLightCenter(JNIEnv* env, jobject clazz,
45750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ) {
45850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
45950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    proxy->setLightCenter((Vector3){lightX, lightY, lightZ});
4604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
46263a06673253914510bbeebd500655008682dade1John Reckstatic void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
46363a06673253914510bbeebd500655008682dade1John Reck        jlong proxyPtr, jboolean opaque) {
46463a06673253914510bbeebd500655008682dade1John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
46563a06673253914510bbeebd500655008682dade1John Reck    proxy->setOpaque(opaque);
46663a06673253914510bbeebd500655008682dade1John Reck}
46763a06673253914510bbeebd500655008682dade1John Reck
468f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reckstatic int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
469ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
470ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
471ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            "Mismatched size expectations, given %d expected %d",
472ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
47319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
474ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
475ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    return proxy->syncAndDrawFrame();
4764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
47817035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reckstatic void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
4794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        jlong proxyPtr) {
48019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
48117035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck    proxy->destroy();
4824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
4834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
484119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckstatic void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
485119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        jlong rootNodePtr, jlong animatingNodePtr) {
486119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
487119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    RenderNode* animatingNode = reinterpret_cast<RenderNode*>(animatingNodePtr);
488119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    rootRenderNode->attachAnimatingNode(animatingNode);
489119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
490119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
4910d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckstatic void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
4923b20251a355c88193c439f928a84ae69483fb488John Reck        jlong functorPtr, jboolean waitForCompletion) {
4930d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
4943b20251a355c88193c439f928a84ae69483fb488John Reck    RenderProxy::invokeFunctor(functor, waitForCompletion);
4950d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck}
4960d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
49719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckstatic jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz,
49819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        jlong proxyPtr) {
49919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
50019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    DeferredLayerUpdater* layer = proxy->createTextureLayer();
50119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    return reinterpret_cast<jlong>(layer);
50219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck}
50319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
5043e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reckstatic void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
5053e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        jlong proxyPtr, jlong nodePtr) {
5063e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
5073e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
5083e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    proxy->buildLayer(node);
5093e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck}
5103e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
51119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckstatic jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
5123731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck        jlong proxyPtr, jlong layerPtr, jobject jbitmap) {
51319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
51419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
5153731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    SkBitmap bitmap;
5163731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
51719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    return proxy->copyLayerInto(layer, bitmap);
51819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck}
51919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
520d72e0a339b54af0c4e731513bbad120dff694723John Reckstatic void android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv* env, jobject clazz,
52119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        jlong proxyPtr, jlong layerPtr) {
52219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
52319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
524d72e0a339b54af0c4e731513bbad120dff694723John Reck    proxy->pushLayerUpdate(layer);
525d72e0a339b54af0c4e731513bbad120dff694723John Reck}
526d72e0a339b54af0c4e731513bbad120dff694723John Reck
527d72e0a339b54af0c4e731513bbad120dff694723John Reckstatic void android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv* env, jobject clazz,
528d72e0a339b54af0c4e731513bbad120dff694723John Reck        jlong proxyPtr, jlong layerPtr) {
529d72e0a339b54af0c4e731513bbad120dff694723John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
530d72e0a339b54af0c4e731513bbad120dff694723John Reck    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
531d72e0a339b54af0c4e731513bbad120dff694723John Reck    proxy->cancelLayerUpdate(layer);
53219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck}
53319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
534918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reckstatic void android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv* env, jobject clazz,
535918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        jlong proxyPtr, jlong layerPtr) {
536918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
537918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
538918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    proxy->detachSurfaceTexture(layer);
539918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck}
540918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck
541f47a594f5250b1914c36423ee6b371f0b8db09d0John Reckstatic void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
542f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        jlong proxyPtr) {
543e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
544f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    proxy->destroyHardwareResources();
545f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck}
546f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
547f47a594f5250b1914c36423ee6b371f0b8db09d0John Reckstatic void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
548f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        jint level) {
549f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    RenderProxy::trimMemory(level);
550e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck}
551e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
5522507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craikstatic void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz,
5532507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik        jstring name, jstring value) {
5542507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    const char* nameCharArray = env->GetStringUTFChars(name, NULL);
5552507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    const char* valueCharArray = env->GetStringUTFChars(value, NULL);
5562507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    RenderProxy::overrideProperty(nameCharArray, valueCharArray);
5572507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    env->ReleaseStringUTFChars(name, nameCharArray);
5582507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    env->ReleaseStringUTFChars(name, valueCharArray);
5592507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik}
5602507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik
56128ad7b52e038ef0cdd89f753d9839444a434b299John Reckstatic void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
56228ad7b52e038ef0cdd89f753d9839444a434b299John Reck        jlong proxyPtr) {
56328ad7b52e038ef0cdd89f753d9839444a434b299John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
56428ad7b52e038ef0cdd89f753d9839444a434b299John Reck    proxy->fence();
56528ad7b52e038ef0cdd89f753d9839444a434b299John Reck}
56628ad7b52e038ef0cdd89f753d9839444a434b299John Reck
567f47a594f5250b1914c36423ee6b371f0b8db09d0John Reckstatic void android_view_ThreadedRenderer_stopDrawing(JNIEnv* env, jobject clazz,
568f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        jlong proxyPtr) {
569f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
570f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    proxy->stopDrawing();
571f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck}
572f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
573a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckstatic void android_view_ThreadedRenderer_notifyFramePending(JNIEnv* env, jobject clazz,
574a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        jlong proxyPtr) {
575a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
576a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    proxy->notifyFramePending();
577a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck}
578a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
579e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reckstatic void android_view_ThreadedRenderer_serializeDisplayListTree(JNIEnv* env, jobject clazz,
580e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck        jlong proxyPtr) {
581e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
582e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    proxy->serializeDisplayListTree();
583e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck}
584e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
585fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckstatic void android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv* env, jobject clazz,
586ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        jlong proxyPtr, jobject javaFileDescriptor, jint dumpFlags) {
587fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
588fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
589ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    proxy->dumpProfileInfo(fd, dumpFlags);
590fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck}
591fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
592edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckstatic void android_view_ThreadedRenderer_dumpProfileData(JNIEnv* env, jobject clazz,
593edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        jbyteArray jdata, jobject javaFileDescriptor) {
594edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
595edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    ScopedByteArrayRO buffer(env, jdata);
596edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    if (buffer.get()) {
597edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        JankTracker::dumpBuffer(buffer.get(), buffer.size(), fd);
598edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    }
599edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck}
600edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
601ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhnestatic void android_view_ThreadedRenderer_addRenderNode(JNIEnv* env, jobject clazz,
602ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        jlong proxyPtr, jlong renderNodePtr, jboolean placeFront) {
603ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
604ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
605ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    proxy->addRenderNode(renderNode, placeFront);
606ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne}
607ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
608ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhnestatic void android_view_ThreadedRenderer_removeRenderNode(JNIEnv* env, jobject clazz,
609ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        jlong proxyPtr, jlong renderNodePtr) {
610ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
611ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
612ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    proxy->removeRenderNode(renderNode);
613ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne}
614ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
615ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhnestatic void android_view_ThreadedRendererd_drawRenderNode(JNIEnv* env, jobject clazz,
616ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        jlong proxyPtr, jlong renderNodePtr) {
617ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
618ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
619ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    proxy->drawRenderNode(renderNode);
620ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne}
621ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
622b816087962aba0019b022303330f03b897b580edSkuhnestatic void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env,
623ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        jobject clazz, jlong proxyPtr, jint left, jint top, jint right, jint bottom) {
624ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
625b816087962aba0019b022303330f03b897b580edSkuhne    proxy->setContentDrawBounds(left, top, right, bottom);
626ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne}
627edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
628cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck// ----------------------------------------------------------------------------
629910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales// FrameMetricsObserver
63006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales// ----------------------------------------------------------------------------
63106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
632910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Moralesstatic jlong android_view_ThreadedRenderer_addFrameMetricsObserver(JNIEnv* env,
63306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        jclass clazz, jlong proxyPtr, jobject fso) {
63406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    JavaVM* vm = nullptr;
63506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    if (env->GetJavaVM(&vm) != JNI_OK) {
63606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        LOG_ALWAYS_FATAL("Unable to get Java VM");
63706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        return 0;
63806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
63906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
64006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    renderthread::RenderProxy* renderProxy =
64106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales            reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
64206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
643910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    FrameMetricsObserver* observer = new ObserverProxy(vm, fso);
644910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    renderProxy->addFrameMetricsObserver(observer);
64506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    return reinterpret_cast<jlong>(observer);
64606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales}
64706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
648910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Moralesstatic void android_view_ThreadedRenderer_removeFrameMetricsObserver(JNIEnv* env, jclass clazz,
64906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        jlong proxyPtr, jlong observerPtr) {
650910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    FrameMetricsObserver* observer = reinterpret_cast<FrameMetricsObserver*>(observerPtr);
65106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    renderthread::RenderProxy* renderProxy =
65206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales            reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
65306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
654910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    renderProxy->removeFrameMetricsObserver(observer);
65506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales}
65606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
65706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales// ----------------------------------------------------------------------------
65884a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck// Shaders
65984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck// ----------------------------------------------------------------------------
66084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
66184a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reckstatic void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
66284a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck        jstring diskCachePath) {
66384a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
66484a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    egl_cache_t::get()->setCacheFilename(cacheArray);
66584a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    env->ReleaseStringUTFChars(diskCachePath, cacheArray);
66684a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck}
66784a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
66884a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck// ----------------------------------------------------------------------------
66903d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine// Layers
67003d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine// ----------------------------------------------------------------------------
67103d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine
67203d8f76836c5950374bc9030a78706d25ac233e9Michael Lentinestatic void android_view_ThreadedRenderer_setupVulkanLayerPath(JNIEnv* env, jobject clazz,
67303d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine        jstring layerPath) {
67403d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine
67503d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    const char* layerArray = env->GetStringUTFChars(layerPath, NULL);
67603d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    vulkan::LoaderData::GetInstance().layer_path = layerArray;
67703d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    env->ReleaseStringUTFChars(layerPath, layerArray);
67803d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine}
67903d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine
68003d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine// ----------------------------------------------------------------------------
681cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck// JNI Glue
682cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck// ----------------------------------------------------------------------------
683cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
684cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckconst char* const kClassPathName = "android/view/ThreadedRenderer";
685cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
68676f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
6873b20251a355c88193c439f928a84ae69483fb488John Reck    { "nSetAtlas", "(JLandroid/view/GraphicBuffer;[J)V",   (void*) android_view_ThreadedRenderer_setAtlas },
688edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    { "nSetProcessStatsBuffer", "(JI)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer },
689e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode },
690e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy },
6914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
692e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties },
693b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    { "nSetName", "(JLjava/lang/String;)V", (void*) android_view_ThreadedRenderer_setName },
6940bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot    { "nInitialize", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_initialize },
6954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
69601a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
69750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    { "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
69850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
69963a06673253914510bbeebd500655008682dade1John Reck    { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
700ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
70117035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck    { "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy },
702119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
7033b20251a355c88193c439f928a84ae69483fb488John Reck    { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
70419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
7053e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
7063731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    { "nCopyLayerInto", "(JJLandroid/graphics/Bitmap;)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
707d72e0a339b54af0c4e731513bbad120dff694723John Reck    { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
708d72e0a339b54af0c4e731513bbad120dff694723John Reck    { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
709918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
710f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    { "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources },
711f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    { "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory },
7122507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    { "nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V",  (void*) android_view_ThreadedRenderer_overrideProperty },
71328ad7b52e038ef0cdd89f753d9839444a434b299John Reck    { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
714f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    { "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing },
715a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
716e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    { "nSerializeDisplayListTree", "(J)V", (void*) android_view_ThreadedRenderer_serializeDisplayListTree },
717ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    { "nDumpProfileInfo", "(JLjava/io/FileDescriptor;I)V", (void*) android_view_ThreadedRenderer_dumpProfileInfo },
718edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    { "nDumpProfileData", "([BLjava/io/FileDescriptor;)V", (void*) android_view_ThreadedRenderer_dumpProfileData },
71984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    { "setupShadersDiskCache", "(Ljava/lang/String;)V",
72084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck                (void*) android_view_ThreadedRenderer_setupShadersDiskCache },
72103d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    { "setupVulkanLayerPath", "(Ljava/lang/String;)V",
72203d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine                (void*) android_view_ThreadedRenderer_setupVulkanLayerPath },
723ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    { "nAddRenderNode", "(JJZ)V", (void*) android_view_ThreadedRenderer_addRenderNode},
724ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
725ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
726b816087962aba0019b022303330f03b897b580edSkuhne    { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
727910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    { "nAddFrameMetricsObserver",
728910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            "(JLandroid/view/FrameMetricsObserver;)J",
729910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            (void*)android_view_ThreadedRenderer_addFrameMetricsObserver },
730910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    { "nRemoveFrameMetricsObserver",
73106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales            "(JJ)V",
732910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            (void*)android_view_ThreadedRenderer_removeFrameMetricsObserver },
733cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck};
734cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
735cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckint register_android_view_ThreadedRenderer(JNIEnv* env) {
736910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver");
737910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie(
738910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;");
739910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    gFrameMetricsObserverClassInfo.messageQueue = GetFieldIDOrDie(
740910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            env, observerClass, "mMessageQueue", "Landroid/os/MessageQueue;");
741910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    gFrameMetricsObserverClassInfo.callback = GetMethodIDOrDie(
742910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            env, observerClass, "notifyDataAvailable", "(I)V");
743910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales
744910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    jclass metricsClass = FindClassOrDie(env, "android/view/FrameMetrics");
745910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
746910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales            env, metricsClass, "mTimingData", "[J");
74706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
748ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
749cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
750cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
751cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}; // namespace android
752