diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp index 92e20c477669e..974c8635b3df1 100644 --- a/libs/hwui/WebViewFunctorManager.cpp +++ b/libs/hwui/WebViewFunctorManager.cpp @@ -126,7 +126,14 @@ void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { renderthread::CanvasContext::getActiveContext(); if (activeContext != nullptr) { ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl(); - if (rootSurfaceControl) overlayParams.overlaysMode = OverlaysMode::Enabled; + if (rootSurfaceControl) { + overlayParams.overlaysMode = OverlaysMode::Enabled; + int32_t rgid = activeContext->getSurfaceControlGenerationId(); + if (mParentSurfaceControlGenerationId != rgid) { + reparentSurfaceControl(rootSurfaceControl); + mParentSurfaceControlGenerationId = rgid; + } + } } } @@ -195,6 +202,7 @@ ASurfaceControl* WebViewFunctor::getSurfaceControl() { LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!"); auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions(); + mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId(); mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl"); ASurfaceTransaction* transaction = funcs.transactionCreateFunc(); activeContext->prepareSurfaceControlForWebview(); @@ -218,6 +226,17 @@ void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) { } } +void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) { + ATRACE_NAME("WebViewFunctor::reparentSurfaceControl"); + if (mSurfaceControl == nullptr) return; + + auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions(); + ASurfaceTransaction* transaction = funcs.transactionCreateFunc(); + funcs.transactionReparentFunc(transaction, mSurfaceControl, parent); + mergeTransaction(transaction); + funcs.transactionDeleteFunc(transaction); +} + WebViewFunctorManager& WebViewFunctorManager::instance() { static WebViewFunctorManager sInstance; return sInstance; diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h index a84cda5505677..048d1fbe1c7cb 100644 --- a/libs/hwui/WebViewFunctorManager.h +++ b/libs/hwui/WebViewFunctorManager.h @@ -84,6 +84,9 @@ public: return sp{new Handle(*this)}; } +private: + void reparentSurfaceControl(ASurfaceControl* parent); + private: WebViewFunctorCallbacks mCallbacks; void* const mData; @@ -91,6 +94,7 @@ private: RenderMode mMode; bool mHasContext = false; bool mCreatedHandle = false; + int32_t mParentSurfaceControlGenerationId = 0; ASurfaceControl* mSurfaceControl = nullptr; }; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 0c9711ba80254..81cee6103d220 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -201,6 +201,7 @@ void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) { funcs.releaseFunc(mSurfaceControl); } mSurfaceControl = surfaceControl; + mSurfaceControlGenerationId++; mExpectSurfaceStats = surfaceControl != nullptr; if (mSurfaceControl != nullptr) { funcs.acquireFunc(mSurfaceControl); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 3279ccb8e5970..85af3e4fb0b63 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -110,6 +110,7 @@ public: GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); } ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; } + int32_t getSurfaceControlGenerationId() const { return mSurfaceControlGenerationId; } // Won't take effect until next EGLSurface creation void setSwapBehavior(SwapBehavior swapBehavior); @@ -253,6 +254,9 @@ private: // The SurfaceControl reference is passed from ViewRootImpl, can be set to // NULL to remove the reference ASurfaceControl* mSurfaceControl = nullptr; + // id to track surface control changes and WebViewFunctor uses it to determine + // whether reparenting is needed + int32_t mSurfaceControlGenerationId = 0; // stopped indicates the CanvasContext will reject actual redraw operations, // and defer repaint until it is un-stopped bool mStopped = false; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 524407d2b9b08..f83c0a4926f9f 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -98,6 +98,10 @@ ASurfaceControlFunctions::ASurfaceControlFunctions() { LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr, "Failed to find required symbol ASurfaceTransaction_apply!"); + transactionReparentFunc = (AST_reparent)dlsym(handle_, "ASurfaceTransaction_reparent"); + LOG_ALWAYS_FATAL_IF(transactionReparentFunc == nullptr, + "Failed to find required symbol transactionReparentFunc!"); + transactionSetVisibilityFunc = (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility"); LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr, diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index c5e3746587b87..05d225b856dbf 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -94,6 +94,9 @@ typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats); typedef ASurfaceTransaction* (*AST_create)(); typedef void (*AST_delete)(ASurfaceTransaction* transaction); typedef void (*AST_apply)(ASurfaceTransaction* transaction); +typedef void (*AST_reparent)(ASurfaceTransaction* aSurfaceTransaction, + ASurfaceControl* aSurfaceControl, + ASurfaceControl* newParentASurfaceControl); typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, int8_t visibility); typedef void (*AST_setZOrder)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, @@ -113,6 +116,7 @@ struct ASurfaceControlFunctions { AST_create transactionCreateFunc; AST_delete transactionDeleteFunc; AST_apply transactionApplyFunc; + AST_reparent transactionReparentFunc; AST_setVisibility transactionSetVisibilityFunc; AST_setZOrder transactionSetZOrderFunc; };