Merge "Cleanup GL objects on the correct thread." into honeycomb
This commit is contained in:
@@ -160,7 +160,8 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
static native void nResizeLayer(int layerId, int layerTextureId, int width, int height,
|
||||
int[] layerInfo);
|
||||
static native void nDestroyLayer(int layerId, int layerTextureId);
|
||||
|
||||
static native void nDestroyLayerDeferred(int layerId, int layerTextureId);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Canvas management
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -128,7 +128,7 @@ class GLES20Layer extends HardwareLayer {
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (mLayerId != 0 || mLayerTextureId != 0) {
|
||||
GLES20Canvas.nDestroyLayer(mLayerId, mLayerTextureId);
|
||||
GLES20Canvas.nDestroyLayerDeferred(mLayerId, mLayerTextureId);
|
||||
}
|
||||
} finally {
|
||||
super.finalize();
|
||||
|
||||
@@ -501,6 +501,11 @@ static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env,
|
||||
LayerRenderer::destroyLayer(layerId, layerTextureId);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env,
|
||||
jobject clazz, jint layerId, jint layerTextureId) {
|
||||
LayerRenderer::destroyLayerDeferred(layerId, layerTextureId);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawLayer(JNIEnv* env,
|
||||
jobject canvas, OpenGLRenderer* renderer,
|
||||
jfloat left, jfloat top, jfloat right, jfloat bottom,
|
||||
@@ -593,13 +598,14 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nGetDisplayListRenderer", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListRenderer },
|
||||
{ "nDrawDisplayList", "(II)V", (void*) android_view_GLES20Canvas_drawDisplayList },
|
||||
|
||||
{ "nInterrupt", "(I)V", (void*) android_view_GLES20Canvas_interrupt },
|
||||
{ "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume },
|
||||
{ "nInterrupt", "(I)V", (void*) android_view_GLES20Canvas_interrupt },
|
||||
{ "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume },
|
||||
|
||||
{ "nCreateLayerRenderer", "(I)I", (void*) android_view_GLES20Canvas_createLayerRenderer },
|
||||
{ "nCreateLayer", "(II[I)I", (void*) android_view_GLES20Canvas_createLayer },
|
||||
{ "nResizeLayer", "(IIII[I)V", (void*) android_view_GLES20Canvas_resizeLayer },
|
||||
{ "nDestroyLayer", "(II)V", (void*) android_view_GLES20Canvas_destroyLayer },
|
||||
{ "nDestroyLayerDeferred", "(II)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred },
|
||||
{ "nDrawLayer", "(IFFFFIFFI)V",
|
||||
(void*) android_view_GLES20Canvas_drawLayer },
|
||||
|
||||
|
||||
@@ -106,6 +106,32 @@ void Caches::clearGarbage() {
|
||||
textureCache.clearGarbage();
|
||||
gradientCache.clearGarbage();
|
||||
pathCache.clearGarbage();
|
||||
|
||||
Mutex::Autolock _l(mGarbageLock);
|
||||
|
||||
size_t count = mFboGarbage.size();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
GLuint fbo = mFboGarbage.itemAt(i);
|
||||
if (fbo) glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
mFboGarbage.clear();
|
||||
|
||||
count = mTextureGarbage.size();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
GLuint texture = mTextureGarbage.itemAt(i);
|
||||
if (texture) glDeleteTextures(1, &texture);
|
||||
}
|
||||
mTextureGarbage.clear();
|
||||
}
|
||||
|
||||
void Caches::deleteFboDeferred(GLuint fbo) {
|
||||
Mutex::Autolock _l(mGarbageLock);
|
||||
mFboGarbage.push(fbo);
|
||||
}
|
||||
|
||||
void Caches::deleteTextureDeferred(GLuint texture) {
|
||||
Mutex::Autolock _l(mGarbageLock);
|
||||
mTextureGarbage.push(texture);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -90,6 +90,10 @@ class Caches: public Singleton<Caches> {
|
||||
TextureVertex* mRegionMesh;
|
||||
GLuint mRegionMeshIndices;
|
||||
|
||||
mutable Mutex mGarbageLock;
|
||||
Vector<GLuint> mFboGarbage;
|
||||
Vector<GLuint> mTextureGarbage;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Indicates whether the renderer is in debug mode.
|
||||
@@ -105,6 +109,16 @@ public:
|
||||
*/
|
||||
void clearGarbage();
|
||||
|
||||
/**
|
||||
* Can be used to delete an FBO from a non EGL thread.
|
||||
*/
|
||||
void deleteFboDeferred(GLuint fbo);
|
||||
|
||||
/**
|
||||
* Can be used to delete a texture from a non EGL thread.
|
||||
*/
|
||||
void deleteTextureDeferred(GLuint texture);
|
||||
|
||||
/**
|
||||
* Binds the VBO used to render simple textured quads.
|
||||
*/
|
||||
|
||||
@@ -116,5 +116,11 @@ void LayerRenderer::destroyLayer(GLuint fbo, GLuint texture) {
|
||||
if (texture) glDeleteTextures(1, &texture);
|
||||
}
|
||||
|
||||
void LayerRenderer::destroyLayerDeferred(GLuint fbo, GLuint texture) {
|
||||
Caches& caches = Caches::getInstance();
|
||||
if (fbo) caches.deleteFboDeferred(fbo);
|
||||
if (texture) caches.deleteTextureDeferred(texture);
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
static void resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height,
|
||||
uint32_t* layerWidth, uint32_t* layerHeight);
|
||||
static void destroyLayer(GLuint fbo, GLuint texture);
|
||||
static void destroyLayerDeferred(GLuint fbo, GLuint texture);
|
||||
|
||||
private:
|
||||
GLuint mFbo;
|
||||
|
||||
Reference in New Issue
Block a user