libvulkan: Set window transform based on swapchain preTransform

Bug: 26927663
Change-Id: I385a363dccbeae2329d25712d30dc629fdce2074
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index c40636e..5fefc62 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -154,6 +154,32 @@
     }
 }
 
+int InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform) {
+    switch (transform) {
+        case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
+            return NATIVE_WINDOW_TRANSFORM_ROT_270;
+        case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
+            return NATIVE_WINDOW_TRANSFORM_ROT_180;
+        case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
+            return NATIVE_WINDOW_TRANSFORM_ROT_90;
+        // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform.
+        // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
+        //     return NATIVE_WINDOW_TRANSFORM_FLIP_H;
+        // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
+        //     return NATIVE_WINDOW_TRANSFORM_FLIP_H |
+        //            NATIVE_WINDOW_TRANSFORM_ROT_90;
+        // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
+        //     return NATIVE_WINDOW_TRANSFORM_FLIP_V;
+        // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
+        //     return NATIVE_WINDOW_TRANSFORM_FLIP_V |
+        //            NATIVE_WINDOW_TRANSFORM_ROT_90;
+        case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
+        case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
+        default:
+            return 0;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 struct Surface {
@@ -455,6 +481,26 @@
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
+    // VkSwapchainCreateInfo::preTransform indicates the transformation the app
+    // applied during rendering. native_window_set_transform() expects the
+    // inverse: the transform the app is requesting that the compositor perform
+    // during composition. With native windows, pre-transform works by rendering
+    // with the same transform the compositor is applying (as in Vulkan), but
+    // then requesting the inverse transform, so that when the compositor does
+    // it's job the two transforms cancel each other out and the compositor ends
+    // up applying an identity transform to the app's buffer.
+    err = native_window_set_buffers_transform(
+        surface.window.get(),
+        InvertTransformToNative(create_info->preTransform));
+    if (err != 0) {
+        // TODO(jessehall): Improve error reporting. Can we enumerate possible
+        // errors and translate them to valid Vulkan result codes?
+        ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
+              InvertTransformToNative(create_info->preTransform),
+              strerror(-err), err);
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
     err = native_window_set_scaling_mode(
         surface.window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
     if (err != 0) {