diff options
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/libEGL')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/Config.cpp | 41 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/Config.h | 6 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/Display.cpp | 721 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/Display.h | 59 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp | 596 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/Surface.h | 48 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp | 453 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc | 102 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj | 195 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/main.cpp | 20 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/main.h | 1 | ||||
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/resource.h | 14 |
12 files changed, 1700 insertions, 556 deletions
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp index 284f61d..89bc8d8 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp @@ -19,10 +19,10 @@ using namespace std; namespace egl { -Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample) +Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) : mDisplayMode(displayMode), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample) { - set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample); + set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight); } void Config::setDefaults() @@ -62,8 +62,10 @@ void Config::setDefaults() mTransparentBlueValue = EGL_DONT_CARE; } -void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample) +void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) { + mBindToTextureRGB = EGL_FALSE; + mBindToTextureRGBA = EGL_FALSE; switch (renderTargetFormat) { case D3DFMT_A1R5G5B5: @@ -86,6 +88,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mGreenSize = 8; mBlueSize = 8; mAlphaSize = 8; + mBindToTextureRGBA = true; break; case D3DFMT_R5G6B5: mBufferSize = 16; @@ -100,6 +103,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mGreenSize = 8; mBlueSize = 8; mAlphaSize = 0; + mBindToTextureRGB = true; break; default: UNREACHABLE(); // Other formats should not be valid @@ -107,8 +111,6 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mLuminanceSize = 0; mAlphaMaskSize = 0; - mBindToTextureRGB = EGL_FALSE; - mBindToTextureRGBA = EGL_FALSE; mColorBufferType = EGL_RGB_BUFFER; mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG; mConfigID = 0; @@ -116,6 +118,10 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter switch (depthStencilFormat) { + case D3DFMT_UNKNOWN: + mDepthSize = 0; + mStencilSize = 0; + break; // case D3DFMT_D16_LOCKABLE: // mDepthSize = 16; // mStencilSize = 0; @@ -158,9 +164,9 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mLevel = 0; mMatchNativePixmap = EGL_NONE; - mMaxPBufferWidth = 0; - mMaxPBufferHeight = 0; - mMaxPBufferPixels = 0; + mMaxPBufferWidth = texWidth; + mMaxPBufferHeight = texHeight; + mMaxPBufferPixels = texWidth*texHeight; mMaxSwapInterval = maxInterval; mMinSwapInterval = minInterval; mNativeRenderable = EGL_FALSE; @@ -282,9 +288,9 @@ ConfigSet::ConfigSet() { } -void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample) +void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) { - Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample); + Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight); mSet.insert(config); } @@ -315,28 +321,31 @@ bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break; case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break; case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break; - case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == attribute[1]; break; + case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum) attribute[1]; break; case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break; case EGL_LEVEL: match = config->mLevel >= attribute[1]; break; - case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break; + case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean) attribute[1]; break; case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break; case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break; case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break; case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break; - case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == attribute[1]; break; + case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum) attribute[1]; break; case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break; case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break; case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break; - case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == attribute[1]; break; - case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == attribute[1]; break; + case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean) attribute[1]; break; + case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean) attribute[1]; break; case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break; case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break; case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break; case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break; - case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == attribute[1]; break; + case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum) attribute[1]; break; case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break; case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break; case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break; + case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break; + case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break; + case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break; default: return false; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Config.h b/Source/ThirdParty/ANGLE/src/libEGL/Config.h index b340f56..95626ed 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Config.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Config.h @@ -26,10 +26,10 @@ class Display; class Config { public: - Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample); + Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight); void setDefaults(); - void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample); + void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight); EGLConfig getHandle() const; const D3DDISPLAYMODE mDisplayMode; @@ -99,7 +99,7 @@ class ConfigSet public: ConfigSet(); - void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample); + void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight); size_t size() const; bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); const egl::Config *get(EGLConfig configHandle); diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp index 6f1a335..6a5cfd3 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 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. // @@ -11,24 +11,70 @@ #include "libEGL/Display.h" #include <algorithm> +#include <map> #include <vector> #include "common/debug.h" +#include "libGLESv2/mathutil.h" +#include "libGLESv2/utilities.h" #include "libEGL/main.h" -#define REF_RAST 0 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros -#define ENABLE_D3D9EX 1 // Enables use of the IDirect3D9Ex interface, when available +// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros +#define REF_RAST 0 + +// The "Debug This Pixel..." feature in PIX often fails when using the +// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 +// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file. +#if !defined(ANGLE_ENABLE_D3D9EX) +// Enables use of the IDirect3D9Ex interface, when available +#define ANGLE_ENABLE_D3D9EX 1 +#endif // !defined(ANGLE_ENABLE_D3D9EX) namespace egl { -Display::Display(HDC deviceContext) : mDc(deviceContext) +namespace +{ + typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; + DisplayMap displays; +} + +egl::Display *Display::getDisplay(EGLNativeDisplayType displayId) +{ + if (displays.find(displayId) != displays.end()) + { + return displays[displayId]; + } + + egl::Display *display = NULL; + + if (displayId == EGL_DEFAULT_DISPLAY) + { + display = new egl::Display(displayId, (HDC)NULL, false); + } + else if (displayId == EGL_SOFTWARE_DISPLAY_ANGLE) + { + display = new egl::Display(displayId, (HDC)NULL, true); + } + else + { + // FIXME: Check if displayId is a valid display device context + + display = new egl::Display(displayId, (HDC)displayId, false); + } + + displays[displayId] = display; + return display; +} + +Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software) : mDc(deviceContext) { mD3d9Module = NULL; mD3d9 = NULL; - mD3d9ex = NULL; + mD3d9Ex = NULL; mDevice = NULL; + mDeviceEx = NULL; mDeviceWindow = NULL; mAdapter = D3DADAPTER_DEFAULT; @@ -41,11 +87,21 @@ Display::Display(HDC deviceContext) : mDc(deviceContext) mMinSwapInterval = 1; mMaxSwapInterval = 1; + mSoftwareDevice = software; + mDisplayId = displayId; + mDeviceLost = false; } Display::~Display() { terminate(); + + DisplayMap::iterator thisDisplay = displays.find(mDisplayId); + + if (thisDisplay != displays.end()) + { + displays.erase(thisDisplay); + } } bool Display::initialize() @@ -55,17 +111,15 @@ bool Display::initialize() return true; } - mD3d9Module = LoadLibrary(TEXT("d3d9.dll")); - if (mD3d9Module == NULL) + if (mSoftwareDevice) { - terminate(); - return false; + mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); + } + else + { + mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); } - - typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT); - Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9")); - - if (Direct3DCreate9Ptr == NULL) + if (mD3d9Module == NULL) { terminate(); return false; @@ -77,15 +131,15 @@ bool Display::initialize() // Use Direct3D9Ex if available. Among other things, this version is less // inclined to report a lost context, for example when the user switches // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. - if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex))) + if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { - ASSERT(mD3d9ex); - mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); + ASSERT(mD3d9Ex); + mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else { - mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION); + mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } if (mD3d9) @@ -140,6 +194,8 @@ bool Display::initialize() if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);} if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);} + mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); + const D3DFORMAT renderTargetFormats[] = { D3DFMT_A1R5G5B5, @@ -152,6 +208,7 @@ bool Display::initialize() const D3DFORMAT depthStencilFormats[] = { + D3DFMT_UNKNOWN, // D3DFMT_D16_LOCKABLE, D3DFMT_D32, // D3DFMT_D15S1, @@ -179,17 +236,26 @@ bool Display::initialize() for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++) { D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex]; - HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); + HRESULT result = D3D_OK; + + if(depthStencilFormat != D3DFMT_UNKNOWN) + { + result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); + } if (SUCCEEDED(result)) { - HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); + if(depthStencilFormat != D3DFMT_UNKNOWN) + { + result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); + } if (SUCCEEDED(result)) { // FIXME: enumerate multi-sampling - configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0); + configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0, + mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight); } } } @@ -215,11 +281,19 @@ bool Display::initialize() return false; } + initExtensionString(); + static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + if (!createDevice()) + { + terminate(); + return false; + } + return true; } @@ -235,10 +309,16 @@ void Display::terminate() destroyContext(*mContextSet.begin()); } + while (!mEventQueryPool.empty()) + { + mEventQueryPool.back()->Release(); + mEventQueryPool.pop_back(); + } + if (mDevice) { // If the device is lost, reset it first to prevent leaving the driver in an unstable state - if (FAILED(mDevice->TestCooperativeLevel())) + if (testDeviceLost()) { resetDevice(); } @@ -247,6 +327,12 @@ void Display::terminate() mDevice = NULL; } + if (mDeviceEx) + { + mDeviceEx->Release(); + mDeviceEx = NULL; + } + if (mD3d9) { mD3d9->Release(); @@ -259,15 +345,14 @@ void Display::terminate() mDeviceWindow = NULL; } - if (mD3d9ex) + if (mD3d9Ex) { - mD3d9ex->Release(); - mD3d9ex = NULL; + mD3d9Ex->Release(); + mD3d9Ex = NULL; } if (mD3d9Module) { - FreeLibrary(mD3d9Module); mD3d9Module = NULL; } } @@ -277,8 +362,11 @@ void Display::startScene() if (!mSceneStarted) { long result = mDevice->BeginScene(); - ASSERT(SUCCEEDED(result)); - mSceneStarted = true; + if (SUCCEEDED(result)) { + // This is defensive checking against the device being + // lost at unexpected times. + mSceneStarted = true; + } } } @@ -286,8 +374,9 @@ void Display::endScene() { if (mSceneStarted) { - long result = mDevice->EndScene(); - ASSERT(SUCCEEDED(result)); + // EndScene can fail if the device was lost, for example due + // to a TDR during a draw call. + mDevice->EndScene(); mSceneStarted = false; } } @@ -332,6 +421,9 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break; case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break; case EGL_CONFORMANT: *value = configuration->mConformant; break; + case EGL_MAX_PBUFFER_WIDTH: *value = configuration->mMaxPBufferWidth; break; + case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->mMaxPBufferHeight; break; + case EGL_MAX_PBUFFER_PIXELS: *value = configuration->mMaxPBufferPixels; break; default: return false; } @@ -362,48 +454,251 @@ bool Display::createDevice() } } + if (mD3d9Ex) + { + result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx); + ASSERT(SUCCEEDED(result)); + } + + initializeDevice(); + + return true; +} + +// do any one-time device initialization +// NOTE: this is also needed after a device lost/reset +// to reset the scene status and ensure the default states are reset. +void Display::initializeDevice() +{ // Permanent non-default states mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE); mSceneStarted = false; - - return true; } bool Display::resetDevice() { D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - HRESULT result; - - do + + HRESULT result = D3D_OK; + bool lost = testDeviceLost(); + int attempts = 3; + + while (lost && attempts > 0) { - Sleep(0); // Give the graphics driver some CPU time + if (mDeviceEx) + { + Sleep(500); // Give the graphics driver some CPU time + result = mDeviceEx->ResetEx(&presentParameters, NULL); + } + else + { + result = mDevice->TestCooperativeLevel(); + + while (result == D3DERR_DEVICELOST) + { + Sleep(100); // Give the graphics driver some CPU time + result = mDevice->TestCooperativeLevel(); + } - result = mDevice->Reset(&presentParameters); + if (result == D3DERR_DEVICENOTRESET) + { + result = mDevice->Reset(&presentParameters); + } + } + + lost = testDeviceLost(); + attempts --; } - while (result == D3DERR_DEVICELOST); if (FAILED(result)) { + ERR("Reset/ResetEx failed multiple times: 0x%08X", result); return error(EGL_BAD_ALLOC, false); } - ASSERT(SUCCEEDED(result)); + // reset device defaults + initializeDevice(); return true; } -Surface *Display::createWindowSurface(HWND window, EGLConfig config) +EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList) { const Config *configuration = mConfigSet.get(config); + EGLint postSubBufferSupported = EGL_FALSE; + + if (attribList) + { + while (*attribList != EGL_NONE) + { + switch (attribList[0]) + { + case EGL_RENDER_BUFFER: + switch (attribList[1]) + { + case EGL_BACK_BUFFER: + break; + case EGL_SINGLE_BUFFER: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + postSubBufferSupported = attribList[1]; + break; + case EGL_VG_COLORSPACE: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + case EGL_VG_ALPHA_FORMAT: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + attribList += 2; + } + } + + if (hasExistingWindowSurface(window)) + { + return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); + } + + if (testDeviceLost()) + { + if (!restoreLostDevice()) + return EGL_NO_SURFACE; + } + + Surface *surface = new Surface(this, configuration, window, postSubBufferSupported); + + if (!surface->initialize()) + { + delete surface; + return EGL_NO_SURFACE; + } + + mSurfaceSet.insert(surface); + + return success(surface); +} + +EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList) +{ + EGLint width = 0, height = 0; + EGLenum textureFormat = EGL_NO_TEXTURE; + EGLenum textureTarget = EGL_NO_TEXTURE; + const Config *configuration = mConfigSet.get(config); + + if (attribList) + { + while (*attribList != EGL_NONE) + { + switch (attribList[0]) + { + case EGL_WIDTH: + width = attribList[1]; + break; + case EGL_HEIGHT: + height = attribList[1]; + break; + case EGL_LARGEST_PBUFFER: + if (attribList[1] != EGL_FALSE) + UNIMPLEMENTED(); // FIXME + break; + case EGL_TEXTURE_FORMAT: + switch (attribList[1]) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + textureFormat = attribList[1]; + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + break; + case EGL_TEXTURE_TARGET: + switch (attribList[1]) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_2D: + textureTarget = attribList[1]; + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + break; + case EGL_MIPMAP_TEXTURE: + if (attribList[1] != EGL_FALSE) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + break; + case EGL_VG_COLORSPACE: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + case EGL_VG_ALPHA_FORMAT: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + attribList += 2; + } + } + + if (width < 0 || height < 0) + { + return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + } + + if (width == 0 || height == 0) + { + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + if (textureFormat != EGL_NO_TEXTURE && !getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height))) + { + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || + (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) + { + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT)) + { + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) || + (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE)) + { + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + if (testDeviceLost()) + { + if (!restoreLostDevice()) + return EGL_NO_SURFACE; + } + + Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget); + + if (!surface->initialize()) + { + delete surface; + return EGL_NO_SURFACE; + } - Surface *surface = new Surface(this, configuration, window); mSurfaceSet.insert(surface); - return surface; + return success(surface); } -EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext) +EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess) { if (!mDevice) { @@ -412,28 +707,56 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha return NULL; } } - else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device + else if (testDeviceLost()) // Lost device { - if (!resetDevice()) - { + if (!restoreLostDevice()) return NULL; - } - - // Restore any surfaces that may have been lost - for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) - { - (*surface)->resetSwapChain(); - } } const egl::Config *config = mConfigSet.get(configHandle); - gl::Context *context = glCreateContext(config, shareContext); + gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess); mContextSet.insert(context); + mDeviceLost = false; return context; } +bool Display::restoreLostDevice() +{ + for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++) + { + if ((*ctx)->isResetNotificationEnabled()) + return false; // If reset notifications have been requested, application must delete all contexts first + } + + // Release surface resources to make the Reset() succeed + for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) + { + (*surface)->release(); + } + + while (!mEventQueryPool.empty()) + { + mEventQueryPool.back()->Release(); + mEventQueryPool.pop_back(); + } + + if (!resetDevice()) + { + return false; + } + + // Restore any surfaces that may have been lost + for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) + { + (*surface)->resetSwapChain(); + } + + return true; +} + + void Display::destroySurface(egl::Surface *surface) { delete surface; @@ -444,17 +767,24 @@ void Display::destroyContext(gl::Context *context) { glDestroyContext(context); mContextSet.erase(context); +} - if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel())) // Last context of a lost device +void Display::notifyDeviceLost() +{ + for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++) { - for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) - { - (*surface)->release(); - } + (*context)->markContextLost(); } + mDeviceLost = true; + error(EGL_CONTEXT_LOST); +} + +bool Display::isDeviceLost() +{ + return mDeviceLost; } -bool Display::isInitialized() +bool Display::isInitialized() const { return mD3d9 != NULL && mConfigSet.size() > 0; } @@ -515,6 +845,118 @@ D3DCAPS9 Display::getDeviceCaps() return mDeviceCaps; } +D3DADAPTER_IDENTIFIER9 *Display::getAdapterIdentifier() +{ + return &mAdapterIdentifier; +} + +bool Display::testDeviceLost() +{ + if (mDeviceEx) + { + return FAILED(mDeviceEx->CheckDeviceState(NULL)); + } + else if (mDevice) + { + return FAILED(mDevice->TestCooperativeLevel()); + } + + return false; // No device yet, so no reset required +} + +bool Display::testDeviceResettable() +{ + HRESULT status = D3D_OK; + + if (mDeviceEx) + { + status = mDeviceEx->CheckDeviceState(NULL); + } + else if (mDevice) + { + status = mDevice->TestCooperativeLevel(); + } + + switch (status) + { + case D3DERR_DEVICENOTRESET: + case D3DERR_DEVICEHUNG: + return true; + default: + return false; + } +} + +void Display::sync(bool block) +{ + HRESULT result; + + IDirect3DQuery9* query = allocateEventQuery(); + if (!query) + { + return; + } + + result = query->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + + do + { + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + + if(block && result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + Sleep(0); + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (testDeviceLost()) + { + result = D3DERR_DEVICELOST; + } + } + } + while(block && result == S_FALSE); + + freeEventQuery(query); + + if (isDeviceLostError(result)) + { + notifyDeviceLost(); + } +} + +IDirect3DQuery9* Display::allocateEventQuery() +{ + IDirect3DQuery9 *query = NULL; + + if (mEventQueryPool.empty()) + { + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); + ASSERT(SUCCEEDED(result)); + } + else + { + query = mEventQueryPool.back(); + mEventQueryPool.pop_back(); + } + + return query; +} + +void Display::freeEventQuery(IDirect3DQuery9* query) +{ + if (mEventQueryPool.size() > 1000) + { + query->Release(); + } + else + { + mEventQueryPool.push_back(query); + } +} + void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) { for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) @@ -526,7 +968,7 @@ void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) } } -bool Display::getCompressedTextureSupport() +bool Display::getDXT1TextureSupport() { D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -534,7 +976,23 @@ bool Display::getCompressedTextureSupport() return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); } -bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) +bool Display::getDXT3TextureSupport() +{ + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3)); +} + +bool Display::getDXT5TextureSupport() +{ + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5)); +} + +bool Display::getFloat32TextureSupport(bool *filtering, bool *renderable) { D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -549,7 +1007,7 @@ bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); - if (!filtering && !renderable) + if (!*filtering && !*renderable) { return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && @@ -562,7 +1020,7 @@ bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) } } -bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable) +bool Display::getFloat16TextureSupport(bool *filtering, bool *renderable) { D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -577,7 +1035,7 @@ bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable) SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); - if (!filtering && !renderable) + if (!*filtering && !*renderable) { return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && @@ -608,7 +1066,7 @@ bool Display::getLuminanceAlphaTextureSupport() D3DPOOL Display::getBufferPool(DWORD usage) const { - if (mD3d9ex != NULL) + if (mD3d9Ex != NULL) { return D3DPOOL_DEFAULT; } @@ -623,16 +1081,35 @@ D3DPOOL Display::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Display::getEventQuerySupport() +D3DPOOL Display::getTexturePool(bool renderable) const { - IDirect3DQuery9 *query; - HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); - if (SUCCEEDED(result)) + if (mD3d9Ex != NULL) { - query->Release(); + return D3DPOOL_DEFAULT; + } + else + { + if (!renderable) + { + return D3DPOOL_MANAGED; + } } - return result != D3DERR_NOTAVAILABLE; + return D3DPOOL_DEFAULT; +} + +bool Display::getEventQuerySupport() +{ + IDirect3DQuery9 *query = allocateEventQuery(); + if (query) + { + freeEventQuery(query); + return true; + } + else + { + return false; + } } D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters() @@ -656,4 +1133,102 @@ D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters() return presentParameters; } -}
\ No newline at end of file + +void Display::initExtensionString() +{ + HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); + + mExtensionString = ""; + + // Multi-vendor (EXT) extensions + mExtensionString += "EGL_EXT_create_context_robustness "; + + // ANGLE-specific extensions + if (shareHandleSupported()) + { + mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer "; + } + + mExtensionString += "EGL_ANGLE_query_surface_pointer "; + + if (swiftShader) + { + mExtensionString += "EGL_ANGLE_software_display "; + } + + if (shareHandleSupported()) + { + mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle "; + } + + mExtensionString += "EGL_NV_post_sub_buffer"; + + std::string::size_type end = mExtensionString.find_last_not_of(' '); + if (end != std::string::npos) + { + mExtensionString.resize(end+1); + } +} + +const char *Display::getExtensionString() const +{ + return mExtensionString.c_str(); +} + +bool Display::shareHandleSupported() const +{ + // PIX doesn't seem to support using share handles, so disable them. + return isD3d9ExDevice() && !gl::perfActive(); +} + +// Only Direct3D 10 ready devices support all the necessary vertex texture formats. +// We test this using D3D9 by checking support for the R16F format. +bool Display::getVertexTextureSupport() const +{ + if (!isInitialized() || mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0)) + { + return false; + } + + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F); + + return SUCCEEDED(result); +} + +bool Display::getNonPower2TextureSupport() const +{ + return !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && + !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL); +} + +bool Display::getOcclusionQuerySupport() const +{ + if (!isInitialized()) + { + return false; + } + + IDirect3DQuery9 *query = NULL; + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query); + + if (SUCCEEDED(result) && query) + { + query->Release(); + return true; + } + else + { + return false; + } +} + +bool Display::getInstancingSupport() const +{ + return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.h b/Source/ThirdParty/ANGLE/src/libEGL/Display.h index 4b74e1e..5028431 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Display.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 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. // @@ -18,6 +18,7 @@ #include <d3d9.h> #include <set> +#include <vector> #include "libGLESv2/Context.h" @@ -29,8 +30,6 @@ namespace egl class Display { public: - Display(HDC deviceContext); - ~Display(); bool initialize(); @@ -39,16 +38,19 @@ class Display virtual void startScene(); virtual void endScene(); + static egl::Display *getDisplay(EGLNativeDisplayType displayId); + bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); - egl::Surface *createWindowSurface(HWND window, EGLConfig config); - EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext); + EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList); + EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList); + EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess); void destroySurface(egl::Surface *surface); void destroyContext(gl::Context *context); - bool isInitialized(); + bool isInitialized() const; bool isValidConfig(EGLConfig config); bool isValidContext(gl::Context *context); bool isValidSurface(egl::Surface *surface); @@ -59,20 +61,45 @@ class Display virtual IDirect3DDevice9 *getDevice(); virtual D3DCAPS9 getDeviceCaps(); + virtual D3DADAPTER_IDENTIFIER9 *getAdapterIdentifier(); + virtual bool testDeviceLost(); + virtual bool testDeviceResettable(); + virtual void sync(bool block); + virtual IDirect3DQuery9* allocateEventQuery(); + virtual void freeEventQuery(IDirect3DQuery9* query); virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); - virtual bool getCompressedTextureSupport(); + virtual bool getDXT1TextureSupport(); + virtual bool getDXT3TextureSupport(); + virtual bool getDXT5TextureSupport(); virtual bool getEventQuerySupport(); - virtual bool getFloatTextureSupport(bool *filtering, bool *renderable); - virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable); + virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); + virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); virtual bool getLuminanceTextureSupport(); virtual bool getLuminanceAlphaTextureSupport(); + virtual bool getVertexTextureSupport() const; + virtual bool getNonPower2TextureSupport() const; + virtual bool getOcclusionQuerySupport() const; + virtual bool getInstancingSupport() const; virtual D3DPOOL getBufferPool(DWORD usage) const; + virtual D3DPOOL getTexturePool(bool renderable) const; + + virtual void notifyDeviceLost(); + bool isDeviceLost(); + + bool isD3d9ExDevice() const { return mD3d9Ex != NULL; } + const char *getExtensionString() const; + bool shareHandleSupported() const; private: DISALLOW_COPY_AND_ASSIGN(Display); + Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software); + D3DPRESENT_PARAMETERS getDefaultPresentParameters(); + bool restoreLostDevice(); + + EGLNativeDisplayType mDisplayId; const HDC mDc; HMODULE mD3d9Module; @@ -80,14 +107,21 @@ class Display UINT mAdapter; D3DDEVTYPE mDeviceType; IDirect3D9 *mD3d9; // Always valid after successful initialization. - IDirect3D9Ex *mD3d9ex; // Might be null if D3D9Ex is not supported. + IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. IDirect3DDevice9 *mDevice; + IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. + + // A pool of event queries that are currently unused. + std::vector<IDirect3DQuery9*> mEventQueryPool; + D3DCAPS9 mDeviceCaps; + D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; HWND mDeviceWindow; bool mSceneStarted; EGLint mMaxSwapInterval; EGLint mMinSwapInterval; + bool mSoftwareDevice; typedef std::set<Surface*> SurfaceSet; SurfaceSet mSurfaceSet; @@ -96,9 +130,14 @@ class Display typedef std::set<gl::Context*> ContextSet; ContextSet mContextSet; + bool mDeviceLost; bool createDevice(); + void initializeDevice(); bool resetDevice(); + + void initExtensionString(); + std::string mExtensionString; }; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp index 2736a7f..07ad3cf 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp @@ -13,21 +13,43 @@ #include "libEGL/Surface.h" #include "common/debug.h" +#include "libGLESv2/Texture.h" #include "libEGL/main.h" #include "libEGL/Display.h" +#include <dwmapi.h> + namespace egl { -Surface::Surface(Display *display, const Config *config, HWND window) - : mDisplay(display), mConfig(config), mWindow(window) + +namespace +{ +const int versionWindowsVista = MAKEWORD(0x00, 0x06); +const int versionWindows7 = MAKEWORD(0x01, 0x06); + +// Return the version of the operating system in a format suitable for ordering +// comparison. +int getComparableOSVersion() +{ + DWORD version = GetVersion(); + int majorVersion = LOBYTE(LOWORD(version)); + int minorVersion = HIBYTE(LOWORD(version)); + return MAKEWORD(minorVersion, majorVersion); +} +} + +Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported) + : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) { mSwapChain = NULL; mDepthStencil = NULL; - mBackBuffer = NULL; - mFlipTexture = NULL; - mFlipState = NULL; - mPreFlipState = NULL; + mRenderTarget = NULL; + mOffscreenTexture = NULL; + mShareHandle = NULL; + mTexture = NULL; + mTextureFormat = EGL_NO_TEXTURE; + mTextureTarget = EGL_NO_TEXTURE; mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio mRenderBuffer = EGL_BACK_BUFFER; @@ -36,7 +58,25 @@ Surface::Surface(Display *display, const Config *config, HWND window) setSwapInterval(1); subclassWindow(); - resetSwapChain(); +} + +Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType) + : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) +{ + mSwapChain = NULL; + mDepthStencil = NULL; + mRenderTarget = NULL; + mOffscreenTexture = NULL; + mWindowSubclassed = false; + mTexture = NULL; + mTextureFormat = textureFormat; + mTextureTarget = textureType; + + mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio + mRenderBuffer = EGL_BACK_BUFFER; + mSwapBehavior = EGL_BUFFER_PRESERVED; + mSwapInterval = -1; + setSwapInterval(1); } Surface::~Surface() @@ -45,6 +85,34 @@ Surface::~Surface() release(); } +bool Surface::initialize() +{ + ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil); + + if (!resetSwapChain()) + return false; + + // Modify present parameters for this window, if we are composited, + // to minimize the amount of queuing done by DWM between our calls to + // present and the actual screen. + if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) { + BOOL isComposited; + HRESULT result = DwmIsCompositionEnabled(&isComposited); + if (SUCCEEDED(result) && isComposited) { + DWM_PRESENT_PARAMETERS presentParams; + memset(&presentParams, 0, sizeof(presentParams)); + presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS); + presentParams.cBuffer = 2; + + result = DwmSetPresentParameters(mWindow, &presentParams); + if (FAILED(result)) + ERR("Unable to set present parameters: 0x%08X", result); + } + } + + return true; +} + void Surface::release() { if (mSwapChain) @@ -53,68 +121,116 @@ void Surface::release() mSwapChain = NULL; } - if (mBackBuffer) - { - mBackBuffer->Release(); - mBackBuffer = NULL; - } - if (mDepthStencil) { mDepthStencil->Release(); mDepthStencil = NULL; } - if (mFlipTexture) + if (mRenderTarget) { - mFlipTexture->Release(); - mFlipTexture = NULL; + mRenderTarget->Release(); + mRenderTarget = NULL; } - if (mFlipState) + if (mOffscreenTexture) { - mFlipState->Release(); - mFlipState = NULL; + mOffscreenTexture->Release(); + mOffscreenTexture = NULL; } - if (mPreFlipState) + if (mTexture) { - mPreFlipState->Release(); - mPreFlipState = NULL; + mTexture->releaseTexImage(); + mTexture = NULL; } } -void Surface::resetSwapChain() +bool Surface::resetSwapChain() { + if (!mWindow) + { + return resetSwapChain(mWidth, mHeight); + } + RECT windowRect; if (!GetClientRect(getWindowHandle(), &windowRect)) { ASSERT(false); ERR("Could not retrieve the window dimensions"); - return; + return false; } - resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); + return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); } -void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) +bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) { IDirect3DDevice9 *device = mDisplay->getDevice(); if (device == NULL) { - return; + return false; + } + + IDirect3DSurface9* preservedRenderTarget = NULL; + if (mPostSubBufferSupported && mRenderTarget) + { + preservedRenderTarget = mRenderTarget; + preservedRenderTarget->AddRef(); } // Evict all non-render target textures to system memory and release all resources // before reallocating them to free up as much video memory as possible. device->EvictManagedResources(); release(); - + D3DPRESENT_PARAMETERS presentParameters = {0}; + HRESULT result; + + bool useFlipEx = (getComparableOSVersion() >= versionWindows7) && mDisplay->isD3d9ExDevice(); + + // FlipEx causes unseemly stretching when resizing windows AND when one + // draws outside of the WM_PAINT callback. While this is seldom a problem in + // single process applications, it is particuarly noticeable in multiprocess + // applications. Therefore, if the creator process of our window is not in + // the current process, disable use of FlipEx. + DWORD windowPID; + GetWindowThreadProcessId(mWindow, &windowPID); + if (windowPID != GetCurrentProcessId()) + { + useFlipEx = false; + } + + // Various hardware does not support D3DSWAPEFFECT_FLIPEX when either the + // device format or back buffer format is not 32-bit. + HDC deviceContext = GetDC(0); + int deviceFormatBits = GetDeviceCaps(deviceContext, BITSPIXEL); + ReleaseDC(0, deviceContext); + if (mConfig->mBufferSize != 32 || deviceFormatBits != 32) + { + useFlipEx = false; + } + + // D3DSWAPEFFECT_FLIPEX is always VSYNCed + if (mSwapInterval == 0) + { + useFlipEx = false; + } + + // D3DSWAPEFFECT_FLIPEX does not preserve the back buffer. + if (mPostSubBufferSupported) + { + useFlipEx = false; + } presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; + // We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX. + // We do this because DirectX docs are a bit vague whether to set this to 1 + // or 2. The runtime seems to accept 1, so we speculate that either it is + // forcing it to 2 without telling us, or better, doing something smart + // behind the scenes knowing that we don't need more. presentParameters.BackBufferCount = 1; presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; presentParameters.EnableAutoDepthStencil = FALSE; @@ -123,200 +239,131 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = mPresentInterval; - presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + // Use flipEx on Win7 or greater. + if(useFlipEx) + presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX; + else + presentParameters.SwapEffect = mPostSubBufferSupported ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferHeight = backbufferHeight; - HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); - - if (FAILED(result)) + if (mWindow) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); + } else { + HANDLE *pShareHandle = NULL; + if (mDisplay->shareHandleSupported()) { + pShareHandle = &mShareHandle; + } - ERR("Could not create additional swap chains: %08lX", result); - release(); - return error(EGL_BAD_ALLOC); + result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, + presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); } - result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, - presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, - presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); - if (FAILED(result)) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); - ERR("Could not create depthstencil surface for new swap chain: %08lX", result); + ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); release(); - return error(EGL_BAD_ALLOC); - } - ASSERT(SUCCEEDED(result)); - - result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, - presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mFlipTexture, NULL); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - ERR("Could not create flip texture for new swap chain: %08lX", result); - release(); - return error(EGL_BAD_ALLOC); - } - - mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); - mWidth = presentParameters.BackBufferWidth; - mHeight = presentParameters.BackBufferHeight; - - mPresentIntervalDirty = false; - - InvalidateRect(mWindow, NULL, FALSE); - - // The flip state block recorded mFlipTexture so it is now invalid. - releaseRecordedState(device); -} - -HWND Surface::getWindowHandle() -{ - return mWindow; -} - -void Surface::writeRecordableFlipState(IDirect3DDevice9 *device) -{ - // Disable all pipeline operations - device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - device->SetRenderState(D3DRS_STENCILENABLE, FALSE); - device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); - device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); - device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); - - // Just sample the texture - device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture. - device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); - device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle - device->SetScissorRect(&scissorRect); - D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; - device->SetViewport(&viewport); -} - -void Surface::applyFlipState(IDirect3DDevice9 *device) -{ - HRESULT hr; - - if (mFlipState == NULL) - { - // Create two state blocks both recording the states that are changed when swapping. - - // mPreFlipState will record the original state each entry. - hr = device->BeginStateBlock(); - ASSERT(SUCCEEDED(hr)); - writeRecordableFlipState(device); - hr = device->EndStateBlock(&mPreFlipState); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - - if (SUCCEEDED(hr)) + + if (preservedRenderTarget) { - mPreFlipState->Capture(); + preservedRenderTarget->Release(); + preservedRenderTarget = NULL; } - // mFlipState will record the state for the swap operation. - hr = device->BeginStateBlock(); - ASSERT(SUCCEEDED(hr)); - - writeRecordableFlipState(device); - - hr = device->EndStateBlock(&mFlipState); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - - if (FAILED(hr)) + if(isDeviceLostError(result)) { - mFlipState = NULL; - mPreFlipState->Release(); - mPreFlipState = NULL; + mDisplay->notifyDeviceLost(); + return false; } else { - hr = mFlipState->Apply(); - ASSERT(SUCCEEDED(hr)); + return error(EGL_BAD_ALLOC, false); + } + } + + if (mWindow) + { + mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget); + if (!preservedRenderTarget) + { + InvalidateRect(mWindow, NULL, FALSE); } } else { - hr = mPreFlipState->Capture(); - ASSERT(SUCCEEDED(hr)); - hr = mFlipState->Apply(); - ASSERT(SUCCEEDED(hr)); + mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); } - device->GetRenderTarget(0, &mPreFlipBackBuffer); - device->GetDepthStencilSurface(&mPreFlipDepthStencil); + if (preservedRenderTarget) + { + RECT rect = + { + 0, 0, + mWidth, mHeight + }; - device->SetRenderTarget(0, mBackBuffer); - device->SetDepthStencilSurface(NULL); -} + if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth)) + { + rect.right = presentParameters.BackBufferWidth; + } -void Surface::restoreState(IDirect3DDevice9 *device) -{ - device->SetRenderTarget(0, mPreFlipBackBuffer); - device->SetDepthStencilSurface(mPreFlipDepthStencil); + if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight)) + { + rect.bottom = presentParameters.BackBufferHeight; + } - if (mPreFlipBackBuffer) + mDisplay->endScene(); + device->StretchRect(preservedRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); + + preservedRenderTarget->Release(); + preservedRenderTarget = NULL; + } + + if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) { - mPreFlipBackBuffer->Release(); - mPreFlipBackBuffer = NULL; + result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, + presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, + presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); } - if (mPreFlipDepthStencil) + if (FAILED(result)) { - mPreFlipDepthStencil->Release(); - mPreFlipDepthStencil = NULL; + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); + + ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + release(); + return error(EGL_BAD_ALLOC, false); } - mPreFlipState->Apply(); + mWidth = presentParameters.BackBufferWidth; + mHeight = presentParameters.BackBufferHeight; + + mPresentIntervalDirty = false; + return true; } -// On the next flip, this will cause the state to be recorded from scratch. -// In particular we need to do this if the flip texture changes. -void Surface::releaseRecordedState(IDirect3DDevice9 *device) +HWND Surface::getWindowHandle() { - if (mFlipState) - { - mFlipState->Release(); - mFlipState = NULL; - } - - if (mPreFlipState) - { - mPreFlipState->Release(); - mPreFlipState = NULL; - } + return mWindow; } + + #define kSurfaceProperty _TEXT("Egl::SurfaceOwner") #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") -static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { - if (message == WM_SIZE) { +static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) +{ + if (message == WM_SIZE) + { Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty)); - if(surf) { - surf->checkForOutOfDateSwapChain(); + if(surf) + { + surf->checkForOutOfDateSwapChain(); } } WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc)); @@ -325,39 +372,55 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam void Surface::subclassWindow() { - SetLastError(0); - LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc)); - if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) { - mWindowSubclassed = false; - return; - } + if (!mWindow) + { + return; + } - SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this)); - SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc)); - mWindowSubclassed = true; + DWORD processId; + DWORD threadId = GetWindowThreadProcessId(mWindow, &processId); + if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId()) + { + return; + } + + SetLastError(0); + LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); + if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) + { + mWindowSubclassed = false; + return; + } + + SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this)); + SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc)); + mWindowSubclassed = true; } void Surface::unsubclassWindow() { - if(!mWindowSubclassed) - return; - - // un-subclass - LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc)); - - // Check the windowproc is still SurfaceWindowProc. - // If this assert fails, then it is likely the application has subclassed the - // hwnd as well and did not unsubclass before destroying its EGL context. The - // application should be modified to either subclass before initializing the - // EGL context, or to unsubclass before destroying the EGL context. - if(parentWndFunc) { - LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc); - ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc)); - } + if(!mWindowSubclassed) + { + return; + } + + // un-subclass + LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc)); - RemoveProp(mWindow, kSurfaceProperty); - RemoveProp(mWindow, kParentWndProc); - mWindowSubclassed = false; + // Check the windowproc is still SurfaceWindowProc. + // If this assert fails, then it is likely the application has subclassed the + // hwnd as well and did not unsubclass before destroying its EGL context. The + // application should be modified to either subclass before initializing the + // EGL context, or to unsubclass before destroying the EGL context. + if(parentWndFunc) + { + LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc); + ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); + } + + RemoveProp(mWindow, kSurfaceProperty); + RemoveProp(mWindow, kParentWndProc); + mWindowSubclassed = false; } bool Surface::checkForOutOfDateSwapChain() @@ -402,40 +465,79 @@ DWORD Surface::convertInterval(EGLint interval) return D3DPRESENT_INTERVAL_DEFAULT; } - bool Surface::swap() { if (mSwapChain) { - IDirect3DDevice9 *device = mDisplay->getDevice(); + mDisplay->endScene(); + + HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + return error(EGL_BAD_ALLOC, false); + } + + if (isDeviceLostError(result)) + { + mDisplay->notifyDeviceLost(); + return false; + } - applyFlipState(device); - device->SetTexture(0, mFlipTexture); + ASSERT(SUCCEEDED(result)); - // Render the texture upside down into the back buffer - // Texcoords are chosen to flip the renderTarget about its Y axis. - float w = static_cast<float>(getWidth()); - float h = static_cast<float>(getHeight()); - float quad[4][6] = {{0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f}, - {w - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f}, - {w - 0.5f, h - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f}, - {0 - 0.5f, h - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}}; // x, y, z, rhw, u, v + checkForOutOfDateSwapChain(); + } + + return true; +} - mDisplay->startScene(); - device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); +bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (x < 0 || y < 0 || width < 0 || height < 0) + { + return error(EGL_BAD_PARAMETER, false); + } - restoreState(device); + if (!mPostSubBufferSupported) + { + // Spec is not clear about how this should be handled. + return true; + } + if (mSwapChain) + { mDisplay->endScene(); - HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); + RECT rect = + { + x, mHeight - y - height, + x + width, mHeight - y + }; + + if (rect.right > mWidth) + { + rect.right = mWidth; + } + + if (rect.bottom > mHeight) + { + rect.bottom = mHeight; + } + + if (rect.left == rect.right || rect.top == rect.bottom) + { + return true; + } + + HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) { return error(EGL_BAD_ALLOC, false); } - if (result == D3DERR_DEVICELOST) + if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED) { return error(EGL_CONTEXT_LOST, false); } @@ -458,16 +560,19 @@ EGLint Surface::getHeight() const return mHeight; } -IDirect3DSurface9 *Surface::getRenderTarget() +EGLint Surface::isPostSubBufferSupported() const { - IDirect3DSurface9 *textureSurface = NULL; + return mPostSubBufferSupported; +} - if (mFlipTexture) +IDirect3DSurface9 *Surface::getRenderTarget() +{ + if (mRenderTarget) { - mFlipTexture->GetSurfaceLevel(0, &textureSurface); + mRenderTarget->AddRef(); } - return textureSurface; + return mRenderTarget; } IDirect3DSurface9 *Surface::getDepthStencil() @@ -480,6 +585,16 @@ IDirect3DSurface9 *Surface::getDepthStencil() return mDepthStencil; } +IDirect3DTexture9 *Surface::getOffscreenTexture() +{ + if (mOffscreenTexture) + { + mOffscreenTexture->AddRef(); + } + + return mOffscreenTexture; +} + void Surface::setSwapInterval(EGLint interval) { if (mSwapInterval == interval) @@ -494,4 +609,29 @@ void Surface::setSwapInterval(EGLint interval) mPresentInterval = convertInterval(mSwapInterval); mPresentIntervalDirty = true; } + +EGLenum Surface::getTextureFormat() const +{ + return mTextureFormat; +} + +EGLenum Surface::getTextureTarget() const +{ + return mTextureTarget; +} + +void Surface::setBoundTexture(gl::Texture2D *texture) +{ + mTexture = texture; +} + +gl::Texture2D *Surface::getBoundTexture() const +{ + return mTexture; +} + +D3DFORMAT Surface::getFormat() const +{ + return mConfig->mRenderTargetFormat; +} } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h index 422d3d5..35260de 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h @@ -17,6 +17,11 @@ #include "common/angleutils.h" +namespace gl +{ +class Texture2D; +} + namespace egl { class Display; @@ -25,48 +30,56 @@ class Config; class Surface { public: - Surface(Display *display, const egl::Config *config, HWND window); + Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported); + Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget); ~Surface(); + bool initialize(); void release(); - void resetSwapChain(); + bool resetSwapChain(); HWND getWindowHandle(); bool swap(); + bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); virtual EGLint getWidth() const; virtual EGLint getHeight() const; + virtual EGLint isPostSubBufferSupported() const; + virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getDepthStencil(); + virtual IDirect3DTexture9 *getOffscreenTexture(); + + HANDLE getShareHandle() { return mShareHandle; } void setSwapInterval(EGLint interval); bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update + virtual EGLenum getTextureFormat() const; + virtual EGLenum getTextureTarget() const; + virtual D3DFORMAT getFormat() const; + + virtual void setBoundTexture(gl::Texture2D *texture); + virtual gl::Texture2D *getBoundTexture() const; + private: DISALLOW_COPY_AND_ASSIGN(Surface); Display *const mDisplay; IDirect3DSwapChain9 *mSwapChain; - IDirect3DSurface9 *mBackBuffer; IDirect3DSurface9 *mDepthStencil; - IDirect3DTexture9 *mFlipTexture; + IDirect3DSurface9* mRenderTarget; + IDirect3DTexture9* mOffscreenTexture; + + HANDLE mShareHandle; void subclassWindow(); void unsubclassWindow(); - void resetSwapChain(int backbufferWidth, int backbufferHeight); + bool resetSwapChain(int backbufferWidth, int backbufferHeight); static DWORD convertInterval(EGLint interval); - void applyFlipState(IDirect3DDevice9 *device); - void restoreState(IDirect3DDevice9 *device); - void writeRecordableFlipState(IDirect3DDevice9 *device); - void releaseRecordedState(IDirect3DDevice9 *device); - IDirect3DStateBlock9 *mFlipState; - IDirect3DStateBlock9 *mPreFlipState; - IDirect3DSurface9 *mPreFlipBackBuffer; - IDirect3DSurface9 *mPreFlipDepthStencil; - const HWND mWindow; // Window that the surface is created for. bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking const egl::Config *mConfig; // EGL config surface was created with @@ -81,13 +94,16 @@ private: EGLint mPixelAspectRatio; // Display aspect ratio EGLenum mRenderBuffer; // Render buffer EGLenum mSwapBehavior; // Buffer swap behavior -// EGLenum textureFormat; // Format of texture: RGB, RGBA, or no texture -// EGLenum textureTarget; // Type of texture: 2D or no texture + EGLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture + EGLenum mTextureTarget; // Type of texture: 2D or no texture // EGLenum vgAlphaFormat; // Alpha format for OpenVG // EGLenum vgColorSpace; // Color space for OpenVG EGLint mSwapInterval; + EGLint mPostSubBufferSupported; + DWORD mPresentInterval; bool mPresentIntervalDirty; + gl::Texture2D *mTexture; }; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp index 8dfe6e5..4b7f9e1 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp @@ -9,13 +9,15 @@ #include <exception> #include "common/debug.h" +#include "common/version.h" #include "libGLESv2/Context.h" +#include "libGLESv2/Texture.h" #include "libEGL/main.h" #include "libEGL/Display.h" -bool validate(egl::Display *display) +bool validateDisplay(egl::Display *display) { if (display == EGL_NO_DISPLAY) { @@ -30,9 +32,9 @@ bool validate(egl::Display *display) return true; } -bool validate(egl::Display *display, EGLConfig config) +bool validateConfig(egl::Display *display, EGLConfig config) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -45,9 +47,9 @@ bool validate(egl::Display *display, EGLConfig config) return true; } -bool validate(egl::Display *display, gl::Context *context) +bool validateContext(egl::Display *display, gl::Context *context) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -60,9 +62,9 @@ bool validate(egl::Display *display, gl::Context *context) return true; } -bool validate(egl::Display *display, egl::Surface *surface) +bool validateSurface(egl::Display *display, egl::Surface *surface) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -79,7 +81,7 @@ extern "C" { EGLint __stdcall eglGetError(void) { - TRACE("()"); + EVENT("()"); EGLint error = egl::getCurrentError(); @@ -93,34 +95,21 @@ EGLint __stdcall eglGetError(void) EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id) { - TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); + EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); try { - // FIXME: Return the same EGLDisplay handle when display_id already created a display - - if (display_id == EGL_DEFAULT_DISPLAY) - { - return new egl::Display((HDC)NULL); - } - else - { - // FIXME: Check if display_id is a valid display device context - - return new egl::Display((HDC)display_id); - } + return egl::Display::getDisplay(display_id); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); } - - return EGL_NO_DISPLAY; } EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy, major, minor); try @@ -146,13 +135,11 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) { - TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy); + EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); try { @@ -171,19 +158,17 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return NULL; } @@ -193,11 +178,11 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) case EGL_CLIENT_APIS: return success("OpenGL_ES"); case EGL_EXTENSIONS: - return success(""); + return display->getExtensionString(); case EGL_VENDOR: - return success("TransGaming Inc."); + return success("Google Inc."); case EGL_VERSION: - return success("1.4 (git-devel "__DATE__" " __TIME__")"); + return success("1.4 (ANGLE "VERSION_STRING")"); } return error(EGL_BAD_PARAMETER, (const char*)NULL); @@ -206,13 +191,11 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) { return error(EGL_BAD_ALLOC, (const char*)NULL); } - - return NULL; } EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", dpy, configs, config_size, num_config); @@ -220,7 +203,7 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -243,13 +226,11 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", dpy, attrib_list, configs, config_size, num_config); @@ -257,7 +238,7 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -282,20 +263,18 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, config, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_FALSE; } @@ -311,20 +290,18 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } @@ -336,113 +313,70 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } - if (attrib_list) - { - while (*attrib_list != EGL_NONE) - { - switch (attrib_list[0]) - { - case EGL_RENDER_BUFFER: - switch (attrib_list[1]) - { - case EGL_BACK_BUFFER: - break; - case EGL_SINGLE_BUFFER: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported - default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); - } - break; - case EGL_VG_COLORSPACE: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); - case EGL_VG_ALPHA_FORMAT: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); - default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); - } - - attrib_list += 2; - } - } - - if (display->hasExistingWindowSurface(window)) - { - return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); - } - - EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config); - - return success(surface); + return display->createWindowSurface(window, config, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, config, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME - - return success(EGL_NO_DISPLAY); + return display->createOffscreenSurface(config, NULL, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } UNIMPLEMENTED(); // FIXME - return success(EGL_NO_DISPLAY); + return success(EGL_NO_SURFACE); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -460,20 +394,19 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, surface, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -483,8 +416,6 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint return error(EGL_BAD_SURFACE, EGL_FALSE); } - egl::Surface *eglSurface = (egl::Surface*)surface; - switch (attribute) { case EGL_VG_ALPHA_FORMAT: @@ -535,6 +466,9 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint case EGL_WIDTH: *value = eglSurface->getWidth(); break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + *value = eglSurface->isPostSubBufferSupported(); + break; default: return error(EGL_BAD_ATTRIBUTE, EGL_FALSE); } @@ -545,13 +479,48 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } +} - return EGL_FALSE; +EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value) +{ + TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)", + dpy, surface, attribute, value); + + try + { + egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; + + if (!validateSurface(display, eglSurface)) + { + return EGL_FALSE; + } + + if (surface == EGL_NO_SURFACE) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + switch (attribute) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + *value = (void*) eglSurface->getShareHandle(); + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + } + + return success(EGL_TRUE); + } + catch(std::bad_alloc&) + { + return error(EGL_BAD_ALLOC, EGL_FALSE); + } } EGLBoolean __stdcall eglBindAPI(EGLenum api) { - TRACE("(EGLenum api = 0x%X)", api); + EVENT("(EGLenum api = 0x%X)", api); try { @@ -574,13 +543,11 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLenum __stdcall eglQueryAPI(void) { - TRACE("()"); + EVENT("()"); try { @@ -592,13 +559,11 @@ EGLenum __stdcall eglQueryAPI(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitClient(void) { - TRACE("()"); + EVENT("()"); try { @@ -610,13 +575,11 @@ EGLBoolean __stdcall eglWaitClient(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglReleaseThread(void) { - TRACE("()"); + EVENT("()"); try { @@ -628,13 +591,11 @@ EGLBoolean __stdcall eglReleaseThread(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, buftype, buffer, config, attrib_list); @@ -642,33 +603,35 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME + if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer) + { + return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + } - return success(EGL_NO_SURFACE); + return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", dpy, surface, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -681,24 +644,46 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + if (buffer != EGL_BACK_BUFFER) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->getBoundTexture()) + { + return error(EGL_BAD_ACCESS, EGL_FALSE); + } + + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } + + if (!glBindTexImage(eglSurface)) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } return success(EGL_TRUE); } @@ -706,24 +691,43 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + if (buffer != EGL_BACK_BUFFER) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } + + gl::Texture2D *texture = eglSurface->getBoundTexture(); + + if (texture) + { + texture->releaseTexImage(); + } return success(EGL_TRUE); } @@ -731,19 +735,17 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -763,29 +765,45 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); try { // Get the requested client version (default is 1) and check it is two. EGLint client_version = 1; + bool reset_notification = false; + bool robust_access = false; + if (attrib_list) { for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2) { - if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION) + switch (attribute[0]) { + case EGL_CONTEXT_CLIENT_VERSION: client_version = attribute[1]; - } - else - { + break; + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: + if (attribute[1] == EGL_TRUE) + { + return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented + // robust_access = true; + } + else if (attribute[1] != EGL_FALSE) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + break; + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: + if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT) + reset_notification = true; + else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + break; + default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); } } @@ -796,34 +814,41 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); } + if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification) + { + return error(EGL_BAD_MATCH, EGL_NO_CONTEXT); + } + egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_CONTEXT; } - EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context)); + EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access); - return success(context); + if (context) + return success(context); + else + return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } - - return EGL_NO_CONTEXT; } EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); try { egl::Display *display = static_cast<egl::Display*>(dpy); + gl::Context *context = static_cast<gl::Context*>(ctx); - if (!validate(display)) + if (!validateContext(display, context)) { return EGL_FALSE; } @@ -833,7 +858,7 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) return error(EGL_BAD_CONTEXT, EGL_FALSE); } - display->destroyContext((gl::Context*)ctx); + display->destroyContext(context); return success(EGL_TRUE); } @@ -841,13 +866,11 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, draw, read, ctx); try @@ -856,18 +879,24 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface gl::Context *context = static_cast<gl::Context*>(ctx); IDirect3DDevice9 *device = display->getDevice(); - if (!device || FAILED(device->TestCooperativeLevel())) + if (!device || display->testDeviceLost()) + { + display->notifyDeviceLost(); + return EGL_FALSE; + } + + if (display->isDeviceLost()) { return error(EGL_CONTEXT_LOST, EGL_FALSE); } - if (ctx != EGL_NO_CONTEXT && !validate(display, context)) + if (ctx != EGL_NO_CONTEXT && !validateContext(display, context)) { return EGL_FALSE; } - if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) || - (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read)))) + if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) || + (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read)))) { return EGL_FALSE; } @@ -889,13 +918,11 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLContext __stdcall eglGetCurrentContext(void) { - TRACE("()"); + EVENT("()"); try { @@ -907,13 +934,11 @@ EGLContext __stdcall eglGetCurrentContext(void) { return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } - - return EGL_NO_CONTEXT; } EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) { - TRACE("(EGLint readdraw = %d)", readdraw); + EVENT("(EGLint readdraw = %d)", readdraw); try { @@ -936,13 +961,11 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLDisplay __stdcall eglGetCurrentDisplay(void) { - TRACE("()"); + EVENT("()"); try { @@ -954,20 +977,19 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void) { return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); } - - return EGL_NO_DISPLAY; } EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, ctx, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + gl::Context *context = static_cast<gl::Context*>(ctx); - if (!validate(display)) + if (!validateContext(display, context)) { return EGL_FALSE; } @@ -980,13 +1002,11 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitGL(void) { - TRACE("()"); + EVENT("()"); try { @@ -998,13 +1018,11 @@ EGLBoolean __stdcall eglWaitGL(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitNative(EGLint engine) { - TRACE("(EGLint engine = %d)", engine); + EVENT("(EGLint engine = %d)", engine); try { @@ -1016,30 +1034,32 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + if (surface == EGL_NO_SURFACE) { return error(EGL_BAD_SURFACE, EGL_FALSE); } - egl::Surface *eglSurface = (egl::Surface*)surface; - if (eglSurface->swap()) { return success(EGL_TRUE); @@ -1055,17 +1075,23 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + UNIMPLEMENTED(); // FIXME return success(0); @@ -1074,13 +1100,48 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ { return error(EGL_BAD_ALLOC, EGL_FALSE); } +} + +EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height); + + try + { + egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); + + if (!validateSurface(display, eglSurface)) + { + return EGL_FALSE; + } + + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->postSubBuffer(x, y, width, height)) + { + return success(EGL_TRUE); + } + } + catch(std::bad_alloc&) + { + return error(EGL_BAD_ALLOC, EGL_FALSE); + } return EGL_FALSE; } __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname) { - TRACE("(const char *procname = \"%s\")", procname); + EVENT("(const char *procname = \"%s\")", procname); try { @@ -1092,6 +1153,8 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char static const Extension eglExtensions[] = { + {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE}, + {"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV}, {"", NULL}, }; @@ -1109,7 +1172,5 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char { return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL); } - - return NULL; } } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc new file mode 100644 index 0000000..5d1f32f --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc @@ -0,0 +1,102 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <windows.h> +#include "../common/version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""../common/version.h""\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "ANGLE libEGL Dynamic Link Library" + VALUE "FileVersion", VERSION_STRING + VALUE "InternalName", "libEGL" + VALUE "LegalCopyright", "Copyright (C) 2011 Google Inc." + VALUE "OriginalFilename", "libEGL.dll" + VALUE "PrivateBuild", VERSION_STRING + VALUE "ProductName", "ANGLE libEGL Dynamic Link Library" + VALUE "ProductVersion", VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj index 4f8d0b2..c3e8a4b 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj @@ -12,6 +12,9 @@ <Platform Name="Win32" /> + <Platform + Name="x64" + /> </Platforms> <ToolFiles> </ToolFiles> @@ -47,9 +50,11 @@ BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" + WarnAsError="true" /> <Tool Name="VCManagedResourceCompilerTool" @@ -62,9 +67,10 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="dxguid.lib" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" LinkIncremental="2" ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" GenerateDebugInformation="true" SubSystem="2" RandomizedBaseAddress="1" @@ -125,9 +131,11 @@ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0" RuntimeLibrary="0" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" + WarnAsError="true" /> <Tool Name="VCManagedResourceCompilerTool" @@ -140,9 +148,10 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="dxguid.lib" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" LinkIncremental="1" ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" GenerateDebugInformation="true" SubSystem="2" OptimizeReferences="2" @@ -174,6 +183,172 @@ CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" /> </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(ProjectDir)/..; $(ProjectDir)/../../include" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + WarnAsError="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" + LinkIncremental="2" + ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" + GenerateDebugInformation="true" + SubSystem="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="$(ProjectDir)/..; $(ProjectDir)/../../include" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + WarnAsError="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" + LinkIncremental="1" + ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" + GenerateDebugInformation="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" + /> + </Configuration> </Configurations> <References> </References> @@ -238,14 +413,26 @@ > </File> <File + RelativePath=".\resource.h" + > + </File> + <File RelativePath=".\Surface.h" > </File> + <File + RelativePath="..\common\version.h" + > + </File> </Filter> <File RelativePath=".\libEGL.def" > </File> + <File + RelativePath=".\libEGL.rc" + > + </File> </Files> <Globals> </Globals> diff --git a/Source/ThirdParty/ANGLE/src/libEGL/main.cpp b/Source/ThirdParty/ANGLE/src/libEGL/main.cpp index d9902d2..1c107bf 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/main.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/main.cpp @@ -18,16 +18,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { case DLL_PROCESS_ATTACH: { - #ifndef NDEBUG - FILE *debug = fopen("debug.txt", "rt"); - - if (debug) - { - fclose(debug); - debug = fopen("debug.txt", "wt"); // Erase - fclose(debug); - } - #endif +#if !defined(ANGLE_DISABLE_TRACE) + FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt"); + + if (debug) + { + fclose(debug); + debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase + fclose(debug); + } +#endif currentTLS = TlsAlloc(); diff --git a/Source/ThirdParty/ANGLE/src/libEGL/main.h b/Source/ThirdParty/ANGLE/src/libEGL/main.h index d6dc759..d09d9e6 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/main.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/main.h @@ -11,6 +11,7 @@ #define EGLAPI #include <EGL/egl.h> +#include <EGL/eglext.h> namespace egl { diff --git a/Source/ThirdParty/ANGLE/src/libEGL/resource.h b/Source/ThirdParty/ANGLE/src/libEGL/resource.h new file mode 100644 index 0000000..3921f4c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libEGL/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by libEGL.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif |