Merge "DeferredLayerUpdater: clean up Layer lifecycle"

This commit is contained in:
Sergey Vasilinets
2017-02-14 01:28:24 +00:00
committed by Android (Google) Code Review
6 changed files with 30 additions and 43 deletions

View File

@@ -132,7 +132,7 @@ final class HardwareLayer {
}
public void setSurfaceTexture(SurfaceTexture surface) {
nSetSurfaceTexture(mFinalizer.get(), surface, false);
nSetSurfaceTexture(mFinalizer.get(), surface);
mRenderer.pushLayerUpdate(this);
}
@@ -148,7 +148,6 @@ final class HardwareLayer {
private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
private static native void nSetLayerPaint(long layerUpdater, long paint);
private static native void nSetTransform(long layerUpdater, long matrix);
private static native void nSetSurfaceTexture(long layerUpdater,
SurfaceTexture surface, boolean isAlreadyAttached);
private static native void nSetSurfaceTexture(long layerUpdater, SurfaceTexture surface);
private static native void nUpdateSurfaceTexture(long layerUpdater);
}

View File

@@ -66,10 +66,10 @@ static void android_view_HardwareLayer_setTransform(JNIEnv* env, jobject clazz,
}
static void android_view_HardwareLayer_setSurfaceTexture(JNIEnv* env, jobject clazz,
jlong layerUpdaterPtr, jobject surface, jboolean isAlreadyAttached) {
jlong layerUpdaterPtr, jobject surface) {
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
layer->setSurfaceTexture(surfaceTexture, !isAlreadyAttached);
layer->setSurfaceTexture(surfaceTexture);
}
static void android_view_HardwareLayer_updateSurfaceTexture(JNIEnv* env, jobject clazz,
@@ -88,7 +88,7 @@ static const JNINativeMethod gMethods[] = {
{ "nPrepare", "(JIIZ)Z", (void*) android_view_HardwareLayer_prepare },
{ "nSetLayerPaint", "(JJ)V", (void*) android_view_HardwareLayer_setLayerPaint },
{ "nSetTransform", "(JJ)V", (void*) android_view_HardwareLayer_setTransform },
{ "nSetSurfaceTexture", "(JLandroid/graphics/SurfaceTexture;Z)V",
{ "nSetSurfaceTexture", "(JLandroid/graphics/SurfaceTexture;)V",
(void*) android_view_HardwareLayer_setSurfaceTexture },
{ "nUpdateSurfaceTexture", "(J)V", (void*) android_view_HardwareLayer_updateSurfaceTexture },
};

View File

@@ -31,7 +31,7 @@ DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState, CreateLayer
, mBlend(false)
, mSurfaceTexture(nullptr)
, mTransform(nullptr)
, mNeedsGLContextAttach(false)
, mGLContextAttached(false)
, mUpdateTexImage(false)
, mLayer(nullptr)
, mLayerApi(layerApi)
@@ -47,10 +47,21 @@ DeferredLayerUpdater::~DeferredLayerUpdater() {
}
void DeferredLayerUpdater::destroyLayer() {
if (mLayer) {
mLayer->postDecStrong();
mLayer = nullptr;
if (!mLayer) {
return;
}
if (mSurfaceTexture.get() && mLayerApi == Layer::Api::OpenGL && mGLContextAttached) {
status_t err = mSurfaceTexture->detachFromContext();
mGLContextAttached = false;
if (err != 0) {
// TODO: Elevate to fatal exception
ALOGE("Failed to detach SurfaceTexture from context %d", err);
}
}
mLayer->postDecStrong();
mLayer = nullptr;
}
void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
@@ -78,8 +89,9 @@ void DeferredLayerUpdater::apply() {
LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
"apply surfaceTexture with non GL backend %x, GL %x, VK %x",
mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
if (mNeedsGLContextAttach) {
mNeedsGLContextAttach = false;
if (!mGLContextAttached) {
mGLContextAttached = true;
mUpdateTexImage = true;
mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId());
}
if (mUpdateTexImage) {
@@ -169,16 +181,7 @@ void DeferredLayerUpdater::updateLayer(bool forceFilter, GLenum renderTarget,
void DeferredLayerUpdater::detachSurfaceTexture() {
if (mSurfaceTexture.get()) {
if (mLayerApi == Layer::Api::OpenGL) {
status_t err = mSurfaceTexture->detachFromContext();
if (err != 0) {
// TODO: Elevate to fatal exception
ALOGE("Failed to detach SurfaceTexture from context %d", err);
}
if (mLayer) {
static_cast<GlLayer*>(mLayer)->clearTexture();
}
}
destroyLayer();
mSurfaceTexture = nullptr;
}
}

View File

@@ -68,9 +68,8 @@ public:
return false;
}
ANDROID_API void setSurfaceTexture(const sp<GLConsumer>& texture, bool needsAttach) {
ANDROID_API void setSurfaceTexture(const sp<GLConsumer>& texture) {
if (texture.get() != mSurfaceTexture.get()) {
mNeedsGLContextAttach = needsAttach;
mSurfaceTexture = texture;
GLenum target = texture->getCurrentTextureTarget();
@@ -122,7 +121,7 @@ private:
SkBlendMode mMode = SkBlendMode::kSrcOver;
sp<GLConsumer> mSurfaceTexture;
SkMatrix* mTransform;
bool mNeedsGLContextAttach;
bool mGLContextAttached;
bool mUpdateTexImage;
Layer* mLayer;

View File

@@ -43,7 +43,10 @@ GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHe
}
GlLayer::~GlLayer() {
if (texture.mId) {
// There's a rare possibility that Caches could have been destroyed already
// since this method is queued up as a task.
// Since this is a reset method, treat this as non-fatal.
if (caches.isInitialized() && texture.mId) {
texture.deleteTexture();
}
}
@@ -64,15 +67,5 @@ void GlLayer::generateTexture() {
}
}
void GlLayer::clearTexture() {
// There's a rare possibility that Caches could have been destroyed already
// since this method is queued up as a task.
// Since this is a reset method, treat this as non-fatal.
if (caches.isInitialized()) {
caches.textureState().unbindTexture(texture.mId);
}
texture.mId = 0;
}
}; // namespace uirenderer
}; // namespace android

View File

@@ -87,13 +87,6 @@ public:
void bindTexture() const;
void generateTexture();
/**
* When the caller frees the texture itself, the caller
* must call this method to tell this layer that it lost
* the texture.
*/
void clearTexture();
/**
* Lost the GL context but the layer is still around, mark it invalid internally
* so the dtor knows not to do any GL work