Loading core/java/android/view/ThreadedRenderer.java +43 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,11 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.Trace; import android.util.Log; import android.util.TimeUtils; import android.view.Surface.OutOfResourcesException; import android.view.View.AttachInfo; Loading Loading @@ -65,6 +69,8 @@ public class ThreadedRenderer extends HardwareRenderer { private Choreographer mChoreographer; ThreadedRenderer(boolean translucent) { AtlasInitializer.sInstance.init(); long rootNodePtr = nCreateRootRenderNode(); mRootNode = RenderNode.adopt(rootNodePtr); mRootNode.setClipToBounds(false); Loading Loading @@ -292,8 +298,43 @@ public class ThreadedRenderer extends HardwareRenderer { } } /** @hide */ public static native void postToRenderThread(Runnable runnable); private static class AtlasInitializer { static AtlasInitializer sInstance = new AtlasInitializer(); private boolean mInitialized = false; private AtlasInitializer() {} synchronized void init() { if (mInitialized) return; IBinder binder = ServiceManager.getService("assetatlas"); if (binder == null) return; IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder); try { if (atlas.isCompatible(android.os.Process.myPpid())) { GraphicBuffer buffer = atlas.getBuffer(); if (buffer != null) { long[] map = atlas.getMap(); if (map != null) { nSetAtlas(buffer, map); mInitialized = true; } // If IAssetAtlas is not the same class as the IBinder // we are using a remote service and we can safely // destroy the graphic buffer if (atlas.getClass() != binder.getClass()) { buffer.destroy(); } } } } catch (RemoteException e) { Log.w(LOG_TAG, "Could not acquire atlas", e); } } } private static native void nSetAtlas(GraphicBuffer buffer, long[] map); private static native long nCreateRootRenderNode(); private static native long nCreateProxy(boolean translucent, long rootRenderNode); Loading core/jni/android_view_ThreadedRenderer.cpp +36 −4 Original line number Diff line number Diff line Loading @@ -26,8 +26,11 @@ #include <android_runtime/android_view_Surface.h> #include <system/window.h> #include "android_view_GraphicBuffer.h" #include <Animator.h> #include <RenderNode.h> #include <renderthread/CanvasContext.h> #include <renderthread/RenderProxy.h> #include <renderthread/RenderTask.h> #include <renderthread/RenderThread.h> Loading Loading @@ -67,6 +70,26 @@ private: jobject mRunnable; }; class SetAtlasTask : public RenderTask { public: SetAtlasTask(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size) : mBuffer(buffer) , mMap(map) , mMapSize(size) { } virtual void run() { CanvasContext::setTextureAtlas(mBuffer, mMap, mMapSize); mMap = 0; delete this; } private: sp<GraphicBuffer> mBuffer; int64_t* mMap; size_t mMapSize; }; class OnFinishedEvent { public: OnFinishedEvent(BaseAnimator* animator, AnimationListener* listener) Loading Loading @@ -127,9 +150,18 @@ private: std::vector<OnFinishedEvent> mOnFinishedEvents; }; static void android_view_ThreadedRenderer_postToRenderThread(JNIEnv* env, jobject clazz, jobject jrunnable) { RenderTask* task = new JavaTask(env, jrunnable); static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, jobject graphicBuffer, jlongArray atlasMapArray) { sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer); jsize len = env->GetArrayLength(atlasMapArray); if (len <= 0) { ALOGW("Failed to initialize atlas, invalid map length: %d", len); return; } int64_t* map = new int64_t[len]; env->GetLongArrayRegion(atlasMapArray, 0, len, map); SetAtlasTask* task = new SetAtlasTask(buffer, map, len); RenderThread::getInstance().queue(task); } Loading Loading @@ -275,7 +307,7 @@ const char* const kClassPathName = "android/view/ThreadedRenderer"; static JNINativeMethod gMethods[] = { #ifdef USE_OPENGL_RENDERER { "postToRenderThread", "(Ljava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_postToRenderThread }, { "nSetAtlas", "(Landroid/view/GraphicBuffer;[J)V", (void*) android_view_ThreadedRenderer_setAtlas }, { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode }, { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy }, { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy }, Loading libs/hwui/renderthread/CanvasContext.cpp +35 −3 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ public: bool enableDirtyRegions(EGLSurface surface); void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); private: GlobalContext(); // GlobalContext is never destroyed, method is purposely not implemented Loading @@ -118,6 +120,10 @@ private: bool mCanSetDirtyRegions; EGLSurface mCurrentSurface; sp<GraphicBuffer> mAtlasBuffer; int64_t* mAtlasMap; size_t mAtlasMapSize; }; GlobalContext* GlobalContext::sContext = 0; Loading @@ -135,7 +141,9 @@ GlobalContext::GlobalContext() , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) , mRequestDirtyRegions(load_dirty_regions_property()) , mCurrentSurface(EGL_NO_SURFACE) { , mCurrentSurface(EGL_NO_SURFACE) , mAtlasMap(NULL) , mAtlasMapSize(0) { mCanSetDirtyRegions = mRequestDirtyRegions; ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); } Loading Loading @@ -201,9 +209,28 @@ void GlobalContext::createContext() { "Failed to create context, error = %s", egl_error_str()); } void GlobalContext::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) { // Already initialized if (mAtlasBuffer.get()) { ALOGW("Multiple calls to setTextureAtlas!"); delete map; return; } mAtlasBuffer = buffer; mAtlasMap = map; mAtlasMapSize = mapSize; if (hasContext()) { usePBufferSurface(); initAtlas(); } } void GlobalContext::initAtlas() { // TODO implement // For now just run without an atlas Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize); } void GlobalContext::usePBufferSurface() { Loading Loading @@ -533,6 +560,11 @@ void CanvasContext::requireGlContext() { } } void CanvasContext::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) { GlobalContext::get()->setTextureAtlas(buffer, map, mapSize); } } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ libs/hwui/renderthread/CanvasContext.h +3 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,9 @@ public: Layer* createRenderLayer(int width, int height); Layer* createTextureLayer(); ANDROID_API static void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); private: void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info); void prepareTree(TreeInfo& info); Loading Loading
core/java/android/view/ThreadedRenderer.java +43 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,11 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.Trace; import android.util.Log; import android.util.TimeUtils; import android.view.Surface.OutOfResourcesException; import android.view.View.AttachInfo; Loading Loading @@ -65,6 +69,8 @@ public class ThreadedRenderer extends HardwareRenderer { private Choreographer mChoreographer; ThreadedRenderer(boolean translucent) { AtlasInitializer.sInstance.init(); long rootNodePtr = nCreateRootRenderNode(); mRootNode = RenderNode.adopt(rootNodePtr); mRootNode.setClipToBounds(false); Loading Loading @@ -292,8 +298,43 @@ public class ThreadedRenderer extends HardwareRenderer { } } /** @hide */ public static native void postToRenderThread(Runnable runnable); private static class AtlasInitializer { static AtlasInitializer sInstance = new AtlasInitializer(); private boolean mInitialized = false; private AtlasInitializer() {} synchronized void init() { if (mInitialized) return; IBinder binder = ServiceManager.getService("assetatlas"); if (binder == null) return; IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder); try { if (atlas.isCompatible(android.os.Process.myPpid())) { GraphicBuffer buffer = atlas.getBuffer(); if (buffer != null) { long[] map = atlas.getMap(); if (map != null) { nSetAtlas(buffer, map); mInitialized = true; } // If IAssetAtlas is not the same class as the IBinder // we are using a remote service and we can safely // destroy the graphic buffer if (atlas.getClass() != binder.getClass()) { buffer.destroy(); } } } } catch (RemoteException e) { Log.w(LOG_TAG, "Could not acquire atlas", e); } } } private static native void nSetAtlas(GraphicBuffer buffer, long[] map); private static native long nCreateRootRenderNode(); private static native long nCreateProxy(boolean translucent, long rootRenderNode); Loading
core/jni/android_view_ThreadedRenderer.cpp +36 −4 Original line number Diff line number Diff line Loading @@ -26,8 +26,11 @@ #include <android_runtime/android_view_Surface.h> #include <system/window.h> #include "android_view_GraphicBuffer.h" #include <Animator.h> #include <RenderNode.h> #include <renderthread/CanvasContext.h> #include <renderthread/RenderProxy.h> #include <renderthread/RenderTask.h> #include <renderthread/RenderThread.h> Loading Loading @@ -67,6 +70,26 @@ private: jobject mRunnable; }; class SetAtlasTask : public RenderTask { public: SetAtlasTask(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size) : mBuffer(buffer) , mMap(map) , mMapSize(size) { } virtual void run() { CanvasContext::setTextureAtlas(mBuffer, mMap, mMapSize); mMap = 0; delete this; } private: sp<GraphicBuffer> mBuffer; int64_t* mMap; size_t mMapSize; }; class OnFinishedEvent { public: OnFinishedEvent(BaseAnimator* animator, AnimationListener* listener) Loading Loading @@ -127,9 +150,18 @@ private: std::vector<OnFinishedEvent> mOnFinishedEvents; }; static void android_view_ThreadedRenderer_postToRenderThread(JNIEnv* env, jobject clazz, jobject jrunnable) { RenderTask* task = new JavaTask(env, jrunnable); static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, jobject graphicBuffer, jlongArray atlasMapArray) { sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer); jsize len = env->GetArrayLength(atlasMapArray); if (len <= 0) { ALOGW("Failed to initialize atlas, invalid map length: %d", len); return; } int64_t* map = new int64_t[len]; env->GetLongArrayRegion(atlasMapArray, 0, len, map); SetAtlasTask* task = new SetAtlasTask(buffer, map, len); RenderThread::getInstance().queue(task); } Loading Loading @@ -275,7 +307,7 @@ const char* const kClassPathName = "android/view/ThreadedRenderer"; static JNINativeMethod gMethods[] = { #ifdef USE_OPENGL_RENDERER { "postToRenderThread", "(Ljava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_postToRenderThread }, { "nSetAtlas", "(Landroid/view/GraphicBuffer;[J)V", (void*) android_view_ThreadedRenderer_setAtlas }, { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode }, { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy }, { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy }, Loading
libs/hwui/renderthread/CanvasContext.cpp +35 −3 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ public: bool enableDirtyRegions(EGLSurface surface); void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); private: GlobalContext(); // GlobalContext is never destroyed, method is purposely not implemented Loading @@ -118,6 +120,10 @@ private: bool mCanSetDirtyRegions; EGLSurface mCurrentSurface; sp<GraphicBuffer> mAtlasBuffer; int64_t* mAtlasMap; size_t mAtlasMapSize; }; GlobalContext* GlobalContext::sContext = 0; Loading @@ -135,7 +141,9 @@ GlobalContext::GlobalContext() , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) , mRequestDirtyRegions(load_dirty_regions_property()) , mCurrentSurface(EGL_NO_SURFACE) { , mCurrentSurface(EGL_NO_SURFACE) , mAtlasMap(NULL) , mAtlasMapSize(0) { mCanSetDirtyRegions = mRequestDirtyRegions; ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); } Loading Loading @@ -201,9 +209,28 @@ void GlobalContext::createContext() { "Failed to create context, error = %s", egl_error_str()); } void GlobalContext::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) { // Already initialized if (mAtlasBuffer.get()) { ALOGW("Multiple calls to setTextureAtlas!"); delete map; return; } mAtlasBuffer = buffer; mAtlasMap = map; mAtlasMapSize = mapSize; if (hasContext()) { usePBufferSurface(); initAtlas(); } } void GlobalContext::initAtlas() { // TODO implement // For now just run without an atlas Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize); } void GlobalContext::usePBufferSurface() { Loading Loading @@ -533,6 +560,11 @@ void CanvasContext::requireGlContext() { } } void CanvasContext::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) { GlobalContext::get()->setTextureAtlas(buffer, map, mapSize); } } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */
libs/hwui/renderthread/CanvasContext.h +3 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,9 @@ public: Layer* createRenderLayer(int width, int height); Layer* createTextureLayer(); ANDROID_API static void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); private: void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info); void prepareTree(TreeInfo& info); Loading