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
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,
vk::ImageViewHelper *imageViews,
vk::ImageHelper *resolveImage,
......
......@@ -91,6 +91,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
const vk::Format &getImageFormat() const;
gl::Extents getExtents() const;
gl::Extents getRotatedExtents() const;
gl::LevelIndex getLevelIndex() const { return mLevelIndexGL; }
uint32_t getLayerIndex() const { return mLayerIndex; }
uint32_t getLayerCount() const { return mLayerCount; }
......
......@@ -605,6 +605,45 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk)
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)
{
// 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,
for (uint32_t imageIndex = 0; imageIndex < imageCount; ++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);
member.imageViews.init(renderer);
}
......@@ -1316,13 +1356,7 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
resolveRegion.srcOffset = {};
resolveRegion.dstSubresource = resolveRegion.srcSubresource;
resolveRegion.dstOffset = {};
resolveRegion.extent = image.image.getExtents();
// 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);
}
resolveRegion.extent = image.image.getRotatedExtents();
mColorImageMS.resolve(&image.image, resolveRegion, commandBuffer);
}
......@@ -1638,11 +1672,21 @@ EGLint WindowSurfaceVk::getWidth() const
return static_cast<EGLint>(mColorRenderTarget.getExtents().width);
}
EGLint WindowSurfaceVk::getRotatedWidth() const
{
return static_cast<EGLint>(mColorRenderTarget.getRotatedExtents().width);
}
EGLint WindowSurfaceVk::getHeight() const
{
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
{
DisplayVk *displayVk = vk::GetImpl(display);
......@@ -1737,7 +1781,7 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk,
VkFramebufferCreateInfo framebufferInfo = {};
const gl::Extents extents = mColorRenderTarget.getExtents();
const gl::Extents rotatedExtents = mColorRenderTarget.getRotatedExtents();
std::array<VkImageView, 2> imageViews = {};
if (mDepthStencilImage.valid())
......@@ -1752,13 +1796,9 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk,
framebufferInfo.renderPass = compatibleRenderPass.getHandle();
framebufferInfo.attachmentCount = (mDepthStencilImage.valid() ? 2u : 1u);
framebufferInfo.pAttachments = imageViews.data();
framebufferInfo.width = static_cast<uint32_t>(extents.width);
framebufferInfo.height = static_cast<uint32_t>(extents.height);
if (Is90DegreeRotation(getPreTransform()))
{
std::swap(framebufferInfo.width, framebufferInfo.height);
}
framebufferInfo.layers = 1;
framebufferInfo.width = static_cast<uint32_t>(rotatedExtents.width);
framebufferInfo.height = static_cast<uint32_t>(rotatedExtents.height);
framebufferInfo.layers = 1;
if (isMultiSampled())
{
......
......@@ -208,6 +208,8 @@ class WindowSurfaceVk : public SurfaceVk
// width and height can change with client window resizing
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint getRotatedWidth() const;
EGLint getRotatedHeight() const;
// Note: windows cannot be resized on Android. The approach requires
// calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is
// expensive; and there are troublesome timing issues for other parts of
......
......@@ -3504,6 +3504,7 @@ ImageHelper::ImageHelper(ImageHelper &&other)
mTilingMode(other.mTilingMode),
mUsage(other.mUsage),
mExtents(other.mExtents),
mRotatedAspectRatio(other.mRotatedAspectRatio),
mFormat(other.mFormat),
mSamples(other.mSamples),
mImageSerial(other.mImageSerial),
......@@ -3538,6 +3539,7 @@ void ImageHelper::resetCachedProperties()
mTilingMode = VK_IMAGE_TILING_OPTIMAL;
mUsage = 0;
mExtents = {};
mRotatedAspectRatio = false;
mFormat = nullptr;
mSamples = 1;
mImageSerial = kInvalidImageSerial;
......@@ -3660,7 +3662,7 @@ angle::Result ImageHelper::init(Context *context,
angle::Result ImageHelper::initMSAASwapchain(Context *context,
gl::TextureType textureType,
const VkExtent3D &extents,
bool rotatedAspectRation,
bool rotatedAspectRatio,
const Format &format,
GLint samples,
VkImageUsageFlags usage,
......@@ -3673,10 +3675,11 @@ angle::Result ImageHelper::initMSAASwapchain(Context *context,
ANGLE_TRY(initExternal(context, textureType, extents, format, samples, usage,
kVkImageCreateFlagsNone, ImageLayout::Undefined, nullptr, baseLevel,
maxLevel, mipLevels, layerCount, isRobustResourceInitEnabled));
if (rotatedAspectRation)
if (rotatedAspectRatio)
{
std::swap(mExtents.width, mExtents.height);
}
mRotatedAspectRatio = rotatedAspectRatio;
return angle::Result::Continue;
}
......@@ -3699,16 +3702,17 @@ angle::Result ImageHelper::initExternal(Context *context,
ASSERT(!IsAnySubresourceContentDefined(mContentDefined));
ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined));
mImageType = gl_vk::GetImageType(textureType);
mExtents = extents;
mFormat = &format;
mSamples = std::max(samples, 1);
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mBaseLevel = baseLevel;
mMaxLevel = maxLevel;
mLevelCount = mipLevels;
mLayerCount = layerCount;
mUsage = usage;
mImageType = gl_vk::GetImageType(textureType);
mExtents = extents;
mRotatedAspectRatio = false;
mFormat = &format;
mSamples = std::max(samples, 1);
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mBaseLevel = baseLevel;
mMaxLevel = maxLevel;
mLevelCount = mipLevels;
mLayerCount = layerCount;
mUsage = usage;
// Validate that mLayerCount is compatible with the texture type
ASSERT(textureType != gl::TextureType::_3D || mLayerCount == 1);
......@@ -3791,7 +3795,8 @@ void ImageHelper::releaseStagingBuffer(RendererVk *renderer)
void ImageHelper::resetImageWeakReference()
{
mImage.reset();
mImageSerial = kInvalidImageSerial;
mImageSerial = kInvalidImageSerial;
mRotatedAspectRatio = false;
}
angle::Result ImageHelper::initializeNonZeroMemory(Context *context, VkDeviceSize size)
......@@ -4096,6 +4101,7 @@ void ImageHelper::destroy(RendererVk *renderer)
void ImageHelper::init2DWeakReference(Context *context,
VkImage handle,
const gl::Extents &glExtents,
bool rotatedAspectRatio,
const Format &format,
GLint samples,
bool isRobustResourceInitEnabled)
......@@ -4105,12 +4111,13 @@ void ImageHelper::init2DWeakReference(Context *context,
ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined));
gl_vk::GetExtent(glExtents, &mExtents);
mFormat = &format;
mSamples = std::max(samples, 1);
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 1;
mLevelCount = 1;
mRotatedAspectRatio = rotatedAspectRatio;
mFormat = &format;
mSamples = std::max(samples, 1);
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 1;
mLevelCount = 1;
mImage.setHandle(handle);
......@@ -4129,12 +4136,13 @@ angle::Result ImageHelper::init2DStaging(Context *context,
ASSERT(!IsAnySubresourceContentDefined(mStencilContentDefined));
gl_vk::GetExtent(glExtents, &mExtents);
mImageType = VK_IMAGE_TYPE_2D;
mFormat = &format;
mSamples = 1;
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mLayerCount = layerCount;
mLevelCount = 1;
mRotatedAspectRatio = false;
mImageType = VK_IMAGE_TYPE_2D;
mFormat = &format;
mSamples = 1;
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
mLayerCount = layerCount;
mLevelCount = 1;
mCurrentLayout = ImageLayout::Undefined;
......@@ -4249,6 +4257,26 @@ gl::Extents ImageHelper::getLevelExtents2D(LevelIndex levelVk) const
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
{
return mFormat->actualImageFormat().hasDepthOrStencilBits();
......
......@@ -1345,7 +1345,7 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result initMSAASwapchain(Context *context,
gl::TextureType textureType,
const VkExtent3D &extents,
bool rotatedAspectRation,
bool rotatedAspectRatio,
const Format &format,
GLint samples,
VkImageUsageFlags usage,
......@@ -1453,6 +1453,7 @@ class ImageHelper final : public Resource, public angle::Subject
void init2DWeakReference(Context *context,
VkImage handle,
const gl::Extents &glExtents,
bool rotatedAspectRatio,
const Format &format,
GLint samples,
bool isRobustResourceInitEnabled);
......@@ -1466,6 +1467,7 @@ class ImageHelper final : public Resource, public angle::Subject
VkImageUsageFlags getUsage() const { return mUsage; }
VkImageType getType() const { return mImageType; }
const VkExtent3D &getExtents() const { return mExtents; }
const VkExtent3D getRotatedExtents() const;
uint32_t getLayerCount() const { return mLayerCount; }
uint32_t getLevelCount() const { return mLevelCount; }
const Format &getFormat() const { return *mFormat; }
......@@ -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
// image.
gl::Extents getLevelExtents2D(LevelIndex levelVk) const;
gl::Extents getRotatedLevelExtents2D(LevelIndex levelVk) const;
bool isDepthOrStencil() const;
// Clear either color or depth/stencil based on image format.
......@@ -1941,7 +1944,13 @@ class ImageHelper final : public Resource, public angle::Subject
VkImageType mImageType;
VkImageTiling mTilingMode;
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;
bool mRotatedAspectRatio;
const Format *mFormat;
GLint mSamples;
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