Commit 60b03e62 by Ian Elliott Committed by Commit Bot

Create getRotatedExtents() and related methods

Created: - WindowsSurfaceVk::getRotatedWidth() - WindowsSurfaceVk::getRotatedHeight() - RenderTarget::getRotatedExtents() - ImageHelper::getRotatedExtents() - ImageHelper::getRotatedLevelExtents2D() Note: The FramebufferVk class doesn't use any of these methods Bug: b/175793022 Change-Id: I64395688bfdb172d32853763743fc5f266a6b792 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2686102 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 741f4039
...@@ -230,6 +230,13 @@ gl::Extents RenderTargetVk::getExtents() const ...@@ -230,6 +230,13 @@ gl::Extents RenderTargetVk::getExtents() const
return mImage->getLevelExtents2D(levelVk); return mImage->getLevelExtents2D(levelVk);
} }
gl::Extents RenderTargetVk::getRotatedExtents() const
{
ASSERT(mImage && mImage->valid());
vk::LevelIndex levelVk = mImage->toVkLevel(mLevelIndexGL);
return mImage->getRotatedLevelExtents2D(levelVk);
}
void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image,
vk::ImageViewHelper *imageViews, vk::ImageViewHelper *imageViews,
vk::ImageHelper *resolveImage, vk::ImageHelper *resolveImage,
......
...@@ -91,6 +91,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -91,6 +91,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
const vk::Format &getImageFormat() const; const vk::Format &getImageFormat() const;
gl::Extents getExtents() const; gl::Extents getExtents() const;
gl::Extents getRotatedExtents() const;
gl::LevelIndex getLevelIndex() const { return mLevelIndexGL; } gl::LevelIndex getLevelIndex() const { return mLevelIndexGL; }
uint32_t getLayerIndex() const { return mLayerIndex; } uint32_t getLayerIndex() const { return mLayerIndex; }
uint32_t getLayerCount() const { return mLayerCount; } uint32_t getLayerCount() const { return mLayerCount; }
......
...@@ -605,6 +605,45 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk) ...@@ -605,6 +605,45 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk)
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1); gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
// Introduction to Android rotation and pre-rotation:
//
// Android devices have one native orientation, but a window may be displayed in a different
// orientation. This results in the window being "rotated" relative to the native orientation.
// For example, the native orientation of a Pixel 4 is portrait (i.e. height > width).
// However, many games want to be landscape (i.e. width > height). Some applications will
// adapt to whatever orientation the user places the device in (e.g. auto-rotation).
//
// A convention is used within ANGLE of referring to the "rotated" and "non-rotated" aspects of
// a topic (e.g. a window's extents, a scissor, a viewport):
//
// - Non-rotated. This refers to the way that the application views the window. Rotation is
// an Android concept, not a GL concept. An application may view its window as landscape or
// portrait, but not necessarily view its window as being rotated. For example, an
// application will set a scissor and viewport in a manner consistent with its view of the
// window size (i.e. a non-rotated manner).
//
// - Rotated. This refers to the way that Vulkan views the window. If the window's
// orientation is the same as the native orientation, the rotated view will happen to be
// equivalent to the non-rotated view, but regardless of the window's orientation, ANGLE uses
// the "rotated" term as whatever the Vulkan view of the window is.
//
// Most of ANGLE is designed to work with the non-rotated view of the window. This is
// certainly true of the ANGLE front-end. It is also true of most of the Vulkan back-end,
// which is still translating GL to Vulkan. Only part of the Vulkan back-end needs to
// communicate directly to Vulkan in terms of the window's rotation. For example, the viewport
// and scissor calculations are done with non-rotated values; and then the final values are
// rotated.
//
// ANGLE learns about the window's rotation from mSurfaceCaps.currentTransform. If
// currentTransform is non-IDENTITY, ANGLE must "pre-rotate" various aspects of its work
// (e.g. rotate vertices in the vertex shaders, change scissor, viewport, and render-pass
// renderArea). The swapchain's transform is given the value of mSurfaceCaps.currentTransform.
// That prevents SurfaceFlinger from doing a rotation blit for every frame (which is costly in
// terms of performance and power).
//
// When a window is rotated 90 or 270 degrees, the aspect ratio changes. The width and height
// are swapped. The x/y and width/height of various values in ANGLE must also be swapped
// before communicating the values to Vulkan.
if (renderer->getFeatures().enablePreRotateSurfaces.enabled) if (renderer->getFeatures().enablePreRotateSurfaces.enabled)
{ {
// Use the surface's transform. For many platforms, this will always be identity (ANGLE // Use the surface's transform. For many platforms, this will always be identity (ANGLE
...@@ -1032,7 +1071,8 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, ...@@ -1032,7 +1071,8 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
for (uint32_t imageIndex = 0; imageIndex < imageCount; ++imageIndex) for (uint32_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
{ {
SwapchainImage &member = mSwapchainImages[imageIndex]; SwapchainImage &member = mSwapchainImages[imageIndex];
member.image.init2DWeakReference(context, swapchainImages[imageIndex], extents, format, 1, member.image.init2DWeakReference(context, swapchainImages[imageIndex], extents,
Is90DegreeRotation(getPreTransform()), format, 1,
robustInit); robustInit);
member.imageViews.init(renderer); member.imageViews.init(renderer);
} }
...@@ -1316,13 +1356,7 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk, ...@@ -1316,13 +1356,7 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
resolveRegion.srcOffset = {}; resolveRegion.srcOffset = {};
resolveRegion.dstSubresource = resolveRegion.srcSubresource; resolveRegion.dstSubresource = resolveRegion.srcSubresource;
resolveRegion.dstOffset = {}; resolveRegion.dstOffset = {};
resolveRegion.extent = image.image.getExtents(); resolveRegion.extent = image.image.getRotatedExtents();
// ImageHelper extents are non-rotated. If the window is 90 or 270 degrees, swap the width
// and height.
if (Is90DegreeRotation(getPreTransform()))
{
std::swap(resolveRegion.extent.width, resolveRegion.extent.height);
}
mColorImageMS.resolve(&image.image, resolveRegion, commandBuffer); mColorImageMS.resolve(&image.image, resolveRegion, commandBuffer);
} }
...@@ -1638,11 +1672,21 @@ EGLint WindowSurfaceVk::getWidth() const ...@@ -1638,11 +1672,21 @@ EGLint WindowSurfaceVk::getWidth() const
return static_cast<EGLint>(mColorRenderTarget.getExtents().width); return static_cast<EGLint>(mColorRenderTarget.getExtents().width);
} }
EGLint WindowSurfaceVk::getRotatedWidth() const
{
return static_cast<EGLint>(mColorRenderTarget.getRotatedExtents().width);
}
EGLint WindowSurfaceVk::getHeight() const EGLint WindowSurfaceVk::getHeight() const
{ {
return static_cast<EGLint>(mColorRenderTarget.getExtents().height); return static_cast<EGLint>(mColorRenderTarget.getExtents().height);
} }
EGLint WindowSurfaceVk::getRotatedHeight() const
{
return static_cast<EGLint>(mColorRenderTarget.getRotatedExtents().height);
}
egl::Error WindowSurfaceVk::getUserWidth(const egl::Display *display, EGLint *value) const egl::Error WindowSurfaceVk::getUserWidth(const egl::Display *display, EGLint *value) const
{ {
DisplayVk *displayVk = vk::GetImpl(display); DisplayVk *displayVk = vk::GetImpl(display);
...@@ -1737,7 +1781,7 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk, ...@@ -1737,7 +1781,7 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk,
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
const gl::Extents extents = mColorRenderTarget.getExtents(); const gl::Extents rotatedExtents = mColorRenderTarget.getRotatedExtents();
std::array<VkImageView, 2> imageViews = {}; std::array<VkImageView, 2> imageViews = {};
if (mDepthStencilImage.valid()) if (mDepthStencilImage.valid())
...@@ -1752,13 +1796,9 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk, ...@@ -1752,13 +1796,9 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk,
framebufferInfo.renderPass = compatibleRenderPass.getHandle(); framebufferInfo.renderPass = compatibleRenderPass.getHandle();
framebufferInfo.attachmentCount = (mDepthStencilImage.valid() ? 2u : 1u); framebufferInfo.attachmentCount = (mDepthStencilImage.valid() ? 2u : 1u);
framebufferInfo.pAttachments = imageViews.data(); framebufferInfo.pAttachments = imageViews.data();
framebufferInfo.width = static_cast<uint32_t>(extents.width); framebufferInfo.width = static_cast<uint32_t>(rotatedExtents.width);
framebufferInfo.height = static_cast<uint32_t>(extents.height); framebufferInfo.height = static_cast<uint32_t>(rotatedExtents.height);
if (Is90DegreeRotation(getPreTransform())) framebufferInfo.layers = 1;
{
std::swap(framebufferInfo.width, framebufferInfo.height);
}
framebufferInfo.layers = 1;
if (isMultiSampled()) if (isMultiSampled())
{ {
......
...@@ -208,6 +208,8 @@ class WindowSurfaceVk : public SurfaceVk ...@@ -208,6 +208,8 @@ class WindowSurfaceVk : public SurfaceVk
// width and height can change with client window resizing // width and height can change with client window resizing
EGLint getWidth() const override; EGLint getWidth() const override;
EGLint getHeight() const override; EGLint getHeight() const override;
EGLint getRotatedWidth() const;
EGLint getRotatedHeight() const;
// Note: windows cannot be resized on Android. The approach requires // Note: windows cannot be resized on Android. The approach requires
// calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is
// expensive; and there are troublesome timing issues for other parts of // expensive; and there are troublesome timing issues for other parts of
......
...@@ -3504,6 +3504,7 @@ ImageHelper::ImageHelper(ImageHelper &&other) ...@@ -3504,6 +3504,7 @@ ImageHelper::ImageHelper(ImageHelper &&other)
mTilingMode(other.mTilingMode), mTilingMode(other.mTilingMode),
mUsage(other.mUsage), mUsage(other.mUsage),
mExtents(other.mExtents), mExtents(other.mExtents),
mRotatedAspectRatio(other.mRotatedAspectRatio),
mFormat(other.mFormat), mFormat(other.mFormat),
mSamples(other.mSamples), mSamples(other.mSamples),
mImageSerial(other.mImageSerial), mImageSerial(other.mImageSerial),
...@@ -3538,6 +3539,7 @@ void ImageHelper::resetCachedProperties() ...@@ -3538,6 +3539,7 @@ void ImageHelper::resetCachedProperties()
mTilingMode = VK_IMAGE_TILING_OPTIMAL; mTilingMode = VK_IMAGE_TILING_OPTIMAL;
mUsage = 0; mUsage = 0;
mExtents = {}; mExtents = {};
mRotatedAspectRatio = false;
mFormat = nullptr; mFormat = nullptr;
mSamples = 1; mSamples = 1;
mImageSerial = kInvalidImageSerial; mImageSerial = kInvalidImageSerial;
...@@ -3660,7 +3662,7 @@ angle::Result ImageHelper::init(Context *context, ...@@ -3660,7 +3662,7 @@ angle::Result ImageHelper::init(Context *context,
angle::Result ImageHelper::initMSAASwapchain(Context *context, angle::Result ImageHelper::initMSAASwapchain(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
const VkExtent3D &extents, const VkExtent3D &extents,
bool rotatedAspectRation, bool rotatedAspectRatio,
const Format &format, const Format &format,
GLint samples, GLint samples,
VkImageUsageFlags usage, VkImageUsageFlags usage,
...@@ -3673,10 +3675,11 @@ angle::Result ImageHelper::initMSAASwapchain(Context *context, ...@@ -3673,10 +3675,11 @@ angle::Result ImageHelper::initMSAASwapchain(Context *context,
ANGLE_TRY(initExternal(context, textureType, extents, format, samples, usage, ANGLE_TRY(initExternal(context, textureType, extents, format, samples, usage,
kVkImageCreateFlagsNone, ImageLayout::Undefined, nullptr, baseLevel, kVkImageCreateFlagsNone, ImageLayout::Undefined, nullptr, baseLevel,
maxLevel, mipLevels, layerCount, isRobustResourceInitEnabled)); maxLevel, mipLevels, layerCount, isRobustResourceInitEnabled));
if (rotatedAspectRation) if (rotatedAspectRatio)
{ {
std::swap(mExtents.width, mExtents.height); std::swap(mExtents.width, mExtents.height);
} }
mRotatedAspectRatio = rotatedAspectRatio;
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -3699,16 +3702,17 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -3699,16 +3702,17 @@ angle::Result ImageHelper::initExternal(Context *context,
ASSERT(!IsAnySubresourceContentDefined(mContentDefined)); ASSERT(!IsAnySubresourceContentDefined(mContentDefined));
ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined)); ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined));
mImageType = gl_vk::GetImageType(textureType); mImageType = gl_vk::GetImageType(textureType);
mExtents = extents; mExtents = extents;
mFormat = &format; mRotatedAspectRatio = false;
mSamples = std::max(samples, 1); mFormat = &format;
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial(); mSamples = std::max(samples, 1);
mBaseLevel = baseLevel; mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mMaxLevel = maxLevel; mBaseLevel = baseLevel;
mLevelCount = mipLevels; mMaxLevel = maxLevel;
mLayerCount = layerCount; mLevelCount = mipLevels;
mUsage = usage; mLayerCount = layerCount;
mUsage = usage;
// Validate that mLayerCount is compatible with the texture type // Validate that mLayerCount is compatible with the texture type
ASSERT(textureType != gl::TextureType::_3D || mLayerCount == 1); ASSERT(textureType != gl::TextureType::_3D || mLayerCount == 1);
...@@ -3791,7 +3795,8 @@ void ImageHelper::releaseStagingBuffer(RendererVk *renderer) ...@@ -3791,7 +3795,8 @@ void ImageHelper::releaseStagingBuffer(RendererVk *renderer)
void ImageHelper::resetImageWeakReference() void ImageHelper::resetImageWeakReference()
{ {
mImage.reset(); mImage.reset();
mImageSerial = kInvalidImageSerial; mImageSerial = kInvalidImageSerial;
mRotatedAspectRatio = false;
} }
angle::Result ImageHelper::initializeNonZeroMemory(Context *context, VkDeviceSize size) angle::Result ImageHelper::initializeNonZeroMemory(Context *context, VkDeviceSize size)
...@@ -4096,6 +4101,7 @@ void ImageHelper::destroy(RendererVk *renderer) ...@@ -4096,6 +4101,7 @@ void ImageHelper::destroy(RendererVk *renderer)
void ImageHelper::init2DWeakReference(Context *context, void ImageHelper::init2DWeakReference(Context *context,
VkImage handle, VkImage handle,
const gl::Extents &glExtents, const gl::Extents &glExtents,
bool rotatedAspectRatio,
const Format &format, const Format &format,
GLint samples, GLint samples,
bool isRobustResourceInitEnabled) bool isRobustResourceInitEnabled)
...@@ -4105,12 +4111,13 @@ void ImageHelper::init2DWeakReference(Context *context, ...@@ -4105,12 +4111,13 @@ void ImageHelper::init2DWeakReference(Context *context,
ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined)); ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined));
gl_vk::GetExtent(glExtents, &mExtents); gl_vk::GetExtent(glExtents, &mExtents);
mFormat = &format; mRotatedAspectRatio = rotatedAspectRatio;
mSamples = std::max(samples, 1); mFormat = &format;
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial(); mSamples = std::max(samples, 1);
mCurrentLayout = ImageLayout::Undefined; mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mLayerCount = 1; mCurrentLayout = ImageLayout::Undefined;
mLevelCount = 1; mLayerCount = 1;
mLevelCount = 1;
mImage.setHandle(handle); mImage.setHandle(handle);
...@@ -4129,12 +4136,13 @@ angle::Result ImageHelper::init2DStaging(Context *context, ...@@ -4129,12 +4136,13 @@ angle::Result ImageHelper::init2DStaging(Context *context,
ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined)); ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined));
gl_vk::GetExtent(glExtents, &mExtents); gl_vk::GetExtent(glExtents, &mExtents);
mImageType = VK_IMAGE_TYPE_2D; mRotatedAspectRatio = false;
mFormat = &format; mImageType = VK_IMAGE_TYPE_2D;
mSamples = 1; mFormat = &format;
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial(); mSamples = 1;
mLayerCount = layerCount; mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mLevelCount = 1; mLayerCount = layerCount;
mLevelCount = 1;
mCurrentLayout = ImageLayout::Undefined; mCurrentLayout = ImageLayout::Undefined;
...@@ -4249,6 +4257,26 @@ gl::Extents ImageHelper::getLevelExtents2D(LevelIndex levelVk) const ...@@ -4249,6 +4257,26 @@ gl::Extents ImageHelper::getLevelExtents2D(LevelIndex levelVk) const
return extents; return extents;
} }
const VkExtent3D ImageHelper::getRotatedExtents() const
{
VkExtent3D extents = mExtents;
if (mRotatedAspectRatio)
{
std::swap(extents.width, extents.height);
}
return extents;
}
gl::Extents ImageHelper::getRotatedLevelExtents2D(LevelIndex levelVk) const
{
gl::Extents extents = getLevelExtents2D(levelVk);
if (mRotatedAspectRatio)
{
std::swap(extents.width, extents.height);
}
return extents;
}
bool ImageHelper::isDepthOrStencil() const bool ImageHelper::isDepthOrStencil() const
{ {
return mFormat->actualImageFormat().hasDepthOrStencilBits(); return mFormat->actualImageFormat().hasDepthOrStencilBits();
......
...@@ -1345,7 +1345,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1345,7 +1345,7 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result initMSAASwapchain(Context *context, angle::Result initMSAASwapchain(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
const VkExtent3D &extents, const VkExtent3D &extents,
bool rotatedAspectRation, bool rotatedAspectRatio,
const Format &format, const Format &format,
GLint samples, GLint samples,
VkImageUsageFlags usage, VkImageUsageFlags usage,
...@@ -1453,6 +1453,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1453,6 +1453,7 @@ class ImageHelper final : public Resource, public angle::Subject
void init2DWeakReference(Context *context, void init2DWeakReference(Context *context,
VkImage handle, VkImage handle,
const gl::Extents &glExtents, const gl::Extents &glExtents,
bool rotatedAspectRatio,
const Format &format, const Format &format,
GLint samples, GLint samples,
bool isRobustResourceInitEnabled); bool isRobustResourceInitEnabled);
...@@ -1466,6 +1467,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1466,6 +1467,7 @@ class ImageHelper final : public Resource, public angle::Subject
VkImageUsageFlags getUsage() const { return mUsage; } VkImageUsageFlags getUsage() const { return mUsage; }
VkImageType getType() const { return mImageType; } VkImageType getType() const { return mImageType; }
const VkExtent3D &getExtents() const { return mExtents; } const VkExtent3D &getExtents() const { return mExtents; }
const VkExtent3D getRotatedExtents() const;
uint32_t getLayerCount() const { return mLayerCount; } uint32_t getLayerCount() const { return mLayerCount; }
uint32_t getLevelCount() const { return mLevelCount; } uint32_t getLevelCount() const { return mLevelCount; }
const Format &getFormat() const { return *mFormat; } const Format &getFormat() const { return *mFormat; }
...@@ -1485,6 +1487,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1485,6 +1487,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Helper function to calculate the extents of a render target created for a certain mip of the // Helper function to calculate the extents of a render target created for a certain mip of the
// image. // image.
gl::Extents getLevelExtents2D(LevelIndex levelVk) const; gl::Extents getLevelExtents2D(LevelIndex levelVk) const;
gl::Extents getRotatedLevelExtents2D(LevelIndex levelVk) const;
bool isDepthOrStencil() const; bool isDepthOrStencil() const;
// Clear either color or depth/stencil based on image format. // Clear either color or depth/stencil based on image format.
...@@ -1941,7 +1944,13 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1941,7 +1944,13 @@ class ImageHelper final : public Resource, public angle::Subject
VkImageType mImageType; VkImageType mImageType;
VkImageTiling mTilingMode; VkImageTiling mTilingMode;
VkImageUsageFlags mUsage; VkImageUsageFlags mUsage;
// For Android swapchain images, the Vulkan VkImage must be "rotated". However, most of ANGLE
// uses non-rotated extents (i.e. the way the application views the extents--see "Introduction
// to Android rotation and pre-rotation" in "SurfaceVk.cpp"). Thus, mExtents are non-rotated.
// The rotated extents are also stored along with a bool that indicates if the aspect ratio is
// different between the rotated and non-rotated extents.
VkExtent3D mExtents; VkExtent3D mExtents;
bool mRotatedAspectRatio;
const Format *mFormat; const Format *mFormat;
GLint mSamples; GLint mSamples;
ImageSerial mImageSerial; ImageSerial mImageSerial;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment