Hash :
c898ec1a
Author :
Date :
2019-11-04T15:20:18
Add EGL GGP extensions.
This CL adds two new extensions:
* EGL_ANGLE_ggp_stream_descriptor:
Introduces a new attribute to CreateWindowSurface. Allows the app
to pass in a stream descriptor to VkCreateSurfaceKHR.
Mirrors VK_GGP_stream_descriptor_surface.
* EGL_ANGLE_swap_with_frame_token:
Introduces a new function 'eglSwapBuffersWithFrameTokenANGLE'. This
allows the app to pass a GGP frame token down to vkQueuePresentKHR.
Mirrors VK_GGP_frame_token.
Bug: angleproject:4078
Change-Id: I4313ac4c264e68999905049f661bc64b44f72fab
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1897315
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SurfaceVk.h:
// Defines the class interface for SurfaceVk, implementing SurfaceImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
#define LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
#include <vulkan/vulkan.h>
#include "libANGLE/renderer/SurfaceImpl.h"
#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx
{
class RendererVk;
class SurfaceVk : public SurfaceImpl
{
public:
angle::Result getAttachmentRenderTarget(const gl::Context *context,
GLenum binding,
const gl::ImageIndex &imageIndex,
GLsizei samples,
FramebufferAttachmentRenderTarget **rtOut) override;
protected:
SurfaceVk(const egl::SurfaceState &surfaceState);
~SurfaceVk() override;
RenderTargetVk mColorRenderTarget;
RenderTargetVk mDepthStencilRenderTarget;
};
class OffscreenSurfaceVk : public SurfaceVk
{
public:
OffscreenSurfaceVk(const egl::SurfaceState &surfaceState);
~OffscreenSurfaceVk() override;
egl::Error initialize(const egl::Display *display) override;
void destroy(const egl::Display *display) override;
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
const gl::FramebufferState &state) override;
egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context,
EGLint x,
EGLint y,
EGLint width,
EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
egl::Error bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint buffer) override;
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
void setSwapInterval(EGLint interval) override;
// width and height can change with client window resizing
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
angle::Result initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override;
vk::ImageHelper *getColorAttachmentImage();
private:
struct AttachmentImage final : angle::NonCopyable
{
AttachmentImage();
~AttachmentImage();
angle::Result initialize(DisplayVk *displayVk,
EGLint width,
EGLint height,
const vk::Format &vkFormat,
GLint samples);
void destroy(const egl::Display *display);
vk::ImageHelper image;
vk::ImageViewHelper imageViews;
};
angle::Result initializeImpl(DisplayVk *displayVk);
EGLint mWidth;
EGLint mHeight;
AttachmentImage mColorAttachment;
AttachmentImage mDepthStencilAttachment;
};
// Data structures used in WindowSurfaceVk
namespace impl
{
// The submission fence of the context used to throttle the CPU.
struct SwapHistory : angle::NonCopyable
{
SwapHistory();
SwapHistory(SwapHistory &&other) = delete;
SwapHistory &operator=(SwapHistory &&other) = delete;
~SwapHistory();
void destroy(RendererVk *renderer);
angle::Result waitFence(ContextVk *contextVk);
// Fence associated with the last submitted work to render to this swapchain image.
vk::Shared<vk::Fence> sharedFence;
};
static constexpr size_t kSwapHistorySize = 2;
// Old swapchain and associated present semaphores that need to be scheduled for destruction when
// appropriate.
struct SwapchainCleanupData : angle::NonCopyable
{
SwapchainCleanupData();
SwapchainCleanupData(SwapchainCleanupData &&other);
~SwapchainCleanupData();
void destroy(VkDevice device, vk::Recycler<vk::Semaphore> *semaphoreRecycler);
// The swapchain to be destroyed.
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
// Any present semaphores that were pending destruction at the time the swapchain was
// recreated will be scheduled for destruction at the same time as the swapchain.
std::vector<vk::Semaphore> semaphores;
};
// A circular buffer per image stores the semaphores used for presenting that image. Taking the
// swap history into account, only the oldest semaphore is guaranteed to be no longer in use by the
// presentation engine. See doc/PresentSemaphores.md for details.
//
// Old swapchains are scheduled to be destroyed at the same time as the first semaphore used to
// present an image of the new swapchain. This is to ensure that the presentation engine is no
// longer presenting an image from the old swapchain.
struct ImagePresentHistory : angle::NonCopyable
{
ImagePresentHistory();
ImagePresentHistory(ImagePresentHistory &&other);
~ImagePresentHistory();
vk::Semaphore semaphore;
std::vector<SwapchainCleanupData> oldSwapchains;
};
// Swapchain images and their associated objects.
struct SwapchainImage : angle::NonCopyable
{
SwapchainImage();
SwapchainImage(SwapchainImage &&other);
~SwapchainImage();
vk::ImageHelper image;
vk::ImageViewHelper imageViews;
vk::Framebuffer framebuffer;
// A circular array of semaphores used for presenting this image.
static constexpr size_t kPresentHistorySize = kSwapHistorySize + 1;
std::array<ImagePresentHistory, kPresentHistorySize> presentHistory;
size_t currentPresentHistoryIndex = 0;
};
} // namespace impl
class WindowSurfaceVk : public SurfaceVk
{
public:
WindowSurfaceVk(const egl::SurfaceState &surfaceState, EGLNativeWindowType window);
~WindowSurfaceVk() override;
void destroy(const egl::Display *display) override;
egl::Error initialize(const egl::Display *display) override;
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
const gl::FramebufferState &state) override;
egl::Error swap(const gl::Context *context) override;
egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects) override;
egl::Error postSubBuffer(const gl::Context *context,
EGLint x,
EGLint y,
EGLint width,
EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
egl::Error bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint buffer) override;
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
void setSwapInterval(EGLint interval) override;
// width and height can change with client window resizing
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
angle::Result initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override;
angle::Result getCurrentFramebuffer(ContextVk *context,
const vk::RenderPass &compatibleRenderPass,
vk::Framebuffer **framebufferOut);
vk::Semaphore getAcquireImageSemaphore();
protected:
angle::Result swapImpl(const gl::Context *context,
EGLint *rects,
EGLint n_rects,
const void *pNextChain);
EGLNativeWindowType mNativeWindowType;
VkSurfaceKHR mSurface;
VkSurfaceCapabilitiesKHR mSurfaceCaps;
private:
virtual angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut) = 0;
virtual angle::Result getCurrentWindowSize(vk::Context *context, gl::Extents *extentsOut) = 0;
angle::Result initializeImpl(DisplayVk *displayVk);
angle::Result recreateSwapchain(ContextVk *contextVk,
const gl::Extents &extents,
uint32_t swapHistoryIndex);
angle::Result createSwapChain(vk::Context *context,
const gl::Extents &extents,
VkSwapchainKHR oldSwapchain);
angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk,
uint32_t swapHistoryIndex,
bool presentOutOfDate);
angle::Result resizeSwapchainImages(vk::Context *context, uint32_t imageCount);
void releaseSwapchainImages(ContextVk *contextVk);
void destroySwapChainImages(DisplayVk *displayVk);
VkResult nextSwapchainImage(vk::Context *context);
angle::Result present(ContextVk *contextVk,
EGLint *rects,
EGLint n_rects,
const void *pNextChain,
bool *presentOutOfDate);
angle::Result updateAndDrawOverlay(ContextVk *contextVk, impl::SwapchainImage *image) const;
angle::Result newPresentSemaphore(vk::Context *context, vk::Semaphore *semaphoreOut);
bool isMultiSampled() const;
std::vector<VkPresentModeKHR> mPresentModes;
VkSwapchainKHR mSwapchain;
// Cached information used to recreate swapchains.
VkPresentModeKHR mSwapchainPresentMode; // Current swapchain mode
VkPresentModeKHR mDesiredSwapchainPresentMode; // Desired mode set through setSwapInterval()
uint32_t mMinImageCount;
VkSurfaceTransformFlagBitsKHR mPreTransform;
VkCompositeAlphaFlagBitsKHR mCompositeAlpha;
// A circular buffer that stores the submission fence of the context on every swap. The CPU is
// throttled by waiting for the 2nd previous serial to finish.
std::array<impl::SwapHistory, impl::kSwapHistorySize> mSwapHistory;
size_t mCurrentSwapHistoryIndex;
// The previous swapchain which needs to be scheduled for destruction when appropriate. This
// will be done when the first image of the current swapchain is presented. If there were
// older swapchains pending destruction when the swapchain is recreated, they will accumulate
// and be destroyed with the previous swapchain.
//
// Note that if the user resizes the window such that the swapchain is recreated every frame,
// this array can go grow indefinitely.
std::vector<impl::SwapchainCleanupData> mOldSwapchains;
std::vector<impl::SwapchainImage> mSwapchainImages;
vk::Semaphore mAcquireImageSemaphore;
uint32_t mCurrentSwapchainImageIndex;
vk::Recycler<vk::Semaphore> mPresentSemaphoreRecycler;
// Depth/stencil image. Possibly multisampled.
vk::ImageHelper mDepthStencilImage;
vk::ImageViewHelper mDepthStencilImageViews;
// Multisample color image, view and framebuffer, if multisampling enabled.
vk::ImageHelper mColorImageMS;
vk::ImageViewHelper mColorImageMSViews;
vk::Framebuffer mFramebufferMS;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_