Merge "Fix crash where trim memory resulted in HWUI deleting the surface." into tm-qpr-dev am: 90f20aaaf6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20068650

Change-Id: Ie2f2b600e2418e74145bb4b3f59a08f2f9da5375
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-09-28 21:01:49 +00:00
committed by Automerger Merge Worker
5 changed files with 28 additions and 7 deletions

View File

@@ -53,8 +53,12 @@ SkiaOpenGLPipeline::~SkiaOpenGLPipeline() {
} }
MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() { MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() {
// TODO: Figure out why this workaround is needed, see b/13913604 // In case the surface was destroyed (e.g. a previous trimMemory call) we
// In the meantime this matches the behavior of GLRenderer, so it is not a regression // need to recreate it here.
if (!isSurfaceReady() && mNativeWindow) {
setSurface(mNativeWindow.get(), mSwapBehavior);
}
EGLint error = 0; EGLint error = 0;
if (!mEglManager.makeCurrent(mEglSurface, &error)) { if (!mEglManager.makeCurrent(mEglSurface, &error)) {
return MakeCurrentResult::AlreadyCurrent; return MakeCurrentResult::AlreadyCurrent;
@@ -166,6 +170,9 @@ void SkiaOpenGLPipeline::onStop() {
} }
bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) { bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) {
mNativeWindow = surface;
mSwapBehavior = swapBehavior;
if (mEglSurface != EGL_NO_SURFACE) { if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface); mEglManager.destroySurface(mEglSurface);
mEglSurface = EGL_NO_SURFACE; mEglSurface = EGL_NO_SURFACE;
@@ -182,7 +189,8 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh
if (mEglSurface != EGL_NO_SURFACE) { if (mEglSurface != EGL_NO_SURFACE) {
const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); const bool isPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
ALOGE_IF(preserveBuffer != isPreserved, "Unable to match the desired swap behavior.");
return true; return true;
} }

View File

@@ -61,7 +61,8 @@ protected:
private: private:
renderthread::EglManager& mEglManager; renderthread::EglManager& mEglManager;
EGLSurface mEglSurface = EGL_NO_SURFACE; EGLSurface mEglSurface = EGL_NO_SURFACE;
bool mBufferPreserved = false; sp<ANativeWindow> mNativeWindow;
renderthread::SwapBehavior mSwapBehavior = renderthread::SwapBehavior::kSwap_discardBuffer;
}; };
} /* namespace skiapipeline */ } /* namespace skiapipeline */

View File

@@ -55,7 +55,12 @@ VulkanManager& SkiaVulkanPipeline::vulkanManager() {
} }
MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { MakeCurrentResult SkiaVulkanPipeline::makeCurrent() {
return MakeCurrentResult::AlreadyCurrent; // In case the surface was destroyed (e.g. a previous trimMemory call) we
// need to recreate it here.
if (!isSurfaceReady() && mNativeWindow) {
setSurface(mNativeWindow.get(), SwapBehavior::kSwap_default);
}
return isContextReady() ? MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed;
} }
Frame SkiaVulkanPipeline::getFrame() { Frame SkiaVulkanPipeline::getFrame() {
@@ -130,7 +135,11 @@ DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
void SkiaVulkanPipeline::onStop() {} void SkiaVulkanPipeline::onStop() {}
bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) { // We can safely ignore the swap behavior because VkManager will always operate
// in a mode equivalent to EGLManager::SwapBehavior::kBufferAge
bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior /*swapBehavior*/) {
mNativeWindow = surface;
if (mVkSurface) { if (mVkSurface) {
vulkanManager().destroySurface(mVkSurface); vulkanManager().destroySurface(mVkSurface);
mVkSurface = nullptr; mVkSurface = nullptr;

View File

@@ -61,6 +61,7 @@ private:
renderthread::VulkanManager& vulkanManager(); renderthread::VulkanManager& vulkanManager();
renderthread::VulkanSurface* mVkSurface = nullptr; renderthread::VulkanSurface* mVkSurface = nullptr;
sp<ANativeWindow> mNativeWindow;
}; };
} /* namespace skiapipeline */ } /* namespace skiapipeline */

View File

@@ -404,7 +404,9 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
EXPECT_TRUE(pipeline->isSurfaceReady()); EXPECT_TRUE(pipeline->isSurfaceReady());
renderThread.destroyRenderingContext(); renderThread.destroyRenderingContext();
EXPECT_FALSE(pipeline->isSurfaceReady()); EXPECT_FALSE(pipeline->isSurfaceReady());
LOG_ALWAYS_FATAL_IF(pipeline->isSurfaceReady());
pipeline->makeCurrent();
EXPECT_TRUE(pipeline->isSurfaceReady());
} }
RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, pictureCallback) { RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, pictureCallback) {