libvulkan: Fix dEQP-VK.api.object_management.alloc_callback_fail.instance

The loader was crashing when a std::vector::resize() operation called
the test-provided allocator, which returned failure, and then the
vector blindly started writing into the returned pointer.

Obvious in hindsight, but stdlib containers+strings + user-provided
allocation funcs implies that the loader must be built with exceptions
enabled, and must be exception-safe at least where it uses
containers/strings. We were doing neither.

This change has the minimally invasive fix, which is to (a) throw an
exception from the stdlib Allocator when the app-provided allocation
function fails, and (b) wrap every stdlib operation that might
allocate in a try..catch and turn it into a
VK_ERROR_OUT_OF_HOST_MEMORY error.

This is pretty unsatisfying and I'm not happy with the resulting
mismash of error-handling styles, with having exceptions at all in
code that was not written to be exception-safe, or with the
fine-grained try..catch. We need to decide whether to keep using parts
of stdlib that can allocate, and rewrite a lot of code to be
exception-friendly, or we need to replace the stdlib code with manual
containers and strings. Bug 26732452 filed.

Change-Id: I6f096f25a43a0e3c5f56796c2af19f114d2edac6
(cherry picked from commit ccca46db073dfadc81a68ac1533d8859ed3e109a)
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 75cabc1..2392b5c 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -77,10 +77,13 @@
         : allocator_(other.allocator_), scope_(other.scope_) {}
 
     T* allocate(size_t n) const {
-        return static_cast<T*>(allocator_.pfnAllocation(
+        T* p = static_cast<T*>(allocator_.pfnAllocation(
             allocator_.pUserData, n * sizeof(T), alignof(T), scope_));
+        if (!p)
+            throw std::bad_alloc();
+        return p;
     }
-    void deallocate(T* p, size_t) const {
+    void deallocate(T* p, size_t) const noexcept {
         return allocator_.pfnFree(allocator_.pUserData, p);
     }
 
@@ -93,10 +96,15 @@
 
 template <typename T, typename Host>
 std::shared_ptr<T> InitSharedPtr(Host host, T* obj) {
-    obj->common.incRef(&obj->common);
-    return std::shared_ptr<T>(
-        obj, NativeBaseDeleter<T>(),
-        VulkanAllocator<T>(*GetAllocator(host), AllocScope<Host>::kScope));
+    try {
+        obj->common.incRef(&obj->common);
+        return std::shared_ptr<T>(
+            obj, NativeBaseDeleter<T>(),
+            VulkanAllocator<T>(*GetAllocator(host), AllocScope<Host>::kScope));
+    } catch (std::bad_alloc&) {
+        obj->common.decRef(&obj->common);
+        return nullptr;
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -161,6 +169,12 @@
     Surface* surface = new (mem) Surface;
 
     surface->window = InitSharedPtr(instance, pCreateInfo->window);
+    if (!surface->window) {
+        ALOGE("surface creation failed: out of memory");
+        surface->~Surface();
+        allocator->pfnFree(allocator->pUserData, surface);
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
 
     // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN.
     int err =
@@ -468,6 +482,13 @@
             break;
         }
         img.buffer = InitSharedPtr(device, buffer);
+        if (!img.buffer) {
+            ALOGE("swapchain creation failed: out of memory");
+            surface.window->cancelBuffer(surface.window.get(), buffer,
+                                         img.dequeue_fence);
+            result = VK_ERROR_OUT_OF_HOST_MEMORY;
+            break;
+        }
         img.dequeued = true;
 
         image_create.extent =