summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2014-05-13 13:39:31 -0700
committerJohn Reck <jreck@google.com>2014-05-13 14:54:42 -0700
commit66f0be65a1046f54ddce0498b242c1fa0776b1ea (patch)
tree87a356caef9f007ac0919504dc8dcb45831a76ee
parent515396a6b5ee3eab57fed87ee0f4aa63783e2e61 (diff)
downloadframeworks_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.java45
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp40
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp38
-rw-r--r--libs/hwui/renderthread/CanvasContext.h3
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);