Revert "Revert "Dynamically load the vulkan library in our test tools""

This reverts commit c8dd283c9a784d1e115019f5b4a1b0e082513203.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> Revert "Dynamically load the vulkan library in our test tools"
> 
> This reverts commit 77d6feaa69d95c42f4e77195e92de33917995544.
> 
> Reason for revert: breaking google 3
> 
> Original change's description:
> > Dynamically load the vulkan library in our test tools
> > 
> > Bug: skia:
> > Change-Id: I7c1f6cbb2b50ca284f40cf4b9ef49a76083b38c6
> > Reviewed-on: https://skia-review.googlesource.com/68643
> > Reviewed-by: Chris Dalton <csmartdalton@google.com>
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
> 
> TBR=egdaniel@google.com,csmartdalton@google.com
> 
> Change-Id: I6b2588e71f1876868fcf8f2b3c91a96e7c689045
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:
> Reviewed-on: https://skia-review.googlesource.com/69780
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,csmartdalton@google.com

Change-Id: I758aec07114305f0add086eecb1deb94d0140dcf
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/69900
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index e0c45fe..742f095 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -170,18 +170,6 @@
   }
   libs = []
   lib_dirs = []
-  if (skia_use_vulkan) {
-    if (skia_vulkan_sdk != "" && !is_android && !is_fuchsia) {
-      if (is_win) {
-        lib_dirs += [
-          "$skia_vulkan_sdk/Bin",
-          "$skia_vulkan_sdk/Lib",
-        ]
-      } else {
-        lib_dirs += [ "$skia_vulkan_sdk/lib/" ]
-      }
-    }
-  }
   if (skia_enable_gpu) {
     include_dirs += [ "src/gpu" ]
   }
@@ -1046,11 +1034,7 @@
       }
       if (skia_use_vulkan) {
         sources += [ "tools/gpu/vk/VkTestContext.cpp" ]
-        if (is_win) {
-          libs += [ "vulkan-1.lib" ]
-        } else {
-          libs += [ "vulkan" ]
-        }
+        sources += [ "tools/gpu/vk/VkTestUtils.cpp" ]
       }
       if (skia_use_metal) {
         sources += [ "tools/gpu/mtl/MtlTestContext.mm" ]
diff --git a/tools/gpu/vk/VkTestContext.cpp b/tools/gpu/vk/VkTestContext.cpp
index e329583..daaa55b 100644
--- a/tools/gpu/vk/VkTestContext.cpp
+++ b/tools/gpu/vk/VkTestContext.cpp
@@ -10,9 +10,9 @@
 #ifdef SK_VULKAN
 
 #include "GrContext.h"
+#include "VkTestUtils.h"
 #include "vk/GrVkInterface.h"
 #include "vk/GrVkUtil.h"
-#include <vulkan/vulkan.h>
 
 namespace {
 /**
@@ -114,8 +114,12 @@
         if (sharedContext) {
             backendContext = sharedContext->getVkBackendContext();
         } else {
-            backendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr,
-                                                            vkGetDeviceProcAddr));
+            PFN_vkGetInstanceProcAddr instProc;
+            PFN_vkGetDeviceProcAddr devProc;
+            if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+                return nullptr;
+            }
+            backendContext.reset(GrVkBackendContext::Create(instProc, devProc));
         }
         if (!backendContext) {
             return nullptr;
diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp
new file mode 100644
index 0000000..3033076
--- /dev/null
+++ b/tools/gpu/vk/VkTestUtils.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "VkTestUtils.h"
+
+#ifdef SK_VULKAN
+
+#include "../ports/SkOSLibrary.h"
+
+namespace sk_gpu_test {
+
+bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr* instProc,
+                                                   PFN_vkGetDeviceProcAddr* devProc) {
+    static void* vkLib = nullptr;
+    static PFN_vkGetInstanceProcAddr localInstProc = nullptr;
+    static PFN_vkGetDeviceProcAddr localDevProc = nullptr;
+    if (!vkLib) {
+#if defined _WIN32
+        vkLib = DynamicLoadLibrary("vulkan-1.dll");
+#else
+        vkLib = DynamicLoadLibrary("libvulkan.so");
+#endif
+        if (!vkLib) {
+            return false;
+        }
+        localInstProc = (PFN_vkGetInstanceProcAddr) GetProcedureAddress(vkLib,
+                                                                        "vkGetInstanceProcAddr");
+        localDevProc = (PFN_vkGetDeviceProcAddr) GetProcedureAddress(vkLib,
+                                                                     "vkGetDeviceProcAddr");
+    }
+    if (!localInstProc || !localDevProc) {
+        return false;
+    }
+    *instProc = localInstProc;
+    *devProc = localDevProc;
+    return true;
+}
+}
+
+#endif
diff --git a/tools/gpu/vk/VkTestUtils.h b/tools/gpu/vk/VkTestUtils.h
new file mode 100644
index 0000000..43e9dfd
--- /dev/null
+++ b/tools/gpu/vk/VkTestUtils.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef VkTestUtils_DEFINED
+#define VkTestUtils_DEFINED
+
+#ifdef SK_VULKAN
+
+#include "vk/GrVkDefines.h"
+
+namespace sk_gpu_test {
+    bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr*, PFN_vkGetDeviceProcAddr*);
+}
+
+#endif
+#endif
+
diff --git a/tools/viewer/sk_app/VulkanWindowContext.cpp b/tools/viewer/sk_app/VulkanWindowContext.cpp
index a9124d5..5e0f124 100644
--- a/tools/viewer/sk_app/VulkanWindowContext.cpp
+++ b/tools/viewer/sk_app/VulkanWindowContext.cpp
@@ -22,14 +22,16 @@
 #undef CreateSemaphore
 #endif
 
-#define GET_PROC(F) f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk" #F)
-#define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk" #F)
+#define GET_PROC(F) f ## F = (PFN_vk ## F) fGetInstanceProcAddr(instance, "vk" #F)
+#define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) fGetDeviceProcAddr(device, "vk" #F)
 
 namespace sk_app {
 
 VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
                                          CreateVkSurfaceFn createVkSurface,
-                                         CanPresentFn canPresent)
+                                         CanPresentFn canPresent,
+                                         PFN_vkGetInstanceProcAddr instProc,
+                                         PFN_vkGetDeviceProcAddr devProc)
     : WindowContext(params)
     , fCreateVkSurfaceFn(createVkSurface)
     , fCanPresentFn(canPresent)
@@ -40,12 +42,14 @@
     , fSurfaces(nullptr)
     , fCommandPool(VK_NULL_HANDLE)
     , fBackbuffers(nullptr) {
+    fGetInstanceProcAddr = instProc;
+    fGetDeviceProcAddr = devProc;
     this->initializeContext();
 }
 
 void VulkanWindowContext::initializeContext() {
     // any config code here (particularly for msaa)?
-    fBackendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr, vkGetDeviceProcAddr,
+    fBackendContext.reset(GrVkBackendContext::Create(fGetInstanceProcAddr, fGetDeviceProcAddr,
                                                      &fPresentQueueIndex, fCanPresentFn));
 
     if (!(fBackendContext->fExtensions & kKHR_surface_GrVkExtensionFlag) ||
@@ -66,6 +70,7 @@
     GET_DEV_PROC(GetSwapchainImagesKHR);
     GET_DEV_PROC(AcquireNextImageKHR);
     GET_DEV_PROC(QueuePresentKHR);
+    GET_DEV_PROC(GetDeviceQueue);
 
     fContext = GrContext::MakeVulkan(fBackendContext.get(), fDisplayParams.fGrContextOptions);
 
@@ -90,7 +95,7 @@
     }
 
     // create presentQueue
-    vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQueue);
+    fGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQueue);
 }
 
 bool VulkanWindowContext::createSwapchain(int width, int height,
diff --git a/tools/viewer/sk_app/VulkanWindowContext.h b/tools/viewer/sk_app/VulkanWindowContext.h
index 81e5f3d..d02b114 100644
--- a/tools/viewer/sk_app/VulkanWindowContext.h
+++ b/tools/viewer/sk_app/VulkanWindowContext.h
@@ -47,7 +47,8 @@
     /** Platform specific function that determines whether presentation will succeed. */
     using CanPresentFn = GrVkBackendContext::CanPresentFn;
 
-    VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn);
+    VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn,
+                        PFN_vkGetInstanceProcAddr, PFN_vkGetDeviceProcAddr);
 
 private:
     void initializeContext();
@@ -82,6 +83,10 @@
     CreateVkSurfaceFn fCreateVkSurfaceFn;
     CanPresentFn      fCanPresentFn;
 
+    // Vulkan GetProcAddr functions
+    VkPtr<PFN_vkGetInstanceProcAddr> fGetInstanceProcAddr;
+    VkPtr<PFN_vkGetDeviceProcAddr> fGetDeviceProcAddr;
+
     // WSI interface functions
     VkPtr<PFN_vkDestroySurfaceKHR> fDestroySurfaceKHR;
     VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> fGetPhysicalDeviceSurfaceSupportKHR;
@@ -94,7 +99,7 @@
     VkPtr<PFN_vkGetSwapchainImagesKHR> fGetSwapchainImagesKHR;
     VkPtr<PFN_vkAcquireNextImageKHR> fAcquireNextImageKHR;
     VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
-    VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
+    VkPtr<PFN_vkGetDeviceQueue> fGetDeviceQueue;
 
     VkSurfaceKHR      fSurface;
     VkSwapchainKHR    fSwapchain;
diff --git a/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp b/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp
index b50e152..a7d8aa7 100644
--- a/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp
+++ b/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp
@@ -9,15 +9,22 @@
 #include "WindowContextFactory_android.h"
 #include "../VulkanWindowContext.h"
 
+#include "vk/VkTestUtils.h"
+
 namespace sk_app {
 
 namespace window_context_factory {
 
 WindowContext* NewVulkanForAndroid(ANativeWindow* window, const DisplayParams& params) {
-    auto createVkSurface = [window] (VkInstance instance) -> VkSurfaceKHR {
+    PFN_vkGetInstanceProcAddr instProc;
+    PFN_vkGetDeviceProcAddr devProc;
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+        return nullptr;
+    }
+
+    auto createVkSurface = [window, instProc] (VkInstance instance) -> VkSurfaceKHR {
         PFN_vkCreateAndroidSurfaceKHR createAndroidSurfaceKHR =
-                (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(instance,
-                                                                     "vkCreateAndroidSurfaceKHR");
+                (PFN_vkCreateAndroidSurfaceKHR) instProc(instance, "vkCreateAndroidSurfaceKHR");
 
         if (!window) {
             return VK_NULL_HANDLE;
@@ -38,7 +45,8 @@
 
     auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
 
-    WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent);
+    WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent,
+                                                 instProc, devProc);
     if (!ctx->isValid()) {
         delete ctx;
         return nullptr;
diff --git a/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp b/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp
index b94e8ed..b2f1ffc 100644
--- a/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp
+++ b/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp
@@ -10,6 +10,8 @@
 #include "vk/GrVkInterface.h"
 #include "vk/GrVkUtil.h"
 
+#include "vk/VkTestUtils.h"
+
 #include <X11/Xlib-xcb.h>
 
 #include "WindowContextFactory_unix.h"
@@ -20,12 +22,17 @@
 namespace window_context_factory {
 
 WindowContext* NewVulkanForXlib(const XlibWindowInfo& info, const DisplayParams& displayParams) {
-    auto createVkSurface = [&info](VkInstance instance) -> VkSurfaceKHR {
+    PFN_vkGetInstanceProcAddr instProc;
+    PFN_vkGetDeviceProcAddr devProc;
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+        return nullptr;
+    }
+
+    auto createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR {
         static PFN_vkCreateXcbSurfaceKHR createXcbSurfaceKHR = nullptr;
         if (!createXcbSurfaceKHR) {
             createXcbSurfaceKHR =
-                    (PFN_vkCreateXcbSurfaceKHR) vkGetInstanceProcAddr(instance,
-                                                                      "vkCreateXcbSurfaceKHR");
+                    (PFN_vkCreateXcbSurfaceKHR) instProc(instance, "vkCreateXcbSurfaceKHR");
         }
 
         VkSurfaceKHR surface;
@@ -46,15 +53,14 @@
         return surface;
     };
 
-    auto canPresent = [&info](VkInstance instance, VkPhysicalDevice physDev,
+    auto canPresent = [&info, instProc](VkInstance instance, VkPhysicalDevice physDev,
                               uint32_t queueFamilyIndex) {
         static PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
                                                 getPhysicalDeviceXcbPresentationSupportKHR = nullptr;
         if (!getPhysicalDeviceXcbPresentationSupportKHR) {
             getPhysicalDeviceXcbPresentationSupportKHR =
                 (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
-                        vkGetInstanceProcAddr(instance,
-                                              "vkGetPhysicalDeviceXcbPresentationSupportKHR");
+                    instProc(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
         }
 
 
@@ -66,7 +72,8 @@
                                                                     visualID);
         return (VK_FALSE != check);
     };
-    WindowContext* context = new VulkanWindowContext(displayParams, createVkSurface, canPresent);
+    WindowContext* context = new VulkanWindowContext(displayParams, createVkSurface, canPresent,
+                                                     instProc, devProc);
     if (!context->isValid()) {
         delete context;
         return nullptr;
diff --git a/tools/viewer/sk_app/win/VulkanWindowContext_win.cpp b/tools/viewer/sk_app/win/VulkanWindowContext_win.cpp
index dbb59c1..16c527c 100644
--- a/tools/viewer/sk_app/win/VulkanWindowContext_win.cpp
+++ b/tools/viewer/sk_app/win/VulkanWindowContext_win.cpp
@@ -15,15 +15,23 @@
 #include "vk/GrVkInterface.h"
 #include "vk/GrVkUtil.h"
 
+#include "vk/VkTestUtils.h"
+
 namespace sk_app {
 namespace window_context_factory {
 
 WindowContext* NewVulkanForWin(HWND hwnd, const DisplayParams& params) {
-    auto createVkSurface = [hwnd] (VkInstance instance) -> VkSurfaceKHR {
+    PFN_vkGetInstanceProcAddr instProc;
+    PFN_vkGetDeviceProcAddr devProc;
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+        return nullptr;
+    }
+
+    auto createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
         static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
         if (!createWin32SurfaceKHR) {
             createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
-                vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
+                instProc(instance, "vkCreateWin32SurfaceKHR");
         }
         HINSTANCE hinstance = GetModuleHandle(0);
         VkSurfaceKHR surface;
@@ -44,22 +52,22 @@
         return surface;
     };
 
-    auto canPresent = [] (VkInstance instance, VkPhysicalDevice physDev,
-                          uint32_t queueFamilyIndex) {
+    auto canPresent = [instProc] (VkInstance instance, VkPhysicalDevice physDev,
+                                  uint32_t queueFamilyIndex) {
         static PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
                                             getPhysicalDeviceWin32PresentationSupportKHR = nullptr;
         if (!getPhysicalDeviceWin32PresentationSupportKHR) {
             getPhysicalDeviceWin32PresentationSupportKHR =
                 (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
-                    vkGetInstanceProcAddr(instance,
-                                          "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+                    instProc(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
         }
 
         VkBool32 check = getPhysicalDeviceWin32PresentationSupportKHR(physDev, queueFamilyIndex);
         return (VK_FALSE != check);
     };
 
-    WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent);
+    WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent,
+                                                 instProc, devProc);
     if (!ctx->isValid()) {
         delete ctx;
         return nullptr;