Commit 18cc14b5 by Geoff Lang

Add an EGL_ANGLE_surface_orientation extension.

BUG=angleproject:1262 Change-Id: I863c46c8557604da045447550f7d69831c9f06b5 Reviewed-on: https://chromium-review.googlesource.com/318780Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 329af698
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 ...@@ -509,6 +509,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 #define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
#endif /* EGL_ANGLE_flexible_surface_compatibility */ #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 #ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1 #define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286 #define EGL_DISCARD_SAMPLES_ARM 0x3286
......
...@@ -609,6 +609,7 @@ DisplayExtensions::DisplayExtensions() ...@@ -609,6 +609,7 @@ DisplayExtensions::DisplayExtensions()
querySurfacePointer(false), querySurfacePointer(false),
windowFixedSize(false), windowFixedSize(false),
keyedMutex(false), keyedMutex(false),
surfaceOrientation(false),
postSubBuffer(false), postSubBuffer(false),
createContext(false), createContext(false),
deviceQuery(false), deviceQuery(false),
...@@ -636,6 +637,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -636,6 +637,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &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_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings); InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings);
......
...@@ -427,6 +427,9 @@ struct DisplayExtensions ...@@ -427,6 +427,9 @@ struct DisplayExtensions
// EGL_ANGLE_keyed_mutex // EGL_ANGLE_keyed_mutex
bool keyedMutex; bool keyedMutex;
// EGL_ANGLE_surface_orientation
bool surfaceOrientation;
// EGL_NV_post_sub_buffer // EGL_NV_post_sub_buffer
bool postSubBuffer; bool postSubBuffer;
......
...@@ -57,7 +57,8 @@ Config::Config() ...@@ -57,7 +57,8 @@ Config::Config()
transparentType(EGL_NONE), transparentType(EGL_NONE),
transparentRedValue(0), transparentRedValue(0),
transparentGreenValue(0), transparentGreenValue(0),
transparentBlueValue(0) transparentBlueValue(0),
optimalOrientation(0)
{ {
} }
...@@ -251,6 +252,9 @@ std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) c ...@@ -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_WIDTH: match = config.maxPBufferWidth >= attributeValue; break;
case EGL_MAX_PBUFFER_HEIGHT: match = config.maxPBufferHeight >= attributeValue; break; case EGL_MAX_PBUFFER_HEIGHT: match = config.maxPBufferHeight >= attributeValue; break;
case EGL_MAX_PBUFFER_PIXELS: match = config.maxPBufferPixels >= 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(); default: UNREACHABLE();
} }
......
...@@ -64,6 +64,7 @@ struct Config ...@@ -64,6 +64,7 @@ struct Config
EGLint transparentRedValue; // Transparent red value EGLint transparentRedValue; // Transparent red value
EGLint transparentGreenValue; // Transparent green value EGLint transparentGreenValue; // Transparent green value
EGLint transparentBlueValue; // Transparent blue value EGLint transparentBlueValue; // Transparent blue value
EGLint optimalOrientation; // Optimal window surface orientation
}; };
class ConfigSet class ConfigSet
......
...@@ -483,6 +483,15 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL ...@@ -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_WIDTH: *value = configuration->maxPBufferWidth; break;
case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break; case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break;
case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; 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: default:
return false; return false;
} }
......
...@@ -41,6 +41,7 @@ Surface::Surface(rx::SurfaceImpl *impl, ...@@ -41,6 +41,7 @@ Surface::Surface(rx::SurfaceImpl *impl,
// FIXME: Determine actual pixel aspect ratio // FIXME: Determine actual pixel aspect ratio
mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)), mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
mRenderBuffer(EGL_BACK_BUFFER), mRenderBuffer(EGL_BACK_BUFFER),
mOrientation(0),
mSwapBehavior(impl->getSwapBehavior()) mSwapBehavior(impl->getSwapBehavior())
{ {
mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
...@@ -60,6 +61,8 @@ Surface::Surface(rx::SurfaceImpl *impl, ...@@ -60,6 +61,8 @@ Surface::Surface(rx::SurfaceImpl *impl,
mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
} }
mOrientation = attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0);
mDefaultFramebuffer = createDefaultFramebuffer(); mDefaultFramebuffer = createDefaultFramebuffer();
ASSERT(mDefaultFramebuffer != nullptr); ASSERT(mDefaultFramebuffer != nullptr);
} }
......
...@@ -82,6 +82,7 @@ class Surface final : public gl::FramebufferAttachmentObject ...@@ -82,6 +82,7 @@ class Surface final : public gl::FramebufferAttachmentObject
{ {
return mFlexibleSurfaceCompatibilityRequested; return mFlexibleSurfaceCompatibilityRequested;
} }
EGLint getOrientation() const { return mOrientation; }
private: private:
virtual ~Surface(); virtual ~Surface();
...@@ -116,6 +117,8 @@ class Surface final : public gl::FramebufferAttachmentObject ...@@ -116,6 +117,8 @@ class Surface final : public gl::FramebufferAttachmentObject
EGLenum mRenderBuffer; // Render buffer EGLenum mRenderBuffer; // Render buffer
EGLenum mSwapBehavior; // Buffer swap behavior EGLenum mSwapBehavior; // Buffer swap behavior
EGLint mOrientation;
BindingPointer<gl::Texture> mTexture; BindingPointer<gl::Texture> mTexture;
}; };
......
...@@ -172,6 +172,7 @@ SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration, ...@@ -172,6 +172,7 @@ SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration,
EGLint width = attribs.get(EGL_WIDTH, 0); EGLint width = attribs.get(EGL_WIDTH, 0);
EGLint height = attribs.get(EGL_HEIGHT, 0); EGLint height = attribs.get(EGL_HEIGHT, 0);
EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE); EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE);
EGLint orientation = attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0);
if (!fixedSize) if (!fixedSize)
{ {
...@@ -179,8 +180,8 @@ SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration, ...@@ -179,8 +180,8 @@ SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration,
height = -1; height = -1;
} }
return SurfaceD3D::createFromWindow( return SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize,
mRenderer, mDisplay, configuration, window, fixedSize, width, height); width, height, orientation);
} }
SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::Config *configuration, SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::Config *configuration,
......
...@@ -143,7 +143,11 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -143,7 +143,11 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
// Direct3D Specific methods // Direct3D Specific methods
virtual DeviceIdentifier getAdapterIdentifier() const = 0; 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 generateSwizzle(gl::Texture *texture) = 0;
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0; virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
......
...@@ -24,13 +24,20 @@ namespace rx ...@@ -24,13 +24,20 @@ namespace rx
SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle, SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle,
EGLint width, EGLint height) 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, SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer,
EGLint fixedSize, EGLint width, EGLint height) 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, SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
...@@ -39,12 +46,14 @@ SurfaceD3D::SurfaceD3D(RendererD3D *renderer, ...@@ -39,12 +46,14 @@ SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
EGLint width, EGLint width,
EGLint height, EGLint height,
EGLint fixedSize, EGLint fixedSize,
EGLint orientation,
EGLClientBuffer shareHandle, EGLClientBuffer shareHandle,
EGLNativeWindowType window) EGLNativeWindowType window)
: SurfaceImpl(), : SurfaceImpl(),
mRenderer(renderer), mRenderer(renderer),
mDisplay(display), mDisplay(display),
mFixedSize(fixedSize == EGL_TRUE), mFixedSize(fixedSize == EGL_TRUE),
mOrientation(orientation),
mRenderTargetFormat(config->renderTargetFormat), mRenderTargetFormat(config->renderTargetFormat),
mDepthStencilFormat(config->depthStencilFormat), mDepthStencilFormat(config->depthStencilFormat),
mSwapChain(nullptr), mSwapChain(nullptr),
...@@ -128,7 +137,8 @@ egl::Error SurfaceD3D::resetSwapChain() ...@@ -128,7 +137,8 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight; height = mHeight;
} }
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, mDepthStencilFormat); mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat,
mDepthStencilFormat, mOrientation);
if (!mSwapChain) if (!mSwapChain)
{ {
return egl::Error(EGL_BAD_ALLOC); return egl::Error(EGL_BAD_ALLOC);
......
...@@ -25,8 +25,14 @@ class RendererD3D; ...@@ -25,8 +25,14 @@ class RendererD3D;
class SurfaceD3D : public SurfaceImpl class SurfaceD3D : public SurfaceImpl
{ {
public: public:
static SurfaceD3D *createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, static SurfaceD3D *createFromWindow(RendererD3D *renderer,
EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height); 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, static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLClientBuffer shareHandle, EGLint width, EGLint height); EGLClientBuffer shareHandle, EGLint width, EGLint height);
~SurfaceD3D() override; ~SurfaceD3D() override;
...@@ -60,8 +66,15 @@ class SurfaceD3D : public SurfaceImpl ...@@ -60,8 +66,15 @@ class SurfaceD3D : public SurfaceImpl
FramebufferAttachmentRenderTarget **rtOut) override; FramebufferAttachmentRenderTarget **rtOut) override;
private: private:
SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height, SurfaceD3D(RendererD3D *renderer,
EGLint fixedSize, EGLClientBuffer shareHandle, EGLNativeWindowType window); 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 swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight); egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight);
...@@ -71,6 +84,7 @@ class SurfaceD3D : public SurfaceImpl ...@@ -71,6 +84,7 @@ class SurfaceD3D : public SurfaceImpl
egl::Display *mDisplay; egl::Display *mDisplay;
bool mFixedSize; bool mFixedSize;
GLint mOrientation;
GLenum mRenderTargetFormat; GLenum mRenderTargetFormat;
GLenum mDepthStencilFormat; GLenum mDepthStencilFormat;
......
...@@ -989,6 +989,8 @@ egl::ConfigSet Renderer11::generateConfigs() const ...@@ -989,6 +989,8 @@ egl::ConfigSet Renderer11::generateConfigs() const
const gl::Caps &rendererCaps = getRendererCaps(); const gl::Caps &rendererCaps = getRendererCaps();
const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps(); const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
const EGLint optimalSurfaceOrientation = EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
egl::ConfigSet configs; egl::ConfigSet configs;
for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++) for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++)
{ {
...@@ -1043,6 +1045,7 @@ egl::ConfigSet Renderer11::generateConfigs() const ...@@ -1043,6 +1045,7 @@ egl::ConfigSet Renderer11::generateConfigs() const
config.transparentRedValue = 0; config.transparentRedValue = 0;
config.transparentGreenValue = 0; config.transparentGreenValue = 0;
config.transparentBlueValue = 0; config.transparentBlueValue = 0;
config.optimalOrientation = optimalSurfaceOrientation;
configs.add(config); configs.add(config);
} }
...@@ -1070,6 +1073,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions ...@@ -1070,6 +1073,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
outExtensions->querySurfacePointer = true; outExtensions->querySurfacePointer = true;
outExtensions->windowFixedSize = true; outExtensions->windowFixedSize = true;
outExtensions->surfaceOrientation = true;
// D3D11 does not support present with dirty rectangles until DXGI 1.2. // D3D11 does not support present with dirty rectangles until DXGI 1.2.
outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2; outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2;
...@@ -1136,9 +1140,14 @@ gl::Error Renderer11::finish() ...@@ -1136,9 +1140,14 @@ gl::Error Renderer11::finish()
return gl::Error(GL_NO_ERROR); 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() void *Renderer11::getD3DDevice()
...@@ -2399,12 +2408,7 @@ void Renderer11::markAllStateDirty() ...@@ -2399,12 +2408,7 @@ void Renderer11::markAllStateDirty()
{ {
TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++) markRenderTargetStateDirty();
{
mAppliedRTVs[rtIndex] = DirtyPointer;
}
mAppliedDSV = DirtyPointer;
mDepthStencilInitialized = false;
// We reset the current SRV data because it might not be in sync with D3D's state // 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 // anymore. For example when a currently used SRV is used as an RTV, D3D silently
...@@ -2468,6 +2472,16 @@ void Renderer11::markAllStateDirty() ...@@ -2468,6 +2472,16 @@ void Renderer11::markAllStateDirty()
mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; 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() void Renderer11::releaseDeviceResources()
{ {
mStateCache.clear(); mStateCache.clear();
......
...@@ -111,7 +111,11 @@ class Renderer11 : public RendererD3D ...@@ -111,7 +111,11 @@ class Renderer11 : public RendererD3D
gl::Error flush() override; gl::Error flush() override;
gl::Error finish() 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 generateSwizzle(gl::Texture *texture);
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
...@@ -139,6 +143,7 @@ class Renderer11 : public RendererD3D ...@@ -139,6 +143,7 @@ class Renderer11 : public RendererD3D
void applyTransformFeedbackBuffers(const gl::State &state) override; void applyTransformFeedbackBuffers(const gl::State &state) override;
virtual void markAllStateDirty(); virtual void markAllStateDirty();
void markRenderTargetStateDirty();
// lost device // lost device
bool testDeviceLost() override; bool testDeviceLost() override;
......
...@@ -20,8 +20,12 @@ class Renderer11; ...@@ -20,8 +20,12 @@ class Renderer11;
class SwapChain11 : public SwapChainD3D class SwapChain11 : public SwapChainD3D
{ {
public: public:
SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, SwapChain11(Renderer11 *renderer,
GLenum backBufferFormat, GLenum depthBufferFormat); NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation);
virtual ~SwapChain11(); virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
...@@ -47,24 +51,36 @@ class SwapChain11 : public SwapChainD3D ...@@ -47,24 +51,36 @@ class SwapChain11 : public SwapChainD3D
private: private:
void release(); void release();
void initPassThroughResources(); 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; 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; Renderer11 *mRenderer;
EGLint mHeight; EGLint mHeight;
EGLint mWidth; EGLint mWidth;
const EGLint mOrientation;
bool mAppCreatedShareHandle; bool mAppCreatedShareHandle;
unsigned int mSwapInterval; unsigned int mSwapInterval;
bool mPassThroughResourcesInit; bool mPassThroughResourcesInit;
bool mFirstSwap;
DXGISwapChain *mSwapChain; DXGISwapChain *mSwapChain;
IDXGISwapChain1 *mSwapChain1; IDXGISwapChain1 *mSwapChain1;
IDXGIKeyedMutex *mKeyedMutex; IDXGIKeyedMutex *mKeyedMutex;
ID3D11Texture2D *mBackBufferTexture; ID3D11Texture2D *mBackBufferTexture;
ID3D11RenderTargetView *mBackBufferRTView; ID3D11RenderTargetView *mBackBufferRTView;
ID3D11ShaderResourceView *mBackBufferSRView;
const bool mNeedsOffscreenTexture;
ID3D11Texture2D *mOffscreenTexture; ID3D11Texture2D *mOffscreenTexture;
ID3D11RenderTargetView *mOffscreenRTView; ID3D11RenderTargetView *mOffscreenRTView;
ID3D11ShaderResourceView *mOffscreenSRView; ID3D11ShaderResourceView *mOffscreenSRView;
...@@ -78,6 +94,7 @@ class SwapChain11 : public SwapChainD3D ...@@ -78,6 +94,7 @@ class SwapChain11 : public SwapChainD3D
ID3D11InputLayout *mPassThroughIL; ID3D11InputLayout *mPassThroughIL;
ID3D11VertexShader *mPassThroughVS; ID3D11VertexShader *mPassThroughVS;
ID3D11PixelShader *mPassThroughPS; ID3D11PixelShader *mPassThroughPS;
ID3D11RasterizerState *mPassThroughRS;
SurfaceRenderTarget11 mColorRenderTarget; SurfaceRenderTarget11 mColorRenderTarget;
SurfaceRenderTarget11 mDepthStencilRenderTarget; SurfaceRenderTarget11 mDepthStencilRenderTarget;
......
...@@ -59,7 +59,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory ...@@ -59,7 +59,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
swapChainDesc.Stereo = FALSE; swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0; 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.BufferCount = 1;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH; swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
...@@ -84,7 +85,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory ...@@ -84,7 +85,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 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.Flags = 0;
swapChainDesc.OutputWindow = mWindow; swapChainDesc.OutputWindow = mWindow;
swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Count = 1;
......
...@@ -652,9 +652,14 @@ gl::Error Renderer9::finish() ...@@ -652,9 +652,14 @@ gl::Error Renderer9::finish()
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow,
{ HANDLE shareHandle,
return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
{
return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat,
orientation);
} }
void *Renderer9::getD3DDevice() void *Renderer9::getD3DDevice()
......
...@@ -79,7 +79,11 @@ class Renderer9 : public RendererD3D ...@@ -79,7 +79,11 @@ class Renderer9 : public RendererD3D
gl::Error flush() override; gl::Error flush() override;
gl::Error finish() 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); gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery);
void freeEventQuery(IDirect3DQuery9* query); void freeEventQuery(IDirect3DQuery9* query);
......
...@@ -15,21 +15,27 @@ ...@@ -15,21 +15,27 @@
namespace rx namespace rx
{ {
SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, SwapChain9::SwapChain9(Renderer9 *renderer,
GLenum backBufferFormat, GLenum depthBufferFormat) NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
: SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
mRenderer(renderer), mRenderer(renderer),
mWidth(-1),
mHeight(-1),
mOrientation(orientation),
mSwapInterval(-1),
mSwapChain(nullptr),
mBackBuffer(nullptr),
mRenderTarget(nullptr),
mDepthStencil(nullptr),
mOffscreenTexture(nullptr),
mColorRenderTarget(this, false), mColorRenderTarget(this, false),
mDepthStencilRenderTarget(this, true) mDepthStencilRenderTarget(this, true)
{ {
mSwapChain = NULL; ASSERT(mOrientation == 0);
mBackBuffer = NULL;
mDepthStencil = NULL;
mRenderTarget = NULL;
mOffscreenTexture = NULL;
mWidth = -1;
mHeight = -1;
mSwapInterval = -1;
} }
SwapChain9::~SwapChain9() SwapChain9::~SwapChain9()
......
...@@ -20,8 +20,12 @@ class Renderer9; ...@@ -20,8 +20,12 @@ class Renderer9;
class SwapChain9 : public SwapChainD3D class SwapChain9 : public SwapChainD3D
{ {
public: public:
SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, SwapChain9(Renderer9 *renderer,
GLenum backBufferFormat, GLenum depthBufferFormat); NativeWindow nativeWindow,
HANDLE shareHandle,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation);
virtual ~SwapChain9(); virtual ~SwapChain9();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
...@@ -47,6 +51,7 @@ class SwapChain9 : public SwapChainD3D ...@@ -47,6 +51,7 @@ class SwapChain9 : public SwapChainD3D
Renderer9 *mRenderer; Renderer9 *mRenderer;
EGLint mHeight; EGLint mHeight;
EGLint mWidth; EGLint mWidth;
EGLint mOrientation;
EGLint mSwapInterval; EGLint mSwapInterval;
IDirect3DSwapChain9 *mSwapChain; IDirect3DSwapChain9 *mSwapChain;
......
...@@ -372,6 +372,13 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin ...@@ -372,6 +372,13 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin
} }
break; 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: case EGL_VG_COLORSPACE:
return Error(EGL_BAD_MATCH); return Error(EGL_BAD_MATCH);
......
...@@ -437,6 +437,16 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -437,6 +437,16 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
} }
*value = eglSurface->flexibleSurfaceCompatibilityRequested(); *value = eglSurface->flexibleSurfaceCompatibilityRequested();
break; 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: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; 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