summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp274
1 files changed, 167 insertions, 107 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
index f567f47525..7657aef79e 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -8,10 +8,11 @@
#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/Surface.h"
-#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/SwapChainD3D.h"
#include <tchar.h>
@@ -21,60 +22,62 @@
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, 0, EGL_FALSE,
- shareHandle, NULL);
-}
-
-SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer,
- egl::Display *display,
- const egl::Config *config,
- EGLNativeWindowType window,
- EGLint fixedSize,
- EGLint directComposition,
- EGLint width,
- EGLint height,
- EGLint orientation)
-{
- return new SurfaceD3D(renderer, display, config, width, height, fixedSize, orientation,
- directComposition, static_cast<EGLClientBuffer>(0), window);
-}
-
-SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
+SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
egl::Display *display,
- const egl::Config *config,
- EGLint width,
- EGLint height,
- EGLint fixedSize,
- EGLint orientation,
- EGLint directComposition,
- EGLClientBuffer shareHandle,
- EGLNativeWindowType window)
- : SurfaceImpl(),
+ EGLNativeWindowType window,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+ : SurfaceImpl(state),
mRenderer(renderer),
mDisplay(display),
- mFixedSize(fixedSize == EGL_TRUE),
- mOrientation(orientation),
- mRenderTargetFormat(config->renderTargetFormat),
- mDepthStencilFormat(config->depthStencilFormat),
+ mFixedSize(window == nullptr || attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE),
+ mOrientation(static_cast<EGLint>(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0))),
+ mRenderTargetFormat(state.config->renderTargetFormat),
+ mDepthStencilFormat(state.config->depthStencilFormat),
mSwapChain(nullptr),
mSwapIntervalDirty(true),
mWindowSubclassed(false),
- mNativeWindow(window, config, directComposition == EGL_TRUE),
- mWidth(width),
- mHeight(height),
+ mNativeWindow(renderer->createNativeWindow(window, state.config, attribs)),
+ mWidth(static_cast<EGLint>(attribs.get(EGL_WIDTH, 0))),
+ mHeight(static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0))),
mSwapInterval(1),
- mShareHandle(reinterpret_cast<HANDLE *>(shareHandle))
+ mShareHandle(0),
+ mD3DTexture(nullptr)
{
subclassWindow();
+ if (window != nullptr && !mFixedSize)
+ {
+ mWidth = -1;
+ mHeight = -1;
+ }
+
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ mShareHandle = static_cast<HANDLE>(clientBuffer);
+ break;
+
+ case EGL_D3D_TEXTURE_ANGLE:
+ mD3DTexture = static_cast<IUnknown *>(clientBuffer);
+ ASSERT(mD3DTexture != nullptr);
+ mD3DTexture->AddRef();
+ ANGLE_SWALLOW_ERR(mRenderer->getD3DTextureInfo(state.config, mD3DTexture, &mWidth,
+ &mHeight, &mRenderTargetFormat));
+ break;
+
+ default:
+ break;
+ }
}
SurfaceD3D::~SurfaceD3D()
{
unsubclassWindow();
releaseSwapChain();
+ SafeDelete(mNativeWindow);
+ SafeRelease(mD3DTexture);
}
void SurfaceD3D::releaseSwapChain()
@@ -82,41 +85,41 @@ void SurfaceD3D::releaseSwapChain()
SafeDelete(mSwapChain);
}
-egl::Error SurfaceD3D::initialize()
+egl::Error SurfaceD3D::initialize(const egl::Display *display)
{
- if (mNativeWindow.getNativeWindow())
+ if (mNativeWindow->getNativeWindow())
{
- if (!mNativeWindow.initialize())
+ if (!mNativeWindow->initialize())
{
- return egl::Error(EGL_BAD_SURFACE);
+ return egl::EglBadSurface();
}
}
- egl::Error error = resetSwapChain();
- if (error.isError())
- {
- return error;
- }
-
- return egl::Error(EGL_SUCCESS);
+ ANGLE_TRY(resetSwapChain(display));
+ return egl::NoError();
}
-FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::Framebuffer::Data &data)
+FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::FramebufferState &data)
{
- return mRenderer->createFramebuffer(data);
+ return mRenderer->createDefaultFramebuffer(data);
}
egl::Error SurfaceD3D::bindTexImage(gl::Texture *, EGLint)
{
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
egl::Error SurfaceD3D::releaseTexImage(EGLint)
{
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
+{
+ return mSwapChain->getSyncValues(ust, msc, sbc);
}
-egl::Error SurfaceD3D::resetSwapChain()
+egl::Error SurfaceD3D::resetSwapChain(const egl::Display *display)
{
ASSERT(!mSwapChain);
@@ -126,11 +129,11 @@ egl::Error SurfaceD3D::resetSwapChain()
if (!mFixedSize)
{
RECT windowRect;
- if (!mNativeWindow.getClientRect(&windowRect))
+ if (!mNativeWindow->getClientRect(&windowRect))
{
ASSERT(false);
- return egl::Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions");
+ return egl::EglBadSurface() << "Could not retrieve the window dimensions";
}
width = windowRect.right - windowRect.left;
@@ -143,29 +146,34 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight;
}
- mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat,
- mDepthStencilFormat, mOrientation);
+ mSwapChain =
+ mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat,
+ mDepthStencilFormat, mOrientation, mState.config->samples);
if (!mSwapChain)
{
- return egl::Error(EGL_BAD_ALLOC);
+ return egl::EglBadAlloc();
}
- egl::Error error = resetSwapChain(width, height);
+ // This is a bit risky to pass the proxy context here, but it can happen at almost any time.
+ egl::Error error = resetSwapChain(display->getProxyContext(), width, height);
if (error.isError())
{
SafeDelete(mSwapChain);
return error;
}
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
-egl::Error SurfaceD3D::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+egl::Error SurfaceD3D::resizeSwapChain(const gl::Context *context,
+ int backbufferWidth,
+ int backbufferHeight)
{
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
ASSERT(mSwapChain);
- EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight));
+ EGLint status =
+ mSwapChain->resize(context, std::max(1, backbufferWidth), std::max(1, backbufferHeight));
if (status == EGL_CONTEXT_LOST)
{
@@ -180,15 +188,18 @@ egl::Error SurfaceD3D::resizeSwapChain(int backbufferWidth, int backbufferHeight
mWidth = backbufferWidth;
mHeight = backbufferHeight;
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
-egl::Error SurfaceD3D::resetSwapChain(int backbufferWidth, int backbufferHeight)
+egl::Error SurfaceD3D::resetSwapChain(const gl::Context *context,
+ int backbufferWidth,
+ int backbufferHeight)
{
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
ASSERT(mSwapChain);
- EGLint status = mSwapChain->reset(std::max(1, backbufferWidth), std::max(1, backbufferHeight), mSwapInterval);
+ EGLint status = mSwapChain->reset(context, std::max(1, backbufferWidth),
+ std::max(1, backbufferHeight), mSwapInterval);
if (status == EGL_CONTEXT_LOST)
{
@@ -204,17 +215,20 @@ egl::Error SurfaceD3D::resetSwapChain(int backbufferWidth, int backbufferHeight)
mHeight = backbufferHeight;
mSwapIntervalDirty = false;
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
-egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+egl::Error SurfaceD3D::swapRect(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
{
if (!mSwapChain)
{
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here
if (x + width > mWidth)
{
width = mWidth - x;
@@ -224,11 +238,10 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
height = mHeight - y;
}
-#endif
if (width != 0 && height != 0)
{
- EGLint status = mSwapChain->swapRect(x, y, width, height);
+ EGLint status = mSwapChain->swapRect(context, x, y, width, height);
if (status == EGL_CONTEXT_LOST)
{
@@ -241,34 +254,36 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
}
}
- checkForOutOfDateSwapChain();
+ ANGLE_TRY(checkForOutOfDateSwapChain(context));
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+#define kDisplayProperty _TEXT("Egl::Display")
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
- if (message == WM_SIZE)
- {
- SurfaceD3D* surf = reinterpret_cast<SurfaceD3D*>(GetProp(hwnd, kSurfaceProperty));
- if(surf)
- {
- surf->checkForOutOfDateSwapChain();
- }
- }
- WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
- return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+ if (message == WM_SIZE)
+ {
+ SurfaceD3D* surf = reinterpret_cast<SurfaceD3D*>(GetProp(hwnd, kSurfaceProperty));
+ if(surf)
+ {
+ egl::Display *display = reinterpret_cast<egl::Display *>(GetProp(hwnd, kDisplayProperty));
+ surf->checkForOutOfDateSwapChain(display->getProxyContext());
+ }
+ }
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
#endif
void SurfaceD3D::subclassWindow()
{
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- HWND window = mNativeWindow.getNativeWindow();
+ HWND window = mNativeWindow->getNativeWindow();
if (!window)
{
return;
@@ -291,6 +306,7 @@ void SurfaceD3D::subclassWindow()
SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ SetProp(window, kDisplayProperty, reinterpret_cast<HANDLE>(mDisplay));
mWindowSubclassed = true;
#endif
}
@@ -303,7 +319,7 @@ void SurfaceD3D::unsubclassWindow()
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- HWND window = mNativeWindow.getNativeWindow();
+ HWND window = mNativeWindow->getNativeWindow();
if (!window)
{
return;
@@ -320,30 +336,31 @@ void SurfaceD3D::unsubclassWindow()
if(parentWndFunc)
{
LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
- UNUSED_ASSERTION_VARIABLE(prevWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
}
RemoveProp(window, kSurfaceProperty);
RemoveProp(window, kParentWndProc);
+ RemoveProp(window, kDisplayProperty);
#endif
mWindowSubclassed = false;
}
-bool SurfaceD3D::checkForOutOfDateSwapChain()
+
+egl::Error SurfaceD3D::checkForOutOfDateSwapChain(const gl::Context *context)
{
RECT client;
int clientWidth = getWidth();
int clientHeight = getHeight();
bool sizeDirty = false;
- if (!mFixedSize && !mNativeWindow.isIconic())
+ if (!mFixedSize && !mNativeWindow->isIconic())
{
// The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized
// because that's not a useful size to render to.
- if (!mNativeWindow.getClientRect(&client))
+ if (!mNativeWindow->getClientRect(&client))
{
- ASSERT(false);
- return false;
+ UNREACHABLE();
+ return egl::NoError();
}
// Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
@@ -352,28 +369,30 @@ bool SurfaceD3D::checkForOutOfDateSwapChain()
sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
}
- bool wasDirty = (mSwapIntervalDirty || sizeDirty);
-
if (mSwapIntervalDirty)
{
- resetSwapChain(clientWidth, clientHeight);
+ ANGLE_TRY(resetSwapChain(context, clientWidth, clientHeight));
}
else if (sizeDirty)
{
- resizeSwapChain(clientWidth, clientHeight);
+ ANGLE_TRY(resizeSwapChain(context, clientWidth, clientHeight));
}
- return wasDirty;
+ return egl::NoError();
}
-egl::Error SurfaceD3D::swap()
+egl::Error SurfaceD3D::swap(const gl::Context *context)
{
- return swapRect(0, 0, mWidth, mHeight);
+ return swapRect(context, 0, 0, mWidth, mHeight);
}
-egl::Error SurfaceD3D::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+egl::Error SurfaceD3D::postSubBuffer(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
{
- return swapRect(x, y, width, height);
+ return swapRect(context, x, y, width, height);
}
rx::SwapChainD3D *SurfaceD3D::getSwapChain() const
@@ -429,13 +448,15 @@ egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value)
}
else UNREACHABLE();
- return egl::Error(EGL_SUCCESS);
+ return egl::NoError();
}
-gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target,
+gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut)
{
- if (target.binding() == GL_BACK)
+ if (binding == GL_BACK)
{
*rtOut = mSwapChain->getColorRenderTarget();
}
@@ -443,7 +464,46 @@ gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment:
{
*rtOut = mSwapChain->getDepthStencilRenderTarget();
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
+}
+
+WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+ : SurfaceD3D(state,
+ renderer,
+ display,
+ window,
+ 0,
+ static_cast<EGLClientBuffer>(0),
+ attribs)
+{
+}
+
+WindowSurfaceD3D::~WindowSurfaceD3D()
+{
}
+PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+ : SurfaceD3D(state,
+ renderer,
+ display,
+ static_cast<EGLNativeWindowType>(0),
+ buftype,
+ clientBuffer,
+ attribs)
+{
}
+
+PbufferSurfaceD3D::~PbufferSurfaceD3D()
+{
+}
+
+} // namespace rc