Merge "Fix ThreadedRenderer.setEnabled()"
This commit is contained in:
@@ -838,6 +838,11 @@ public class GLRenderer extends HardwareRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void pauseSurface(Surface surface) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
boolean initializeEgl() {
|
||||
synchronized (sEglLock) {
|
||||
if (sEgl == null && sEglConfig == null) {
|
||||
|
||||
@@ -233,6 +233,13 @@ public abstract class HardwareRenderer {
|
||||
*/
|
||||
abstract void updateSurface(Surface surface) throws OutOfResourcesException;
|
||||
|
||||
/**
|
||||
* Stops any rendering into the surface. Use this if it is unclear whether
|
||||
* or not the surface used by the HardwareRenderer will be changing. It
|
||||
* Suspends any rendering into the surface, but will not do any destruction
|
||||
*/
|
||||
abstract void pauseSurface(Surface surface);
|
||||
|
||||
/**
|
||||
* Destroys all hardware rendering resources associated with the specified
|
||||
* view hierarchy.
|
||||
|
||||
@@ -54,27 +54,45 @@ public class ThreadedRenderer extends HardwareRenderer {
|
||||
|
||||
private int mWidth, mHeight;
|
||||
private long mNativeProxy;
|
||||
private boolean mInitialized = false;
|
||||
|
||||
ThreadedRenderer(boolean translucent) {
|
||||
mNativeProxy = nCreateProxy(translucent);
|
||||
setEnabled(mNativeProxy != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
void destroy(boolean full) {
|
||||
mInitialized = false;
|
||||
updateEnabledState(null);
|
||||
nDestroyCanvas(mNativeProxy);
|
||||
}
|
||||
|
||||
private void updateEnabledState(Surface surface) {
|
||||
if (surface == null || !surface.isValid()) {
|
||||
setEnabled(false);
|
||||
} else {
|
||||
setEnabled(mInitialized);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean initialize(Surface surface) throws OutOfResourcesException {
|
||||
mInitialized = true;
|
||||
updateEnabledState(surface);
|
||||
return nInitialize(mNativeProxy, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateSurface(Surface surface) throws OutOfResourcesException {
|
||||
updateEnabledState(surface);
|
||||
nUpdateSurface(mNativeProxy, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
void pauseSurface(Surface surface) {
|
||||
nPauseSurface(mNativeProxy, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
void destroyHardwareResources(View view) {
|
||||
destroyResources(view);
|
||||
@@ -267,6 +285,7 @@ public class ThreadedRenderer extends HardwareRenderer {
|
||||
|
||||
private static native boolean nInitialize(long nativeProxy, Surface window);
|
||||
private static native void nUpdateSurface(long nativeProxy, Surface window);
|
||||
private static native void nPauseSurface(long nativeProxy, Surface window);
|
||||
private static native void nSetup(long nativeProxy, int width, int height);
|
||||
private static native void nSetDisplayListData(long nativeProxy, long displayList,
|
||||
long newData);
|
||||
|
||||
@@ -1421,6 +1421,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
host.getMeasuredHeight() + ", params=" + params);
|
||||
}
|
||||
|
||||
if (mAttachInfo.mHardwareRenderer != null) {
|
||||
// relayoutWindow may decide to destroy mSurface. As that decision
|
||||
// happens in WindowManager service, we need to be defensive here
|
||||
// and stop using the surface in case it gets destroyed.
|
||||
mAttachInfo.mHardwareRenderer.pauseSurface(mSurface);
|
||||
}
|
||||
final int surfaceGenerationId = mSurface.getGenerationId();
|
||||
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
|
||||
if (!mDrawDuringWindowsAnimating &&
|
||||
|
||||
@@ -84,7 +84,7 @@ static jboolean android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject cl
|
||||
jlong proxyPtr, jobject jsurface) {
|
||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||
sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
|
||||
return proxy->initialize(window.get());
|
||||
return proxy->initialize(window);
|
||||
}
|
||||
|
||||
static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
|
||||
@@ -94,7 +94,17 @@ static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject cla
|
||||
if (jsurface) {
|
||||
window = android_view_Surface_getNativeWindow(env, jsurface);
|
||||
}
|
||||
proxy->updateSurface(window.get());
|
||||
proxy->updateSurface(window);
|
||||
}
|
||||
|
||||
static void android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
|
||||
jlong proxyPtr, jobject jsurface) {
|
||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||
sp<ANativeWindow> window;
|
||||
if (jsurface) {
|
||||
window = android_view_Surface_getNativeWindow(env, jsurface);
|
||||
}
|
||||
proxy->pauseSurface(window);
|
||||
}
|
||||
|
||||
static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz,
|
||||
@@ -203,6 +213,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
|
||||
{ "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
|
||||
{ "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
|
||||
{ "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface },
|
||||
{ "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup },
|
||||
{ "nSetDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_setDisplayListData },
|
||||
{ "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList },
|
||||
|
||||
@@ -347,6 +347,7 @@ void CanvasContext::setSurface(EGLNativeWindowType window) {
|
||||
|
||||
if (mEglSurface != EGL_NO_SURFACE) {
|
||||
mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface);
|
||||
mGlobalContext->makeCurrent(mEglSurface);
|
||||
mHaveNewSurface = true;
|
||||
}
|
||||
}
|
||||
@@ -356,14 +357,15 @@ void CanvasContext::swapBuffers() {
|
||||
mHaveNewSurface = false;
|
||||
}
|
||||
|
||||
void CanvasContext::makeCurrent() {
|
||||
void CanvasContext::requireSurface() {
|
||||
LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
|
||||
"requireSurface() called but no surface set!");
|
||||
mGlobalContext->makeCurrent(mEglSurface);
|
||||
}
|
||||
|
||||
bool CanvasContext::initialize(EGLNativeWindowType window) {
|
||||
if (mCanvas) return false;
|
||||
setSurface(window);
|
||||
makeCurrent();
|
||||
mCanvas = new OpenGLRenderer();
|
||||
mCanvas->initProperties();
|
||||
return true;
|
||||
@@ -371,7 +373,11 @@ bool CanvasContext::initialize(EGLNativeWindowType window) {
|
||||
|
||||
void CanvasContext::updateSurface(EGLNativeWindowType window) {
|
||||
setSurface(window);
|
||||
makeCurrent();
|
||||
}
|
||||
|
||||
void CanvasContext::pauseSurface(EGLNativeWindowType window) {
|
||||
// TODO: For now we just need a fence, in the future suspend any animations
|
||||
// and such to prevent from trying to render into this surface
|
||||
}
|
||||
|
||||
void CanvasContext::setup(int width, int height) {
|
||||
@@ -460,7 +466,7 @@ void CanvasContext::invokeFunctors() {
|
||||
|
||||
if (!mCanvas) return;
|
||||
|
||||
makeCurrent();
|
||||
requireSurface();
|
||||
Rect dirty;
|
||||
mCanvas->invokeFunctors(dirty);
|
||||
}
|
||||
@@ -491,12 +497,12 @@ void CanvasContext::runWithGlContext(RenderTask* task) {
|
||||
}
|
||||
|
||||
Layer* CanvasContext::createRenderLayer(int width, int height) {
|
||||
requireGlContext();
|
||||
requireSurface();
|
||||
return LayerRenderer::createRenderLayer(width, height);
|
||||
}
|
||||
|
||||
Layer* CanvasContext::createTextureLayer() {
|
||||
requireGlContext();
|
||||
requireSurface();
|
||||
return LayerRenderer::createTextureLayer();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
bool initialize(EGLNativeWindowType window);
|
||||
void updateSurface(EGLNativeWindowType window);
|
||||
void pauseSurface(EGLNativeWindowType window);
|
||||
void setup(int width, int height);
|
||||
void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
|
||||
void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters);
|
||||
@@ -83,7 +84,7 @@ public:
|
||||
private:
|
||||
void setSurface(EGLNativeWindowType window);
|
||||
void swapBuffers();
|
||||
void makeCurrent();
|
||||
void requireSurface();
|
||||
|
||||
friend class InvokeFunctorsTask;
|
||||
void invokeFunctors();
|
||||
|
||||
@@ -92,10 +92,10 @@ CREATE_BRIDGE2(initialize, CanvasContext* context, EGLNativeWindowType window) {
|
||||
return (void*) args->context->initialize(args->window);
|
||||
}
|
||||
|
||||
bool RenderProxy::initialize(EGLNativeWindowType window) {
|
||||
bool RenderProxy::initialize(const sp<ANativeWindow>& window) {
|
||||
SETUP_TASK(initialize);
|
||||
args->context = mContext;
|
||||
args->window = window;
|
||||
args->window = window.get();
|
||||
return (bool) postAndWait(task);
|
||||
}
|
||||
|
||||
@@ -104,11 +104,23 @@ CREATE_BRIDGE2(updateSurface, CanvasContext* context, EGLNativeWindowType window
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RenderProxy::updateSurface(EGLNativeWindowType window) {
|
||||
void RenderProxy::updateSurface(const sp<ANativeWindow>& window) {
|
||||
SETUP_TASK(updateSurface);
|
||||
args->context = mContext;
|
||||
args->window = window;
|
||||
post(task);
|
||||
args->window = window.get();
|
||||
postAndWait(task);
|
||||
}
|
||||
|
||||
CREATE_BRIDGE2(pauseSurface, CanvasContext* context, EGLNativeWindowType window) {
|
||||
args->context->pauseSurface(args->window);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RenderProxy::pauseSurface(const sp<ANativeWindow>& window) {
|
||||
SETUP_TASK(pauseSurface);
|
||||
args->context = mContext;
|
||||
args->window = window.get();
|
||||
postAndWait(task);
|
||||
}
|
||||
|
||||
CREATE_BRIDGE3(setup, CanvasContext* context, int width, int height) {
|
||||
|
||||
@@ -59,8 +59,9 @@ public:
|
||||
ANDROID_API RenderProxy(bool translucent);
|
||||
ANDROID_API virtual ~RenderProxy();
|
||||
|
||||
ANDROID_API bool initialize(EGLNativeWindowType window);
|
||||
ANDROID_API void updateSurface(EGLNativeWindowType window);
|
||||
ANDROID_API bool initialize(const sp<ANativeWindow>& window);
|
||||
ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
|
||||
ANDROID_API void pauseSurface(const sp<ANativeWindow>& window);
|
||||
ANDROID_API void setup(int width, int height);
|
||||
ANDROID_API void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
|
||||
ANDROID_API void drawDisplayList(RenderNode* displayList,
|
||||
|
||||
Reference in New Issue
Block a user