diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-22 09:04:29 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-22 09:25:54 +0200 |
commit | aed5a7168354c6ae47687d20b4bd3f0adcc14f8e (patch) | |
tree | d2060479a7c12fdba8c1955e5d363754feffabb8 /src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp | |
parent | d3d10cf23d61f4a011f1a7e9abdee1a92717e80f (diff) | |
parent | 628fa13ea4d6ff0e2e2ee76c9adfc78676de3c59 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/corelib/statemachine/qstatemachine.cpp
src/corelib/statemachine/qstatemachine_p.h
src/gui/painting/qdrawhelper.cpp
src/plugins/platforms/xcb/qxcbnativeinterface.cpp
src/plugins/platforms/xcb/qxcbwindow.cpp
src/plugins/platforms/xcb/qxcbwindow.h
src/testlib/qtestblacklist.cpp
src/tools/qdoc/node.cpp
src/tools/qdoc/node.h
tests/auto/gui/painting/qcolor/tst_qcolor.cpp
Change-Id: I6c78b7b162001712d5774293f501b06b4ff32684
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp new file mode 100644 index 0000000000..add5d62fae --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp @@ -0,0 +1,357 @@ +// +// Copyright (c) 2014 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. +// + +// DisplayD3D.cpp: D3D implementation of egl::Display + +#include "libANGLE/renderer/d3d/DisplayD3D.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Config.h" +#include "libANGLE/Display.h" +#include "libANGLE/Surface.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/SwapChainD3D.h" +#include "platform/Platform.h" + +#include <EGL/eglext.h> + +#if defined (ANGLE_ENABLE_D3D9) +# include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#endif // ANGLE_ENABLE_D3D9 + +#if defined (ANGLE_ENABLE_D3D11) +# include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#endif // ANGLE_ENABLE_D3D11 + +#if defined (ANGLE_TEST_CONFIG) +# define ANGLE_DEFAULT_D3D11 1 +#endif + +#if !defined(ANGLE_DEFAULT_D3D11) +// Enables use of the Direct3D 11 API for a default display, when available +# define ANGLE_DEFAULT_D3D11 0 +#endif + +namespace rx +{ + +typedef RendererD3D *(*CreateRendererD3DFunction)(egl::Display*); + +template <typename RendererType> +static RendererD3D *CreateTypedRendererD3D(egl::Display *display) +{ + return new RendererType(display); +} + +egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) +{ + ASSERT(outRenderer != nullptr); + + std::vector<CreateRendererD3DFunction> rendererCreationFunctions; + + const auto &attribMap = display->getAttributeMap(); + EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId(); + + EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + +# if defined(ANGLE_ENABLE_D3D11) + if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || + nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE || + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>); + } +# endif + +# if defined(ANGLE_ENABLE_D3D9) + if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE) + { + rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>); + } +# endif + + if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE && + nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE && + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) + { + // The default display is requested, try the D3D9 and D3D11 renderers, order them using + // the definition of ANGLE_DEFAULT_D3D11 +# if ANGLE_DEFAULT_D3D11 +# if defined(ANGLE_ENABLE_D3D11) + rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>); +# endif +# if defined(ANGLE_ENABLE_D3D9) + rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>); +# endif +# else +# if defined(ANGLE_ENABLE_D3D9) + rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>); +# endif +# if defined(ANGLE_ENABLE_D3D11) + rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>); +# endif +# endif + } + + egl::Error result(EGL_NOT_INITIALIZED, "No available renderers."); + for (size_t i = 0; i < rendererCreationFunctions.size(); i++) + { + RendererD3D *renderer = rendererCreationFunctions[i](display); + result = renderer->initialize(); + +# if defined(ANGLE_ENABLE_D3D11) + if (renderer->getRendererClass() == RENDERER_D3D11) + { + ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D11_INIT_ERRORS); + + angle::Platform *platform = ANGLEPlatformCurrent(); + platform->histogramEnumeration("GPU.ANGLE.D3D11InitializeResult", + result.getID(), NUM_D3D11_INIT_ERRORS); + } +# endif + +# if defined(ANGLE_ENABLE_D3D9) + if (renderer->getRendererClass() == RENDERER_D3D9) + { + ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D9_INIT_ERRORS); + + angle::Platform *platform = ANGLEPlatformCurrent(); + platform->histogramEnumeration("GPU.ANGLE.D3D9InitializeResult", + result.getID(), NUM_D3D9_INIT_ERRORS); + } +# endif + + if (!result.isError()) + { + *outRenderer = renderer; + break; + } + else + { + // Failed to create the renderer, try the next + SafeDelete(renderer); + } + } + + return result; +} + +DisplayD3D::DisplayD3D() + : mRenderer(nullptr) +{ +} + +egl::Error DisplayD3D::createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, + const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +{ + ASSERT(mRenderer != nullptr); + + EGLint width = attribs.get(EGL_WIDTH, 0); + EGLint height = attribs.get(EGL_HEIGHT, 0); + EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE); + + if (!fixedSize) + { + width = -1; + height = -1; + } + + SurfaceD3D *surface = SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize, + width, height); + egl::Error error = surface->initialize(); + if (error.isError()) + { + SafeDelete(surface); + return error; + } + + *outSurface = surface; + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayD3D::createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs, + SurfaceImpl **outSurface) +{ + ASSERT(mRenderer != nullptr); + + EGLint width = attribs.get(EGL_WIDTH, 0); + EGLint height = attribs.get(EGL_HEIGHT, 0); + + SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, NULL, width, height); + egl::Error error = surface->initialize(); + if (error.isError()) + { + SafeDelete(surface); + return error; + } + + *outSurface = surface; + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayD3D::createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +{ + ASSERT(mRenderer != nullptr); + + EGLint width = attribs.get(EGL_WIDTH, 0); + EGLint height = attribs.get(EGL_HEIGHT, 0); + + SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, shareHandle, + width, height); + egl::Error error = surface->initialize(); + if (error.isError()) + { + SafeDelete(surface); + return error; + } + + *outSurface = surface; + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayD3D::createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap, + const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +{ + ASSERT(mRenderer != nullptr); + + UNIMPLEMENTED(); + *outSurface = nullptr; + return egl::Error(EGL_BAD_DISPLAY); +} + +egl::Error DisplayD3D::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, + gl::Context **outContext) +{ + ASSERT(mRenderer != nullptr); + + EGLint clientVersion = attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1); + bool notifyResets = (attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION_EXT) == EGL_LOSE_CONTEXT_ON_RESET_EXT); + bool robustAccess = (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE); + + *outContext = new gl::Context(config, clientVersion, shareContext, mRenderer, notifyResets, robustAccess); + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayD3D::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayD3D::initialize(egl::Display *display) +{ + ASSERT(mRenderer == nullptr && display != nullptr); + mDisplay = display; + return CreateRendererD3D(display, &mRenderer); +} + +void DisplayD3D::terminate() +{ + SafeDelete(mRenderer); +} + +egl::ConfigSet DisplayD3D::generateConfigs() const +{ + ASSERT(mRenderer != nullptr); + return mRenderer->generateConfigs(); +} + +bool DisplayD3D::isDeviceLost() const +{ + ASSERT(mRenderer != nullptr); + return mRenderer->isDeviceLost(); +} + +bool DisplayD3D::testDeviceLost() +{ + ASSERT(mRenderer != nullptr); + return mRenderer->testDeviceLost(); +} + +egl::Error DisplayD3D::restoreLostDevice() +{ + // Release surface resources to make the Reset() succeed + for (auto it = mSurfaceSet.cbegin(); it != mSurfaceSet.cend(); ++it) + { + const auto &surface = *it; + if (surface->getBoundTexture()) + { + surface->releaseTexImage(EGL_BACK_BUFFER); + } + SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface); + surfaceD3D->releaseSwapChain(); + } + + if (!mRenderer->resetDevice()) + { + return egl::Error(EGL_BAD_ALLOC); + } + + // Restore any surfaces that may have been lost + for (auto it = mSurfaceSet.cbegin(); it != mSurfaceSet.cend(); ++it) + { + const auto &surface = *it; + SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface); + + egl::Error error = surfaceD3D->resetSwapChain(); + if (error.isError()) + { + return error; + } + } + + return egl::Error(EGL_SUCCESS); +} + +bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const +{ + return NativeWindow::isValidNativeWindow(window); +} + +void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + // ANGLE-specific extensions + if (mRenderer->getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = true; + } + + outExtensions->querySurfacePointer = true; + outExtensions->windowFixedSize = true; + + if (mRenderer->getPostSubBufferSupport()) + { + outExtensions->postSubBuffer = true; + } + + outExtensions->createContext = true; +} + +std::string DisplayD3D::getVendorString() const +{ + std::string vendorString = "Google Inc."; + if (mRenderer) + { + vendorString += " " + mRenderer->getVendorString(); + } + + return vendorString; +} + +void DisplayD3D::generateCaps(egl::Caps *outCaps) const +{ + // Display must be initialized to generate caps + ASSERT(mRenderer != nullptr); + + outCaps->textureNPOT = mRenderer->getRendererExtensions().textureNPOT; +} + +} |