Loading core/jni/android_view_ThreadedRenderer.cpp +43 −13 Original line number Diff line number Diff line Loading @@ -49,6 +49,14 @@ using namespace android::uirenderer::renderthread; static jmethodID gRunnableMethod; static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm); } return env; } class JavaTask : public RenderTask { public: JavaTask(JNIEnv* env, jobject jrunnable) { Loading @@ -57,20 +65,13 @@ public: } virtual void run() { env()->CallVoidMethod(mRunnable, gRunnableMethod); env()->DeleteGlobalRef(mRunnable); JNIEnv* env = getenv(mVm); env->CallVoidMethod(mRunnable, gRunnableMethod); env->DeleteGlobalRef(mRunnable); delete this; }; private: JNIEnv* env() { JNIEnv* env; if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { return 0; } return env; } JavaVM* mVm; jobject mRunnable; }; Loading Loading @@ -122,12 +123,34 @@ private: std::vector<OnFinishedEvent> mOnFinishedEvents; }; class RootRenderNode : public RenderNode, public AnimationHook { class RenderingException : public MessageHandler { public: RootRenderNode() : RenderNode() { RenderingException(JavaVM* vm, const std::string& message) : mVm(vm) , mMessage(message) { } virtual void handleMessage(const Message&) { throwException(mVm, mMessage); } static void throwException(JavaVM* vm, const std::string& message) { JNIEnv* env = getenv(vm); jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); } private: JavaVM* mVm; std::string mMessage; }; class RootRenderNode : public RenderNode, AnimationHook, ErrorHandler { public: RootRenderNode(JNIEnv* env) : RenderNode() { mLooper = Looper::getForThread(); LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create RootRenderNode on a thread with a looper!"); env->GetJavaVM(&mVm); } virtual ~RootRenderNode() {} Loading @@ -137,10 +160,16 @@ public: mOnFinishedEvents.push_back(event); } virtual void onError(const std::string& message) { mLooper->sendMessage(new RenderingException(mVm, message), 0); } virtual void prepareTree(TreeInfo& info) { info.animationHook = this; info.errorHandler = this; RenderNode::prepareTree(info); info.animationHook = NULL; info.errorHandler = NULL; // post all the finished stuff if (mOnFinishedEvents.size()) { Loading @@ -160,6 +189,7 @@ protected: private: sp<Looper> mLooper; std::vector<OnFinishedEvent> mOnFinishedEvents; JavaVM* mVm; }; static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, Loading @@ -178,7 +208,7 @@ static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, } static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) { RootRenderNode* node = new RootRenderNode(); RootRenderNode* node = new RootRenderNode(env); node->incStrong(0); node->setName("RootRenderNode"); return reinterpret_cast<jlong>(node); Loading libs/hwui/RenderNode.cpp +14 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "RenderNode.h" #include <algorithm> #include <string> #include <SkCanvas.h> #include <algorithm> Loading Loading @@ -158,7 +159,10 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { applyLayerPropertiesToLayer(info); damageSelf(info); } else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) { LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight()); if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) { LayerRenderer::destroyLayer(mLayer); mLayer = 0; } damageSelf(info); } Loading @@ -166,6 +170,15 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { info.damageAccumulator->peekAtDirty(&dirty); info.damageAccumulator->popTransform(); if (!mLayer) { if (info.errorHandler) { std::string msg = "Unable to create layer for "; msg += getName(); info.errorHandler->onError(msg); } return; } if (!dirty.isEmpty()) { mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom); } Loading libs/hwui/TreeInfo.h +11 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #ifndef TREEINFO_H #define TREEINFO_H #include <string> #include <utils/Timers.h> #include "DamageAccumulator.h" Loading @@ -35,6 +37,13 @@ protected: ~AnimationHook() {} }; class ErrorHandler { public: virtual void onError(const std::string& message) = 0; protected: ~ErrorHandler() {} }; // This would be a struct, but we want to PREVENT_COPY_AND_ASSIGN class TreeInfo { PREVENT_COPY_AND_ASSIGN(TreeInfo); Loading Loading @@ -65,6 +74,7 @@ public: , prepareTextures(mode == MODE_FULL) , damageAccumulator(NullDamageAccumulator::instance()) , renderer(0) , errorHandler(0) {} const TraversalMode mode; Loading @@ -78,6 +88,7 @@ public: // The renderer that will be drawing the next frame. Use this to push any // layer updates or similar. May be NULL. OpenGLRenderer* renderer; ErrorHandler* errorHandler; struct Out { Out() Loading Loading
core/jni/android_view_ThreadedRenderer.cpp +43 −13 Original line number Diff line number Diff line Loading @@ -49,6 +49,14 @@ using namespace android::uirenderer::renderthread; static jmethodID gRunnableMethod; static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm); } return env; } class JavaTask : public RenderTask { public: JavaTask(JNIEnv* env, jobject jrunnable) { Loading @@ -57,20 +65,13 @@ public: } virtual void run() { env()->CallVoidMethod(mRunnable, gRunnableMethod); env()->DeleteGlobalRef(mRunnable); JNIEnv* env = getenv(mVm); env->CallVoidMethod(mRunnable, gRunnableMethod); env->DeleteGlobalRef(mRunnable); delete this; }; private: JNIEnv* env() { JNIEnv* env; if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { return 0; } return env; } JavaVM* mVm; jobject mRunnable; }; Loading Loading @@ -122,12 +123,34 @@ private: std::vector<OnFinishedEvent> mOnFinishedEvents; }; class RootRenderNode : public RenderNode, public AnimationHook { class RenderingException : public MessageHandler { public: RootRenderNode() : RenderNode() { RenderingException(JavaVM* vm, const std::string& message) : mVm(vm) , mMessage(message) { } virtual void handleMessage(const Message&) { throwException(mVm, mMessage); } static void throwException(JavaVM* vm, const std::string& message) { JNIEnv* env = getenv(vm); jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); } private: JavaVM* mVm; std::string mMessage; }; class RootRenderNode : public RenderNode, AnimationHook, ErrorHandler { public: RootRenderNode(JNIEnv* env) : RenderNode() { mLooper = Looper::getForThread(); LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create RootRenderNode on a thread with a looper!"); env->GetJavaVM(&mVm); } virtual ~RootRenderNode() {} Loading @@ -137,10 +160,16 @@ public: mOnFinishedEvents.push_back(event); } virtual void onError(const std::string& message) { mLooper->sendMessage(new RenderingException(mVm, message), 0); } virtual void prepareTree(TreeInfo& info) { info.animationHook = this; info.errorHandler = this; RenderNode::prepareTree(info); info.animationHook = NULL; info.errorHandler = NULL; // post all the finished stuff if (mOnFinishedEvents.size()) { Loading @@ -160,6 +189,7 @@ protected: private: sp<Looper> mLooper; std::vector<OnFinishedEvent> mOnFinishedEvents; JavaVM* mVm; }; static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, Loading @@ -178,7 +208,7 @@ static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, } static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) { RootRenderNode* node = new RootRenderNode(); RootRenderNode* node = new RootRenderNode(env); node->incStrong(0); node->setName("RootRenderNode"); return reinterpret_cast<jlong>(node); Loading
libs/hwui/RenderNode.cpp +14 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "RenderNode.h" #include <algorithm> #include <string> #include <SkCanvas.h> #include <algorithm> Loading Loading @@ -158,7 +159,10 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { applyLayerPropertiesToLayer(info); damageSelf(info); } else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) { LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight()); if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) { LayerRenderer::destroyLayer(mLayer); mLayer = 0; } damageSelf(info); } Loading @@ -166,6 +170,15 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { info.damageAccumulator->peekAtDirty(&dirty); info.damageAccumulator->popTransform(); if (!mLayer) { if (info.errorHandler) { std::string msg = "Unable to create layer for "; msg += getName(); info.errorHandler->onError(msg); } return; } if (!dirty.isEmpty()) { mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom); } Loading
libs/hwui/TreeInfo.h +11 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #ifndef TREEINFO_H #define TREEINFO_H #include <string> #include <utils/Timers.h> #include "DamageAccumulator.h" Loading @@ -35,6 +37,13 @@ protected: ~AnimationHook() {} }; class ErrorHandler { public: virtual void onError(const std::string& message) = 0; protected: ~ErrorHandler() {} }; // This would be a struct, but we want to PREVENT_COPY_AND_ASSIGN class TreeInfo { PREVENT_COPY_AND_ASSIGN(TreeInfo); Loading Loading @@ -65,6 +74,7 @@ public: , prepareTextures(mode == MODE_FULL) , damageAccumulator(NullDamageAccumulator::instance()) , renderer(0) , errorHandler(0) {} const TraversalMode mode; Loading @@ -78,6 +88,7 @@ public: // The renderer that will be drawing the next frame. Use this to push any // layer updates or similar. May be NULL. OpenGLRenderer* renderer; ErrorHandler* errorHandler; struct Out { Out() Loading