summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/VulkanSurface.cpp
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2020-08-31 21:21:38 -0700
committerXin Li <delphij@google.com>2020-08-31 21:21:38 -0700
commit628590d7ec80e10a3fc24b1c18a1afb55cca10a8 (patch)
tree4b1c3f52d86d7fb53afbe9e9438468588fa489f8 /libs/hwui/renderthread/VulkanSurface.cpp
parentb11b8ec3aec8bb42f2c07e1c5ac7942da293baa8 (diff)
parentd2d3a20624d968199353ccf6ddbae6f3ac39c9af (diff)
Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)
Bug: 166295507 Merged-In: I3d92a6de21a938f6b352ec26dc23420c0fe02b27 Change-Id: Ifdb80563ef042738778ebb8a7581a97c4e3d96e2
Diffstat (limited to 'libs/hwui/renderthread/VulkanSurface.cpp')
-rw-r--r--libs/hwui/renderthread/VulkanSurface.cpp374
1 files changed, 146 insertions, 228 deletions
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index b2cc23e76b8a..a7ea21d8c4de 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -27,38 +27,14 @@ namespace android {
namespace uirenderer {
namespace renderthread {
-static bool IsTransformSupported(int transform) {
- // For now, only support pure rotations, not flip or flip-and-rotate, until we have
- // more time to test them and build sample code. As far as I know we never actually
- // use anything besides pure rotations anyway.
- return transform == 0 || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 ||
- transform == NATIVE_WINDOW_TRANSFORM_ROT_180 ||
- transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
-}
-
static int InvertTransform(int transform) {
switch (transform) {
- case NATIVE_WINDOW_TRANSFORM_ROT_90:
- return NATIVE_WINDOW_TRANSFORM_ROT_270;
- case NATIVE_WINDOW_TRANSFORM_ROT_180:
- return NATIVE_WINDOW_TRANSFORM_ROT_180;
- case NATIVE_WINDOW_TRANSFORM_ROT_270:
- return NATIVE_WINDOW_TRANSFORM_ROT_90;
- default:
- return 0;
- }
-}
-
-static int ConvertVkTransformToNative(VkSurfaceTransformFlagsKHR 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;
- case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
- case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
+ case ANATIVEWINDOW_TRANSFORM_ROTATE_90:
+ return ANATIVEWINDOW_TRANSFORM_ROTATE_270;
+ case ANATIVEWINDOW_TRANSFORM_ROTATE_180:
+ return ANATIVEWINDOW_TRANSFORM_ROTATE_180;
+ case ANATIVEWINDOW_TRANSFORM_ROTATE_270:
+ return ANATIVEWINDOW_TRANSFORM_ROTATE_90;
default:
return 0;
}
@@ -71,11 +47,11 @@ static SkMatrix GetPreTransformMatrix(SkISize windowSize, int transform) {
switch (transform) {
case 0:
return SkMatrix::I();
- case NATIVE_WINDOW_TRANSFORM_ROT_90:
+ case ANATIVEWINDOW_TRANSFORM_ROTATE_90:
return SkMatrix::MakeAll(0, -1, height, 1, 0, 0, 0, 0, 1);
- case NATIVE_WINDOW_TRANSFORM_ROT_180:
+ case ANATIVEWINDOW_TRANSFORM_ROTATE_180:
return SkMatrix::MakeAll(-1, 0, width, 0, -1, height, 0, 0, 1);
- case NATIVE_WINDOW_TRANSFORM_ROT_270:
+ case ANATIVEWINDOW_TRANSFORM_ROTATE_270:
return SkMatrix::MakeAll(0, 1, 0, -1, 0, width, 0, 0, 1);
default:
LOG_ALWAYS_FATAL("Unsupported Window Transform (%d)", transform);
@@ -83,180 +59,157 @@ static SkMatrix GetPreTransformMatrix(SkISize windowSize, int transform) {
return SkMatrix::I();
}
-void VulkanSurface::ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
- const SkISize& maxSize) {
- SkISize& windowSize = windowInfo->size;
-
- // clamp width & height to handle currentExtent of -1 and protect us from broken hints
- if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() ||
- windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
- int width = std::min(maxSize.width(), std::max(minSize.width(), windowSize.width()));
- int height = std::min(maxSize.height(), std::max(minSize.height(), windowSize.height()));
- ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", windowSize.width(),
- windowSize.height(), width, height);
- windowSize.set(width, height);
- }
-
- windowInfo->actualSize = windowSize;
- if (windowInfo->transform & HAL_TRANSFORM_ROT_90) {
- windowInfo->actualSize.set(windowSize.height(), windowSize.width());
- }
-
- windowInfo->preTransform = GetPreTransformMatrix(windowInfo->size, windowInfo->transform);
-}
-
-static bool ResetNativeWindow(ANativeWindow* window) {
- // -- Reset the native window --
- // The native window might have been used previously, and had its properties
- // changed from defaults. That will affect the answer we get for queries
- // like MIN_UNDEQUEUED_BUFFERS. Reset to a known/default state before we
- // attempt such queries.
+static bool ConnectAndSetWindowDefaults(ANativeWindow* window) {
+ ATRACE_CALL();
int err = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
if (err != 0) {
- ALOGW("native_window_api_connect failed: %s (%d)", strerror(-err), err);
+ ALOGE("native_window_api_connect failed: %s (%d)", strerror(-err), err);
return false;
}
// this will match what we do on GL so pick that here.
err = window->setSwapInterval(window, 1);
if (err != 0) {
- ALOGW("native_window->setSwapInterval(1) failed: %s (%d)", strerror(-err), err);
+ ALOGE("native_window->setSwapInterval(1) failed: %s (%d)", strerror(-err), err);
return false;
}
err = native_window_set_shared_buffer_mode(window, false);
if (err != 0) {
- ALOGW("native_window_set_shared_buffer_mode(false) failed: %s (%d)", strerror(-err), err);
+ ALOGE("native_window_set_shared_buffer_mode(false) failed: %s (%d)", strerror(-err), err);
return false;
}
err = native_window_set_auto_refresh(window, false);
if (err != 0) {
- ALOGW("native_window_set_auto_refresh(false) failed: %s (%d)", strerror(-err), err);
+ ALOGE("native_window_set_auto_refresh(false) failed: %s (%d)", strerror(-err), err);
return false;
}
- return true;
-}
+ err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
+ if (err != 0) {
+ ALOGE("native_window_set_scaling_mode(NATIVE_WINDOW_SCALING_MODE_FREEZE) failed: %s (%d)",
+ strerror(-err), err);
+ return false;
+ }
-class VkSurfaceAutoDeleter {
-public:
- VkSurfaceAutoDeleter(VkInstance instance, VkSurfaceKHR surface,
- PFN_vkDestroySurfaceKHR destroySurfaceKHR)
- : mInstance(instance), mSurface(surface), mDestroySurfaceKHR(destroySurfaceKHR) {}
- ~VkSurfaceAutoDeleter() { destroy(); }
-
- void destroy() {
- if (mSurface != VK_NULL_HANDLE) {
- mDestroySurfaceKHR(mInstance, mSurface, nullptr);
- mSurface = VK_NULL_HANDLE;
- }
+ // Let consumer drive the size of the buffers.
+ err = native_window_set_buffers_dimensions(window, 0, 0);
+ if (err != 0) {
+ ALOGE("native_window_set_buffers_dimensions(0,0) failed: %s (%d)", strerror(-err), err);
+ return false;
+ }
+
+ // Enable auto prerotation, so when buffer size is driven by the consumer
+ // and the transform hint specifies a 90 or 270 degree rotation, the width
+ // and height used for buffer pre-allocation and dequeueBuffer will be
+ // additionally swapped.
+ err = native_window_set_auto_prerotation(window, true);
+ if (err != 0) {
+ ALOGE("VulkanSurface::UpdateWindow() native_window_set_auto_prerotation failed: %s (%d)",
+ strerror(-err), err);
+ return false;
}
-private:
- VkInstance mInstance;
- VkSurfaceKHR mSurface;
- PFN_vkDestroySurfaceKHR mDestroySurfaceKHR;
-};
+ return true;
+}
VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
GrContext* grContext, const VulkanManager& vkManager,
uint32_t extraBuffers) {
- 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 = window;
-
- VkSurfaceKHR vkSurface = VK_NULL_HANDLE;
- VkResult res = vkManager.mCreateAndroidSurfaceKHR(vkManager.mInstance, &surfaceCreateInfo,
- nullptr, &vkSurface);
- if (VK_SUCCESS != res) {
- ALOGE("VulkanSurface::Create() vkCreateAndroidSurfaceKHR failed (%d)", res);
+ // Connect and set native window to default configurations.
+ if (!ConnectAndSetWindowDefaults(window)) {
return nullptr;
}
- VkSurfaceAutoDeleter vkSurfaceDeleter(vkManager.mInstance, vkSurface,
- vkManager.mDestroySurfaceKHR);
-
- SkDEBUGCODE(VkBool32 supported; res = vkManager.mGetPhysicalDeviceSurfaceSupportKHR(
- vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex,
- vkSurface, &supported);
- // All physical devices and queue families on Android must be capable of
- // presentation with any native window.
- SkASSERT(VK_SUCCESS == res && supported););
+ // Initialize WindowInfo struct.
+ WindowInfo windowInfo;
+ if (!InitializeWindowInfoStruct(window, colorMode, colorType, colorSpace, vkManager,
+ extraBuffers, &windowInfo)) {
+ return nullptr;
+ }
- // check for capabilities
- VkSurfaceCapabilitiesKHR caps;
- res = vkManager.mGetPhysicalDeviceSurfaceCapabilitiesKHR(vkManager.mPhysicalDevice, vkSurface,
- &caps);
- if (VK_SUCCESS != res) {
- ALOGE("VulkanSurface::Create() vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed (%d)", res);
+ // Now we attempt to modify the window.
+ if (!UpdateWindow(window, windowInfo)) {
return nullptr;
}
- LOG_ALWAYS_FATAL_IF(0 == (caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR));
+ return new VulkanSurface(window, windowInfo, grContext);
+}
+
+bool VulkanSurface::InitializeWindowInfoStruct(ANativeWindow* window, ColorMode colorMode,
+ SkColorType colorType,
+ sk_sp<SkColorSpace> colorSpace,
+ const VulkanManager& vkManager,
+ uint32_t extraBuffers, WindowInfo* outWindowInfo) {
+ ATRACE_CALL();
- /*
- * We must destroy the VK Surface before attempting to update the window as doing so after
- * will cause the native window to be modified in unexpected ways.
- */
- vkSurfaceDeleter.destroy();
+ int width, height;
+ int err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
+ if (err != 0 || width < 0) {
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, width);
+ return false;
+ }
+ err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
+ if (err != 0 || height < 0) {
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, height);
+ return false;
+ }
+ outWindowInfo->size = SkISize::Make(width, height);
- /*
- * Populate Window Info struct
- */
- WindowInfo windowInfo;
+ int query_value;
+ err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT, &query_value);
+ if (err != 0 || query_value < 0) {
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
+ return false;
+ }
+ outWindowInfo->transform = query_value;
- windowInfo.transform = ConvertVkTransformToNative(caps.supportedTransforms);
- windowInfo.size = SkISize::Make(caps.currentExtent.width, caps.currentExtent.height);
+ outWindowInfo->actualSize = outWindowInfo->size;
+ if (outWindowInfo->transform & ANATIVEWINDOW_TRANSFORM_ROTATE_90) {
+ outWindowInfo->actualSize.set(outWindowInfo->size.height(), outWindowInfo->size.width());
+ }
- const SkISize minSize = SkISize::Make(caps.minImageExtent.width, caps.minImageExtent.height);
- const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height);
- ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize);
+ outWindowInfo->preTransform =
+ GetPreTransformMatrix(outWindowInfo->size, outWindowInfo->transform);
- int query_value;
- int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
+ err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
if (err != 0 || query_value < 0) {
ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
- return nullptr;
+ return false;
}
- auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
+ outWindowInfo->bufferCount =
+ static_cast<uint32_t>(query_value) + sTargetBufferCount + extraBuffers;
- windowInfo.bufferCount = min_undequeued_buffers +
- std::max(sTargetBufferCount + extraBuffers, caps.minImageCount);
- if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
+ err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &query_value);
+ if (err != 0 || query_value < 0) {
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
+ return false;
+ }
+ if (outWindowInfo->bufferCount > static_cast<uint32_t>(query_value)) {
// Application must settle for fewer images than desired:
- windowInfo.bufferCount = caps.maxImageCount;
+ outWindowInfo->bufferCount = static_cast<uint32_t>(query_value);
}
- // Currently Skia requires the images to be color attachments and support all transfer
- // operations.
- VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
- VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
- VK_IMAGE_USAGE_TRANSFER_DST_BIT;
- LOG_ALWAYS_FATAL_IF((caps.supportedUsageFlags & usageFlags) != usageFlags);
-
- windowInfo.dataspace = HAL_DATASPACE_V0_SRGB;
+ outWindowInfo->dataspace = HAL_DATASPACE_V0_SRGB;
if (colorMode == ColorMode::WideColorGamut) {
skcms_Matrix3x3 surfaceGamut;
LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&surfaceGamut),
"Could not get gamut matrix from color space");
if (memcmp(&surfaceGamut, &SkNamedGamut::kSRGB, sizeof(surfaceGamut)) == 0) {
- windowInfo.dataspace = HAL_DATASPACE_V0_SCRGB;
+ outWindowInfo->dataspace = HAL_DATASPACE_V0_SCRGB;
} else if (memcmp(&surfaceGamut, &SkNamedGamut::kDCIP3, sizeof(surfaceGamut)) == 0) {
- windowInfo.dataspace = HAL_DATASPACE_DISPLAY_P3;
+ outWindowInfo->dataspace = HAL_DATASPACE_DISPLAY_P3;
} else {
LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
}
}
- windowInfo.pixelFormat = ColorTypeToPixelFormat(colorType);
+ outWindowInfo->pixelFormat = ColorTypeToPixelFormat(colorType);
VkFormat vkPixelFormat = VK_FORMAT_R8G8B8A8_UNORM;
- if (windowInfo.pixelFormat == PIXEL_FORMAT_RGBA_FP16) {
+ if (outWindowInfo->pixelFormat == PIXEL_FORMAT_RGBA_FP16) {
vkPixelFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
}
@@ -275,7 +228,10 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
imageFormatInfo.format = vkPixelFormat;
imageFormatInfo.type = VK_IMAGE_TYPE_2D;
imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
- imageFormatInfo.usage = usageFlags;
+ // Currently Skia requires the images to be color attachments and support all transfer
+ // operations.
+ imageFormatInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
imageFormatInfo.flags = 0;
VkAndroidHardwareBufferUsageANDROID hwbUsage;
@@ -286,35 +242,27 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
imgFormProps.pNext = &hwbUsage;
- res = vkManager.mGetPhysicalDeviceImageFormatProperties2(vkManager.mPhysicalDevice,
- &imageFormatInfo, &imgFormProps);
+ VkResult res = vkManager.mGetPhysicalDeviceImageFormatProperties2(
+ vkManager.mPhysicalDevice, &imageFormatInfo, &imgFormProps);
if (VK_SUCCESS != res) {
ALOGE("Failed to query GetPhysicalDeviceImageFormatProperties2");
- return nullptr;
+ return false;
}
uint64_t consumerUsage;
- native_window_get_consumer_usage(window, &consumerUsage);
- windowInfo.windowUsageFlags = consumerUsage | hwbUsage.androidHardwareBufferUsage;
-
- /*
- * Now we attempt to modify the window!
- */
- if (!UpdateWindow(window, windowInfo)) {
- return nullptr;
+ err = native_window_get_consumer_usage(window, &consumerUsage);
+ if (err != 0) {
+ ALOGE("native_window_get_consumer_usage failed: %s (%d)", strerror(-err), err);
+ return false;
}
+ outWindowInfo->windowUsageFlags = consumerUsage | hwbUsage.androidHardwareBufferUsage;
- return new VulkanSurface(window, windowInfo, minSize, maxSize, grContext);
+ return true;
}
bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo) {
ATRACE_CALL();
- if (!ResetNativeWindow(window)) {
- return false;
- }
-
- // -- Configure the native window --
int err = native_window_set_buffers_format(window, windowInfo.pixelFormat);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_format(%d) failed: %s (%d)",
@@ -330,15 +278,6 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
return false;
}
- const SkISize& size = windowInfo.actualSize;
- err = native_window_set_buffers_dimensions(window, size.width(), size.height());
- if (err != 0) {
- ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_dimensions(%d,%d) "
- "failed: %s (%d)",
- size.width(), size.height(), strerror(-err), err);
- return false;
- }
-
// native_window_set_buffers_transform() expects 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
@@ -353,16 +292,6 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
return false;
}
- // Vulkan defaults to NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, but this is different than
- // HWUI's expectation
- err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
- if (err != 0) {
- ALOGE("VulkanSurface::UpdateWindow() native_window_set_scaling_mode(SCALE_TO_WINDOW) "
- "failed: %s (%d)",
- strerror(-err), err);
- return false;
- }
-
err = native_window_set_buffer_count(window, windowInfo.bufferCount);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
@@ -377,16 +306,12 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
return false;
}
- return err == 0;
+ return true;
}
VulkanSurface::VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo,
- SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
- : mNativeWindow(window)
- , mWindowInfo(windowInfo)
- , mGrContext(grContext)
- , mMinWindowSize(minWindowSize)
- , mMaxWindowSize(maxWindowSize) {}
+ GrContext* grContext)
+ : mNativeWindow(window), mWindowInfo(windowInfo), mGrContext(grContext) {}
VulkanSurface::~VulkanSurface() {
releaseBuffers();
@@ -429,56 +354,49 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
// value at the end of the function if everything dequeued correctly.
mCurrentBufferInfo = nullptr;
- // check if the native window has been resized or rotated and update accordingly
- SkISize newSize = SkISize::MakeEmpty();
+ // Query the transform hint synced from the initial Surface connect or last queueBuffer. The
+ // auto prerotation on the buffer is based on the same transform hint in use by the producer.
int transformHint = 0;
- mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &newSize.fWidth);
- mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_HEIGHT, &newSize.fHeight);
- mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
- if (newSize != mWindowInfo.actualSize || transformHint != mWindowInfo.transform) {
- WindowInfo newWindowInfo = mWindowInfo;
- newWindowInfo.size = newSize;
- newWindowInfo.transform = IsTransformSupported(transformHint) ? transformHint : 0;
- ComputeWindowSizeAndTransform(&newWindowInfo, mMinWindowSize, mMaxWindowSize);
-
- int err = 0;
- if (newWindowInfo.actualSize != mWindowInfo.actualSize) {
- // reset the native buffers and update the window
- err = native_window_set_buffers_dimensions(mNativeWindow.get(),
- newWindowInfo.actualSize.width(),
- newWindowInfo.actualSize.height());
- if (err != 0) {
- ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
- newWindowInfo.actualSize.width(), newWindowInfo.actualSize.height(),
- strerror(-err), err);
- return nullptr;
- }
+ int err =
+ mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
+
+ // Since auto pre-rotation is enabled, dequeueBuffer to get the consumer driven buffer size
+ // from ANativeWindowBuffer.
+ ANativeWindowBuffer* buffer;
+ int fence_fd;
+ err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fence_fd);
+ if (err != 0) {
+ ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
+ return nullptr;
+ }
+
+ SkISize actualSize = SkISize::Make(buffer->width, buffer->height);
+ if (actualSize != mWindowInfo.actualSize || transformHint != mWindowInfo.transform) {
+ if (actualSize != mWindowInfo.actualSize) {
// reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The
// new NativeBufferInfo storage will be populated lazily as we dequeue each new buffer.
+ mWindowInfo.actualSize = actualSize;
releaseBuffers();
- // TODO should we ask the nativewindow to allocate buffers?
}
- if (newWindowInfo.transform != mWindowInfo.transform) {
+ if (transformHint != mWindowInfo.transform) {
err = native_window_set_buffers_transform(mNativeWindow.get(),
- InvertTransform(newWindowInfo.transform));
+ InvertTransform(transformHint));
if (err != 0) {
- ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
- newWindowInfo.transform, strerror(-err), err);
- newWindowInfo.transform = mWindowInfo.transform;
- ComputeWindowSizeAndTransform(&newWindowInfo, mMinWindowSize, mMaxWindowSize);
+ ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)", transformHint,
+ strerror(-err), err);
+ mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, fence_fd);
+ return nullptr;
}
+ mWindowInfo.transform = transformHint;
}
- mWindowInfo = newWindowInfo;
- }
+ mWindowInfo.size = actualSize;
+ if (mWindowInfo.transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ mWindowInfo.size.set(actualSize.height(), actualSize.width());
+ }
- ANativeWindowBuffer* buffer;
- int fence_fd;
- int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fence_fd);
- if (err != 0) {
- ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
- return nullptr;
+ mWindowInfo.preTransform = GetPreTransformMatrix(mWindowInfo.size, mWindowInfo.transform);
}
uint32_t idx;