Wire up texture atlas
Bug: 14590563 Change-Id: I2dffbc089dc801f5fb2d1c8fd38e1c71d160e110
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user