OSDN Git Service

Fix crash after dequeueNativeBuffer fails
authorStan Iliev <stani@google.com>
Tue, 26 Mar 2019 19:14:34 +0000 (15:14 -0400)
committerStan Iliev <stani@google.com>
Tue, 26 Mar 2019 19:14:34 +0000 (15:14 -0400)
Anytime dequeueNativeBuffer fails, it sets mDequeuedIndex to -1.
This is causing a crash latter, when getCurrentSkSurface tries
to index mNativeBuffers[mDequeuedIndex].
This CL removes mDequeuedIndex and improves Vulkan swapchain
error handling.

Test: Ran Camera app
Bug: 129024275
Change-Id: Ieeb685c3a1b33f23ce2334d286199a44ace53165

libs/hwui/renderthread/VulkanManager.cpp
libs/hwui/renderthread/VulkanSurface.cpp
libs/hwui/renderthread/VulkanSurface.h

index b8ebf3b..c929098 100644 (file)
@@ -493,6 +493,12 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect)
         mDeviceWaitIdle(mDevice);
     }
 
+    VulkanSurface::NativeBufferInfo* bufferInfo = surface->getCurrentBufferInfo();
+    if (!bufferInfo) {
+        // If VulkanSurface::dequeueNativeBuffer failed earlier, then swapBuffers is a no-op.
+        return;
+    }
+
     VkExportSemaphoreCreateInfo exportInfo;
     exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
     exportInfo.pNext = nullptr;
@@ -509,8 +515,6 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect)
     GrBackendSemaphore backendSemaphore;
     backendSemaphore.initVulkan(semaphore);
 
-    VulkanSurface::NativeBufferInfo* bufferInfo = surface->getCurrentBufferInfo();
-
     int fenceFd = -1;
     GrSemaphoresSubmitted submitted =
             bufferInfo->skSurface->flush(SkSurface::BackendSurfaceAccess::kPresent,
index a98eb32..1708d3c 100644 (file)
@@ -420,9 +420,10 @@ void VulkanSurface::releaseBuffers() {
 }
 
 VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
-    // Set the dequeue index to invalid in case of error and only reset it to the correct
+    // Set the mCurrentBufferInfo to invalid in case of error and only reset it to the correct
     // value at the end of the function if everything dequeued correctly.
-    mDequeuedIndex = -1;
+    mCurrentBufferInfo = nullptr;
+
 
     //check if the native window has been resized or rotated and update accordingly
     SkISize newSize = SkISize::MakeEmpty();
@@ -511,7 +512,7 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
         }
     }
 
-    mDequeuedIndex = idx;
+    mCurrentBufferInfo = bufferInfo;
     return bufferInfo;
 }
 
@@ -535,7 +536,8 @@ bool VulkanSurface::presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreF
         ALOGE_IF(err != 0, "native_window_set_surface_damage failed: %s (%d)", strerror(-err), err);
     }
 
-    VulkanSurface::NativeBufferInfo& currentBuffer = mNativeBuffers[mDequeuedIndex];
+    LOG_ALWAYS_FATAL_IF(!mCurrentBufferInfo);
+    VulkanSurface::NativeBufferInfo& currentBuffer = *mCurrentBufferInfo;
     int queuedFd = (semaphoreFd != -1) ? semaphoreFd : currentBuffer.dequeue_fence;
     int err = mNativeWindow->queueBuffer(mNativeWindow.get(), currentBuffer.buffer.get(), queuedFd);
 
@@ -560,7 +562,8 @@ bool VulkanSurface::presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreF
 }
 
 int VulkanSurface::getCurrentBuffersAge() {
-    VulkanSurface::NativeBufferInfo& currentBuffer = mNativeBuffers[mDequeuedIndex];
+    LOG_ALWAYS_FATAL_IF(!mCurrentBufferInfo);
+    VulkanSurface::NativeBufferInfo& currentBuffer = *mCurrentBufferInfo;
     return currentBuffer.hasValidContents ? (mPresentCount - currentBuffer.lastPresentedCount) : 0;
 }
 
index 4fd9cd2..418d40f 100644 (file)
@@ -42,7 +42,9 @@ public:
                                   const VulkanManager& vkManager);
     ~VulkanSurface();
 
-    sk_sp<SkSurface> getCurrentSkSurface() { return mNativeBuffers[mDequeuedIndex].skSurface; }
+    sk_sp<SkSurface> getCurrentSkSurface() {
+        return mCurrentBufferInfo ? mCurrentBufferInfo->skSurface : nullptr;
+    }
     const SkMatrix& getCurrentPreTransform() { return mWindowInfo.preTransform; }
 
 private:
@@ -65,7 +67,7 @@ private:
     };
 
     NativeBufferInfo* dequeueNativeBuffer();
-    NativeBufferInfo* getCurrentBufferInfo() { return &mNativeBuffers[mDequeuedIndex]; }
+    NativeBufferInfo* getCurrentBufferInfo() { return mCurrentBufferInfo; }
     bool presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreFd);
 
     // The width and height are are the logical width and height for when submitting draws to the
@@ -115,8 +117,8 @@ private:
     WindowInfo mWindowInfo;
     GrContext* mGrContext;
 
-    int mDequeuedIndex = -1;
     uint32_t mPresentCount = 0;
+    NativeBufferInfo* mCurrentBufferInfo = nullptr;
 
     const SkISize mMinWindowSize;
     const SkISize mMaxWindowSize;