Merge "DeferredLayerUpdater: clean up Layer lifecycle"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2eaae562fe
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user