diff options
author | John Reck <jreck@google.com> | 2014-05-13 13:39:31 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-05-13 14:54:42 -0700 |
commit | 66f0be65a1046f54ddce0498b242c1fa0776b1ea (patch) | |
tree | 87a356caef9f007ac0919504dc8dcb45831a76ee | |
parent | 515396a6b5ee3eab57fed87ee0f4aa63783e2e61 (diff) | |
download | frameworks_base-66f0be65a1046f54ddce0498b242c1fa0776b1ea.zip frameworks_base-66f0be65a1046f54ddce0498b242c1fa0776b1ea.tar.gz frameworks_base-66f0be65a1046f54ddce0498b242c1fa0776b1ea.tar.bz2 |
Wire up texture atlas
Bug: 14590563
Change-Id: I2dffbc089dc801f5fb2d1c8fd38e1c71d160e110
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 45 | ||||
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 40 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 38 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 3 |
4 files changed, 117 insertions, 9 deletions
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 5653066..17035b1 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -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; @@ -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); @@ -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); diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index cdd036e..d130a6d 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -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> @@ -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) @@ -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); } @@ -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 }, diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 5a23158..5754536 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -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 @@ -118,6 +120,10 @@ private: bool mCanSetDirtyRegions; EGLSurface mCurrentSurface; + + sp<GraphicBuffer> mAtlasBuffer; + int64_t* mAtlasMap; + size_t mAtlasMapSize; }; GlobalContext* GlobalContext::sContext = 0; @@ -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"); } @@ -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() { @@ -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 */ diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index dcb9858..a793d42 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -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); |