Merge "Wire up texture atlas"

This commit is contained in:
John Reck
2014-05-13 21:59:31 +00:00
committed by Android (Google) Code Review
4 changed files with 117 additions and 9 deletions

View File

@@ -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);

View File

@@ -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 },

View File

@@ -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 */

View File

@@ -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);