Rename VulkanViewer to Viewer, take 2.
authorjvanverth <jvanverth@google.com>
Wed, 4 May 2016 20:49:13 +0000 (13:49 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 4 May 2016 20:49:13 +0000 (13:49 -0700)
Also puts Window and Application in sk_app namespace.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1945103003

Review-Url: https://codereview.chromium.org/1945103003

57 files changed:
gyp/most.gyp
gyp/viewer.gyp [new file with mode: 0644]
gyp/vulkanviewer.gyp [deleted file]
platform_tools/android/apps/settings.gradle
platform_tools/android/apps/viewer/build.gradle [new file with mode: 0644]
platform_tools/android/apps/viewer/src/main/AndroidManifest.xml [new file with mode: 0644]
platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java [new file with mode: 0644]
platform_tools/android/apps/vulkanviewer/build.gradle [deleted file]
platform_tools/android/apps/vulkanviewer/src/main/AndroidManifest.xml [deleted file]
platform_tools/android/apps/vulkanviewer/src/main/java/org/skia/vulkanviewer/VulkanViewerActivity.java [deleted file]
platform_tools/android/gyp/skia_android.gypi
platform_tools/android/gyp/viewer.gypi [new file with mode: 0644]
platform_tools/android/gyp/vulkanviewer.gypi [deleted file]
tools/viewer/Application.h [new file with mode: 0644]
tools/viewer/VulkanTestContext.cpp [new file with mode: 0644]
tools/viewer/VulkanTestContext.h [new file with mode: 0644]
tools/viewer/Window.cpp [new file with mode: 0644]
tools/viewer/Window.h [new file with mode: 0644]
tools/viewer/android/VulkanTestContext_android.cpp [new file with mode: 0644]
tools/viewer/android/VulkanTestContext_android.h [new file with mode: 0644]
tools/viewer/android/Window_android.cpp [new file with mode: 0644]
tools/viewer/android/Window_android.h [new file with mode: 0644]
tools/viewer/android/main_android.cpp [new file with mode: 0644]
tools/viewer/viewer/GMSlide.cpp [new file with mode: 0644]
tools/viewer/viewer/GMSlide.h [new file with mode: 0644]
tools/viewer/viewer/SKPSlide.cpp [new file with mode: 0644]
tools/viewer/viewer/SKPSlide.h [new file with mode: 0644]
tools/viewer/viewer/Slide.h [new file with mode: 0644]
tools/viewer/viewer/Viewer.cpp [new file with mode: 0644]
tools/viewer/viewer/Viewer.h [new file with mode: 0644]
tools/viewer/win/VulkanTestContext_win.cpp [new file with mode: 0644]
tools/viewer/win/VulkanTestContext_win.h [new file with mode: 0644]
tools/viewer/win/Window_win.cpp [new file with mode: 0644]
tools/viewer/win/Window_win.h [new file with mode: 0644]
tools/viewer/win/main_win.cpp [new file with mode: 0644]
tools/vulkan/Application.h [deleted file]
tools/vulkan/VulkanTestContext.cpp [deleted file]
tools/vulkan/VulkanTestContext.h [deleted file]
tools/vulkan/Window.cpp [deleted file]
tools/vulkan/Window.h [deleted file]
tools/vulkan/android/VulkanTestContext_android.cpp [deleted file]
tools/vulkan/android/VulkanTestContext_android.h [deleted file]
tools/vulkan/android/Window_android.cpp [deleted file]
tools/vulkan/android/Window_android.h [deleted file]
tools/vulkan/android/main_android.cpp [deleted file]
tools/vulkan/viewer/GMSlide.cpp [deleted file]
tools/vulkan/viewer/GMSlide.h [deleted file]
tools/vulkan/viewer/SKPSlide.cpp [deleted file]
tools/vulkan/viewer/SKPSlide.h [deleted file]
tools/vulkan/viewer/Slide.h [deleted file]
tools/vulkan/viewer/VulkanViewer.cpp [deleted file]
tools/vulkan/viewer/VulkanViewer.h [deleted file]
tools/vulkan/win/VulkanTestContext_win.cpp [deleted file]
tools/vulkan/win/VulkanTestContext_win.h [deleted file]
tools/vulkan/win/Window_win.cpp [deleted file]
tools/vulkan/win/Window_win.h [deleted file]
tools/vulkan/win/main_win.cpp [deleted file]

index f0b56d62c51b0a8cfb04ca4027571cf3aee0b1fe..6d56f8819b346d66dc9b621070743ef3ad7b2b6c 100644 (file)
         'visualbench.gyp:visualbench',
         'fuzz.gyp:fuzz',
         'kilobench.gyp:kilobench',
-        'vulkanviewer.gyp:vulkanviewer',
+        'viewer.gyp:viewer',
       ],
       'conditions': [
         [ 'skia_gpu == 0', {
           'dependencies!': [
             'visualbench.gyp:visualbench',
             'kilobench.gyp:kilobench',
-            'vulkanviewer.gyp:vulkanviewer',
+            'viewer.gyp:viewer',
           ]
         }],
         [ 'skia_os != "android" and skia_os != "linux"', {
@@ -61,7 +61,7 @@
             }],
             [ 'skia_vulkan == 1', {
               'dependencies': [
-                'android_system.gyp:VulkanViewer_APK',
+                'android_system.gyp:Viewer_APK',
               ],
             }],
           ],
@@ -86,7 +86,7 @@
         }],
         [ 'skia_vulkan == 0 or (skia_os != "win" and skia_os != "android")', {
           'dependencies!': [
-            'vulkanviewer.gyp:vulkanviewer',
+            'viewer.gyp:viewer',
           ],
         }],
         [ 'skia_skip_gui',
diff --git a/gyp/viewer.gyp b/gyp/viewer.gyp
new file mode 100644 (file)
index 0000000..d8082ef
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+# GYP file to build performance testbench.
+#
+{
+  'includes': [
+    'apptype_console.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'viewer',
+      'type': 'executable',
+      'includes' : [
+        'gmslides.gypi',
+      ],
+      'include_dirs': [
+        '../bench',
+        '../gm',
+        '../include/private',
+        '../src/core',
+        '../src/effects',
+        '../src/gpu',
+        '../src/images',
+        '../src/image',
+        '../tools/timer',
+      ],
+      'sources': [
+        '../gm/gm.cpp',
+        '<!@(python find.py ../tools/viewer "*.cpp")',
+      ],
+      'dependencies': [
+        'flags.gyp:flags',
+        'gputest.gyp:skgputest',
+        'jsoncpp.gyp:jsoncpp',
+        'skia_lib.gyp:skia_lib',
+        'tools.gyp:crash_handler',
+        'tools.gyp:proc_stats',
+        'tools.gyp:resources',
+        'tools.gyp:sk_tool_utils',
+        'tools.gyp:timer',
+        'tools.gyp:url_data_manager',
+      ],
+      'conditions' : [
+        [ 'skia_os == "android"', {
+          'dependencies': [
+            'android_deps.gyp:Android_EntryPoint',
+            'android_deps.gyp:native_app_glue',
+          ],
+          'link_settings': {
+            'libraries': [
+              '-landroid',
+            ],
+          },
+        }],
+        ['skia_os != "android"', {
+          'sources/': [ ['exclude', '_android.(h|cpp)$'],
+          ],
+        }],
+        ['skia_os != "win"', {
+          'sources/': [ ['exclude', '_win.(h|cpp)$'],
+          ],
+        }],
+      ],
+    },
+  ],
+}
diff --git a/gyp/vulkanviewer.gyp b/gyp/vulkanviewer.gyp
deleted file mode 100644 (file)
index 91c175b..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2016 Google Inc.
-#
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-# GYP file to build performance testbench.
-#
-{
-  'includes': [
-    'apptype_console.gypi',
-  ],
-  'targets': [
-    {
-      'target_name': 'vulkanviewer',
-      'type': 'executable',
-      'includes' : [
-        'gmslides.gypi',
-      ],
-      'include_dirs': [
-        '../bench',
-        '../gm',
-        '../include/private',
-        '../src/core',
-        '../src/effects',
-        '../src/gpu',
-        '../src/images',
-        '../src/image',
-        '../tools/timer',
-      ],
-      'sources': [
-        '../gm/gm.cpp',
-        '<!@(python find.py ../tools/vulkan "*.cpp")',
-      ],
-      'dependencies': [
-        'flags.gyp:flags',
-        'gputest.gyp:skgputest',
-        'jsoncpp.gyp:jsoncpp',
-        'skia_lib.gyp:skia_lib',
-        'tools.gyp:crash_handler',
-        'tools.gyp:proc_stats',
-        'tools.gyp:resources',
-        'tools.gyp:sk_tool_utils',
-        'tools.gyp:timer',
-        'tools.gyp:url_data_manager',
-      ],
-      'conditions' : [
-        [ 'skia_os == "android"', {
-          'dependencies': [
-            'android_deps.gyp:Android_EntryPoint',
-            'android_deps.gyp:native_app_glue',
-          ],
-          'link_settings': {
-            'libraries': [
-              '-landroid',
-            ],
-          },
-        }],
-        ['skia_os != "android"', {
-          'sources/': [ ['exclude', '_android.(h|cpp)$'],
-          ],
-        }],
-        ['skia_os != "win"', {
-          'sources/': [ ['exclude', '_win.(h|cpp)$'],
-          ],
-        }],
-      ],
-    },
-  ],
-}
index 9d103b49be012f5d246a9e0fdfb250c228689ec2..d462ca8bbbd19238f374420dd5bf47a0a3a3267f 100644 (file)
@@ -2,4 +2,4 @@ include ':sample_app'
 include ':visualbench'
 include ':visualbenchsdl'
 include ':canvasproof'
-include ':vulkanviewer'
+include ':viewer'
diff --git a/platform_tools/android/apps/viewer/build.gradle b/platform_tools/android/apps/viewer/build.gradle
new file mode 100644 (file)
index 0000000..79cac8a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+apply plugin: 'com.android.application'
+android {
+    compileSdkVersion 19
+    buildToolsVersion "22.0.1"
+    defaultConfig {
+        applicationId "org.skia.viewer"
+        minSdkVersion 19
+        targetSdkVersion 19
+        versionCode 1
+        versionName "1.0"
+        signingConfig signingConfigs.debug
+    }
+    sourceSets.main.jni.srcDirs = [] //disable automatic ndk-build call
+    sourceSets.main.jniLibs.srcDir "src/main/libs"
+    productFlavors { arm {}; arm64 {}; x86 {}; x86_64 {}; mips {}; mips64 {}; }
+
+    setupSkiaLibraryBuild(project, applicationVariants, "--vulkan CopyViewerDeps", true)
+}
diff --git a/platform_tools/android/apps/viewer/src/main/AndroidManifest.xml b/platform_tools/android/apps/viewer/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..2ed88e1
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- BEGIN_INCLUDE(manifest) -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="org.skia.viewer"
+          android:versionCode="1"
+          android:versionName="1.0">
+
+  <application
+      android:allowBackup="false"
+      android:label="Viewer">
+
+    <activity android:name=".ViewerActivity"
+              android:label="Viewer"
+              android:screenOrientation="portrait"
+              android:configChanges="orientation|keyboardHidden">
+      <meta-data android:name="android.app.lib_name"
+                 android:value="viewer" />
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+
+</manifest>
+<!-- END_INCLUDE(manifest) -->
diff --git a/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java b/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java
new file mode 100644 (file)
index 0000000..950d6b2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+package org.skia.viewer;
+
+import android.app.ActionBar;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.WindowManager;
+
+public class ViewerActivity extends android.app.NativeActivity {
+    static {
+        System.loadLibrary("skia_android");
+    }
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) 
+    {
+        super.onCreate(savedInstanceState);
+        ActionBar ab = this.getActionBar();
+        ab.hide();
+    }
+}
diff --git a/platform_tools/android/apps/vulkanviewer/build.gradle b/platform_tools/android/apps/vulkanviewer/build.gradle
deleted file mode 100644 (file)
index 731be4c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-apply plugin: 'com.android.application'
-android {
-    compileSdkVersion 19
-    buildToolsVersion "22.0.1"
-    defaultConfig {
-        applicationId "org.skia.vulkanviewer"
-        minSdkVersion 19
-        targetSdkVersion 19
-        versionCode 1
-        versionName "1.0"
-        signingConfig signingConfigs.debug
-    }
-    sourceSets.main.jni.srcDirs = [] //disable automatic ndk-build call
-    sourceSets.main.jniLibs.srcDir "src/main/libs"
-    productFlavors { arm {}; arm64 {}; x86 {}; x86_64 {}; mips {}; mips64 {}; }
-
-    setupSkiaLibraryBuild(project, applicationVariants, "--vulkan CopyVulkanViewerDeps", true)
-}
diff --git a/platform_tools/android/apps/vulkanviewer/src/main/AndroidManifest.xml b/platform_tools/android/apps/vulkanviewer/src/main/AndroidManifest.xml
deleted file mode 100644 (file)
index 634c737..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="org.skia.vulkanviewer"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-  <application
-      android:allowBackup="false"
-      android:label="VulkanViewer">
-
-    <activity android:name=".VulkanViewerActivity"
-              android:label="VulkanViewer"
-              android:screenOrientation="portrait"
-              android:configChanges="orientation|keyboardHidden">
-      <meta-data android:name="android.app.lib_name"
-                 android:value="vulkanviewer" />
-      <intent-filter>
-        <action android:name="android.intent.action.MAIN" />
-        <category android:name="android.intent.category.LAUNCHER" />
-      </intent-filter>
-    </activity>
-  </application>
-
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/platform_tools/android/apps/vulkanviewer/src/main/java/org/skia/vulkanviewer/VulkanViewerActivity.java b/platform_tools/android/apps/vulkanviewer/src/main/java/org/skia/vulkanviewer/VulkanViewerActivity.java
deleted file mode 100644 (file)
index 38554ff..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-package org.skia.vulkanviewer;
-
-import android.app.ActionBar;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.view.View;
-import android.view.WindowManager;
-
-public class VulkanViewerActivity extends android.app.NativeActivity {
-    static {
-        System.loadLibrary("skia_android");
-    }
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-        ActionBar ab = this.getActionBar();
-        ab.hide();
-    }
-}
index 29342d97fdb52e50028cd926a75ee492d7cd4961..844bd6ea26b41ca32c2a5b1885903df4eb3ef817 100644 (file)
@@ -49,7 +49,7 @@
   },
   'includes' : [
       'canvasproof.gypi',
-      'vulkanviewer.gypi',
+      'viewer.gypi',
   ],
   'targets': [
     {
diff --git a/platform_tools/android/gyp/viewer.gypi b/platform_tools/android/gyp/viewer.gypi
new file mode 100644 (file)
index 0000000..6d2659b
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright 2015 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+  'targets': [
+    {
+      'target_name': 'CopyViewerDeps',
+      'type': 'none',
+      'dependencies': [
+        'skia_lib.gyp:skia_lib',
+        'viewer.gyp:viewer',
+      ],
+      'copies': [
+        {
+          'destination': '<(android_base)/apps/viewer/src/main/libs/<(android_arch)',
+          'conditions': [
+            [ 'skia_shared_lib', {
+              'files': [
+                '<(SHARED_LIB_DIR)/libskia_android.so',
+                '<(SHARED_LIB_DIR)/libviewer.so',
+              ]}, {
+              'files': [
+                '<(SHARED_LIB_DIR)/libviewer.so',
+              ]}
+           ],
+          ],
+        },
+      ],
+    },
+    {
+      'target_name': 'Viewer_APK',
+      'type': 'none',
+      'dependencies': [ 'CopyViewerDeps', ],
+      'actions': [
+        {
+          'action_name': 'SkiaViewer_apk',
+          'inputs': [
+            '<(android_base)/apps/viewer/src/main/AndroidManifest.xml',
+            '<(android_base)/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java',
+            '<(android_base)/apps/viewer/src/main/libs/<(android_arch)/libviewer.so',
+
+          ],
+          'conditions': [
+            [ 'skia_shared_lib', {
+              'inputs': [
+                '<(android_base)/apps/viewer/src/main/libs/<(android_arch)/libskia_android.so',
+              ],
+            }],
+          ],
+          'outputs': [
+            '../apps/viewer/build/outputs/apk/',
+          ],
+          'action': [
+            '<(android_base)/apps/gradlew',
+            ':viewer:assemble<(android_variant)<(android_buildtype)',
+            '-p<(android_base)/apps/viewer',
+            '-PsuppressNativeBuild',
+            '--daemon',
+          ],
+        },
+      ],
+    },
+  ],
+}
diff --git a/platform_tools/android/gyp/vulkanviewer.gypi b/platform_tools/android/gyp/vulkanviewer.gypi
deleted file mode 100644 (file)
index b431e84..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2015 Google Inc.
-#
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'targets': [
-    {
-      'target_name': 'CopyVulkanViewerDeps',
-      'type': 'none',
-      'dependencies': [
-        'skia_lib.gyp:skia_lib',
-        'vulkanviewer.gyp:vulkanviewer',
-      ],
-      'copies': [
-        {
-          'destination': '<(android_base)/apps/vulkanviewer/src/main/libs/<(android_arch)',
-          'conditions': [
-            [ 'skia_shared_lib', {
-              'files': [
-                '<(SHARED_LIB_DIR)/libskia_android.so',
-                '<(SHARED_LIB_DIR)/libvulkanviewer.so',
-              ]}, {
-              'files': [
-                '<(SHARED_LIB_DIR)/libvulkanviewer.so',
-              ]}
-           ],
-          ],
-        },
-      ],
-    },
-    {
-      'target_name': 'VulkanViewer_APK',
-      'type': 'none',
-      'dependencies': [ 'CopyVulkanViewerDeps', ],
-      'actions': [
-        {
-          'action_name': 'SkiaVulkanViewer_apk',
-          'inputs': [
-            '<(android_base)/apps/vulkanviewer/src/main/AndroidManifest.xml',
-            '<(android_base)/apps/vulkanviewer/src/main/java/com/skia/vulkanviewer/VulkanViewerActivity.java',
-            '<(android_base)/apps/vulkanviewer/src/main/libs/<(android_arch)/libvulkanviewer.so',
-
-          ],
-          'conditions': [
-            [ 'skia_shared_lib', {
-              'inputs': [
-                '<(android_base)/apps/vulkanviewer/src/main/libs/<(android_arch)/libskia_android.so',
-              ],
-            }],
-          ],
-          'outputs': [
-            '../apps/vulkanviewer/build/outputs/apk/',
-          ],
-          'action': [
-            '<(android_base)/apps/gradlew',
-            ':vulkanviewer:assemble<(android_variant)<(android_buildtype)',
-            '-p<(android_base)/apps/vulkanviewer',
-            '-PsuppressNativeBuild',
-            '--daemon',
-          ],
-        },
-      ],
-    },
-  ],
-}
diff --git a/tools/viewer/Application.h b/tools/viewer/Application.h
new file mode 100644 (file)
index 0000000..235ff09
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Application_DEFINED
+#define Application_DEFINED
+
+namespace sk_app {
+
+class Application {
+public:
+    static Application* Create(int argc, char** argv, void* platformData);
+
+    virtual ~Application() {}
+
+    virtual void onIdle(double ms) = 0;
+};
+
+}   // namespace sk_app
+
+#endif
diff --git a/tools/viewer/VulkanTestContext.cpp b/tools/viewer/VulkanTestContext.cpp
new file mode 100644 (file)
index 0000000..e9137c0
--- /dev/null
@@ -0,0 +1,568 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrContext.h"
+#include "SkSurface.h"
+#include "VulkanTestContext.h"
+
+#include "vk/GrVkInterface.h"
+#include "vk/GrVkUtil.h"
+#include "vk/GrVkTypes.h"
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+// windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
+#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)
+
+VulkanTestContext::VulkanTestContext(void* platformData, int msaaSampleCount) 
+                                 : fSurface(VK_NULL_HANDLE)
+                                 , fSwapchain(VK_NULL_HANDLE)
+                                 , fCommandPool(VK_NULL_HANDLE)
+                                 , fBackbuffers(nullptr) {
+
+    // any config code here (particularly for msaa)?
+
+    this->initializeContext(platformData);
+}
+
+void VulkanTestContext::initializeContext(void* platformData) {
+
+    fBackendContext.reset(GrVkBackendContext::Create(&fPresentQueueIndex, canPresent));
+    if (!(fBackendContext->fExtensions & kKHR_surface_GrVkExtensionFlag) ||
+        !(fBackendContext->fExtensions & kKHR_swapchain_GrVkExtensionFlag)) {
+        fBackendContext.reset(nullptr);
+        return;
+    }
+
+    VkInstance instance = fBackendContext->fInstance;
+    VkDevice device = fBackendContext->fDevice;
+    GET_PROC(DestroySurfaceKHR);
+    GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
+    GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
+    GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
+    GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
+    GET_DEV_PROC(CreateSwapchainKHR);
+    GET_DEV_PROC(DestroySwapchainKHR);
+    GET_DEV_PROC(GetSwapchainImagesKHR);
+    GET_DEV_PROC(AcquireNextImageKHR);
+    GET_DEV_PROC(QueuePresentKHR);
+
+    fContext = GrContext::Create(kVulkan_GrBackend, (GrBackendContext)fBackendContext.get());
+
+    fSurface = createVkSurface(instance, platformData);
+    if (VK_NULL_HANDLE == fSurface) {
+        fBackendContext.reset(nullptr);
+        return;
+    }
+
+    VkBool32 supported;
+    VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fBackendContext->fPhysicalDevice,
+                                                       fPresentQueueIndex, fSurface,
+                                                       &supported);
+    if (VK_SUCCESS != res) {
+        this->destroyContext();
+        return;
+    }
+
+    if (!this->createSwapchain(-1, -1)) {
+        this->destroyContext();
+        return;
+    }
+
+    // create presentQueue
+    vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQueue);
+}
+
+bool VulkanTestContext::createSwapchain(uint32_t width, uint32_t height)
+{
+    // check for capabilities
+    VkSurfaceCapabilitiesKHR caps;
+    VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fBackendContext->fPhysicalDevice,
+                                                            fSurface, &caps);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    uint32_t surfaceFormatCount;
+    res = fGetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysicalDevice, fSurface,
+                                              &surfaceFormatCount, nullptr);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
+    VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
+    res = fGetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysicalDevice, fSurface,
+                                              &surfaceFormatCount, surfaceFormats);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    uint32_t presentModeCount;
+    res = fGetPhysicalDeviceSurfacePresentModesKHR(fBackendContext->fPhysicalDevice, fSurface,
+                                                   &presentModeCount, nullptr);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
+    VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
+    res = fGetPhysicalDeviceSurfacePresentModesKHR(fBackendContext->fPhysicalDevice, fSurface,
+                                                    &presentModeCount, presentModes);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    VkExtent2D extent = caps.currentExtent;
+    // use the hints
+    if (extent.width == (uint32_t)-1) {
+        extent.width = width;
+        extent.height = height;
+    }
+
+    // clamp width; to protect us from broken hints
+    if (extent.width < caps.minImageExtent.width) {
+        extent.width = caps.minImageExtent.width;
+    } else if (extent.width > caps.maxImageExtent.width) {
+        extent.width = caps.maxImageExtent.width;
+    }
+    // clamp height
+    if (extent.height < caps.minImageExtent.height) {
+        extent.height = caps.minImageExtent.height;
+    } else if (extent.height > caps.maxImageExtent.height) {
+        extent.height = caps.maxImageExtent.height;
+    }
+    fWidth = (int)extent.width;
+    fHeight = (int)extent.height;
+
+    uint32_t imageCount = caps.minImageCount + 2;
+    if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
+        // Application must settle for fewer images than desired:
+        imageCount = caps.maxImageCount;
+    }
+
+    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+    SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
+    SkASSERT(caps.supportedTransforms & caps.currentTransform);
+    SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
+                                             VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR));
+    VkCompositeAlphaFlagBitsKHR composite_alpha =
+        (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
+                                        VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR :
+                                        VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+
+    // Pick our surface format -- for now, the first one
+    VkFormat surfaceFormat = surfaceFormats[0].format;
+    VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace;
+
+    // If mailbox mode is available, use it, as it is the lowest-latency non-
+    // tearing mode. If not, fall back to FIFO which is always available.
+    VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
+    for (uint32_t i = 0; i < presentModeCount; ++i) {
+        // use mailbox
+        if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
+            mode = presentModes[i];
+            break;
+        }
+    }
+
+    VkSwapchainCreateInfoKHR swapchainCreateInfo;
+    memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
+    swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+    swapchainCreateInfo.surface = fSurface;
+    swapchainCreateInfo.minImageCount = imageCount;
+    swapchainCreateInfo.imageFormat = surfaceFormat;
+    swapchainCreateInfo.imageColorSpace = colorSpace;
+    swapchainCreateInfo.imageExtent = extent;
+    swapchainCreateInfo.imageArrayLayers = 1;
+    swapchainCreateInfo.imageUsage = usageFlags;
+
+    uint32_t queueFamilies[] = { fBackendContext->fGraphicsQueueIndex, fPresentQueueIndex };
+    if (fBackendContext->fGraphicsQueueIndex != fPresentQueueIndex) {
+        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+        swapchainCreateInfo.queueFamilyIndexCount = 2;
+        swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
+    } else {
+        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        swapchainCreateInfo.queueFamilyIndexCount = 0;
+        swapchainCreateInfo.pQueueFamilyIndices = nullptr;
+    }
+
+    swapchainCreateInfo.preTransform = caps.currentTransform;;
+    swapchainCreateInfo.compositeAlpha = composite_alpha;
+    swapchainCreateInfo.presentMode = mode;
+    swapchainCreateInfo.clipped = true;
+    swapchainCreateInfo.oldSwapchain = fSwapchain;
+
+    res = fCreateSwapchainKHR(fBackendContext->fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    // destroy the old swapchain
+    if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
+        GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext->fDevice));
+
+        this->destroyBuffers();
+
+        fDestroySwapchainKHR(fBackendContext->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
+    }
+
+    this->createBuffers(swapchainCreateInfo.imageFormat);
+
+    return true;
+}
+
+void VulkanTestContext::createBuffers(VkFormat format) {
+    GrVkFormatToPixelConfig(format, &fPixelConfig);
+
+    fGetSwapchainImagesKHR(fBackendContext->fDevice, fSwapchain, &fImageCount, nullptr);
+    SkASSERT(fImageCount);
+    fImages = new VkImage[fImageCount];
+    fGetSwapchainImagesKHR(fBackendContext->fDevice, fSwapchain, &fImageCount, fImages);
+
+    // set up initial image layouts and create surfaces
+    fImageLayouts = new VkImageLayout[fImageCount];
+    fSurfaces = new sk_sp<SkSurface>[fImageCount];
+    for (uint32_t i = 0; i < fImageCount; ++i) {
+        fImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
+
+        GrBackendRenderTargetDesc desc;
+        GrVkTextureInfo info;
+        info.fImage = fImages[i];
+        info.fAlloc = VK_NULL_HANDLE;
+        info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+        info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
+        info.fFormat = format;
+        desc.fWidth = fWidth;
+        desc.fHeight = fHeight;
+        desc.fConfig = fPixelConfig;
+        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+        desc.fSampleCnt = 0;
+        desc.fStencilBits = 0;
+        desc.fRenderTargetHandle = (GrBackendObject) &info;
+        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+        fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc, &props);
+    }
+
+    // create the command pool for the command buffers
+    if (VK_NULL_HANDLE == fCommandPool) {
+        VkCommandPoolCreateInfo commandPoolInfo;
+        memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo));
+        commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+        // this needs to be on the render queue
+        commandPoolInfo.queueFamilyIndex = fBackendContext->fGraphicsQueueIndex;
+        commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                            CreateCommandPool(fBackendContext->fDevice, &commandPoolInfo,
+                                              nullptr, &fCommandPool));
+    }
+
+    // set up the backbuffers
+    VkSemaphoreCreateInfo semaphoreInfo;
+    memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
+    semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    semaphoreInfo.pNext = nullptr;
+    semaphoreInfo.flags = 0;
+    VkCommandBufferAllocateInfo commandBuffersInfo;
+    memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo));
+    commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    commandBuffersInfo.pNext = nullptr;
+    commandBuffersInfo.commandPool = fCommandPool;
+    commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    commandBuffersInfo.commandBufferCount = 2;
+    VkFenceCreateInfo fenceInfo;
+    memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
+    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fenceInfo.pNext = nullptr;
+    fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
+
+    // we create one additional backbuffer structure here, because we want to 
+    // give the command buffers they contain a chance to finish before we cycle back
+    fBackbuffers = new BackbufferInfo[fImageCount + 1];
+    for (uint32_t i = 0; i < fImageCount + 1; ++i) {
+        fBackbuffers[i].fImageIndex = -1;
+        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                            CreateSemaphore(fBackendContext->fDevice, &semaphoreInfo,
+                                            nullptr, &fBackbuffers[i].fAcquireSemaphore));
+        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                            CreateSemaphore(fBackendContext->fDevice, &semaphoreInfo,
+                                            nullptr, &fBackbuffers[i].fRenderSemaphore));
+        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                            AllocateCommandBuffers(fBackendContext->fDevice, &commandBuffersInfo,
+                                                   fBackbuffers[i].fTransitionCmdBuffers));
+        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                            CreateFence(fBackendContext->fDevice, &fenceInfo, nullptr,
+                                        &fBackbuffers[i].fUsageFences[0]));
+        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                            CreateFence(fBackendContext->fDevice, &fenceInfo, nullptr,
+                                        &fBackbuffers[i].fUsageFences[1]));
+    }
+    fCurrentBackbufferIndex = fImageCount;
+}
+
+void VulkanTestContext::destroyBuffers() {
+
+    if (fBackbuffers) {
+        for (uint32_t i = 0; i < fImageCount + 1; ++i) {
+            GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                                WaitForFences(fBackendContext->fDevice, 2, 
+                                              fBackbuffers[i].fUsageFences,
+                                true, UINT64_MAX));
+            fBackbuffers[i].fImageIndex = -1;
+            GR_VK_CALL(fBackendContext->fInterface,
+                       DestroySemaphore(fBackendContext->fDevice,
+                                        fBackbuffers[i].fAcquireSemaphore,
+                                        nullptr));
+            GR_VK_CALL(fBackendContext->fInterface,
+                       DestroySemaphore(fBackendContext->fDevice,
+                                        fBackbuffers[i].fRenderSemaphore,
+                                        nullptr));
+            GR_VK_CALL(fBackendContext->fInterface,
+                       FreeCommandBuffers(fBackendContext->fDevice, fCommandPool, 2,
+                                          fBackbuffers[i].fTransitionCmdBuffers));
+            GR_VK_CALL(fBackendContext->fInterface,
+                       DestroyFence(fBackendContext->fDevice, fBackbuffers[i].fUsageFences[0], 0));
+            GR_VK_CALL(fBackendContext->fInterface,
+                       DestroyFence(fBackendContext->fDevice, fBackbuffers[i].fUsageFences[1], 0));
+        }
+    }
+
+    delete[] fBackbuffers;
+    fBackbuffers = nullptr;
+
+    delete[] fSurfaces;
+    fSurfaces = nullptr;
+    delete[] fImageLayouts;
+    fImageLayouts = nullptr;
+    delete[] fImages;
+    fImages = nullptr;
+}
+
+VulkanTestContext::~VulkanTestContext() {
+    this->destroyContext();
+}
+
+void VulkanTestContext::destroyContext() {
+    if (!fBackendContext.get()) {
+        return;
+    }
+
+    GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext->fDevice));
+
+    this->destroyBuffers();
+
+    if (VK_NULL_HANDLE != fCommandPool) {
+        GR_VK_CALL(fBackendContext->fInterface, DestroyCommandPool(fBackendContext->fDevice,
+                                                                   fCommandPool, nullptr));
+        fCommandPool = VK_NULL_HANDLE;
+    }
+
+    if (VK_NULL_HANDLE != fSwapchain) {
+        fDestroySwapchainKHR(fBackendContext->fDevice, fSwapchain, nullptr);
+        fSwapchain = VK_NULL_HANDLE;
+    }
+
+    if (VK_NULL_HANDLE != fSurface) {
+        fDestroySurfaceKHR(fBackendContext->fInstance, fSurface, nullptr);
+        fSurface = VK_NULL_HANDLE;
+    }
+
+    delete fContext;
+
+    fBackendContext.reset(nullptr);
+}
+
+VulkanTestContext::BackbufferInfo* VulkanTestContext::getAvailableBackbuffer() {
+    SkASSERT(fBackbuffers);
+
+    ++fCurrentBackbufferIndex;
+    if (fCurrentBackbufferIndex > fImageCount) {
+        fCurrentBackbufferIndex = 0;
+    }
+
+    BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
+
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        WaitForFences(fBackendContext->fDevice, 2, backbuffer->fUsageFences,
+                                      true, UINT64_MAX));
+    return backbuffer;
+}
+
+SkSurface* VulkanTestContext::getBackbufferSurface() {
+    BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
+    SkASSERT(backbuffer);
+
+    // reset the fence
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        ResetFences(fBackendContext->fDevice, 2, backbuffer->fUsageFences));
+    // semaphores should be in unsignaled state
+
+    // acquire the image
+    VkResult res = fAcquireNextImageKHR(fBackendContext->fDevice, fSwapchain, UINT64_MAX,
+                                        backbuffer->fAcquireSemaphore, VK_NULL_HANDLE,
+                                        &backbuffer->fImageIndex);
+    if (VK_ERROR_SURFACE_LOST_KHR == res) {
+        // need to figure out how to create a new vkSurface without the platformData*
+        // maybe use attach somehow? but need a Window
+        return nullptr;
+    }
+    if (VK_ERROR_OUT_OF_DATE_KHR == res) {
+        // tear swapchain down and try again
+        if (!this->createSwapchain(0, 0)) {
+            return nullptr;
+        }
+
+        // acquire the image
+        res = fAcquireNextImageKHR(fBackendContext->fDevice,  fSwapchain, UINT64_MAX,
+                                   backbuffer->fAcquireSemaphore, VK_NULL_HANDLE,
+                                   &backbuffer->fImageIndex);
+
+        if (VK_SUCCESS != res) {
+            return nullptr;
+        }
+    }
+
+    // set up layout transfer from initial to color attachment
+    VkImageLayout layout = fImageLayouts[backbuffer->fImageIndex];
+    VkPipelineStageFlags srcStageMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ?
+                                        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT :
+                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkAccessFlags srcAccessMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ? 
+                                  0 : VK_ACCESS_MEMORY_READ_BIT;
+    VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+    VkImageMemoryBarrier imageMemoryBarrier = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
+        NULL,                                     // pNext
+        srcAccessMask,                            // outputMask
+        dstAccessMask,                            // inputMask
+        layout,                                   // oldLayout
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
+        fPresentQueueIndex,                       // srcQueueFamilyIndex
+        fBackendContext->fGraphicsQueueIndex,     // dstQueueFamilyIndex
+        fImages[backbuffer->fImageIndex],         // image
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
+    };
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        ResetCommandBuffer(backbuffer->fTransitionCmdBuffers[0], 0));
+    VkCommandBufferBeginInfo info;
+    memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
+    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    info.flags = 0;
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        BeginCommandBuffer(backbuffer->fTransitionCmdBuffers[0], &info));
+
+    GR_VK_CALL(fBackendContext->fInterface, 
+                CmdPipelineBarrier(backbuffer->fTransitionCmdBuffers[0], 
+                                    srcStageMask, dstStageMask, 0,
+                                    0, nullptr,
+                                    0, nullptr,
+                                    1, &imageMemoryBarrier));
+
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        EndCommandBuffer(backbuffer->fTransitionCmdBuffers[0]));  
+
+    VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    // insert the layout transfer into the queue and wait on the acquire
+    VkSubmitInfo submitInfo;
+    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submitInfo.waitSemaphoreCount = 1;
+    submitInfo.pWaitSemaphores = &backbuffer->fAcquireSemaphore;
+    submitInfo.pWaitDstStageMask = &waitDstStageFlags;
+    submitInfo.commandBufferCount = 1;
+    submitInfo.pCommandBuffers = &backbuffer->fTransitionCmdBuffers[0];
+    submitInfo.signalSemaphoreCount = 0;
+    
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        QueueSubmit(fBackendContext->fQueue, 1, &submitInfo, 
+                                    backbuffer->fUsageFences[0]));
+
+    return fSurfaces[backbuffer->fImageIndex].get();
+}
+
+
+void VulkanTestContext::swapBuffers() {
+
+    BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
+
+    VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+    VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+    VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+    VkAccessFlags dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+
+    VkImageMemoryBarrier imageMemoryBarrier = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
+        NULL,                                     // pNext
+        srcAccessMask,                            // outputMask
+        dstAccessMask,                            // inputMask
+        layout,                                   // oldLayout
+        VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,          // newLayout
+        fBackendContext->fGraphicsQueueIndex,     // srcQueueFamilyIndex
+        fPresentQueueIndex,                       // dstQueueFamilyIndex
+        fImages[backbuffer->fImageIndex],         // image
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
+    };
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        ResetCommandBuffer(backbuffer->fTransitionCmdBuffers[1], 0));
+    VkCommandBufferBeginInfo info;
+    memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
+    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    info.flags = 0;
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        BeginCommandBuffer(backbuffer->fTransitionCmdBuffers[1], &info));
+    GR_VK_CALL(fBackendContext->fInterface,
+                CmdPipelineBarrier(backbuffer->fTransitionCmdBuffers[1],
+                srcStageMask, dstStageMask, 0,
+                0, nullptr,
+                0, nullptr,
+                1, &imageMemoryBarrier));
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        EndCommandBuffer(backbuffer->fTransitionCmdBuffers[1]));
+
+    fImageLayouts[backbuffer->fImageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+    // insert the layout transfer into the queue and wait on the acquire
+    VkSubmitInfo submitInfo;
+    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submitInfo.waitSemaphoreCount = 0;
+    submitInfo.pWaitDstStageMask = 0;
+    submitInfo.commandBufferCount = 1;
+    submitInfo.pCommandBuffers = &backbuffer->fTransitionCmdBuffers[1];
+    submitInfo.signalSemaphoreCount = 1;
+    submitInfo.pSignalSemaphores = &backbuffer->fRenderSemaphore;
+
+    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
+                        QueueSubmit(fBackendContext->fQueue, 1, &submitInfo, 
+                                    backbuffer->fUsageFences[1]));
+
+    // Submit present operation to present queue
+    const VkPresentInfoKHR presentInfo =
+    {
+        VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
+        NULL, // pNext
+        1, // waitSemaphoreCount
+        &backbuffer->fRenderSemaphore, // pWaitSemaphores
+        1, // swapchainCount
+        &fSwapchain, // pSwapchains
+        &backbuffer->fImageIndex, // pImageIndices
+        NULL // pResults
+    };
+
+    fQueuePresentKHR(fPresentQueue, &presentInfo);
+
+}
diff --git a/tools/viewer/VulkanTestContext.h b/tools/viewer/VulkanTestContext.h
new file mode 100644 (file)
index 0000000..60b3b80
--- /dev/null
@@ -0,0 +1,114 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef VulkanTestContext_DEFINED
+#define VulkanTestContext_DEFINED
+
+#ifdef SK_VULKAN
+
+#include "GrTypes.h"
+#include "vk/GrVkBackendContext.h"
+
+class SkSurface;
+class GrContext;
+
+class VulkanTestContext {
+public:
+    ~VulkanTestContext();
+
+    // each platform will have to implement these in its CPP file
+    static VkSurfaceKHR createVkSurface(VkInstance, void* platformData);
+    static bool canPresent(VkInstance, VkPhysicalDevice, uint32_t queueFamilyIndex);
+
+    static VulkanTestContext* Create(void* platformData, int msaaSampleCount) {
+        VulkanTestContext* ctx = new VulkanTestContext(platformData, msaaSampleCount);
+        if (!ctx->isValid()) {
+            delete ctx;
+            return nullptr;
+        }
+        return ctx;
+    }
+
+    SkSurface* getBackbufferSurface();
+    void swapBuffers();
+
+    bool makeCurrent() { return true; }
+
+    bool isValid() { return SkToBool(fBackendContext.get()); }
+
+    void resize(uint32_t w, uint32_t h) {
+        this->createSwapchain(w, h); 
+    }
+
+    GrBackendContext getBackendContext() { return (GrBackendContext)fBackendContext.get(); }
+
+private:
+    VulkanTestContext();
+    VulkanTestContext(void*, int msaaSampleCount);
+    void initializeContext(void*);
+    void destroyContext();
+
+    struct BackbufferInfo {
+        uint32_t        fImageIndex;          // image this is associated with
+        VkSemaphore     fAcquireSemaphore;    // we signal on this for acquisition of image
+        VkSemaphore     fRenderSemaphore;     // we wait on this for rendering to be done
+        VkCommandBuffer fTransitionCmdBuffers[2]; // to transition layout between present and render
+        VkFence         fUsageFences[2];      // used to ensure this data is no longer used on GPU
+    };
+
+    BackbufferInfo* getAvailableBackbuffer();
+    bool createSwapchain(uint32_t width, uint32_t height);
+    void createBuffers(VkFormat format);
+    void destroyBuffers();
+
+    SkAutoTUnref<const GrVkBackendContext> fBackendContext;
+
+    // simple wrapper class that exists only to initialize a pointer to NULL
+    template <typename FNPTR_TYPE> class VkPtr {
+    public:
+        VkPtr() : fPtr(NULL) {}
+        VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; }
+        operator FNPTR_TYPE() const { return fPtr; }
+    private:
+        FNPTR_TYPE fPtr;
+    };
+    
+    // WSI interface functions
+    VkPtr<PFN_vkDestroySurfaceKHR> fDestroySurfaceKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> fGetPhysicalDeviceSurfaceSupportKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> fGetPhysicalDeviceSurfaceCapabilitiesKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> fGetPhysicalDeviceSurfaceFormatsKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> fGetPhysicalDeviceSurfacePresentModesKHR;
+
+    VkPtr<PFN_vkCreateSwapchainKHR> fCreateSwapchainKHR;
+    VkPtr<PFN_vkDestroySwapchainKHR> fDestroySwapchainKHR;
+    VkPtr<PFN_vkGetSwapchainImagesKHR> fGetSwapchainImagesKHR;
+    VkPtr<PFN_vkAcquireNextImageKHR> fAcquireNextImageKHR;
+    VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
+    VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
+
+    GrContext*        fContext;
+    VkSurfaceKHR      fSurface;
+    VkSwapchainKHR    fSwapchain;
+    uint32_t          fPresentQueueIndex;
+    VkQueue           fPresentQueue;
+    int               fWidth;
+    int               fHeight;
+    GrPixelConfig     fPixelConfig;
+
+    uint32_t          fImageCount;
+    VkImage*          fImages;         // images in the swapchain
+    VkImageLayout*    fImageLayouts;   // layouts of these images when not color attachment
+    sk_sp<SkSurface>* fSurfaces;       // wrapped surface for those images
+    VkCommandPool     fCommandPool;
+    BackbufferInfo*   fBackbuffers;
+    uint32_t          fCurrentBackbufferIndex;
+};
+
+#endif // SK_VULKAN
+
+#endif
diff --git a/tools/viewer/Window.cpp b/tools/viewer/Window.cpp
new file mode 100644 (file)
index 0000000..6a83a3b
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "Window.h"
+
+#include "SkSurface.h"
+#include "SkCanvas.h"
+#include "VulkanTestContext.h"
+
+namespace sk_app {
+
+static bool default_char_func(SkUnichar c, uint32_t modifiers, void* userData) {
+    return false;
+}
+
+static bool default_key_func(Window::Key key, Window::InputState state, uint32_t modifiers, 
+                             void* userData) {
+    return false;
+}
+
+static bool default_mouse_func(int x, int y, Window::InputState state, uint32_t modifiers, 
+                               void* userData) {
+    return false;
+}
+
+static void default_paint_func(SkCanvas*, void* userData) {}
+
+Window::Window() : fCharFunc(default_char_func)
+                 , fKeyFunc(default_key_func)
+                 , fMouseFunc(default_mouse_func)
+                 , fPaintFunc(default_paint_func) {
+}
+
+void Window::detach() {
+    delete fTestContext;
+    fTestContext = nullptr;
+}
+
+bool Window::onChar(SkUnichar c, uint32_t modifiers) {
+    return fCharFunc(c, modifiers, fCharUserData);
+}
+
+bool Window::onKey(Key key, InputState state, uint32_t modifiers) {
+    return fKeyFunc(key, state, modifiers, fKeyUserData);
+}
+
+bool Window::onMouse(int x, int y, InputState state, uint32_t modifiers) {
+    return fMouseFunc(x, y, state, modifiers, fMouseUserData);
+}
+
+void Window::onPaint() {
+    SkSurface* backbuffer = fTestContext->getBackbufferSurface();
+    if (backbuffer) {
+        // draw into the canvas of this surface
+        SkCanvas* canvas = backbuffer->getCanvas();
+
+        fPaintFunc(canvas, fPaintUserData);
+
+        canvas->flush();
+
+        fTestContext->swapBuffers();
+    } else {
+        // try recreating testcontext
+    }
+
+}
+
+void Window::onResize(uint32_t w, uint32_t h) {
+    fWidth = w;
+    fHeight = h;
+    fTestContext->resize(w, h);
+}
+
+}   // namespace sk_app
diff --git a/tools/viewer/Window.h b/tools/viewer/Window.h
new file mode 100644 (file)
index 0000000..913d2da
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Window_DEFINED
+#define Window_DEFINED
+
+#include "SkTypes.h"
+#include "SkRect.h"
+
+class SkCanvas;
+class VulkanTestContext;
+
+namespace sk_app {
+
+class Window {
+public:
+    static Window* CreateNativeWindow(void* platformData);
+
+    virtual ~Window() {};
+
+    virtual void setTitle(const char*) = 0;
+    virtual void show() = 0;
+    virtual void inval() = 0;
+
+    virtual bool scaleContentToFit() const { return false; }
+    virtual bool supportsContentRect() const { return false; }
+    virtual SkRect getContentRect() { return SkRect::MakeEmpty(); }
+
+    enum BackEndType {
+        kNativeGL_BackendType,
+        kVulkan_BackendType
+    };
+
+    virtual bool attach(BackEndType attachType, int msaaSampleCount) = 0;
+    void detach();
+
+    // input handling
+    enum Key {
+        kNONE_Key,    //corresponds to android's UNKNOWN
+
+        kLeftSoftKey_Key,
+        kRightSoftKey_Key,
+
+        kHome_Key,    //!< the home key - added to match android
+        kBack_Key,    //!< (CLR)
+        kSend_Key,    //!< the green (talk) key
+        kEnd_Key,     //!< the red key
+
+        k0_Key,
+        k1_Key,
+        k2_Key,
+        k3_Key,
+        k4_Key,
+        k5_Key,
+        k6_Key,
+        k7_Key,
+        k8_Key,
+        k9_Key,
+        kStar_Key,    //!< the * key
+        kHash_Key,    //!< the # key
+
+        kUp_Key,
+        kDown_Key,
+        kLeft_Key,
+        kRight_Key,
+
+        kOK_Key,      //!< the center key
+
+        kVolUp_Key,   //!< volume up    - match android
+        kVolDown_Key, //!< volume down  - same
+        kPower_Key,   //!< power button - same
+        kCamera_Key,  //!< camera       - same
+
+        kLast_Key = kCamera_Key
+    };
+    static const int kKeyCount = kLast_Key + 1;
+
+    enum ModifierKeys {
+        kShift_ModifierKey = 1 << 0,
+        kControl_ModifierKey = 1 << 1,
+        kOption_ModifierKey = 1 << 2,   // same as ALT
+        kCommand_ModifierKey = 1 << 3,
+        kFirstPress_ModifierKey = 1 << 4,
+    };
+
+    enum InputState {
+        kDown_InputState,
+        kUp_InputState,
+        kMove_InputState   // only valid for mouse
+    };
+
+    // return value of 'true' means 'I have handled this event'
+    typedef bool(*OnCharFunc)(SkUnichar c, uint32_t modifiers, void* userData);
+    typedef bool(*OnKeyFunc)(Key key, InputState state, uint32_t modifiers, void* userData);
+    typedef bool(*OnMouseFunc)(int x, int y, InputState state, uint32_t modifiers, void* userData);
+    typedef void(*OnPaintFunc)(SkCanvas*, void* userData);
+
+    void registerCharFunc(OnCharFunc func, void* userData) {
+        fCharFunc = func;
+        fCharUserData = userData;
+    }
+
+    void registerKeyFunc(OnKeyFunc func, void* userData) {
+        fKeyFunc = func;
+        fKeyUserData = userData;
+    }
+
+    void registerMouseFunc(OnMouseFunc func, void* userData) {
+        fMouseFunc = func;
+        fMouseUserData = userData;
+    }
+
+    void registerPaintFunc(OnPaintFunc func, void* userData) {
+        fPaintFunc = func;
+        fPaintUserData = userData;
+    }
+
+    bool onChar(SkUnichar c, uint32_t modifiers);
+    bool onKey(Key key, InputState state, uint32_t modifiers);
+    bool onMouse(int x, int y, InputState state, uint32_t modifiers);
+    void onPaint();
+    void onResize(uint32_t width, uint32_t height);
+
+    uint32_t width() { return fWidth; }
+    uint32_t height() { return fHeight;  }
+
+protected:
+    Window();
+
+    uint32_t     fWidth;
+    uint32_t     fHeight;
+
+    OnCharFunc   fCharFunc;
+    void*        fCharUserData;
+    OnKeyFunc    fKeyFunc;
+    void*        fKeyUserData;
+    OnMouseFunc  fMouseFunc;
+    void*        fMouseUserData;
+    OnPaintFunc  fPaintFunc;
+    void*        fPaintUserData;
+
+    VulkanTestContext* fTestContext;
+};
+
+}   // namespace sk_app
+#endif
diff --git a/tools/viewer/android/VulkanTestContext_android.cpp b/tools/viewer/android/VulkanTestContext_android.cpp
new file mode 100644 (file)
index 0000000..58dbcb2
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "VulkanTestContext_android.h"
+
+#include "vk/GrVkInterface.h"
+#include "vk/GrVkUtil.h"
+
+VkSurfaceKHR VulkanTestContext::createVkSurface(VkInstance instance, void* platformData) {
+    static PFN_vkCreateAndroidSurfaceKHR createAndroidSurfaceKHR = nullptr;
+    if (!createAndroidSurfaceKHR) {
+        createAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(instance,
+                                                                       "vkCreateAndroidSurfaceKHR");
+    }
+
+    if (!platformData) {
+        return VK_NULL_HANDLE;
+    }
+    ContextPlatformData_android* androidPlatformData =
+                                           reinterpret_cast<ContextPlatformData_android*>(platformData);
+    VkSurfaceKHR surface;
+
+    VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
+    memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
+    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+    surfaceCreateInfo.pNext = nullptr;
+    surfaceCreateInfo.flags = 0;
+    surfaceCreateInfo.window = androidPlatformData->fNativeWindow;
+
+    VkResult res = createAndroidSurfaceKHR(instance, &surfaceCreateInfo,
+                                           nullptr, &surface);
+    return (VK_SUCCESS == res) ? surface : VK_NULL_HANDLE;
+}
+
+bool VulkanTestContext::canPresent(VkInstance instance, VkPhysicalDevice physDev,
+                                   uint32_t queueFamilyIndex) {
+    return true;
+}
diff --git a/tools/viewer/android/VulkanTestContext_android.h b/tools/viewer/android/VulkanTestContext_android.h
new file mode 100644 (file)
index 0000000..66ed35c
--- /dev/null
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef VULKANTESTCONTEXT_ANDROID_DEFINED
+#define VULKANTESTCONTEXT_ANDROID_DEFINED
+
+#ifdef SK_VULKAN
+
+#include "../VulkanTestContext.h"
+
+struct ANativeWindow;
+
+struct ContextPlatformData_android {
+    ANativeWindow* fNativeWindow;
+};
+
+#endif // SK_VULKAN
+
+#endif
diff --git a/tools/viewer/android/Window_android.cpp b/tools/viewer/android/Window_android.cpp
new file mode 100644 (file)
index 0000000..ebccb8b
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "Window_android.h"
+
+#include "VulkanTestContext_android.h"
+
+namespace sk_app {
+
+Window* Window::CreateNativeWindow(void* platformData) {
+    Window_android* window = new Window_android();
+    if (!window->init((android_app*)platformData)) {
+        delete window;
+        return nullptr;
+    }
+    return window;
+}
+
+static void handle_cmd(struct android_app* app, int32_t cmd);
+static int32_t handle_input(struct android_app* app, AInputEvent* event);
+
+bool Window_android::init(android_app* app) {
+    SkASSERT(app);
+    mApp = app;
+    mApp->userData = this;
+    mApp->onAppCmd = handle_cmd;
+    mApp->onInputEvent = handle_input;
+    return true;
+}
+
+void Window_android::setTitle(const char* title) {
+    //todo
+    SkDebugf("Title: %s", title);
+}
+
+bool Window_android::attach(BackEndType attachType, int msaaSampleCount) {
+    if (kVulkan_BackendType != attachType) {
+        return false;
+    }
+
+    mSampleCount = msaaSampleCount;
+
+    // We delay the creation of fTestContext until Android informs us that
+    // the native window is ready to use.
+    return true;
+}
+
+void Window_android::initDisplay(ANativeWindow* window) {
+    SkASSERT(window);
+    ContextPlatformData_android platformData;
+    platformData.fNativeWindow = window;
+    fTestContext = VulkanTestContext::Create((void*)&platformData, mSampleCount);
+}
+
+static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
+    if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
+        SkDebugf("Failure writing android_app cmd: %s\n", strerror(errno));
+    }
+}
+
+void Window_android::inval() {
+    android_app_write_cmd(mApp, APP_CMD_INVAL_WINDOW);
+}
+
+void Window_android::paintIfNeeded() {
+    if (mApp->window || !mContentRect.isEmpty()) {
+        this->onPaint();
+    }
+}
+
+/**
+ * Process the next main command.
+ */
+static void handle_cmd(struct android_app* app, int32_t cmd) {
+    Window_android* window = (Window_android*)app->userData;
+    switch (cmd) {
+        case APP_CMD_INIT_WINDOW:
+            // The window is being shown, get it ready.
+            SkASSERT(app->window);
+            window->initDisplay(app->window);
+            window->paintIfNeeded();
+            break;
+        case APP_CMD_WINDOW_RESIZED: {
+            int width = ANativeWindow_getWidth(app->window);
+            int height = ANativeWindow_getHeight(app->window);
+            window->onResize(width, height);
+            break;
+        }
+        case APP_CMD_CONTENT_RECT_CHANGED:
+            window->setContentRect(app->contentRect.left, app->contentRect.top,
+                                   app->contentRect.right, app->contentRect.bottom);
+            window->paintIfNeeded();
+            break;
+        case APP_CMD_TERM_WINDOW:
+            // The window is being hidden or closed, clean it up.
+            window->detach();
+            break;
+        case APP_CMD_INVAL_WINDOW:
+            window->paintIfNeeded();
+            break;
+    }
+}
+
+static Window::Key get_key(int32_t keycode) {
+    static const struct {
+        int32_t     fAndroidKey;
+        Window::Key fWindowKey;
+    } gPair[] = {
+        { AKEYCODE_BACK, Window::kBack_Key },
+        { AKEYCODE_VOLUME_UP, Window::kLeft_Key },
+        { AKEYCODE_VOLUME_DOWN, Window::kRight_Key }
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
+        if (gPair[i].fAndroidKey == keycode) {
+            return gPair[i].fWindowKey;
+        }
+    }
+    return Window::kNONE_Key;
+}
+
+static Window::InputState get_action(int32_t action) {
+    static const struct {
+        int32_t            fAndroidAction;
+        Window::InputState fInputState;
+    } gPair[] = {
+        { AKEY_STATE_DOWN, Window::kDown_InputState },
+        { AKEY_STATE_UP, Window::kUp_InputState },
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
+        if (gPair[i].fAndroidAction == action) {
+            return gPair[i].fInputState;
+        }
+    }
+    return Window::kMove_InputState;
+}
+
+static int32_t get_key_modifiers(AInputEvent* event) {
+    static const struct {
+        int32_t fAndroidState;
+        int32_t fWindowModifier;
+    } gPair[] = {
+        { AMETA_SHIFT_ON, Window::kShift_ModifierKey },
+        { AMETA_CTRL_ON, Window::kControl_ModifierKey },
+    };
+
+    int32_t metaState = AKeyEvent_getMetaState(event);
+    int32_t modifiers = 0;
+
+    if (AKeyEvent_getRepeatCount(event) == 0) {
+        modifiers |= Window::kFirstPress_ModifierKey;
+    }
+
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
+        if (gPair[i].fAndroidState == metaState) {
+            modifiers |= gPair[i].fWindowModifier;
+        }
+    }
+    return modifiers;
+}
+
+/**
+ * Process the next input event.
+ */
+static int32_t handle_input(struct android_app* app, AInputEvent* event) {
+    Window_android* window = (Window_android*)app->userData;
+    switch(AInputEvent_getType(event)) {
+        case AINPUT_EVENT_TYPE_MOTION:
+            break;
+        case AINPUT_EVENT_TYPE_KEY:
+            Window::Key key = get_key(AKeyEvent_getKeyCode(event));
+            Window::InputState state = get_action(AKeyEvent_getAction(event));
+            int32_t mod = get_key_modifiers(event);
+            window->onKey(key, state, mod);
+            return true; // eat all key events
+    }
+    return 0;
+}
+
+}   // namespace sk_app
diff --git a/tools/viewer/android/Window_android.h b/tools/viewer/android/Window_android.h
new file mode 100644 (file)
index 0000000..6099f89
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Window_android_DEFINED
+#define Window_android_DEFINED
+
+#include "../Window.h"
+#include <android_native_app_glue.h>
+
+namespace sk_app {
+
+enum {
+    /**
+     * Leave plenty of space between this item and the ones defined in the glue layer
+     */
+       APP_CMD_INVAL_WINDOW = 64,
+};
+
+class Window_android : public Window {
+public:
+       Window_android() : Window() {}
+    ~Window_android() override {}
+
+    bool init(android_app* app_state);
+    void initDisplay(ANativeWindow* window);
+
+    void setTitle(const char*) override;
+    void show() override {}
+
+    bool attach(BackEndType attachType, int msaaSampleCount) override;
+    void inval() override;
+
+    void paintIfNeeded();
+
+    bool scaleContentToFit() const override { return true; }
+    bool supportsContentRect() const override { return true; }
+    SkRect getContentRect() override { return mContentRect; }
+    void setContentRect(int l, int t, int r, int b) { mContentRect.set(l,t,r,b); }
+
+private:
+    android_app* mApp = nullptr;
+    SkRect mContentRect;
+    int mSampleCount = 0;
+};
+
+}   // namespace sk_app
+
+#endif
diff --git a/tools/viewer/android/main_android.cpp b/tools/viewer/android/main_android.cpp
new file mode 100644 (file)
index 0000000..9334f0c
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include <jni.h>
+#include <errno.h>
+
+#include <android_native_app_glue.h>
+
+#include "../Application.h"
+#include "Timer.h"
+
+static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
+
+using sk_app::Application;
+
+/**
+ * This is the main entry point of a native application that is using
+ * android_native_app_glue.  It runs in its own thread, with its own
+ * event loop for receiving input events and doing other things.
+ */
+void android_main(struct android_app* state) {
+    // Make sure glue isn't stripped.
+    app_dummy();
+
+    static const char* gCmdLine[] = {
+        "viewer",
+        "--skps",
+        "/data/local/tmp/skp",
+    };
+
+    std::unique_ptr<Application> vkApp(Application::Create(SK_ARRAY_COUNT(gCmdLine),
+                                                           const_cast<char**>(gCmdLine),
+                                                           state));
+
+    double currentTime = 0.0;
+    double previousTime = 0.0;
+
+    // loop waiting for stuff to do.
+    while (1) {
+        // Read all pending events.
+        int ident;
+        int events;
+        struct android_poll_source* source;
+
+        // block forever waiting for events.
+        while ((ident=ALooper_pollAll(-1, NULL, &events,
+                (void**)&source)) >= 0) {
+
+            // Process this event.
+            if (source != NULL) {
+                source->process(state, source);
+            }
+
+            // Check if we are exiting.
+            if (state->destroyRequested != 0) {
+                return;
+            }
+
+            previousTime = currentTime;
+            currentTime = now_ms();
+            vkApp->onIdle(currentTime - previousTime);
+        }
+    }
+}
+//END_INCLUDE(all)
diff --git a/tools/viewer/viewer/GMSlide.cpp b/tools/viewer/viewer/GMSlide.cpp
new file mode 100644 (file)
index 0000000..6096044
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+/*
+* Copyright 2014 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "GMSlide.h"
+#include "SkCanvas.h"
+
+GMSlide::GMSlide(skiagm::GM* gm) : fGM(gm) {
+    fName.printf("GM_%s", gm->getName());
+}
+
+GMSlide::~GMSlide() { delete fGM; }
+
+void GMSlide::draw(SkCanvas* canvas) {
+    // Do we care about timing the draw of the background (once)?
+    // Does the GM ever rely on drawBackground to lazily compute something?
+    fGM->drawBackground(canvas);
+    fGM->drawContent(canvas);
+}
+
+bool GMSlide::animate(const SkAnimTimer& timer) {
+    return fGM->animate(timer);
+}
diff --git a/tools/viewer/viewer/GMSlide.h b/tools/viewer/viewer/GMSlide.h
new file mode 100644 (file)
index 0000000..6b03527
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef GMSlide_DEFINED
+#define GMSlide_DEFINED
+
+#include "Slide.h"
+#include "gm.h"
+
+class GMSlide : public Slide {
+public:
+    GMSlide(skiagm::GM* gm);
+    ~GMSlide() override;
+
+    SkISize getDimensions() const override { return fGM->getISize(); }
+
+    void draw(SkCanvas* canvas) override;
+    bool animate(const SkAnimTimer&) override;
+
+private:
+    skiagm::GM* fGM;
+};
+
+
+#endif
diff --git a/tools/viewer/viewer/SKPSlide.cpp b/tools/viewer/viewer/SKPSlide.cpp
new file mode 100644 (file)
index 0000000..6a9899b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "SKPSlide.h"
+
+#include "SkCanvas.h"
+#include "SkCommonFlags.h"
+#include "SkOSFile.h"
+#include "SkStream.h"
+
+SKPSlide::SKPSlide(const SkString& name, const SkString& path) : fPath(path) {
+    fName = name;
+}
+
+SKPSlide::~SKPSlide() {}
+
+void SKPSlide::draw(SkCanvas* canvas) {
+    if (fPic.get()) {
+        bool isOffset = SkToBool(fCullRect.left() | fCullRect.top());
+        if (isOffset) {
+            canvas->save();
+            canvas->translate(SkIntToScalar(-fCullRect.left()), SkIntToScalar(-fCullRect.top()));
+        }
+
+        canvas->drawPicture(fPic.get());
+
+        if (isOffset) {
+            canvas->restore();
+        }
+    }
+}
+
+static sk_sp<SkPicture> read_picture(const char path[]) {
+    SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
+    if (stream.get() == nullptr) {
+        SkDebugf("Could not read %s.\n", path);
+        return nullptr;
+    }
+
+    auto pic = SkPicture::MakeFromStream(stream.get());
+    if (!pic) {
+        SkDebugf("Could not read %s as an SkPicture.\n", path);
+    }
+    return pic;
+}
+
+void SKPSlide::load() {
+    fPic = read_picture(fPath.c_str());
+    fCullRect = fPic->cullRect().roundOut();
+}
+
+void SKPSlide::unload() {
+    fPic.reset(nullptr);
+}
diff --git a/tools/viewer/viewer/SKPSlide.h b/tools/viewer/viewer/SKPSlide.h
new file mode 100644 (file)
index 0000000..42845fa
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef SKPSlide_DEFINED
+#define SKPSlide_DEFINED
+
+#include "Slide.h"
+#include "SkPicture.h"
+
+class SKPSlide : public Slide {
+public:
+    SKPSlide(const SkString& name, const SkString& path);
+    ~SKPSlide() override;
+
+    SkISize getDimensions() const override { return fCullRect.size(); }
+
+    void draw(SkCanvas* canvas) override;
+    void load() override;
+    void unload() override;
+
+private:
+    SkString               fPath;
+    sk_sp<const SkPicture> fPic;
+    SkIRect                fCullRect;
+};
+
+#endif
diff --git a/tools/viewer/viewer/Slide.h b/tools/viewer/viewer/Slide.h
new file mode 100644 (file)
index 0000000..cdc225b
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Slide_DEFINED
+#define Slide_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkSize.h"
+#include "SkString.h"
+
+class SkCanvas;
+class SkAnimTimer;
+
+class Slide : public SkRefCnt {
+public:
+    virtual ~Slide() {}
+
+    virtual SkISize getDimensions() const = 0;
+
+    virtual void draw(SkCanvas* canvas) = 0;
+    virtual bool animate(const SkAnimTimer&) { return false;  }
+    virtual void load() {}
+    virtual void unload() {}
+
+    SkString getName() { return fName; }
+
+protected:
+    SkString    fName;
+};
+
+
+#endif
diff --git a/tools/viewer/viewer/Viewer.cpp b/tools/viewer/viewer/Viewer.cpp
new file mode 100644 (file)
index 0000000..ededc1f
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "Viewer.h"
+
+#include "GMSlide.h"
+#include "SKPSlide.h"
+
+#include "SkCanvas.h"
+#include "SkCommonFlags.h"
+#include "SkOSFile.h"
+#include "SkRandom.h"
+#include "SkStream.h"
+
+using namespace sk_app;
+
+Application* Application::Create(int argc, char** argv, void* platformData) {
+    return new Viewer(argc, argv, platformData);
+}
+
+static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t modifiers,
+                           void* userData) {
+    Viewer* vv = reinterpret_cast<Viewer*>(userData);
+
+    return vv->onKey(key, state, modifiers);
+}
+
+static bool on_char_handler(SkUnichar c, uint32_t modifiers, void* userData) {
+    Viewer* vv = reinterpret_cast<Viewer*>(userData);
+
+    return vv->onChar(c, modifiers);
+}
+
+static void on_paint_handler(SkCanvas* canvas, void* userData) {
+    Viewer* vv = reinterpret_cast<Viewer*>(userData);
+
+    return vv->onPaint(canvas);
+}
+
+DEFINE_bool2(fullscreen, f, true, "Run fullscreen.");
+DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON identifying this builder.");
+DEFINE_string2(match, m, nullptr,
+               "[~][^]substring[$] [...] of bench name to run.\n"
+               "Multiple matches may be separated by spaces.\n"
+               "~ causes a matching bench to always be skipped\n"
+               "^ requires the start of the bench to match\n"
+               "$ requires the end of the bench to match\n"
+               "^ and $ requires an exact match\n"
+               "If a bench does not match any list entry,\n"
+               "it is skipped unless some list entry starts with ~");
+DEFINE_string(skps, "skps", "Directory to read skps from.");
+
+Viewer::Viewer(int argc, char** argv, void* platformData)
+    : fCurrentMeasurement(0)
+    , fDisplayStats(false)
+    , fZoomCenterX(0.0f)
+    , fZoomCenterY(0.0f)
+    , fZoomLevel(0.0f)
+    , fZoomScale(SK_Scalar1)
+{
+    memset(fMeasurements, 0, sizeof(fMeasurements));
+
+    SkDebugf("Command line arguments: ");
+    for (int i = 1; i < argc; ++i) {
+        SkDebugf("%s ", argv[i]);
+    }
+    SkDebugf("\n");
+
+    SkCommandLineFlags::Parse(argc, argv);
+
+    fWindow = Window::CreateNativeWindow(platformData);
+    fWindow->attach(Window::kVulkan_BackendType, 0);
+
+    // register callbacks
+    fWindow->registerKeyFunc(on_key_handler, this);
+    fWindow->registerCharFunc(on_char_handler, this);
+    fWindow->registerPaintFunc(on_paint_handler, this);
+
+    // set up slides
+    this->initSlides();
+
+    fAnimTimer.run();
+
+    // set up first frame
+    fCurrentSlide = 0;
+    setupCurrentSlide(-1);
+    updateMatrix();
+
+    fWindow->show();
+}
+
+void Viewer::initSlides() {
+    const skiagm::GMRegistry* gms(skiagm::GMRegistry::Head());
+    while (gms) {
+        SkAutoTDelete<skiagm::GM> gm(gms->factory()(nullptr));
+
+        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gm->getName())) {
+            sk_sp<Slide> slide(new GMSlide(gm.release()));
+            fSlides.push_back(slide);
+        }
+
+        gms = gms->next();
+    }
+
+    // reverse array
+    for (int i = 0; i < fSlides.count()/2; ++i) {
+        sk_sp<Slide> temp = fSlides[i];
+        fSlides[i] = fSlides[fSlides.count() - i - 1];
+        fSlides[fSlides.count() - i - 1] = temp;
+    }
+
+    // SKPs
+    for (int i = 0; i < FLAGS_skps.count(); i++) {
+        if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
+            if (SkCommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) {
+                continue;
+            }
+
+            SkString path(FLAGS_skps[i]);
+            sk_sp<SKPSlide> slide(new SKPSlide(SkOSPath::Basename(path.c_str()), path));
+            if (slide) {
+                fSlides.push_back(slide);
+            }
+        } else {
+            SkOSFile::Iter it(FLAGS_skps[i], ".skp");
+            SkString skpName;
+            while (it.next(&skpName)) {
+                if (SkCommandLineFlags::ShouldSkip(FLAGS_match, skpName.c_str())) {
+                    continue;
+                }
+
+                SkString path = SkOSPath::Join(FLAGS_skps[i], skpName.c_str());
+                sk_sp<SKPSlide> slide(new SKPSlide(skpName, path));
+                if (slide) {
+                    fSlides.push_back(slide);
+                }
+            }
+        }
+    }
+}
+
+
+Viewer::~Viewer() {
+    fWindow->detach();
+    delete fWindow;
+}
+
+void Viewer::setupCurrentSlide(int previousSlide) {
+    SkString title("Viewer: ");
+    title.append(fSlides[fCurrentSlide]->getName());
+    fSlides[fCurrentSlide]->load();
+    if (previousSlide >= 0) {
+        fSlides[previousSlide]->unload();
+    }
+    fWindow->setTitle(title.c_str());
+    fWindow->inval();
+}
+
+#define MAX_ZOOM_LEVEL  8
+#define MIN_ZOOM_LEVEL  -8
+
+void Viewer::changeZoomLevel(float delta) {
+    fZoomLevel += delta;
+    if (fZoomLevel > 0) {
+        fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL);
+        fZoomScale = fZoomLevel + SK_Scalar1;
+    } else if (fZoomLevel < 0) {
+        fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL);
+        fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel);
+    } else {
+        fZoomScale = SK_Scalar1;
+    }
+    this->updateMatrix();
+}
+
+void Viewer::updateMatrix(){
+    SkMatrix m;
+    m.reset();
+
+    if (fZoomLevel) {
+        SkPoint center;
+        //m = this->getLocalMatrix();//.invert(&m);
+        m.mapXY(fZoomCenterX, fZoomCenterY, &center);
+        SkScalar cx = center.fX;
+        SkScalar cy = center.fY;
+
+        m.setTranslate(-cx, -cy);
+        m.postScale(fZoomScale, fZoomScale);
+        m.postTranslate(cx, cy);
+    }
+
+    // TODO: add gesture support
+    // Apply any gesture matrix
+    //m.preConcat(fGesture.localM());
+    //m.preConcat(fGesture.globalM());
+
+    fLocalMatrix = m;
+}
+
+bool Viewer::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) {
+    if (Window::kDown_InputState == state) {
+        switch (key) {
+            case Window::kRight_Key: {
+                int previousSlide = fCurrentSlide;
+                fCurrentSlide++;
+                if (fCurrentSlide >= fSlides.count()) {
+                    fCurrentSlide = 0;
+                }
+                setupCurrentSlide(previousSlide);
+                return true;
+            }
+
+            case Window::kLeft_Key: {
+                int previousSlide = fCurrentSlide;
+                fCurrentSlide--;
+                if (fCurrentSlide < 0) {
+                    fCurrentSlide = fSlides.count() - 1;
+                }
+                SkString title("Viewer: ");
+                title.append(fSlides[fCurrentSlide]->getName());
+                fWindow->setTitle(title.c_str());
+                setupCurrentSlide(previousSlide);
+                return true;
+            }
+
+            case Window::kUp_Key: {
+                this->changeZoomLevel(1.f / 32.f);
+                fWindow->inval();
+                return true;
+            }
+
+            case Window::kDown_Key: {
+                this->changeZoomLevel(-1.f / 32.f);
+                fWindow->inval();
+                return true;
+            }
+
+            default:
+                break;
+        }
+    }
+
+    return false;
+}
+
+bool Viewer::onChar(SkUnichar c, uint32_t modifiers) {
+    if ('s' == c) {
+        fDisplayStats = !fDisplayStats;
+        return true;
+    }
+
+    return false;
+}
+
+void Viewer::onPaint(SkCanvas* canvas) {
+
+    int count = canvas->save();
+
+    if (fWindow->supportsContentRect()) {
+        SkRect contentRect = fWindow->getContentRect();
+        canvas->clipRect(contentRect);
+        canvas->translate(contentRect.fLeft, contentRect.fTop);
+    }
+
+    canvas->clear(SK_ColorWHITE);
+    if (fWindow->supportsContentRect() && fWindow->scaleContentToFit()) {
+        const SkRect contentRect = fWindow->getContentRect();
+        const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
+        const SkRect slideBounds = SkRect::MakeIWH(slideSize.width(), slideSize.height());
+        SkMatrix matrix;
+        matrix.setRectToRect(slideBounds, contentRect, SkMatrix::kCenter_ScaleToFit);
+        canvas->concat(matrix);
+    }
+    canvas->concat(fLocalMatrix);
+
+    fSlides[fCurrentSlide]->draw(canvas);
+    canvas->restoreToCount(count);
+
+    if (fDisplayStats) {
+        drawStats(canvas);
+    }
+}
+
+void Viewer::drawStats(SkCanvas* canvas) {
+    static const float kPixelPerMS = 2.0f;
+    static const int kDisplayWidth = 130;
+    static const int kDisplayHeight = 100;
+    static const int kDisplayPadding = 10;
+    static const int kGraphPadding = 3;
+    static const SkScalar kBaseMS = 1000.f / 60.f;  // ms/frame to hit 60 fps
+
+    SkISize canvasSize = canvas->getDeviceSize();
+    SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth-kDisplayWidth-kDisplayPadding),
+                                   SkIntToScalar(kDisplayPadding),
+                                   SkIntToScalar(kDisplayWidth), SkIntToScalar(kDisplayHeight));
+    SkPaint paint;
+    canvas->save();
+
+    if (fWindow->supportsContentRect()) {
+        SkRect contentRect = fWindow->getContentRect();
+        canvas->clipRect(contentRect);
+        canvas->translate(contentRect.fLeft, contentRect.fTop);
+    }
+
+    canvas->clipRect(rect);
+    paint.setColor(SK_ColorBLACK);
+    canvas->drawRect(rect, paint);
+    // draw the 16ms line
+    paint.setColor(SK_ColorLTGRAY);
+    canvas->drawLine(rect.fLeft, rect.fBottom - kBaseMS*kPixelPerMS,
+                     rect.fRight, rect.fBottom - kBaseMS*kPixelPerMS, paint);
+    paint.setColor(SK_ColorRED);
+    paint.setStyle(SkPaint::kStroke_Style);
+    canvas->drawRect(rect, paint);
+
+    int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding;
+    const int xStep = 2;
+    const int startY = SkScalarTruncToInt(rect.fBottom);
+    int i = fCurrentMeasurement;
+    do {
+        int endY = startY - (int)(fMeasurements[i] * kPixelPerMS + 0.5);  // round to nearest value
+        canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
+                         SkIntToScalar(x), SkIntToScalar(endY), paint);
+        i++;
+        i &= (kMeasurementCount - 1);  // fast mod
+        x += xStep;
+    } while (i != fCurrentMeasurement);
+
+    canvas->restore();
+}
+
+void Viewer::onIdle(double ms) {
+    // Record measurements
+    fMeasurements[fCurrentMeasurement++] = ms;
+    fCurrentMeasurement &= (kMeasurementCount - 1);  // fast mod
+    SkASSERT(fCurrentMeasurement < kMeasurementCount);
+
+    fAnimTimer.updateTime();
+    if (fSlides[fCurrentSlide]->animate(fAnimTimer) || fDisplayStats) {
+        fWindow->inval();
+    }
+}
diff --git a/tools/viewer/viewer/Viewer.h b/tools/viewer/viewer/Viewer.h
new file mode 100644 (file)
index 0000000..43d29ba
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Viewer_DEFINED
+#define Viewer_DEFINED
+
+#include "../Application.h"
+#include "../Window.h"
+#include "gm.h"
+#include "SkAnimTimer.h"
+#include "Slide.h"
+
+class SkCanvas;
+
+class Viewer : public sk_app::Application {
+public:
+    Viewer(int argc, char** argv, void* platformData);
+    ~Viewer() override;
+
+    bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers);
+    bool onChar(SkUnichar, uint32_t modifiers);
+    void onPaint(SkCanvas* canvas);
+    void onIdle(double ms) override;
+
+private:
+    void initSlides();
+    void setupCurrentSlide(int previousSlide);
+
+    void drawStats(SkCanvas* canvas);
+
+    void changeZoomLevel(float delta);
+    void updateMatrix();
+
+    sk_app::Window*        fWindow;
+
+    static const int kMeasurementCount = 64;  // should be power of 2 for fast mod
+    double fMeasurements[kMeasurementCount];
+    int fCurrentMeasurement;
+
+    SkAnimTimer            fAnimTimer;
+    SkTArray<sk_sp<Slide>> fSlides;
+    int                    fCurrentSlide;
+
+    bool                   fDisplayStats;
+
+    // transform data
+    SkMatrix               fLocalMatrix;
+    SkScalar               fZoomCenterX;
+    SkScalar               fZoomCenterY;
+    SkScalar               fZoomLevel;
+    SkScalar               fZoomScale;
+
+};
+
+
+#endif
diff --git a/tools/viewer/win/VulkanTestContext_win.cpp b/tools/viewer/win/VulkanTestContext_win.cpp
new file mode 100644 (file)
index 0000000..37ef667
--- /dev/null
@@ -0,0 +1,58 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "VulkanTestContext_win.h"
+
+#include "vk/GrVkInterface.h"
+#include "vk/GrVkUtil.h"
+
+// Platform dependant call
+VkSurfaceKHR VulkanTestContext::createVkSurface(VkInstance instance, void* platformData) {
+    static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
+    if (!createWin32SurfaceKHR) {
+        createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(instance,
+                                                                         "vkCreateWin32SurfaceKHR");
+    }
+
+    if (!platformData) {
+        return VK_NULL_HANDLE;
+    }
+    ContextPlatformData_win* winPlatformData = 
+                                           reinterpret_cast<ContextPlatformData_win*>(platformData);
+    VkSurfaceKHR surface;
+
+    VkWin32SurfaceCreateInfoKHR surfaceCreateInfo;
+    memset(&surfaceCreateInfo, 0, sizeof(VkWin32SurfaceCreateInfoKHR));
+    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+    surfaceCreateInfo.pNext = nullptr;
+    surfaceCreateInfo.flags = 0;
+    surfaceCreateInfo.hinstance = winPlatformData->fHInstance;
+    surfaceCreateInfo.hwnd = winPlatformData->fHWnd;
+
+    VkResult res = createWin32SurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
+    if (VK_SUCCESS != res) {
+        return VK_NULL_HANDLE;
+    }
+
+    return surface;
+}
+
+// Platform dependant call
+bool VulkanTestContext::canPresent(VkInstance instance, VkPhysicalDevice physDev, 
+                                   uint32_t queueFamilyIndex) {
+    static PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR 
+                                             getPhysicalDeviceWin32PresentationSupportKHR = nullptr;
+    if (!getPhysicalDeviceWin32PresentationSupportKHR) {
+        getPhysicalDeviceWin32PresentationSupportKHR = 
+            (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) vkGetInstanceProcAddr(instance,
+                                                  "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+    }
+
+    VkBool32 check = getPhysicalDeviceWin32PresentationSupportKHR(physDev, queueFamilyIndex);
+    return (VK_FALSE != check);
+}
diff --git a/tools/viewer/win/VulkanTestContext_win.h b/tools/viewer/win/VulkanTestContext_win.h
new file mode 100644 (file)
index 0000000..59b5c2c
--- /dev/null
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef VULKANTESTCONTEXT_WIN_DEFINED
+#define VULKANTESTCONTEXT_WIN_DEFINED
+
+#ifdef SK_VULKAN
+
+#include <windows.h>
+#include "../VulkanTestContext.h"
+
+// for Windows
+struct ContextPlatformData_win {
+    HINSTANCE fHInstance;
+    HWND      fHWnd;
+};
+
+#endif // SK_VULKAN
+
+#endif
diff --git a/tools/viewer/win/Window_win.cpp b/tools/viewer/win/Window_win.cpp
new file mode 100644 (file)
index 0000000..d5711b7
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "Window_win.h"
+
+#include <tchar.h>
+#include <windows.h>
+#include <windowsx.h>
+
+#include "SkUtils.h"
+#include "VulkanTestContext_win.h"
+
+namespace sk_app {
+
+Window* Window::CreateNativeWindow(void* platformData) {
+    HINSTANCE hInstance = (HINSTANCE)platformData;
+
+    Window_win* window = new Window_win();
+    if (!window->init(hInstance)) {
+        delete window;
+        return nullptr;
+    }
+
+    return window;
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+bool Window_win::init(HINSTANCE hInstance) {
+    fHInstance = hInstance ? hInstance : GetModuleHandle(nullptr);
+
+    WNDCLASSEX wcex;
+    // The main window class name
+    static const TCHAR gSZWindowClass[] = _T("SkiaApp");
+
+    wcex.cbSize = sizeof(WNDCLASSEX);
+
+    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+    wcex.lpfnWndProc = WndProc;
+    wcex.cbClsExtra = 0;
+    wcex.cbWndExtra = 0;
+    wcex.hInstance = fHInstance;
+    wcex.hIcon = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);
+    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);;
+    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    wcex.lpszMenuName = nullptr;
+    wcex.lpszClassName = gSZWindowClass;
+    wcex.hIconSm = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);;
+
+    if (!RegisterClassEx(&wcex)) {
+        return false;
+    }
+
+   /*
+    if (fullscreen)
+    {
+        DEVMODE dmScreenSettings;
+        // If full screen set the screen to maximum size of the users desktop and 32bit.
+        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
+        dmScreenSettings.dmSize = sizeof(dmScreenSettings);
+        dmScreenSettings.dmPelsWidth = (unsigned long)width;
+        dmScreenSettings.dmPelsHeight = (unsigned long)height;
+        dmScreenSettings.dmBitsPerPel = 32;
+        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+
+        // Change the display settings to full screen.
+        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
+
+        // Set the position of the window to the top left corner.
+        posX = posY = 0;
+    } 
+    */
+ //   gIsFullscreen = fullscreen;
+
+    fHWnd = CreateWindow(gSZWindowClass, nullptr, WS_OVERLAPPEDWINDOW,
+                         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, fHInstance, nullptr);
+    if (!fHWnd)
+    {
+        return false;
+    }
+
+    SetWindowLongPtr(fHWnd, GWLP_USERDATA, (LONG_PTR)this);
+
+    return true;
+}
+
+static Window::Key get_key(WPARAM vk) {
+    static const struct {
+        WPARAM      fVK;
+        Window::Key fKey;
+    } gPair[] = {
+        { VK_BACK, Window::kBack_Key },
+        { VK_CLEAR, Window::kBack_Key },
+        { VK_RETURN, Window::kOK_Key },
+        { VK_UP, Window::kUp_Key },
+        { VK_DOWN, Window::kDown_Key },
+        { VK_LEFT, Window::kLeft_Key },
+        { VK_RIGHT, Window::kRight_Key }
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
+        if (gPair[i].fVK == vk) {
+            return gPair[i].fKey;
+        }
+    }
+    return Window::kNONE_Key;
+}
+
+static uint32_t get_modifiers(UINT message, WPARAM wParam, LPARAM lParam) {
+    uint32_t modifiers = 0;
+
+    switch (message) {
+        case WM_UNICHAR:
+        case WM_CHAR:
+            if (0 == (lParam & (1 << 30))) {
+                modifiers |= Window::kFirstPress_ModifierKey;
+            }
+            if (lParam & (1 << 29)) {
+                modifiers |= Window::kOption_ModifierKey;
+            }
+            break;
+
+        case WM_KEYDOWN:
+        case WM_SYSKEYDOWN:
+            if (0 == (lParam & (1 << 30))) {
+                modifiers |= Window::kFirstPress_ModifierKey;
+            }
+            if (lParam & (1 << 29)) {
+                modifiers |= Window::kOption_ModifierKey;
+            }
+            break;
+
+        case WM_KEYUP:
+        case WM_SYSKEYUP:
+            if (lParam & (1 << 29)) {
+                modifiers |= Window::kOption_ModifierKey;
+            }
+            break;
+
+        case WM_LBUTTONDOWN:
+        case WM_LBUTTONUP:
+        case WM_MOUSEMOVE:
+            if (wParam & MK_CONTROL) {
+                modifiers |= Window::kControl_ModifierKey;
+            }
+            if (wParam & MK_SHIFT) {
+                modifiers |= Window::kShift_ModifierKey;
+            }
+    }
+
+    return modifiers;
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    PAINTSTRUCT ps;
+    HDC hdc;
+
+    Window_win* window = (Window_win*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+    bool eventHandled = false;
+
+    switch (message) {
+        case WM_PAINT:
+            hdc = BeginPaint(hWnd, &ps);
+            window->onPaint();
+            EndPaint(hWnd, &ps);
+            eventHandled = true;
+            break;
+
+        case WM_CLOSE:
+        case WM_DESTROY:
+            PostQuitMessage(0);
+            eventHandled = true;
+            break;
+
+        case WM_ACTIVATE:
+            // disable/enable rendering here, depending on wParam != WA_INACTIVE
+            break;
+
+        case WM_SIZE:
+            window->onResize(LOWORD(lParam), HIWORD(lParam));
+            eventHandled = true;
+            break;
+
+        case WM_UNICHAR:
+            eventHandled = window->onChar((SkUnichar)wParam, 
+                                          get_modifiers(message, wParam, lParam));
+            break;
+
+        case WM_CHAR: {
+            const uint16_t* c = reinterpret_cast<uint16_t*>(&wParam);
+            eventHandled = window->onChar(SkUTF16_NextUnichar(&c), 
+                                          get_modifiers(message, wParam, lParam));
+        } break;
+
+        case WM_KEYDOWN:
+        case WM_SYSKEYDOWN:
+            eventHandled = window->onKey(get_key(wParam), Window::kDown_InputState, 
+                                         get_modifiers(message, wParam, lParam));
+            break;
+
+        case WM_KEYUP:
+        case WM_SYSKEYUP:
+            eventHandled = window->onKey(get_key(wParam), Window::kUp_InputState,
+                                         get_modifiers(message, wParam, lParam));
+            break;
+
+        case WM_LBUTTONDOWN:
+        case WM_LBUTTONUP: {
+            int xPos = GET_X_LPARAM(lParam);
+            int yPos = GET_Y_LPARAM(lParam);
+
+            //if (!gIsFullscreen)
+            //{
+            //    RECT rc = { 0, 0, 640, 480 };
+            //    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
+            //    xPos -= rc.left;
+            //    yPos -= rc.top;
+            //}
+
+            Window::InputState istate = ((wParam & MK_LBUTTON) != 0) ? Window::kDown_InputState
+                                                                     : Window::kUp_InputState;
+
+            eventHandled = window->onMouse(xPos, yPos, istate, 
+                                            get_modifiers(message, wParam, lParam));
+        } break;
+
+        case WM_MOUSEMOVE: 
+            // only track if left button is down
+            if ((wParam & MK_LBUTTON) != 0) {
+                int xPos = GET_X_LPARAM(lParam);
+                int yPos = GET_Y_LPARAM(lParam);
+
+                //if (!gIsFullscreen)
+                //{
+                //    RECT rc = { 0, 0, 640, 480 };
+                //    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
+                //    xPos -= rc.left;
+                //    yPos -= rc.top;
+                //}
+
+                eventHandled = window->onMouse(xPos, yPos, Window::kMove_InputState,
+                                               get_modifiers(message, wParam, lParam));
+            }
+            break;
+
+        default:
+            return DefWindowProc(hWnd, message, wParam, lParam);
+    }
+
+    return eventHandled ? 0 : 1;
+}
+
+void Window_win::setTitle(const char* title) {
+    SetWindowTextA(fHWnd, title);
+}
+
+void Window_win::show() {
+    ShowWindow(fHWnd, SW_SHOW);
+}
+
+
+bool Window_win::attach(BackEndType attachType, int msaaSampleCount) {
+    if (kVulkan_BackendType != attachType) {
+        return false;
+    }
+
+    ContextPlatformData_win platformData;
+    platformData.fHInstance = fHInstance;
+    platformData.fHWnd = fHWnd;
+
+    fTestContext = VulkanTestContext::Create((void*)&platformData, msaaSampleCount);
+
+    return (SkToBool(fTestContext));
+}
+
+void Window_win::inval() {
+    InvalidateRect(fHWnd, nullptr, false);
+}
+
+}   // namespace sk_app
diff --git a/tools/viewer/win/Window_win.h b/tools/viewer/win/Window_win.h
new file mode 100644 (file)
index 0000000..e295212
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Window_win_DEFINED
+#define Window_win_DEFINED
+
+#include <windows.h>
+#include "../Window.h"
+
+namespace sk_app {
+
+class Window_win : public Window {
+public:
+    Window_win() : Window() {}
+    ~Window_win() override {}
+
+    bool init(HINSTANCE instance);
+
+    void setTitle(const char*) override;
+    void show() override;
+
+    bool attach(BackEndType attachType, int msaaSampleCount) override;
+
+    void inval() override;
+
+private:
+    HINSTANCE fHInstance;
+    HWND      fHWnd;
+};
+
+}   // namespace sk_app
+
+#endif
diff --git a/tools/viewer/win/main_win.cpp b/tools/viewer/win/main_win.cpp
new file mode 100644 (file)
index 0000000..ba1629c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include <windows.h>
+#include <tchar.h>
+
+#include "SkTypes.h"
+#include "Timer.h"
+#include "Window_win.h"
+#include "../Application.h"
+
+using sk_app::Application;
+
+static char* tchar_to_utf8(const TCHAR* str) {
+#ifdef _UNICODE
+    int size = WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), NULL, 0, NULL, NULL);
+    char* str8 = (char*)sk_malloc_throw(size + 1);
+    WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), str8, size, NULL, NULL);
+    str8[size] = '\0';
+    return str8;
+#else
+    return _strdup(str);
+#endif
+}
+
+static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
+
+// This file can work with GUI or CONSOLE subsystem types since we define _tWinMain and main().
+
+static int main_common(HINSTANCE hInstance, int show, int argc, char**argv);
+
+int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
+                       int nCmdShow) {
+
+    // convert from lpCmdLine to argc, argv.
+    char* argv[4096];
+    int argc = 0;
+    TCHAR exename[1024], *next;
+    int exenameLen = GetModuleFileName(NULL, exename, SK_ARRAY_COUNT(exename));
+    // we're ignoring the possibility that the exe name exceeds the exename buffer
+    (void)exenameLen;
+    argv[argc++] = tchar_to_utf8(exename);
+    TCHAR* arg = _tcstok_s(lpCmdLine, _T(" "), &next);
+    while (arg != NULL) {
+        argv[argc++] = tchar_to_utf8(arg);
+        arg = _tcstok_s(NULL, _T(" "), &next);
+    }
+    int result = main_common(hInstance, nCmdShow, argc, argv);
+    for (int i = 0; i < argc; ++i) {
+        sk_free(argv[i]);
+    }
+    return result;
+}
+
+int main(int argc, char**argv) {
+    return main_common(GetModuleHandle(NULL), SW_SHOW, argc, argv);
+}
+
+static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) {
+
+    Application* app = Application::Create(argc, argv, (void*)hInstance);
+
+    MSG msg = { 0 };
+
+    double currentTime = 0.0;
+    double previousTime = 0.0;
+
+    // Main message loop
+    while (WM_QUIT != msg.message) {
+        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        } else {
+            previousTime = currentTime;
+            currentTime = now_ms();
+            app->onIdle(currentTime - previousTime);
+        }
+    }
+
+    delete app;
+
+    return (int)msg.wParam;
+}
diff --git a/tools/vulkan/Application.h b/tools/vulkan/Application.h
deleted file mode 100644 (file)
index 4504d17..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef Application_DEFINED
-#define Application_DEFINED
-
-class Application {
-public:
-    static Application* Create(int argc, char** argv, void* platformData);
-
-    virtual ~Application() {}
-
-    virtual void onIdle(double ms) = 0;
-};
-
-#endif
diff --git a/tools/vulkan/VulkanTestContext.cpp b/tools/vulkan/VulkanTestContext.cpp
deleted file mode 100644 (file)
index e9137c0..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrContext.h"
-#include "SkSurface.h"
-#include "VulkanTestContext.h"
-
-#include "vk/GrVkInterface.h"
-#include "vk/GrVkUtil.h"
-#include "vk/GrVkTypes.h"
-
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-// windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
-#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)
-
-VulkanTestContext::VulkanTestContext(void* platformData, int msaaSampleCount) 
-                                 : fSurface(VK_NULL_HANDLE)
-                                 , fSwapchain(VK_NULL_HANDLE)
-                                 , fCommandPool(VK_NULL_HANDLE)
-                                 , fBackbuffers(nullptr) {
-
-    // any config code here (particularly for msaa)?
-
-    this->initializeContext(platformData);
-}
-
-void VulkanTestContext::initializeContext(void* platformData) {
-
-    fBackendContext.reset(GrVkBackendContext::Create(&fPresentQueueIndex, canPresent));
-    if (!(fBackendContext->fExtensions & kKHR_surface_GrVkExtensionFlag) ||
-        !(fBackendContext->fExtensions & kKHR_swapchain_GrVkExtensionFlag)) {
-        fBackendContext.reset(nullptr);
-        return;
-    }
-
-    VkInstance instance = fBackendContext->fInstance;
-    VkDevice device = fBackendContext->fDevice;
-    GET_PROC(DestroySurfaceKHR);
-    GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
-    GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
-    GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
-    GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
-    GET_DEV_PROC(CreateSwapchainKHR);
-    GET_DEV_PROC(DestroySwapchainKHR);
-    GET_DEV_PROC(GetSwapchainImagesKHR);
-    GET_DEV_PROC(AcquireNextImageKHR);
-    GET_DEV_PROC(QueuePresentKHR);
-
-    fContext = GrContext::Create(kVulkan_GrBackend, (GrBackendContext)fBackendContext.get());
-
-    fSurface = createVkSurface(instance, platformData);
-    if (VK_NULL_HANDLE == fSurface) {
-        fBackendContext.reset(nullptr);
-        return;
-    }
-
-    VkBool32 supported;
-    VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fBackendContext->fPhysicalDevice,
-                                                       fPresentQueueIndex, fSurface,
-                                                       &supported);
-    if (VK_SUCCESS != res) {
-        this->destroyContext();
-        return;
-    }
-
-    if (!this->createSwapchain(-1, -1)) {
-        this->destroyContext();
-        return;
-    }
-
-    // create presentQueue
-    vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQueue);
-}
-
-bool VulkanTestContext::createSwapchain(uint32_t width, uint32_t height)
-{
-    // check for capabilities
-    VkSurfaceCapabilitiesKHR caps;
-    VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fBackendContext->fPhysicalDevice,
-                                                            fSurface, &caps);
-    if (VK_SUCCESS != res) {
-        return false;
-    }
-
-    uint32_t surfaceFormatCount;
-    res = fGetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysicalDevice, fSurface,
-                                              &surfaceFormatCount, nullptr);
-    if (VK_SUCCESS != res) {
-        return false;
-    }
-
-    SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
-    VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
-    res = fGetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysicalDevice, fSurface,
-                                              &surfaceFormatCount, surfaceFormats);
-    if (VK_SUCCESS != res) {
-        return false;
-    }
-
-    uint32_t presentModeCount;
-    res = fGetPhysicalDeviceSurfacePresentModesKHR(fBackendContext->fPhysicalDevice, fSurface,
-                                                   &presentModeCount, nullptr);
-    if (VK_SUCCESS != res) {
-        return false;
-    }
-
-    SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
-    VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
-    res = fGetPhysicalDeviceSurfacePresentModesKHR(fBackendContext->fPhysicalDevice, fSurface,
-                                                    &presentModeCount, presentModes);
-    if (VK_SUCCESS != res) {
-        return false;
-    }
-
-    VkExtent2D extent = caps.currentExtent;
-    // use the hints
-    if (extent.width == (uint32_t)-1) {
-        extent.width = width;
-        extent.height = height;
-    }
-
-    // clamp width; to protect us from broken hints
-    if (extent.width < caps.minImageExtent.width) {
-        extent.width = caps.minImageExtent.width;
-    } else if (extent.width > caps.maxImageExtent.width) {
-        extent.width = caps.maxImageExtent.width;
-    }
-    // clamp height
-    if (extent.height < caps.minImageExtent.height) {
-        extent.height = caps.minImageExtent.height;
-    } else if (extent.height > caps.maxImageExtent.height) {
-        extent.height = caps.maxImageExtent.height;
-    }
-    fWidth = (int)extent.width;
-    fHeight = (int)extent.height;
-
-    uint32_t imageCount = caps.minImageCount + 2;
-    if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
-        // Application must settle for fewer images than desired:
-        imageCount = caps.maxImageCount;
-    }
-
-    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
-                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
-                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-    SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
-    SkASSERT(caps.supportedTransforms & caps.currentTransform);
-    SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
-                                             VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR));
-    VkCompositeAlphaFlagBitsKHR composite_alpha =
-        (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
-                                        VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR :
-                                        VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
-
-    // Pick our surface format -- for now, the first one
-    VkFormat surfaceFormat = surfaceFormats[0].format;
-    VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace;
-
-    // If mailbox mode is available, use it, as it is the lowest-latency non-
-    // tearing mode. If not, fall back to FIFO which is always available.
-    VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
-    for (uint32_t i = 0; i < presentModeCount; ++i) {
-        // use mailbox
-        if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
-            mode = presentModes[i];
-            break;
-        }
-    }
-
-    VkSwapchainCreateInfoKHR swapchainCreateInfo;
-    memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
-    swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
-    swapchainCreateInfo.surface = fSurface;
-    swapchainCreateInfo.minImageCount = imageCount;
-    swapchainCreateInfo.imageFormat = surfaceFormat;
-    swapchainCreateInfo.imageColorSpace = colorSpace;
-    swapchainCreateInfo.imageExtent = extent;
-    swapchainCreateInfo.imageArrayLayers = 1;
-    swapchainCreateInfo.imageUsage = usageFlags;
-
-    uint32_t queueFamilies[] = { fBackendContext->fGraphicsQueueIndex, fPresentQueueIndex };
-    if (fBackendContext->fGraphicsQueueIndex != fPresentQueueIndex) {
-        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
-        swapchainCreateInfo.queueFamilyIndexCount = 2;
-        swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
-    } else {
-        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
-        swapchainCreateInfo.queueFamilyIndexCount = 0;
-        swapchainCreateInfo.pQueueFamilyIndices = nullptr;
-    }
-
-    swapchainCreateInfo.preTransform = caps.currentTransform;;
-    swapchainCreateInfo.compositeAlpha = composite_alpha;
-    swapchainCreateInfo.presentMode = mode;
-    swapchainCreateInfo.clipped = true;
-    swapchainCreateInfo.oldSwapchain = fSwapchain;
-
-    res = fCreateSwapchainKHR(fBackendContext->fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
-    if (VK_SUCCESS != res) {
-        return false;
-    }
-
-    // destroy the old swapchain
-    if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
-        GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext->fDevice));
-
-        this->destroyBuffers();
-
-        fDestroySwapchainKHR(fBackendContext->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
-    }
-
-    this->createBuffers(swapchainCreateInfo.imageFormat);
-
-    return true;
-}
-
-void VulkanTestContext::createBuffers(VkFormat format) {
-    GrVkFormatToPixelConfig(format, &fPixelConfig);
-
-    fGetSwapchainImagesKHR(fBackendContext->fDevice, fSwapchain, &fImageCount, nullptr);
-    SkASSERT(fImageCount);
-    fImages = new VkImage[fImageCount];
-    fGetSwapchainImagesKHR(fBackendContext->fDevice, fSwapchain, &fImageCount, fImages);
-
-    // set up initial image layouts and create surfaces
-    fImageLayouts = new VkImageLayout[fImageCount];
-    fSurfaces = new sk_sp<SkSurface>[fImageCount];
-    for (uint32_t i = 0; i < fImageCount; ++i) {
-        fImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
-
-        GrBackendRenderTargetDesc desc;
-        GrVkTextureInfo info;
-        info.fImage = fImages[i];
-        info.fAlloc = VK_NULL_HANDLE;
-        info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-        info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
-        info.fFormat = format;
-        desc.fWidth = fWidth;
-        desc.fHeight = fHeight;
-        desc.fConfig = fPixelConfig;
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
-        desc.fSampleCnt = 0;
-        desc.fStencilBits = 0;
-        desc.fRenderTargetHandle = (GrBackendObject) &info;
-        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
-        fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc, &props);
-    }
-
-    // create the command pool for the command buffers
-    if (VK_NULL_HANDLE == fCommandPool) {
-        VkCommandPoolCreateInfo commandPoolInfo;
-        memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo));
-        commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-        // this needs to be on the render queue
-        commandPoolInfo.queueFamilyIndex = fBackendContext->fGraphicsQueueIndex;
-        commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                            CreateCommandPool(fBackendContext->fDevice, &commandPoolInfo,
-                                              nullptr, &fCommandPool));
-    }
-
-    // set up the backbuffers
-    VkSemaphoreCreateInfo semaphoreInfo;
-    memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
-    semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    semaphoreInfo.pNext = nullptr;
-    semaphoreInfo.flags = 0;
-    VkCommandBufferAllocateInfo commandBuffersInfo;
-    memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo));
-    commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    commandBuffersInfo.pNext = nullptr;
-    commandBuffersInfo.commandPool = fCommandPool;
-    commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    commandBuffersInfo.commandBufferCount = 2;
-    VkFenceCreateInfo fenceInfo;
-    memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
-    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    fenceInfo.pNext = nullptr;
-    fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
-
-    // we create one additional backbuffer structure here, because we want to 
-    // give the command buffers they contain a chance to finish before we cycle back
-    fBackbuffers = new BackbufferInfo[fImageCount + 1];
-    for (uint32_t i = 0; i < fImageCount + 1; ++i) {
-        fBackbuffers[i].fImageIndex = -1;
-        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                            CreateSemaphore(fBackendContext->fDevice, &semaphoreInfo,
-                                            nullptr, &fBackbuffers[i].fAcquireSemaphore));
-        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                            CreateSemaphore(fBackendContext->fDevice, &semaphoreInfo,
-                                            nullptr, &fBackbuffers[i].fRenderSemaphore));
-        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                            AllocateCommandBuffers(fBackendContext->fDevice, &commandBuffersInfo,
-                                                   fBackbuffers[i].fTransitionCmdBuffers));
-        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                            CreateFence(fBackendContext->fDevice, &fenceInfo, nullptr,
-                                        &fBackbuffers[i].fUsageFences[0]));
-        GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                            CreateFence(fBackendContext->fDevice, &fenceInfo, nullptr,
-                                        &fBackbuffers[i].fUsageFences[1]));
-    }
-    fCurrentBackbufferIndex = fImageCount;
-}
-
-void VulkanTestContext::destroyBuffers() {
-
-    if (fBackbuffers) {
-        for (uint32_t i = 0; i < fImageCount + 1; ++i) {
-            GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                                WaitForFences(fBackendContext->fDevice, 2, 
-                                              fBackbuffers[i].fUsageFences,
-                                true, UINT64_MAX));
-            fBackbuffers[i].fImageIndex = -1;
-            GR_VK_CALL(fBackendContext->fInterface,
-                       DestroySemaphore(fBackendContext->fDevice,
-                                        fBackbuffers[i].fAcquireSemaphore,
-                                        nullptr));
-            GR_VK_CALL(fBackendContext->fInterface,
-                       DestroySemaphore(fBackendContext->fDevice,
-                                        fBackbuffers[i].fRenderSemaphore,
-                                        nullptr));
-            GR_VK_CALL(fBackendContext->fInterface,
-                       FreeCommandBuffers(fBackendContext->fDevice, fCommandPool, 2,
-                                          fBackbuffers[i].fTransitionCmdBuffers));
-            GR_VK_CALL(fBackendContext->fInterface,
-                       DestroyFence(fBackendContext->fDevice, fBackbuffers[i].fUsageFences[0], 0));
-            GR_VK_CALL(fBackendContext->fInterface,
-                       DestroyFence(fBackendContext->fDevice, fBackbuffers[i].fUsageFences[1], 0));
-        }
-    }
-
-    delete[] fBackbuffers;
-    fBackbuffers = nullptr;
-
-    delete[] fSurfaces;
-    fSurfaces = nullptr;
-    delete[] fImageLayouts;
-    fImageLayouts = nullptr;
-    delete[] fImages;
-    fImages = nullptr;
-}
-
-VulkanTestContext::~VulkanTestContext() {
-    this->destroyContext();
-}
-
-void VulkanTestContext::destroyContext() {
-    if (!fBackendContext.get()) {
-        return;
-    }
-
-    GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext->fDevice));
-
-    this->destroyBuffers();
-
-    if (VK_NULL_HANDLE != fCommandPool) {
-        GR_VK_CALL(fBackendContext->fInterface, DestroyCommandPool(fBackendContext->fDevice,
-                                                                   fCommandPool, nullptr));
-        fCommandPool = VK_NULL_HANDLE;
-    }
-
-    if (VK_NULL_HANDLE != fSwapchain) {
-        fDestroySwapchainKHR(fBackendContext->fDevice, fSwapchain, nullptr);
-        fSwapchain = VK_NULL_HANDLE;
-    }
-
-    if (VK_NULL_HANDLE != fSurface) {
-        fDestroySurfaceKHR(fBackendContext->fInstance, fSurface, nullptr);
-        fSurface = VK_NULL_HANDLE;
-    }
-
-    delete fContext;
-
-    fBackendContext.reset(nullptr);
-}
-
-VulkanTestContext::BackbufferInfo* VulkanTestContext::getAvailableBackbuffer() {
-    SkASSERT(fBackbuffers);
-
-    ++fCurrentBackbufferIndex;
-    if (fCurrentBackbufferIndex > fImageCount) {
-        fCurrentBackbufferIndex = 0;
-    }
-
-    BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
-
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        WaitForFences(fBackendContext->fDevice, 2, backbuffer->fUsageFences,
-                                      true, UINT64_MAX));
-    return backbuffer;
-}
-
-SkSurface* VulkanTestContext::getBackbufferSurface() {
-    BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
-    SkASSERT(backbuffer);
-
-    // reset the fence
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        ResetFences(fBackendContext->fDevice, 2, backbuffer->fUsageFences));
-    // semaphores should be in unsignaled state
-
-    // acquire the image
-    VkResult res = fAcquireNextImageKHR(fBackendContext->fDevice, fSwapchain, UINT64_MAX,
-                                        backbuffer->fAcquireSemaphore, VK_NULL_HANDLE,
-                                        &backbuffer->fImageIndex);
-    if (VK_ERROR_SURFACE_LOST_KHR == res) {
-        // need to figure out how to create a new vkSurface without the platformData*
-        // maybe use attach somehow? but need a Window
-        return nullptr;
-    }
-    if (VK_ERROR_OUT_OF_DATE_KHR == res) {
-        // tear swapchain down and try again
-        if (!this->createSwapchain(0, 0)) {
-            return nullptr;
-        }
-
-        // acquire the image
-        res = fAcquireNextImageKHR(fBackendContext->fDevice,  fSwapchain, UINT64_MAX,
-                                   backbuffer->fAcquireSemaphore, VK_NULL_HANDLE,
-                                   &backbuffer->fImageIndex);
-
-        if (VK_SUCCESS != res) {
-            return nullptr;
-        }
-    }
-
-    // set up layout transfer from initial to color attachment
-    VkImageLayout layout = fImageLayouts[backbuffer->fImageIndex];
-    VkPipelineStageFlags srcStageMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ?
-                                        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT :
-                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-    VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-    VkAccessFlags srcAccessMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ? 
-                                  0 : VK_ACCESS_MEMORY_READ_BIT;
-    VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
-    VkImageMemoryBarrier imageMemoryBarrier = {
-        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
-        NULL,                                     // pNext
-        srcAccessMask,                            // outputMask
-        dstAccessMask,                            // inputMask
-        layout,                                   // oldLayout
-        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
-        fPresentQueueIndex,                       // srcQueueFamilyIndex
-        fBackendContext->fGraphicsQueueIndex,     // dstQueueFamilyIndex
-        fImages[backbuffer->fImageIndex],         // image
-        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
-    };
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        ResetCommandBuffer(backbuffer->fTransitionCmdBuffers[0], 0));
-    VkCommandBufferBeginInfo info;
-    memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
-    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-    info.flags = 0;
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        BeginCommandBuffer(backbuffer->fTransitionCmdBuffers[0], &info));
-
-    GR_VK_CALL(fBackendContext->fInterface, 
-                CmdPipelineBarrier(backbuffer->fTransitionCmdBuffers[0], 
-                                    srcStageMask, dstStageMask, 0,
-                                    0, nullptr,
-                                    0, nullptr,
-                                    1, &imageMemoryBarrier));
-
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        EndCommandBuffer(backbuffer->fTransitionCmdBuffers[0]));  
-
-    VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-    // insert the layout transfer into the queue and wait on the acquire
-    VkSubmitInfo submitInfo;
-    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
-    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-    submitInfo.waitSemaphoreCount = 1;
-    submitInfo.pWaitSemaphores = &backbuffer->fAcquireSemaphore;
-    submitInfo.pWaitDstStageMask = &waitDstStageFlags;
-    submitInfo.commandBufferCount = 1;
-    submitInfo.pCommandBuffers = &backbuffer->fTransitionCmdBuffers[0];
-    submitInfo.signalSemaphoreCount = 0;
-    
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        QueueSubmit(fBackendContext->fQueue, 1, &submitInfo, 
-                                    backbuffer->fUsageFences[0]));
-
-    return fSurfaces[backbuffer->fImageIndex].get();
-}
-
-
-void VulkanTestContext::swapBuffers() {
-
-    BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
-
-    VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-    VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-    VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
-    VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-    VkAccessFlags dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
-
-    VkImageMemoryBarrier imageMemoryBarrier = {
-        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
-        NULL,                                     // pNext
-        srcAccessMask,                            // outputMask
-        dstAccessMask,                            // inputMask
-        layout,                                   // oldLayout
-        VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,          // newLayout
-        fBackendContext->fGraphicsQueueIndex,     // srcQueueFamilyIndex
-        fPresentQueueIndex,                       // dstQueueFamilyIndex
-        fImages[backbuffer->fImageIndex],         // image
-        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
-    };
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        ResetCommandBuffer(backbuffer->fTransitionCmdBuffers[1], 0));
-    VkCommandBufferBeginInfo info;
-    memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
-    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-    info.flags = 0;
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        BeginCommandBuffer(backbuffer->fTransitionCmdBuffers[1], &info));
-    GR_VK_CALL(fBackendContext->fInterface,
-                CmdPipelineBarrier(backbuffer->fTransitionCmdBuffers[1],
-                srcStageMask, dstStageMask, 0,
-                0, nullptr,
-                0, nullptr,
-                1, &imageMemoryBarrier));
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        EndCommandBuffer(backbuffer->fTransitionCmdBuffers[1]));
-
-    fImageLayouts[backbuffer->fImageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
-
-    // insert the layout transfer into the queue and wait on the acquire
-    VkSubmitInfo submitInfo;
-    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
-    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-    submitInfo.waitSemaphoreCount = 0;
-    submitInfo.pWaitDstStageMask = 0;
-    submitInfo.commandBufferCount = 1;
-    submitInfo.pCommandBuffers = &backbuffer->fTransitionCmdBuffers[1];
-    submitInfo.signalSemaphoreCount = 1;
-    submitInfo.pSignalSemaphores = &backbuffer->fRenderSemaphore;
-
-    GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
-                        QueueSubmit(fBackendContext->fQueue, 1, &submitInfo, 
-                                    backbuffer->fUsageFences[1]));
-
-    // Submit present operation to present queue
-    const VkPresentInfoKHR presentInfo =
-    {
-        VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
-        NULL, // pNext
-        1, // waitSemaphoreCount
-        &backbuffer->fRenderSemaphore, // pWaitSemaphores
-        1, // swapchainCount
-        &fSwapchain, // pSwapchains
-        &backbuffer->fImageIndex, // pImageIndices
-        NULL // pResults
-    };
-
-    fQueuePresentKHR(fPresentQueue, &presentInfo);
-
-}
diff --git a/tools/vulkan/VulkanTestContext.h b/tools/vulkan/VulkanTestContext.h
deleted file mode 100644 (file)
index 60b3b80..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef VulkanTestContext_DEFINED
-#define VulkanTestContext_DEFINED
-
-#ifdef SK_VULKAN
-
-#include "GrTypes.h"
-#include "vk/GrVkBackendContext.h"
-
-class SkSurface;
-class GrContext;
-
-class VulkanTestContext {
-public:
-    ~VulkanTestContext();
-
-    // each platform will have to implement these in its CPP file
-    static VkSurfaceKHR createVkSurface(VkInstance, void* platformData);
-    static bool canPresent(VkInstance, VkPhysicalDevice, uint32_t queueFamilyIndex);
-
-    static VulkanTestContext* Create(void* platformData, int msaaSampleCount) {
-        VulkanTestContext* ctx = new VulkanTestContext(platformData, msaaSampleCount);
-        if (!ctx->isValid()) {
-            delete ctx;
-            return nullptr;
-        }
-        return ctx;
-    }
-
-    SkSurface* getBackbufferSurface();
-    void swapBuffers();
-
-    bool makeCurrent() { return true; }
-
-    bool isValid() { return SkToBool(fBackendContext.get()); }
-
-    void resize(uint32_t w, uint32_t h) {
-        this->createSwapchain(w, h); 
-    }
-
-    GrBackendContext getBackendContext() { return (GrBackendContext)fBackendContext.get(); }
-
-private:
-    VulkanTestContext();
-    VulkanTestContext(void*, int msaaSampleCount);
-    void initializeContext(void*);
-    void destroyContext();
-
-    struct BackbufferInfo {
-        uint32_t        fImageIndex;          // image this is associated with
-        VkSemaphore     fAcquireSemaphore;    // we signal on this for acquisition of image
-        VkSemaphore     fRenderSemaphore;     // we wait on this for rendering to be done
-        VkCommandBuffer fTransitionCmdBuffers[2]; // to transition layout between present and render
-        VkFence         fUsageFences[2];      // used to ensure this data is no longer used on GPU
-    };
-
-    BackbufferInfo* getAvailableBackbuffer();
-    bool createSwapchain(uint32_t width, uint32_t height);
-    void createBuffers(VkFormat format);
-    void destroyBuffers();
-
-    SkAutoTUnref<const GrVkBackendContext> fBackendContext;
-
-    // simple wrapper class that exists only to initialize a pointer to NULL
-    template <typename FNPTR_TYPE> class VkPtr {
-    public:
-        VkPtr() : fPtr(NULL) {}
-        VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; }
-        operator FNPTR_TYPE() const { return fPtr; }
-    private:
-        FNPTR_TYPE fPtr;
-    };
-    
-    // WSI interface functions
-    VkPtr<PFN_vkDestroySurfaceKHR> fDestroySurfaceKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> fGetPhysicalDeviceSurfaceSupportKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> fGetPhysicalDeviceSurfaceCapabilitiesKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> fGetPhysicalDeviceSurfaceFormatsKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> fGetPhysicalDeviceSurfacePresentModesKHR;
-
-    VkPtr<PFN_vkCreateSwapchainKHR> fCreateSwapchainKHR;
-    VkPtr<PFN_vkDestroySwapchainKHR> fDestroySwapchainKHR;
-    VkPtr<PFN_vkGetSwapchainImagesKHR> fGetSwapchainImagesKHR;
-    VkPtr<PFN_vkAcquireNextImageKHR> fAcquireNextImageKHR;
-    VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
-    VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
-
-    GrContext*        fContext;
-    VkSurfaceKHR      fSurface;
-    VkSwapchainKHR    fSwapchain;
-    uint32_t          fPresentQueueIndex;
-    VkQueue           fPresentQueue;
-    int               fWidth;
-    int               fHeight;
-    GrPixelConfig     fPixelConfig;
-
-    uint32_t          fImageCount;
-    VkImage*          fImages;         // images in the swapchain
-    VkImageLayout*    fImageLayouts;   // layouts of these images when not color attachment
-    sk_sp<SkSurface>* fSurfaces;       // wrapped surface for those images
-    VkCommandPool     fCommandPool;
-    BackbufferInfo*   fBackbuffers;
-    uint32_t          fCurrentBackbufferIndex;
-};
-
-#endif // SK_VULKAN
-
-#endif
diff --git a/tools/vulkan/Window.cpp b/tools/vulkan/Window.cpp
deleted file mode 100644 (file)
index 9042a0c..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "Window.h"
-
-#include "SkSurface.h"
-#include "SkCanvas.h"
-#include "VulkanTestContext.h"
-
-static bool default_char_func(SkUnichar c, uint32_t modifiers, void* userData) {
-    return false;
-}
-
-static bool default_key_func(Window::Key key, Window::InputState state, uint32_t modifiers, 
-                             void* userData) {
-    return false;
-}
-
-static bool default_mouse_func(int x, int y, Window::InputState state, uint32_t modifiers, 
-                               void* userData) {
-    return false;
-}
-
-static void default_paint_func(SkCanvas*, void* userData) {}
-
-Window::Window() : fCharFunc(default_char_func)
-                 , fKeyFunc(default_key_func)
-                 , fMouseFunc(default_mouse_func)
-                 , fPaintFunc(default_paint_func) {
-}
-
-void Window::detach() {
-    delete fTestContext;
-    fTestContext = nullptr;
-}
-
-bool Window::onChar(SkUnichar c, uint32_t modifiers) {
-    return fCharFunc(c, modifiers, fCharUserData);
-}
-
-bool Window::onKey(Key key, InputState state, uint32_t modifiers) {
-    return fKeyFunc(key, state, modifiers, fKeyUserData);
-}
-
-bool Window::onMouse(int x, int y, InputState state, uint32_t modifiers) {
-    return fMouseFunc(x, y, state, modifiers, fMouseUserData);
-}
-
-void Window::onPaint() {
-    SkSurface* backbuffer = fTestContext->getBackbufferSurface();
-    if (backbuffer) {
-        // draw into the canvas of this surface
-        SkCanvas* canvas = backbuffer->getCanvas();
-
-        fPaintFunc(canvas, fPaintUserData);
-
-        canvas->flush();
-
-        fTestContext->swapBuffers();
-    } else {
-        // try recreating testcontext
-    }
-
-}
-
-void Window::onResize(uint32_t w, uint32_t h) {
-    fWidth = w;
-    fHeight = h;
-    fTestContext->resize(w, h);
-}
diff --git a/tools/vulkan/Window.h b/tools/vulkan/Window.h
deleted file mode 100644 (file)
index 714d8df..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef Window_DEFINED
-#define Window_DEFINED
-
-#include "SkTypes.h"
-#include "SkRect.h"
-
-class SkCanvas;
-class VulkanTestContext;
-
-class Window {
-public:
-    static Window* CreateNativeWindow(void* platformData);
-
-    virtual ~Window() {};
-
-    virtual void setTitle(const char*) = 0;
-    virtual void show() = 0;
-    virtual void inval() = 0;
-
-    virtual bool scaleContentToFit() const { return false; }
-    virtual bool supportsContentRect() const { return false; }
-    virtual SkRect getContentRect() { return SkRect::MakeEmpty(); }
-
-    enum BackEndType {
-        kNativeGL_BackendType,
-        kVulkan_BackendType
-    };
-
-    virtual bool attach(BackEndType attachType, int msaaSampleCount) = 0;
-    void detach();
-
-    // input handling
-    enum Key {
-        kNONE_Key,    //corresponds to android's UNKNOWN
-
-        kLeftSoftKey_Key,
-        kRightSoftKey_Key,
-
-        kHome_Key,    //!< the home key - added to match android
-        kBack_Key,    //!< (CLR)
-        kSend_Key,    //!< the green (talk) key
-        kEnd_Key,     //!< the red key
-
-        k0_Key,
-        k1_Key,
-        k2_Key,
-        k3_Key,
-        k4_Key,
-        k5_Key,
-        k6_Key,
-        k7_Key,
-        k8_Key,
-        k9_Key,
-        kStar_Key,    //!< the * key
-        kHash_Key,    //!< the # key
-
-        kUp_Key,
-        kDown_Key,
-        kLeft_Key,
-        kRight_Key,
-
-        kOK_Key,      //!< the center key
-
-        kVolUp_Key,   //!< volume up    - match android
-        kVolDown_Key, //!< volume down  - same
-        kPower_Key,   //!< power button - same
-        kCamera_Key,  //!< camera       - same
-
-        kLast_Key = kCamera_Key
-    };
-    static const int kKeyCount = kLast_Key + 1;
-
-    enum ModifierKeys {
-        kShift_ModifierKey = 1 << 0,
-        kControl_ModifierKey = 1 << 1,
-        kOption_ModifierKey = 1 << 2,   // same as ALT
-        kCommand_ModifierKey = 1 << 3,
-        kFirstPress_ModifierKey = 1 << 4,
-    };
-
-    enum InputState {
-        kDown_InputState,
-        kUp_InputState,
-        kMove_InputState   // only valid for mouse
-    };
-
-    // return value of 'true' means 'I have handled this event'
-    typedef bool(*OnCharFunc)(SkUnichar c, uint32_t modifiers, void* userData);
-    typedef bool(*OnKeyFunc)(Key key, InputState state, uint32_t modifiers, void* userData);
-    typedef bool(*OnMouseFunc)(int x, int y, InputState state, uint32_t modifiers, void* userData);
-    typedef void(*OnPaintFunc)(SkCanvas*, void* userData);
-
-    void registerCharFunc(OnCharFunc func, void* userData) {
-        fCharFunc = func;
-        fCharUserData = userData;
-    }
-
-    void registerKeyFunc(OnKeyFunc func, void* userData) {
-        fKeyFunc = func;
-        fKeyUserData = userData;
-    }
-
-    void registerMouseFunc(OnMouseFunc func, void* userData) {
-        fMouseFunc = func;
-        fMouseUserData = userData;
-    }
-
-    void registerPaintFunc(OnPaintFunc func, void* userData) {
-        fPaintFunc = func;
-        fPaintUserData = userData;
-    }
-
-    bool onChar(SkUnichar c, uint32_t modifiers);
-    bool onKey(Key key, InputState state, uint32_t modifiers);
-    bool onMouse(int x, int y, InputState state, uint32_t modifiers);
-    void onPaint();
-    void onResize(uint32_t width, uint32_t height);
-
-    uint32_t width() { return fWidth; }
-    uint32_t height() { return fHeight;  }
-
-protected:
-    Window();
-
-    uint32_t     fWidth;
-    uint32_t     fHeight;
-
-    OnCharFunc   fCharFunc;
-    void*        fCharUserData;
-    OnKeyFunc    fKeyFunc;
-    void*        fKeyUserData;
-    OnMouseFunc  fMouseFunc;
-    void*        fMouseUserData;
-    OnPaintFunc  fPaintFunc;
-    void*        fPaintUserData;
-
-    VulkanTestContext* fTestContext;
-};
-
-
-#endif
diff --git a/tools/vulkan/android/VulkanTestContext_android.cpp b/tools/vulkan/android/VulkanTestContext_android.cpp
deleted file mode 100644 (file)
index 58dbcb2..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "VulkanTestContext_android.h"
-
-#include "vk/GrVkInterface.h"
-#include "vk/GrVkUtil.h"
-
-VkSurfaceKHR VulkanTestContext::createVkSurface(VkInstance instance, void* platformData) {
-    static PFN_vkCreateAndroidSurfaceKHR createAndroidSurfaceKHR = nullptr;
-    if (!createAndroidSurfaceKHR) {
-        createAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(instance,
-                                                                       "vkCreateAndroidSurfaceKHR");
-    }
-
-    if (!platformData) {
-        return VK_NULL_HANDLE;
-    }
-    ContextPlatformData_android* androidPlatformData =
-                                           reinterpret_cast<ContextPlatformData_android*>(platformData);
-    VkSurfaceKHR surface;
-
-    VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
-    memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
-    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
-    surfaceCreateInfo.pNext = nullptr;
-    surfaceCreateInfo.flags = 0;
-    surfaceCreateInfo.window = androidPlatformData->fNativeWindow;
-
-    VkResult res = createAndroidSurfaceKHR(instance, &surfaceCreateInfo,
-                                           nullptr, &surface);
-    return (VK_SUCCESS == res) ? surface : VK_NULL_HANDLE;
-}
-
-bool VulkanTestContext::canPresent(VkInstance instance, VkPhysicalDevice physDev,
-                                   uint32_t queueFamilyIndex) {
-    return true;
-}
diff --git a/tools/vulkan/android/VulkanTestContext_android.h b/tools/vulkan/android/VulkanTestContext_android.h
deleted file mode 100644 (file)
index 66ed35c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef VULKANTESTCONTEXT_ANDROID_DEFINED
-#define VULKANTESTCONTEXT_ANDROID_DEFINED
-
-#ifdef SK_VULKAN
-
-#include "../VulkanTestContext.h"
-
-struct ANativeWindow;
-
-struct ContextPlatformData_android {
-    ANativeWindow* fNativeWindow;
-};
-
-#endif // SK_VULKAN
-
-#endif
diff --git a/tools/vulkan/android/Window_android.cpp b/tools/vulkan/android/Window_android.cpp
deleted file mode 100644 (file)
index 87a4d22..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "Window_android.h"
-
-#include "VulkanTestContext_android.h"
-
-Window* Window::CreateNativeWindow(void* platformData) {
-    Window_android* window = new Window_android();
-    if (!window->init((android_app*)platformData)) {
-        delete window;
-        return nullptr;
-    }
-    return window;
-}
-
-static void handle_cmd(struct android_app* app, int32_t cmd);
-static int32_t handle_input(struct android_app* app, AInputEvent* event);
-
-bool Window_android::init(android_app* app) {
-    SkASSERT(app);
-    mApp = app;
-    mApp->userData = this;
-    mApp->onAppCmd = handle_cmd;
-    mApp->onInputEvent = handle_input;
-    return true;
-}
-
-void Window_android::setTitle(const char* title) {
-    //todo
-    SkDebugf("Title: %s", title);
-}
-
-bool Window_android::attach(BackEndType attachType, int msaaSampleCount) {
-    if (kVulkan_BackendType != attachType) {
-        return false;
-    }
-
-    mSampleCount = msaaSampleCount;
-
-    // We delay the creation of fTestContext until Android informs us that
-    // the native window is ready to use.
-    return true;
-}
-
-void Window_android::initDisplay(ANativeWindow* window) {
-    SkASSERT(window);
-    ContextPlatformData_android platformData;
-    platformData.fNativeWindow = window;
-    fTestContext = VulkanTestContext::Create((void*)&platformData, mSampleCount);
-}
-
-static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
-    if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
-        SkDebugf("Failure writing android_app cmd: %s\n", strerror(errno));
-    }
-}
-
-void Window_android::inval() {
-       android_app_write_cmd(mApp, APP_CMD_INVAL_WINDOW);
-}
-
-void Window_android::paintIfNeeded() {
-    if (mApp->window || !mContentRect.isEmpty()) {
-        this->onPaint();
-    }
-}
-
-/**
- * Process the next main command.
- */
-static void handle_cmd(struct android_app* app, int32_t cmd) {
-    Window_android* window = (Window_android*)app->userData;
-    switch (cmd) {
-        case APP_CMD_INIT_WINDOW:
-            // The window is being shown, get it ready.
-            SkASSERT(app->window);
-            window->initDisplay(app->window);
-            window->paintIfNeeded();
-            break;
-        case APP_CMD_WINDOW_RESIZED: {
-            int width = ANativeWindow_getWidth(app->window);
-            int height = ANativeWindow_getHeight(app->window);
-            window->onResize(width, height);
-            break;
-        }
-        case APP_CMD_CONTENT_RECT_CHANGED:
-            window->setContentRect(app->contentRect.left, app->contentRect.top,
-                                   app->contentRect.right, app->contentRect.bottom);
-            window->paintIfNeeded();
-            break;
-        case APP_CMD_TERM_WINDOW:
-            // The window is being hidden or closed, clean it up.
-            window->detach();
-            break;
-        case APP_CMD_INVAL_WINDOW:
-            window->paintIfNeeded();
-            break;
-    }
-}
-
-static Window::Key get_key(int32_t keycode) {
-    static const struct {
-        int32_t     fAndroidKey;
-        Window::Key fWindowKey;
-    } gPair[] = {
-        { AKEYCODE_BACK, Window::kBack_Key },
-        { AKEYCODE_VOLUME_UP, Window::kLeft_Key },
-        { AKEYCODE_VOLUME_DOWN, Window::kRight_Key }
-    };
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
-        if (gPair[i].fAndroidKey == keycode) {
-            return gPair[i].fWindowKey;
-        }
-    }
-    return Window::kNONE_Key;
-}
-
-static Window::InputState get_action(int32_t action) {
-    static const struct {
-        int32_t            fAndroidAction;
-        Window::InputState fInputState;
-    } gPair[] = {
-        { AKEY_STATE_DOWN, Window::kDown_InputState },
-        { AKEY_STATE_UP, Window::kUp_InputState },
-    };
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
-        if (gPair[i].fAndroidAction == action) {
-            return gPair[i].fInputState;
-        }
-    }
-    return Window::kMove_InputState;
-}
-
-static int32_t get_key_modifiers(AInputEvent* event) {
-    static const struct {
-        int32_t fAndroidState;
-        int32_t fWindowModifier;
-    } gPair[] = {
-        { AMETA_SHIFT_ON, Window::kShift_ModifierKey },
-        { AMETA_CTRL_ON, Window::kControl_ModifierKey },
-    };
-
-    int32_t metaState = AKeyEvent_getMetaState(event);
-    int32_t modifiers = 0;
-
-    if (AKeyEvent_getRepeatCount(event) == 0) {
-       modifiers |= Window::kFirstPress_ModifierKey;
-    }
-
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
-        if (gPair[i].fAndroidState == metaState) {
-            modifiers |= gPair[i].fWindowModifier;
-        }
-    }
-    return modifiers;
-}
-
-/**
- * Process the next input event.
- */
-static int32_t handle_input(struct android_app* app, AInputEvent* event) {
-    Window_android* window = (Window_android*)app->userData;
-    switch(AInputEvent_getType(event)) {
-        case AINPUT_EVENT_TYPE_MOTION:
-            break;
-        case AINPUT_EVENT_TYPE_KEY:
-            Window::Key key = get_key(AKeyEvent_getKeyCode(event));
-            Window::InputState state = get_action(AKeyEvent_getAction(event));
-            int32_t mod = get_key_modifiers(event);
-            window->onKey(key, state, mod);
-            return true; // eat all key events
-    }
-    return 0;
-}
diff --git a/tools/vulkan/android/Window_android.h b/tools/vulkan/android/Window_android.h
deleted file mode 100644 (file)
index fa675fe..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef Window_android_DEFINED
-#define Window_android_DEFINED
-
-#include "../Window.h"
-#include <android_native_app_glue.h>
-
-enum {
-    /**
-     * Leave plenty of space between this item and the ones defined in the glue layer
-     */
-       APP_CMD_INVAL_WINDOW = 64,
-};
-
-class Window_android : public Window {
-public:
-       Window_android() : Window() {}
-    ~Window_android() override {}
-
-    bool init(android_app* app_state);
-    void initDisplay(ANativeWindow* window);
-
-    void setTitle(const char*) override;
-    void show() override {}
-
-    bool attach(BackEndType attachType, int msaaSampleCount) override;
-    void inval() override;
-
-    void paintIfNeeded();
-
-    bool scaleContentToFit() const override { return true; }
-    bool supportsContentRect() const override { return true; }
-    SkRect getContentRect() override { return mContentRect; }
-    void setContentRect(int l, int t, int r, int b) { mContentRect.set(l,t,r,b); }
-
-private:
-    android_app* mApp = nullptr;
-    SkRect mContentRect;
-    int mSampleCount = 0;
-};
-
-#endif
diff --git a/tools/vulkan/android/main_android.cpp b/tools/vulkan/android/main_android.cpp
deleted file mode 100644 (file)
index 783cd1f..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include <jni.h>
-#include <errno.h>
-
-#include <android_native_app_glue.h>
-
-#include "../Application.h"
-#include "Timer.h"
-
-static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
-
-/**
- * This is the main entry point of a native application that is using
- * android_native_app_glue.  It runs in its own thread, with its own
- * event loop for receiving input events and doing other things.
- */
-void android_main(struct android_app* state) {
-    // Make sure glue isn't stripped.
-    app_dummy();
-
-    static const char* gCmdLine[] = {
-        "vulkanviewer",
-        "--skps",
-        "/data/local/tmp/skp",
-    };
-
-    std::unique_ptr<Application> vkApp(Application::Create(SK_ARRAY_COUNT(gCmdLine),
-                                                           const_cast<char**>(gCmdLine),
-                                                           state));
-
-    double currentTime = 0.0;
-    double previousTime = 0.0;
-
-    // loop waiting for stuff to do.
-    while (1) {
-        // Read all pending events.
-        int ident;
-        int events;
-        struct android_poll_source* source;
-
-        // block forever waiting for events.
-        while ((ident=ALooper_pollAll(-1, NULL, &events,
-                (void**)&source)) >= 0) {
-
-            // Process this event.
-            if (source != NULL) {
-                source->process(state, source);
-            }
-
-            // Check if we are exiting.
-            if (state->destroyRequested != 0) {
-                return;
-            }
-
-            previousTime = currentTime;
-            currentTime = now_ms();
-            vkApp->onIdle(currentTime - previousTime);
-        }
-    }
-}
-//END_INCLUDE(all)
diff --git a/tools/vulkan/viewer/GMSlide.cpp b/tools/vulkan/viewer/GMSlide.cpp
deleted file mode 100644 (file)
index 6096044..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-/*
-* Copyright 2014 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "GMSlide.h"
-#include "SkCanvas.h"
-
-GMSlide::GMSlide(skiagm::GM* gm) : fGM(gm) {
-    fName.printf("GM_%s", gm->getName());
-}
-
-GMSlide::~GMSlide() { delete fGM; }
-
-void GMSlide::draw(SkCanvas* canvas) {
-    // Do we care about timing the draw of the background (once)?
-    // Does the GM ever rely on drawBackground to lazily compute something?
-    fGM->drawBackground(canvas);
-    fGM->drawContent(canvas);
-}
-
-bool GMSlide::animate(const SkAnimTimer& timer) {
-    return fGM->animate(timer);
-}
diff --git a/tools/vulkan/viewer/GMSlide.h b/tools/vulkan/viewer/GMSlide.h
deleted file mode 100644 (file)
index 6b03527..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef GMSlide_DEFINED
-#define GMSlide_DEFINED
-
-#include "Slide.h"
-#include "gm.h"
-
-class GMSlide : public Slide {
-public:
-    GMSlide(skiagm::GM* gm);
-    ~GMSlide() override;
-
-    SkISize getDimensions() const override { return fGM->getISize(); }
-
-    void draw(SkCanvas* canvas) override;
-    bool animate(const SkAnimTimer&) override;
-
-private:
-    skiagm::GM* fGM;
-};
-
-
-#endif
diff --git a/tools/vulkan/viewer/SKPSlide.cpp b/tools/vulkan/viewer/SKPSlide.cpp
deleted file mode 100644 (file)
index 6a9899b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "SKPSlide.h"
-
-#include "SkCanvas.h"
-#include "SkCommonFlags.h"
-#include "SkOSFile.h"
-#include "SkStream.h"
-
-SKPSlide::SKPSlide(const SkString& name, const SkString& path) : fPath(path) {
-    fName = name;
-}
-
-SKPSlide::~SKPSlide() {}
-
-void SKPSlide::draw(SkCanvas* canvas) {
-    if (fPic.get()) {
-        bool isOffset = SkToBool(fCullRect.left() | fCullRect.top());
-        if (isOffset) {
-            canvas->save();
-            canvas->translate(SkIntToScalar(-fCullRect.left()), SkIntToScalar(-fCullRect.top()));
-        }
-
-        canvas->drawPicture(fPic.get());
-
-        if (isOffset) {
-            canvas->restore();
-        }
-    }
-}
-
-static sk_sp<SkPicture> read_picture(const char path[]) {
-    SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
-    if (stream.get() == nullptr) {
-        SkDebugf("Could not read %s.\n", path);
-        return nullptr;
-    }
-
-    auto pic = SkPicture::MakeFromStream(stream.get());
-    if (!pic) {
-        SkDebugf("Could not read %s as an SkPicture.\n", path);
-    }
-    return pic;
-}
-
-void SKPSlide::load() {
-    fPic = read_picture(fPath.c_str());
-    fCullRect = fPic->cullRect().roundOut();
-}
-
-void SKPSlide::unload() {
-    fPic.reset(nullptr);
-}
diff --git a/tools/vulkan/viewer/SKPSlide.h b/tools/vulkan/viewer/SKPSlide.h
deleted file mode 100644 (file)
index 42845fa..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef SKPSlide_DEFINED
-#define SKPSlide_DEFINED
-
-#include "Slide.h"
-#include "SkPicture.h"
-
-class SKPSlide : public Slide {
-public:
-    SKPSlide(const SkString& name, const SkString& path);
-    ~SKPSlide() override;
-
-    SkISize getDimensions() const override { return fCullRect.size(); }
-
-    void draw(SkCanvas* canvas) override;
-    void load() override;
-    void unload() override;
-
-private:
-    SkString               fPath;
-    sk_sp<const SkPicture> fPic;
-    SkIRect                fCullRect;
-};
-
-#endif
diff --git a/tools/vulkan/viewer/Slide.h b/tools/vulkan/viewer/Slide.h
deleted file mode 100644 (file)
index cdc225b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef Slide_DEFINED
-#define Slide_DEFINED
-
-#include "SkRefCnt.h"
-#include "SkSize.h"
-#include "SkString.h"
-
-class SkCanvas;
-class SkAnimTimer;
-
-class Slide : public SkRefCnt {
-public:
-    virtual ~Slide() {}
-
-    virtual SkISize getDimensions() const = 0;
-
-    virtual void draw(SkCanvas* canvas) = 0;
-    virtual bool animate(const SkAnimTimer&) { return false;  }
-    virtual void load() {}
-    virtual void unload() {}
-
-    SkString getName() { return fName; }
-
-protected:
-    SkString    fName;
-};
-
-
-#endif
diff --git a/tools/vulkan/viewer/VulkanViewer.cpp b/tools/vulkan/viewer/VulkanViewer.cpp
deleted file mode 100644 (file)
index 79c4968..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "VulkanViewer.h"
-
-#include "GMSlide.h"
-#include "SKPSlide.h"
-
-#include "SkCanvas.h"
-#include "SkCommonFlags.h"
-#include "SkOSFile.h"
-#include "SkRandom.h"
-#include "SkStream.h"
-
-Application* Application::Create(int argc, char** argv, void* platformData) {
-    return new VulkanViewer(argc, argv, platformData);
-}
-
-static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t modifiers,
-                           void* userData) {
-    VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData);
-
-    return vv->onKey(key, state, modifiers);
-}
-
-static bool on_char_handler(SkUnichar c, uint32_t modifiers, void* userData) {
-    VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData);
-
-    return vv->onChar(c, modifiers);
-}
-
-static void on_paint_handler(SkCanvas* canvas, void* userData) {
-    VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData);
-
-    return vv->onPaint(canvas);
-}
-
-DEFINE_bool2(fullscreen, f, true, "Run fullscreen.");
-DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON identifying this builder.");
-DEFINE_string2(match, m, nullptr,
-               "[~][^]substring[$] [...] of bench name to run.\n"
-               "Multiple matches may be separated by spaces.\n"
-               "~ causes a matching bench to always be skipped\n"
-               "^ requires the start of the bench to match\n"
-               "$ requires the end of the bench to match\n"
-               "^ and $ requires an exact match\n"
-               "If a bench does not match any list entry,\n"
-               "it is skipped unless some list entry starts with ~");
-DEFINE_string(skps, "skps", "Directory to read skps from.");
-
-VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData)
-    : fCurrentMeasurement(0)
-    , fDisplayStats(false)
-    , fZoomCenterX(0.0f)
-    , fZoomCenterY(0.0f)
-    , fZoomLevel(0.0f)
-    , fZoomScale(SK_Scalar1)
-{
-    memset(fMeasurements, 0, sizeof(fMeasurements));
-
-    SkDebugf("Command line arguments: ");
-    for (int i = 1; i < argc; ++i) {
-        SkDebugf("%s ", argv[i]);
-    }
-    SkDebugf("\n");
-
-    SkCommandLineFlags::Parse(argc, argv);
-
-    fWindow = Window::CreateNativeWindow(platformData);
-    fWindow->attach(Window::kVulkan_BackendType, 0);
-
-    // register callbacks
-    fWindow->registerKeyFunc(on_key_handler, this);
-    fWindow->registerCharFunc(on_char_handler, this);
-    fWindow->registerPaintFunc(on_paint_handler, this);
-
-    // set up slides
-    this->initSlides();
-
-    fAnimTimer.run();
-
-    // set up first frame
-    fCurrentSlide = 0;
-    setupCurrentSlide(-1);
-    updateMatrix();
-
-    fWindow->show();
-}
-
-void VulkanViewer::initSlides() {
-    const skiagm::GMRegistry* gms(skiagm::GMRegistry::Head());
-    while (gms) {
-        SkAutoTDelete<skiagm::GM> gm(gms->factory()(nullptr));
-
-        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gm->getName())) {
-            sk_sp<Slide> slide(new GMSlide(gm.release()));
-            fSlides.push_back(slide);
-        }
-
-        gms = gms->next();
-    }
-
-    // reverse array
-    for (int i = 0; i < fSlides.count()/2; ++i) {
-        sk_sp<Slide> temp = fSlides[i];
-        fSlides[i] = fSlides[fSlides.count() - i - 1];
-        fSlides[fSlides.count() - i - 1] = temp;
-    }
-
-    // SKPs
-    for (int i = 0; i < FLAGS_skps.count(); i++) {
-        if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
-            if (SkCommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) {
-                continue;
-            }
-
-            SkString path(FLAGS_skps[i]);
-            sk_sp<SKPSlide> slide(new SKPSlide(SkOSPath::Basename(path.c_str()), path));
-            if (slide) {
-                fSlides.push_back(slide);
-            }
-        } else {
-            SkOSFile::Iter it(FLAGS_skps[i], ".skp");
-            SkString skpName;
-            while (it.next(&skpName)) {
-                if (SkCommandLineFlags::ShouldSkip(FLAGS_match, skpName.c_str())) {
-                    continue;
-                }
-
-                SkString path = SkOSPath::Join(FLAGS_skps[i], skpName.c_str());
-                sk_sp<SKPSlide> slide(new SKPSlide(skpName, path));
-                if (slide) {
-                    fSlides.push_back(slide);
-                }
-            }
-        }
-    }
-}
-
-
-VulkanViewer::~VulkanViewer() {
-    fWindow->detach();
-    delete fWindow;
-}
-
-void VulkanViewer::setupCurrentSlide(int previousSlide) {
-    SkString title("VulkanViewer: ");
-    title.append(fSlides[fCurrentSlide]->getName());
-    fSlides[fCurrentSlide]->load();
-    if (previousSlide >= 0) {
-        fSlides[previousSlide]->unload();
-    }
-    fWindow->setTitle(title.c_str());
-    fWindow->inval();
-}
-
-#define MAX_ZOOM_LEVEL  8
-#define MIN_ZOOM_LEVEL  -8
-
-void VulkanViewer::changeZoomLevel(float delta) {
-    fZoomLevel += delta;
-    if (fZoomLevel > 0) {
-        fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL);
-        fZoomScale = fZoomLevel + SK_Scalar1;
-    } else if (fZoomLevel < 0) {
-        fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL);
-        fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel);
-    } else {
-        fZoomScale = SK_Scalar1;
-    }
-    this->updateMatrix();
-}
-
-void VulkanViewer::updateMatrix(){
-    SkMatrix m;
-    m.reset();
-
-    if (fZoomLevel) {
-        SkPoint center;
-        //m = this->getLocalMatrix();//.invert(&m);
-        m.mapXY(fZoomCenterX, fZoomCenterY, &center);
-        SkScalar cx = center.fX;
-        SkScalar cy = center.fY;
-
-        m.setTranslate(-cx, -cy);
-        m.postScale(fZoomScale, fZoomScale);
-        m.postTranslate(cx, cy);
-    }
-
-    // TODO: add gesture support
-    // Apply any gesture matrix
-    //m.preConcat(fGesture.localM());
-    //m.preConcat(fGesture.globalM());
-
-    fLocalMatrix = m;
-}
-
-bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) {
-    if (Window::kDown_InputState == state) {
-        switch (key) {
-            case Window::kRight_Key: {
-                int previousSlide = fCurrentSlide;
-                fCurrentSlide++;
-                if (fCurrentSlide >= fSlides.count()) {
-                    fCurrentSlide = 0;
-                }
-                setupCurrentSlide(previousSlide);
-                return true;
-            }
-
-            case Window::kLeft_Key: {
-                int previousSlide = fCurrentSlide;
-                fCurrentSlide--;
-                if (fCurrentSlide < 0) {
-                    fCurrentSlide = fSlides.count() - 1;
-                }
-                SkString title("VulkanViewer: ");
-                title.append(fSlides[fCurrentSlide]->getName());
-                fWindow->setTitle(title.c_str());
-                setupCurrentSlide(previousSlide);
-                return true;
-            }
-
-            case Window::kUp_Key: {
-                this->changeZoomLevel(1.f / 32.f);
-                fWindow->inval();
-                return true;
-            }
-
-            case Window::kDown_Key: {
-                this->changeZoomLevel(-1.f / 32.f);
-                fWindow->inval();
-                return true;
-            }
-
-            default:
-                break;
-        }
-    }
-
-    return false;
-}
-
-bool VulkanViewer::onChar(SkUnichar c, uint32_t modifiers) {
-    if ('s' == c) {
-        fDisplayStats = !fDisplayStats;
-        return true;
-    }
-
-    return false;
-}
-
-void VulkanViewer::onPaint(SkCanvas* canvas) {
-
-    int count = canvas->save();
-
-    if (fWindow->supportsContentRect()) {
-        SkRect contentRect = fWindow->getContentRect();
-        canvas->clipRect(contentRect);
-        canvas->translate(contentRect.fLeft, contentRect.fTop);
-    }
-
-    canvas->clear(SK_ColorWHITE);
-    if (fWindow->supportsContentRect() && fWindow->scaleContentToFit()) {
-        const SkRect contentRect = fWindow->getContentRect();
-        const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
-        const SkRect slideBounds = SkRect::MakeIWH(slideSize.width(), slideSize.height());
-        SkMatrix matrix;
-        matrix.setRectToRect(slideBounds, contentRect, SkMatrix::kCenter_ScaleToFit);
-        canvas->concat(matrix);
-    }
-    canvas->concat(fLocalMatrix);
-
-    fSlides[fCurrentSlide]->draw(canvas);
-    canvas->restoreToCount(count);
-
-    if (fDisplayStats) {
-        drawStats(canvas);
-    }
-}
-
-void VulkanViewer::drawStats(SkCanvas* canvas) {
-    static const float kPixelPerMS = 2.0f;
-    static const int kDisplayWidth = 130;
-    static const int kDisplayHeight = 100;
-    static const int kDisplayPadding = 10;
-    static const int kGraphPadding = 3;
-    static const SkScalar kBaseMS = 1000.f / 60.f;  // ms/frame to hit 60 fps
-
-    SkISize canvasSize = canvas->getDeviceSize();
-    SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth-kDisplayWidth-kDisplayPadding),
-                                   SkIntToScalar(kDisplayPadding),
-                                   SkIntToScalar(kDisplayWidth), SkIntToScalar(kDisplayHeight));
-    SkPaint paint;
-    canvas->save();
-
-    if (fWindow->supportsContentRect()) {
-        SkRect contentRect = fWindow->getContentRect();
-        canvas->clipRect(contentRect);
-        canvas->translate(contentRect.fLeft, contentRect.fTop);
-    }
-
-    canvas->clipRect(rect);
-    paint.setColor(SK_ColorBLACK);
-    canvas->drawRect(rect, paint);
-    // draw the 16ms line
-    paint.setColor(SK_ColorLTGRAY);
-    canvas->drawLine(rect.fLeft, rect.fBottom - kBaseMS*kPixelPerMS,
-                     rect.fRight, rect.fBottom - kBaseMS*kPixelPerMS, paint);
-    paint.setColor(SK_ColorRED);
-    paint.setStyle(SkPaint::kStroke_Style);
-    canvas->drawRect(rect, paint);
-
-    int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding;
-    const int xStep = 2;
-    const int startY = SkScalarTruncToInt(rect.fBottom);
-    int i = fCurrentMeasurement;
-    do {
-        int endY = startY - (int)(fMeasurements[i] * kPixelPerMS + 0.5);  // round to nearest value
-        canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
-                         SkIntToScalar(x), SkIntToScalar(endY), paint);
-        i++;
-        i &= (kMeasurementCount - 1);  // fast mod
-        x += xStep;
-    } while (i != fCurrentMeasurement);
-
-    canvas->restore();
-}
-
-void VulkanViewer::onIdle(double ms) {
-    // Record measurements
-    fMeasurements[fCurrentMeasurement++] = ms;
-    fCurrentMeasurement &= (kMeasurementCount - 1);  // fast mod
-    SkASSERT(fCurrentMeasurement < kMeasurementCount);
-
-    fAnimTimer.updateTime();
-    if (fSlides[fCurrentSlide]->animate(fAnimTimer) || fDisplayStats) {
-        fWindow->inval();
-    }
-}
diff --git a/tools/vulkan/viewer/VulkanViewer.h b/tools/vulkan/viewer/VulkanViewer.h
deleted file mode 100644 (file)
index 7e39f88..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef VulkanViewer_DEFINED
-#define VulkanViewer_DEFINED
-
-#include "../Application.h"
-#include "../Window.h"
-#include "gm.h"
-#include "SkAnimTimer.h"
-#include "Slide.h"
-
-class SkCanvas;
-
-class VulkanViewer : public Application {
-public:
-    VulkanViewer(int argc, char** argv, void* platformData);
-    ~VulkanViewer() override;
-
-    bool onKey(Window::Key key, Window::InputState state, uint32_t modifiers);
-    bool onChar(SkUnichar, uint32_t modifiers);
-    void onPaint(SkCanvas* canvas);
-    void onIdle(double ms) override;
-
-private:
-    void initSlides();
-    void setupCurrentSlide(int previousSlide);
-
-    void drawStats(SkCanvas* canvas);
-
-    void changeZoomLevel(float delta);
-    void updateMatrix();
-
-    Window*      fWindow;
-
-    static const int kMeasurementCount = 64;  // should be power of 2 for fast mod
-    double fMeasurements[kMeasurementCount];
-    int fCurrentMeasurement;
-
-    SkAnimTimer            fAnimTimer;
-    SkTArray<sk_sp<Slide>> fSlides;
-    int                    fCurrentSlide;
-
-    bool                   fDisplayStats;
-
-    // transform data
-    SkMatrix               fLocalMatrix;
-    SkScalar               fZoomCenterX;
-    SkScalar               fZoomCenterY;
-    SkScalar               fZoomLevel;
-    SkScalar               fZoomScale;
-
-};
-
-
-#endif
diff --git a/tools/vulkan/win/VulkanTestContext_win.cpp b/tools/vulkan/win/VulkanTestContext_win.cpp
deleted file mode 100644 (file)
index 37ef667..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "VulkanTestContext_win.h"
-
-#include "vk/GrVkInterface.h"
-#include "vk/GrVkUtil.h"
-
-// Platform dependant call
-VkSurfaceKHR VulkanTestContext::createVkSurface(VkInstance instance, void* platformData) {
-    static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
-    if (!createWin32SurfaceKHR) {
-        createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(instance,
-                                                                         "vkCreateWin32SurfaceKHR");
-    }
-
-    if (!platformData) {
-        return VK_NULL_HANDLE;
-    }
-    ContextPlatformData_win* winPlatformData = 
-                                           reinterpret_cast<ContextPlatformData_win*>(platformData);
-    VkSurfaceKHR surface;
-
-    VkWin32SurfaceCreateInfoKHR surfaceCreateInfo;
-    memset(&surfaceCreateInfo, 0, sizeof(VkWin32SurfaceCreateInfoKHR));
-    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
-    surfaceCreateInfo.pNext = nullptr;
-    surfaceCreateInfo.flags = 0;
-    surfaceCreateInfo.hinstance = winPlatformData->fHInstance;
-    surfaceCreateInfo.hwnd = winPlatformData->fHWnd;
-
-    VkResult res = createWin32SurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
-    if (VK_SUCCESS != res) {
-        return VK_NULL_HANDLE;
-    }
-
-    return surface;
-}
-
-// Platform dependant call
-bool VulkanTestContext::canPresent(VkInstance instance, VkPhysicalDevice physDev, 
-                                   uint32_t queueFamilyIndex) {
-    static PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR 
-                                             getPhysicalDeviceWin32PresentationSupportKHR = nullptr;
-    if (!getPhysicalDeviceWin32PresentationSupportKHR) {
-        getPhysicalDeviceWin32PresentationSupportKHR = 
-            (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) vkGetInstanceProcAddr(instance,
-                                                  "vkGetPhysicalDeviceWin32PresentationSupportKHR");
-    }
-
-    VkBool32 check = getPhysicalDeviceWin32PresentationSupportKHR(physDev, queueFamilyIndex);
-    return (VK_FALSE != check);
-}
diff --git a/tools/vulkan/win/VulkanTestContext_win.h b/tools/vulkan/win/VulkanTestContext_win.h
deleted file mode 100644 (file)
index 59b5c2c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef VULKANTESTCONTEXT_WIN_DEFINED
-#define VULKANTESTCONTEXT_WIN_DEFINED
-
-#ifdef SK_VULKAN
-
-#include <windows.h>
-#include "../VulkanTestContext.h"
-
-// for Windows
-struct ContextPlatformData_win {
-    HINSTANCE fHInstance;
-    HWND      fHWnd;
-};
-
-#endif // SK_VULKAN
-
-#endif
diff --git a/tools/vulkan/win/Window_win.cpp b/tools/vulkan/win/Window_win.cpp
deleted file mode 100644 (file)
index 58224d6..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "Window_win.h"
-
-#include <tchar.h>
-#include <windows.h>
-#include <windowsx.h>
-
-#include "SkUtils.h"
-#include "VulkanTestContext_win.h"
-
-Window* Window::CreateNativeWindow(void* platformData) {
-    HINSTANCE hInstance = (HINSTANCE)platformData;
-
-    Window_win* window = new Window_win();
-    if (!window->init(hInstance)) {
-        delete window;
-        return nullptr;
-    }
-
-    return window;
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-
-bool Window_win::init(HINSTANCE hInstance) {
-    fHInstance = hInstance ? hInstance : GetModuleHandle(nullptr);
-
-    WNDCLASSEX wcex;
-    // The main window class name
-    static const TCHAR gSZWindowClass[] = _T("SkiaApp");
-
-    wcex.cbSize = sizeof(WNDCLASSEX);
-
-    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
-    wcex.lpfnWndProc = WndProc;
-    wcex.cbClsExtra = 0;
-    wcex.cbWndExtra = 0;
-    wcex.hInstance = fHInstance;
-    wcex.hIcon = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);
-    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);;
-    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    wcex.lpszMenuName = nullptr;
-    wcex.lpszClassName = gSZWindowClass;
-    wcex.hIconSm = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);;
-
-    if (!RegisterClassEx(&wcex)) {
-        return false;
-    }
-
-   /*
-    if (fullscreen)
-    {
-        DEVMODE dmScreenSettings;
-        // If full screen set the screen to maximum size of the users desktop and 32bit.
-        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
-        dmScreenSettings.dmSize = sizeof(dmScreenSettings);
-        dmScreenSettings.dmPelsWidth = (unsigned long)width;
-        dmScreenSettings.dmPelsHeight = (unsigned long)height;
-        dmScreenSettings.dmBitsPerPel = 32;
-        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-
-        // Change the display settings to full screen.
-        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
-
-        // Set the position of the window to the top left corner.
-        posX = posY = 0;
-    } 
-    */
- //   gIsFullscreen = fullscreen;
-
-    fHWnd = CreateWindow(gSZWindowClass, nullptr, WS_OVERLAPPEDWINDOW,
-                         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, fHInstance, nullptr);
-    if (!fHWnd)
-    {
-        return false;
-    }
-
-    SetWindowLongPtr(fHWnd, GWLP_USERDATA, (LONG_PTR)this);
-
-    return true;
-}
-
-static Window::Key get_key(WPARAM vk) {
-    static const struct {
-        WPARAM      fVK;
-        Window::Key fKey;
-    } gPair[] = {
-        { VK_BACK, Window::kBack_Key },
-        { VK_CLEAR, Window::kBack_Key },
-        { VK_RETURN, Window::kOK_Key },
-        { VK_UP, Window::kUp_Key },
-        { VK_DOWN, Window::kDown_Key },
-        { VK_LEFT, Window::kLeft_Key },
-        { VK_RIGHT, Window::kRight_Key }
-    };
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
-        if (gPair[i].fVK == vk) {
-            return gPair[i].fKey;
-        }
-    }
-    return Window::kNONE_Key;
-}
-
-static uint32_t get_modifiers(UINT message, WPARAM wParam, LPARAM lParam) {
-    uint32_t modifiers = 0;
-
-    switch (message) {
-        case WM_UNICHAR:
-        case WM_CHAR:
-            if (0 == (lParam & (1 << 30))) {
-                modifiers |= Window::kFirstPress_ModifierKey;
-            }
-            if (lParam & (1 << 29)) {
-                modifiers |= Window::kOption_ModifierKey;
-            }
-            break;
-
-        case WM_KEYDOWN:
-        case WM_SYSKEYDOWN:
-            if (0 == (lParam & (1 << 30))) {
-                modifiers |= Window::kFirstPress_ModifierKey;
-            }
-            if (lParam & (1 << 29)) {
-                modifiers |= Window::kOption_ModifierKey;
-            }
-            break;
-
-        case WM_KEYUP:
-        case WM_SYSKEYUP:
-            if (lParam & (1 << 29)) {
-                modifiers |= Window::kOption_ModifierKey;
-            }
-            break;
-
-        case WM_LBUTTONDOWN:
-        case WM_LBUTTONUP:
-        case WM_MOUSEMOVE:
-            if (wParam & MK_CONTROL) {
-                modifiers |= Window::kControl_ModifierKey;
-            }
-            if (wParam & MK_SHIFT) {
-                modifiers |= Window::kShift_ModifierKey;
-            }
-    }
-
-    return modifiers;
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-    PAINTSTRUCT ps;
-    HDC hdc;
-
-    Window_win* window = (Window_win*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-    bool eventHandled = false;
-
-    switch (message) {
-        case WM_PAINT:
-            hdc = BeginPaint(hWnd, &ps);
-            window->onPaint();
-            EndPaint(hWnd, &ps);
-            eventHandled = true;
-            break;
-
-        case WM_CLOSE:
-        case WM_DESTROY:
-            PostQuitMessage(0);
-            eventHandled = true;
-            break;
-
-        case WM_ACTIVATE:
-            // disable/enable rendering here, depending on wParam != WA_INACTIVE
-            break;
-
-        case WM_SIZE:
-            window->onResize(LOWORD(lParam), HIWORD(lParam));
-            eventHandled = true;
-            break;
-
-        case WM_UNICHAR:
-            eventHandled = window->onChar((SkUnichar)wParam, 
-                                          get_modifiers(message, wParam, lParam));
-            break;
-
-        case WM_CHAR: {
-            const uint16_t* c = reinterpret_cast<uint16_t*>(&wParam);
-            eventHandled = window->onChar(SkUTF16_NextUnichar(&c), 
-                                          get_modifiers(message, wParam, lParam));
-        } break;
-
-        case WM_KEYDOWN:
-        case WM_SYSKEYDOWN:
-            eventHandled = window->onKey(get_key(wParam), Window::kDown_InputState, 
-                                         get_modifiers(message, wParam, lParam));
-            break;
-
-        case WM_KEYUP:
-        case WM_SYSKEYUP:
-            eventHandled = window->onKey(get_key(wParam), Window::kUp_InputState,
-                                         get_modifiers(message, wParam, lParam));
-            break;
-
-        case WM_LBUTTONDOWN:
-        case WM_LBUTTONUP: {
-            int xPos = GET_X_LPARAM(lParam);
-            int yPos = GET_Y_LPARAM(lParam);
-
-            //if (!gIsFullscreen)
-            //{
-            //    RECT rc = { 0, 0, 640, 480 };
-            //    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
-            //    xPos -= rc.left;
-            //    yPos -= rc.top;
-            //}
-
-            Window::InputState istate = ((wParam & MK_LBUTTON) != 0) ? Window::kDown_InputState
-                                                                     : Window::kUp_InputState;
-
-            eventHandled = window->onMouse(xPos, yPos, istate, 
-                                            get_modifiers(message, wParam, lParam));
-        } break;
-
-        case WM_MOUSEMOVE: 
-            // only track if left button is down
-            if ((wParam & MK_LBUTTON) != 0) {
-                int xPos = GET_X_LPARAM(lParam);
-                int yPos = GET_Y_LPARAM(lParam);
-
-                //if (!gIsFullscreen)
-                //{
-                //    RECT rc = { 0, 0, 640, 480 };
-                //    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
-                //    xPos -= rc.left;
-                //    yPos -= rc.top;
-                //}
-
-                eventHandled = window->onMouse(xPos, yPos, Window::kMove_InputState,
-                                               get_modifiers(message, wParam, lParam));
-            }
-            break;
-
-        default:
-            return DefWindowProc(hWnd, message, wParam, lParam);
-    }
-
-    return eventHandled ? 0 : 1;
-}
-
-void Window_win::setTitle(const char* title) {
-    SetWindowTextA(fHWnd, title);
-}
-
-void Window_win::show() {
-    ShowWindow(fHWnd, SW_SHOW);
-}
-
-
-bool Window_win::attach(BackEndType attachType, int msaaSampleCount) {
-    if (kVulkan_BackendType != attachType) {
-        return false;
-    }
-
-    ContextPlatformData_win platformData;
-    platformData.fHInstance = fHInstance;
-    platformData.fHWnd = fHWnd;
-
-    fTestContext = VulkanTestContext::Create((void*)&platformData, msaaSampleCount);
-
-    return (SkToBool(fTestContext));
-}
-
-void Window_win::inval() {
-    InvalidateRect(fHWnd, nullptr, false);
-}
diff --git a/tools/vulkan/win/Window_win.h b/tools/vulkan/win/Window_win.h
deleted file mode 100644 (file)
index 127fa13..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef Window_win_DEFINED
-#define Window_win_DEFINED
-
-#include <windows.h>
-#include "../Window.h"
-
-class Window_win : public Window {
-public:
-    Window_win() : Window() {}
-    ~Window_win() override {}
-
-    bool init(HINSTANCE instance);
-
-    void setTitle(const char*) override;
-    void show() override;
-
-    bool attach(BackEndType attachType, int msaaSampleCount) override;
-
-    void inval() override;
-
-private:
-    HINSTANCE fHInstance;
-    HWND      fHWnd;
-};
-
-#endif
diff --git a/tools/vulkan/win/main_win.cpp b/tools/vulkan/win/main_win.cpp
deleted file mode 100644 (file)
index c2ad6da..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-* Copyright 2016 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include <windows.h>
-#include <tchar.h>
-
-#include "SkTypes.h"
-#include "Timer.h"
-#include "Window_win.h"
-#include "../Application.h"
-
-static char* tchar_to_utf8(const TCHAR* str) {
-#ifdef _UNICODE
-    int size = WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), NULL, 0, NULL, NULL);
-    char* str8 = (char*)sk_malloc_throw(size + 1);
-    WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), str8, size, NULL, NULL);
-    str8[size] = '\0';
-    return str8;
-#else
-    return _strdup(str);
-#endif
-}
-
-static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
-
-// This file can work with GUI or CONSOLE subsystem types since we define _tWinMain and main().
-
-static int main_common(HINSTANCE hInstance, int show, int argc, char**argv);
-
-int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
-                       int nCmdShow) {
-
-    // convert from lpCmdLine to argc, argv.
-    char* argv[4096];
-    int argc = 0;
-    TCHAR exename[1024], *next;
-    int exenameLen = GetModuleFileName(NULL, exename, SK_ARRAY_COUNT(exename));
-    // we're ignoring the possibility that the exe name exceeds the exename buffer
-    (void)exenameLen;
-    argv[argc++] = tchar_to_utf8(exename);
-    TCHAR* arg = _tcstok_s(lpCmdLine, _T(" "), &next);
-    while (arg != NULL) {
-        argv[argc++] = tchar_to_utf8(arg);
-        arg = _tcstok_s(NULL, _T(" "), &next);
-    }
-    int result = main_common(hInstance, nCmdShow, argc, argv);
-    for (int i = 0; i < argc; ++i) {
-        sk_free(argv[i]);
-    }
-    return result;
-}
-
-int main(int argc, char**argv) {
-    return main_common(GetModuleHandle(NULL), SW_SHOW, argc, argv);
-}
-
-static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) {
-
-    Application* app = Application::Create(argc, argv, (void*)hInstance);
-
-    MSG msg = { 0 };
-
-    double currentTime = 0.0;
-    double previousTime = 0.0;
-
-    // Main message loop
-    while (WM_QUIT != msg.message) {
-        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
-            TranslateMessage(&msg);
-            DispatchMessage(&msg);
-        } else {
-            previousTime = currentTime;
-            currentTime = now_ms();
-            app->onIdle(currentTime - previousTime);
-        }
-    }
-
-    delete app;
-
-    return (int)msg.wParam;
-}