react-native-cesium 1.2.17 → 1.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -607,6 +607,32 @@ void VulkanBackend::createSwapchain() {
607
607
  VkSwapchainCreateInfoKHR swapInfo{};
608
608
  swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
609
609
  swapInfo.surface = surface_;
610
+ // ── Surface rotation (Android pre-rotation) ──────────────────────────────
611
+ // We deliberately let the Android Compositor handle device rotation instead
612
+ // of pre-rotating the scene ourselves: present with an IDENTITY transform so
613
+ // the presentation engine rotates the rendered image to the current device
614
+ // orientation before scan-out.
615
+ //
616
+ // The alternative — preTransform = caps.currentTransform — only renders
617
+ // correctly if the app ALSO swaps the swapchain extent for 90/270 rotations
618
+ // AND bakes a matching rotation into every MVP/VP matrix. Doing neither (as
619
+ // before) made the scene render sideways once the device left its identity
620
+ // orientation: in landscape Android reports ROTATE_90/270, the compositor
621
+ // was told "already handled", and the un-rotated terrain appeared rotated
622
+ // 90° (ground stuck on the side of the screen). Since the swapchain image is
623
+ // the engine's only render target and modern Android display processors
624
+ // rotate essentially for free, the compositor path is both correct and cheap.
625
+ //
626
+ // Consequence: while the device is rotated, preTransform != currentTransform,
627
+ // so vkAcquireNextImageKHR / vkQueuePresentKHR return VK_SUBOPTIMAL_KHR every
628
+ // frame. That is expected here and must NOT trigger swapchain recreation (see
629
+ // beginFrame() / endFrame()); genuine size/orientation changes are driven by
630
+ // surfaceChanged() -> resize() instead.
631
+ VkSurfaceTransformFlagBitsKHR preTransform = caps.currentTransform;
632
+ if (caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
633
+ preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
634
+ }
635
+
610
636
  swapInfo.minImageCount = imageCount;
611
637
  swapInfo.imageFormat = swapchainFormat_;
612
638
  swapInfo.imageColorSpace = colorSpace;
@@ -614,7 +640,7 @@ void VulkanBackend::createSwapchain() {
614
640
  swapInfo.imageArrayLayers = 1;
615
641
  swapInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
616
642
  swapInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
617
- swapInfo.preTransform = caps.currentTransform;
643
+ swapInfo.preTransform = preTransform;
618
644
  swapInfo.compositeAlpha = compositeAlpha;
619
645
  swapInfo.presentMode = pickPresentMode();
620
646
  swapInfo.clipped = VK_TRUE;
@@ -2076,13 +2102,18 @@ void VulkanBackend::beginFrame(const FrameParams& /*params*/) {
2076
2102
  frameBegan_ = false;
2077
2103
  return;
2078
2104
  }
2079
- if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
2105
+ // Only OUT_OF_DATE forces a recreate. VK_SUBOPTIMAL_KHR is expected on every
2106
+ // frame while the device is rotated: we present with an IDENTITY preTransform
2107
+ // and let the compositor rotate (see createSwapchain). The acquired image is
2108
+ // still valid, so we proceed and use it. Genuine size/orientation changes
2109
+ // arrive via surfaceChanged() -> resize() -> needsSwapchainRecreate_.
2110
+ if (result == VK_ERROR_OUT_OF_DATE_KHR) {
2080
2111
  recreateSwapchain();
2081
2112
  result = vkAcquireNextImageKHR(device_, swapchain_, UINT64_MAX,
2082
2113
  imageAvailableSemaphores_[frameIndex_],
2083
2114
  VK_NULL_HANDLE, &imageIndex_);
2084
2115
  }
2085
- if (result != VK_SUCCESS) {
2116
+ if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
2086
2117
  frameBegan_ = false;
2087
2118
  return;
2088
2119
  }
@@ -2355,7 +2386,12 @@ void VulkanBackend::endFrame() {
2355
2386
  presentInfo.pImageIndices = &imageIndex_;
2356
2387
 
2357
2388
  VkResult result = vkQueuePresentKHR(presentQueue_, &presentInfo);
2358
- if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
2389
+ // VK_SUBOPTIMAL_KHR is expected every frame while the device is rotated (we
2390
+ // present an IDENTITY preTransform and let the compositor rotate — see
2391
+ // createSwapchain), so it must NOT trigger a recreate or we'd thrash the
2392
+ // swapchain every frame. Real changes come through surfaceChanged() ->
2393
+ // resize() -> needsSwapchainRecreate_.
2394
+ if (result == VK_ERROR_OUT_OF_DATE_KHR) {
2359
2395
  needsSwapchainRecreate_ = true;
2360
2396
  }
2361
2397
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-cesium",
3
- "version": "1.2.17",
3
+ "version": "1.2.18",
4
4
  "description": "Experimental Cesium rendering for React Native via Nitro",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",