Commit 7f448b58 by Geoff Lang

Add an EGL_ANGLE_surface_orientation extension.

BUG=angleproject:1262 Change-Id: Ifbb0f5302311a68a0c6f02baaea706cbb7055a52 Reviewed-on: https://chromium-review.googlesource.com/320011Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 666cb828
Name
ANGLE_surface_orientation
Name Strings
EGL_ANGLE_surface_orientation
Contributors
Geoff Lang, Google
Contacts
Geoff Lang, Google (geofflang 'at' google 'dot' com)
Status
Draft
Version
Version 1, 2015-12-15
Number
EGL Extension XXX
Extension Type
EGL display extension
Dependencies
Written based on the wording of the EGL 1.5 Specification
(August 7 2014).
Overview
This extension provides a mechanism for querying the most optimal
orientation of a window surface and creating window sufraces with
non-default orientations for the most performant rendering.
New Types
None
New Procedures and Functions
None
New Tokens
New EGLConfig bitmask attribute name:
EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
Accepted as an attribute name in the <attrib_list> argument of
eglCreateWindowSurface and attribute name in the <attribute>
argument of eglQuerySurface:
EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
Valid bitfields in the EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE bitmask
attribute of EGLConfig and EGL_SURFACE_ORIENTATION_ANGLE bitmask attribute
of eglCreateWindowSurface:
EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
Additions to the EGL Specification
Additions to Chapter 3 of the EGL 1.5 Specification (EGL Functions and Errors)
Add to table 3.1 (EGLConfig Attributes)
Attribute Type Notes
------------------------------------- ------- ----------------------
EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE bitmask Optimal window surface
orientation.
Add a paragraph to section 3.4, section Other EGLConfig Attribute
Descriptions.
"EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE is a mask indicating which
window surface orientation will provide the best performance."
Add to table 3.4 (Default values and match criteria for EGLConfig
attributes):
Attribute Default Selection Sort Sort
Criteria Order Priority
------------------------------------- ------- --------- ------- --------
EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0 Exact None
Add a paragraph to section 3.5.1, section Creating On-Screen Rendering
Surfaces.
EGL_SURFACE_ORIENTATION_ANGLE attribute specifies how the surface's content
will appear on the screen. If its value contains
EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE then all displayed content will be
inverted along the vertical axis. Similarly, if its value contains
EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE then all displayed content will be
inverted along the horizontal axis.
Add to table 3.5 (Queryable surface attributes and types):
Attribute Type Description
----------------------------- ------- ----------------------
EGL_SURFACE_ORIENTATION_ANGLE bitmask Orientation of surface
Add a paragraph to section 3.5.6, Surface Attributes:
"Querying EGL_SURFACE_ORIENTATION_ANGLE returns the orientation of the
surface. For a window surface, this is the same attribute value specified
when the surface was created. For other types of surfaces, it is always
0."
Issues
1) What about dirty regions and sub regions specified by extensions such as
NV_post_sub_buffer?
These regions will be applied to the same region of the window as
before because they are often specified based on events from the
operating system. The content in these regions will be displayed
according to the value of EGL_SURFACE_ORIENTATION_ANGLE.
Revision History
Version 1, 2015-12-15 (Geoff Lang)
- Initial draft
......@@ -509,6 +509,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
#endif /* EGL_ANGLE_flexible_surface_compatibility */
#ifndef EGL_ANGLE_surface_orientation
#define EGL_ANGLE_surface_orientation
#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
#endif /* EGL_ANGLE_surface_orientation */
#ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286
......
......@@ -609,6 +609,7 @@ DisplayExtensions::DisplayExtensions()
querySurfacePointer(false),
windowFixedSize(false),
keyedMutex(false),
surfaceOrientation(false),
postSubBuffer(false),
createContext(false),
deviceQuery(false),
......@@ -636,6 +637,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings);
InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings);
InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings);
......
......@@ -427,6 +427,9 @@ struct DisplayExtensions
// EGL_ANGLE_keyed_mutex
bool keyedMutex;
// EGL_ANGLE_surface_orientation
bool surfaceOrientation;
// EGL_NV_post_sub_buffer
bool postSubBuffer;
......
......@@ -57,7 +57,8 @@ Config::Config()
transparentType(EGL_NONE),
transparentRedValue(0),
transparentGreenValue(0),
transparentBlueValue(0)
transparentBlueValue(0),
optimalOrientation(0)
{
}
......@@ -251,6 +252,9 @@ std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) c
case EGL_MAX_PBUFFER_WIDTH: match = config.maxPBufferWidth >= attributeValue; break;
case EGL_MAX_PBUFFER_HEIGHT: match = config.maxPBufferHeight >= attributeValue; break;
case EGL_MAX_PBUFFER_PIXELS: match = config.maxPBufferPixels >= attributeValue; break;
case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
match = config.optimalOrientation == attributeValue;
break;
default: UNREACHABLE();
}
......
......@@ -64,6 +64,7 @@ struct Config
EGLint transparentRedValue; // Transparent red value
EGLint transparentGreenValue; // Transparent green value
EGLint transparentBlueValue; // Transparent blue value
EGLint optimalOrientation; // Optimal window surface orientation
};
class ConfigSet
......
......@@ -483,6 +483,15 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL
case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break;
case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break;
case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break;
case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
if (!getExtensions().surfaceOrientation)
{
return false;
}
*value = configuration->optimalOrientation;
break;
default:
return false;
}
......
......@@ -41,7 +41,9 @@ Surface::Surface(rx::SurfaceImpl *impl,
// FIXME: Determine actual pixel aspect ratio
mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
mRenderBuffer(EGL_BACK_BUFFER),
mSwapBehavior(impl->getSwapBehavior())
mSwapBehavior(impl->getSwapBehavior()),
mOrientation(0),
mTexture()
{
mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
mFlexibleSurfaceCompatibilityRequested =
......@@ -60,6 +62,8 @@ Surface::Surface(rx::SurfaceImpl *impl,
mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
}
mOrientation = attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0);
mDefaultFramebuffer = createDefaultFramebuffer();
ASSERT(mDefaultFramebuffer != nullptr);
}
......
......@@ -82,6 +82,7 @@ class Surface final : public gl::FramebufferAttachmentObject
{
return mFlexibleSurfaceCompatibilityRequested;
}
EGLint getOrientation() const { return mOrientation; }
private:
virtual ~Surface();
......@@ -116,6 +117,8 @@ class Surface final : public gl::FramebufferAttachmentObject
EGLenum mRenderBuffer; // Render buffer
EGLenum mSwapBehavior; // Buffer swap behavior
EGLint mOrientation;
BindingPointer<gl::Texture> mTexture;
};
......
......@@ -172,6 +172,7 @@ SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration,
EGLint width = attribs.get(EGL_WIDTH, 0);
EGLint height = attribs.get(EGL_HEIGHT, 0);
EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE);
EGLint orientation = attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0);
if (!fixedSize)
{
......@@ -179,8 +180,8 @@ SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration,
height = -1;
}
return SurfaceD3D::createFromWindow(
mRenderer, mDisplay, configuration, window, fixedSize, width, height);
return SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize,
width, height, orientation);
}
SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::Config *configuration,
......
......@@ -143,7 +143,11 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
// Direct3D Specific methods
virtual DeviceIdentifier getAdapterIdentifier() const = 0;
virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation) = 0;
virtual gl::Error generateSwizzle(gl::Texture *texture) = 0;
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
......
......@@ -24,13 +24,20 @@ namespace rx
SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle,
EGLint width, EGLint height)
{
return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, shareHandle, NULL);
return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, 0, shareHandle, NULL);
}
SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLNativeWindowType window,
EGLint fixedSize, EGLint width, EGLint height)
SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer,
egl::Display *display,
const egl::Config *config,
EGLNativeWindowType window,
EGLint fixedSize,
EGLint width,
EGLint height,
EGLint orientation)
{
return new SurfaceD3D(renderer, display, config, width, height, fixedSize, static_cast<EGLClientBuffer>(0), window);
return new SurfaceD3D(renderer, display, config, width, height, fixedSize, orientation,
static_cast<EGLClientBuffer>(0), window);
}
SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
......@@ -39,12 +46,14 @@ SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
EGLint width,
EGLint height,
EGLint fixedSize,
EGLint orientation,
EGLClientBuffer shareHandle,
EGLNativeWindowType window)
: SurfaceImpl(),
mRenderer(renderer),
mDisplay(display),
mFixedSize(fixedSize == EGL_TRUE),
mOrientation(orientation),
mRenderTargetFormat(config->renderTargetFormat),
mDepthStencilFormat(config->depthStencilFormat),
mSwapChain(nullptr),
......@@ -128,7 +137,8 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight;
}
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, mDepthStencilFormat);
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat,
mDepthStencilFormat, mOrientation);
if (!mSwapChain)
{
return egl::Error(EGL_BAD_ALLOC);
......
......@@ -25,8 +25,14 @@ class RendererD3D;
class SurfaceD3D : public SurfaceImpl
{
public:
static SurfaceD3D *createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height);
static SurfaceD3D *createFromWindow(RendererD3D *renderer,
egl::Display *display,
const egl::Config *config,
EGLNativeWindowType window,
EGLint fixedSize,
EGLint width,
EGLint height,
EGLint orientation);
static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLClientBuffer shareHandle, EGLint width, EGLint height);
~SurfaceD3D() override;
......@@ -60,8 +66,15 @@ class SurfaceD3D : public SurfaceImpl
FramebufferAttachmentRenderTarget **rtOut) override;
private:
SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
EGLint fixedSize, EGLClientBuffer shareHandle, EGLNativeWindowType window);
SurfaceD3D(RendererD3D *renderer,
egl::Display *display,
const egl::Config *config,
EGLint width,
EGLint height,
EGLint fixedSize,
EGLint orientation,
EGLClientBuffer shareHandle,
EGLNativeWindowType window);
egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight);
......@@ -71,6 +84,7 @@ class SurfaceD3D : public SurfaceImpl
egl::Display *mDisplay;
bool mFixedSize;
GLint mOrientation;
GLenum mRenderTargetFormat;
GLenum mDepthStencilFormat;
......
......@@ -989,6 +989,8 @@ egl::ConfigSet Renderer11::generateConfigs() const
const gl::Caps &rendererCaps = getRendererCaps();
const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
const EGLint optimalSurfaceOrientation = EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
egl::ConfigSet configs;
for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++)
{
......@@ -1043,6 +1045,7 @@ egl::ConfigSet Renderer11::generateConfigs() const
config.transparentRedValue = 0;
config.transparentGreenValue = 0;
config.transparentBlueValue = 0;
config.optimalOrientation = optimalSurfaceOrientation;
configs.add(config);
}
......@@ -1070,6 +1073,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
outExtensions->querySurfacePointer = true;
outExtensions->windowFixedSize = true;
outExtensions->surfaceOrientation = true;
// D3D11 does not support present with dirty rectangles until DXGI 1.2.
outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2;
......@@ -1136,9 +1140,14 @@ gl::Error Renderer11::finish()
return gl::Error(GL_NO_ERROR);
}
SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
{
return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat,
orientation);
}
void *Renderer11::getD3DDevice()
......@@ -2399,12 +2408,7 @@ void Renderer11::markAllStateDirty()
{
TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{
mAppliedRTVs[rtIndex] = DirtyPointer;
}
mAppliedDSV = DirtyPointer;
mDepthStencilInitialized = false;
markRenderTargetStateDirty();
// We reset the current SRV data because it might not be in sync with D3D's state
// anymore. For example when a currently used SRV is used as an RTV, D3D silently
......@@ -2468,6 +2472,16 @@ void Renderer11::markAllStateDirty()
mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
}
void Renderer11::markRenderTargetStateDirty()
{
for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{
mAppliedRTVs[rtIndex] = DirtyPointer;
}
mAppliedDSV = DirtyPointer;
mDepthStencilInitialized = false;
}
void Renderer11::releaseDeviceResources()
{
mStateCache.clear();
......
......@@ -111,7 +111,11 @@ class Renderer11 : public RendererD3D
gl::Error flush() override;
gl::Error finish() override;
virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
SwapChainD3D *createSwapChain(NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation) override;
virtual gl::Error generateSwizzle(gl::Texture *texture);
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
......@@ -139,6 +143,7 @@ class Renderer11 : public RendererD3D
void applyTransformFeedbackBuffers(const gl::State &state) override;
virtual void markAllStateDirty();
void markRenderTargetStateDirty();
// lost device
bool testDeviceLost() override;
......
......@@ -20,8 +20,12 @@ class Renderer11;
class SwapChain11 : public SwapChainD3D
{
public:
SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
SwapChain11(Renderer11 *renderer,
NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation);
virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
......@@ -47,24 +51,36 @@ class SwapChain11 : public SwapChainD3D
private:
void release();
void initPassThroughResources();
void releaseOffscreenTexture();
EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight);
void releaseOffscreenColorBuffer();
void releaseOffscreenDepthBuffer();
EGLint resetOffscreenBuffers(int backbufferWidth, int backbufferHeight);
EGLint resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight);
EGLint resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight);
DXGI_FORMAT getSwapChainNativeFormat() const;
EGLint copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height);
EGLint present(EGLint x, EGLint y, EGLint width, EGLint height);
Renderer11 *mRenderer;
EGLint mHeight;
EGLint mWidth;
const EGLint mOrientation;
bool mAppCreatedShareHandle;
unsigned int mSwapInterval;
bool mPassThroughResourcesInit;
bool mFirstSwap;
DXGISwapChain *mSwapChain;
IDXGISwapChain1 *mSwapChain1;
IDXGIKeyedMutex *mKeyedMutex;
ID3D11Texture2D *mBackBufferTexture;
ID3D11RenderTargetView *mBackBufferRTView;
ID3D11ShaderResourceView *mBackBufferSRView;
const bool mNeedsOffscreenTexture;
ID3D11Texture2D *mOffscreenTexture;
ID3D11RenderTargetView *mOffscreenRTView;
ID3D11ShaderResourceView *mOffscreenSRView;
......@@ -78,6 +94,7 @@ class SwapChain11 : public SwapChainD3D
ID3D11InputLayout *mPassThroughIL;
ID3D11VertexShader *mPassThroughVS;
ID3D11PixelShader *mPassThroughPS;
ID3D11RasterizerState *mPassThroughRS;
SurfaceRenderTarget11 mColorRenderTarget;
SurfaceRenderTarget11 mDepthStencilRenderTarget;
......
......@@ -59,7 +59,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferUsage =
DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferCount = 1;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
......@@ -84,7 +85,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferUsage =
DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.Flags = 0;
swapChainDesc.OutputWindow = mWindow;
swapChainDesc.SampleDesc.Count = 1;
......
......@@ -652,9 +652,14 @@ gl::Error Renderer9::finish()
return gl::Error(GL_NO_ERROR);
}
SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
{
return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat,
orientation);
}
void *Renderer9::getD3DDevice()
......
......@@ -79,7 +79,11 @@ class Renderer9 : public RendererD3D
gl::Error flush() override;
gl::Error finish() override;
virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
SwapChainD3D *createSwapChain(NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation) override;
gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery);
void freeEventQuery(IDirect3DQuery9* query);
......
......@@ -15,21 +15,27 @@
namespace rx
{
SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
SwapChain9::SwapChain9(Renderer9 *renderer,
NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
: SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
mRenderer(renderer),
mWidth(-1),
mHeight(-1),
mOrientation(orientation),
mSwapInterval(-1),
mSwapChain(nullptr),
mBackBuffer(nullptr),
mRenderTarget(nullptr),
mDepthStencil(nullptr),
mOffscreenTexture(nullptr),
mColorRenderTarget(this, false),
mDepthStencilRenderTarget(this, true)
{
mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL;
mRenderTarget = NULL;
mOffscreenTexture = NULL;
mWidth = -1;
mHeight = -1;
mSwapInterval = -1;
ASSERT(mOrientation == 0);
}
SwapChain9::~SwapChain9()
......
......@@ -20,8 +20,12 @@ class Renderer9;
class SwapChain9 : public SwapChainD3D
{
public:
SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
SwapChain9(Renderer9 *renderer,
NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation);
virtual ~SwapChain9();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
......@@ -47,6 +51,7 @@ class SwapChain9 : public SwapChainD3D
Renderer9 *mRenderer;
EGLint mHeight;
EGLint mWidth;
EGLint mOrientation;
EGLint mSwapInterval;
IDirect3DSwapChain9 *mSwapChain;
......
......@@ -372,6 +372,13 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin
}
break;
case EGL_SURFACE_ORIENTATION_ANGLE:
if (!displayExtensions.surfaceOrientation)
{
return Error(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled.");
}
break;
case EGL_VG_COLORSPACE:
return Error(EGL_BAD_MATCH);
......
......@@ -437,6 +437,16 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
}
*value = eglSurface->flexibleSurfaceCompatibilityRequested();
break;
case EGL_SURFACE_ORIENTATION_ANGLE:
if (!display->getExtensions().surfaceOrientation)
{
SetGlobalError(Error(EGL_BAD_ATTRIBUTE,
"EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without "
"EGL_ANGLE_surface_orientation support."));
return EGL_FALSE;
}
*value = eglSurface->getOrientation();
break;
default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE;
......
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