diff options
author | Pierre-Antoine LaFayette <plafayet@codeaurora.org> | 2011-12-29 15:13:33 +0100 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2013-01-20 18:38:26 -0800 |
commit | 70f026a42cf1bee061389fa6ce790ea1186f0703 (patch) | |
tree | b0de5b5676433d2382e7cf1307b54edc19fc42a5 /Source/ThirdParty/ANGLE/src/libEGL | |
parent | a815c626d7df7e24ba9e0df27c27735d4e069ffd (diff) | |
download | external_webkit-70f026a42cf1bee061389fa6ce790ea1186f0703.zip external_webkit-70f026a42cf1bee061389fa6ce790ea1186f0703.tar.gz external_webkit-70f026a42cf1bee061389fa6ce790ea1186f0703.tar.bz2 |
WebGL implementation for Android
Implementation of WebGL in Android WebKit. Exposes a low level 3D
graphics API based on OpenGL ES 2.0 to JavaScript. WebGL is not compiled
by default. It can be enabled by setting ENABLE_WEBGL = true in your
device BoardConfig.mk or directly in external/webkit/Android.mk.
Includes runtime enablement through Browser Settings -> Labs menu.
Enable WebGL debug logs and FPS timing with: adb shell setprop debug.webgl 1
Includes Cross-origin resource sharing support.
Includes fixes for the following Khronos WebGL 1.0.1. tests:
- premultiplyalpha-test.html
- struct-nesting-exceeds-maximum.html
- index-validation.html
- context-attributes-alpha-depth-stencil-antialias.html
- program-test.html
- object-deletion-behaviour.html
Squashed patches:
-----------------------------------------------------------
WebGL implementation for Android
Implementation of WebGL in Android WebKit. Exposes a low level 3D
graphics API based on OpenGL ES 2.0 to JavaScript. WebGL is not compiled
by default. It can be enabled by setting ENABLE_WEBGL = true in your
device BoardConfig.mk or directly in external/webkit/Android.mk. It is
also disabled by default (in WebSettings.cpp) as required by Khronos
until it reaches 100% conformance.
--
From: Anders Edenbrandt <anders.edenbrandt@sonyericsson.com>
Date: Thu, 26 Jan 2012 11:48:41 +0100
WebGL bug fixes and updates
Some updates:
- stability fixes
- image decoder
- redesign of how the FBOs are used
- other bug fixes
--
From: Anders Edenbrandt <anders.edenbrandt@sonyericsson.com>
Date: Tue, 31 Jan 2012 17:20:13 +0100
WebGL code cleanup and bug fixes
--
From: Anders Edenbrandt <anders.edenbrandt@sonyericsson.com>
Date: Thu Mar 15 10:15:33 2012 +0100
More improvements and bug fixes
Updates:
- cleaned up buffer handling, allowing for arbitrary number of buffers
- removed rect from invalidation
- removed screen update request from drawGL
- releasing buffers when the browser is paused
- added missing method 'slice' for typed arrays
- fixed bug in bindFramebuffer
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=c72ff2aa562941d94ceb51ba685d60809ca882a6
Updates to fix some test failures in Khronos Conformance Test Suite:
- Increase max identifier length in shaders to 256
- Add length check on uniforms and attributes
- Add minimal support for compressed textures
(that is, just return the correct error codes)
- Add support for Uint8ClampedByteArray
- Modify how error checking is done on framebuffer operations
- Activate the GL_OES_packed_depth_stencil extension
- Activate the GL_OES_texture_float extension
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=5bfe05848c12a2894697fbb503cfa79981eb96bd
Fix WebGL 1.0.1 premultiplyalpha-test conformance test
Fixing bug with toDataURL when called against a Canvas in which WebGL
content is being rendered and make sure paintRenderingResultsToImageData
isn't used for the premultiplied case.
ihttps://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=5834a1e00f89d898a7a0039d47916b196e40a2c8
Update ANGLE to r1009 to fix WebGL 1.0.1 conformance test
Fixes struct-nesting-exceeds-maximum Khronos WebGL conformance test.
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=ae2392db6360b41a5717f3770a9e63b1bcea45d6
vertexAttribPointer needs to reject large negative offsets
https://bugs.webkit.org/show_bug.cgi?id=85117
Reviewed by Kenneth Russell.
Source/WebCore:
* html/canvas/WebGLRenderingContext.cpp: Use long long for GLsizeiptr and GLintptr
(WebCore):
(WebCore::WebGLRenderingContext::bufferData):
(WebCore::WebGLRenderingContext::bufferSubData):
(WebCore::WebGLRenderingContext::drawElements):
(WebCore::WebGLRenderingContext::getVertexAttribOffset):
(WebCore::WebGLRenderingContext::vertexAttribPointer):
* html/canvas/WebGLRenderingContext.h: Ditto
(WebGLRenderingContext):
* html/canvas/WebGLRenderingContext.idl: Ditto
LayoutTests:
* fast/canvas/webgl/index-validation-expected.txt:
* fast/canvas/webgl/index-validation.html: Add a test case for large negative offset.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@116374 268f45cc-cd09-0410-ab3c-d52691b4dbfc
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=b3a02a0942a0e2c44d23961382145fad6016b2ef
Fix for context-attributes-alpha-depth-stencil-antialias
Support for alpha, depth and stencil to fix WebGL Khronos 1.0.1
conformance test. Report back that antialiasing is not supported on our
platform.
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=22e98195ac73e7e12a59d5b9a42dfc4e2252b475
WebGLRenderingContext should defer caching program info
https://bugs.webkit.org/show_bug.cgi?id=83513
Reviewed by Kenneth Russell.
* html/canvas/WebGLProgram.cpp:
(WebCore::WebGLProgram::WebGLProgram):
(WebCore::WebGLProgram::numActiveAttribLocations): call cacheInfoIfNeeded();
(WebCore::WebGLProgram::getActiveAttribLocation): Ditto.
(WebCore::WebGLProgram::isUsingVertexAttrib0): Ditto.
(WebCore::WebGLProgram::getLinkStatus): Ditto.
(WebCore):
(WebCore::WebGLProgram::cacheActiveAttribLocations):
(WebCore::WebGLProgram::cacheInfoIfNeeded): Cache link status, active attire locations, etc if needed.
(WebCore::WebGLProgram::increaseLinkCount): also invalidate cached info.
* html/canvas/WebGLProgram.h:
(WebGLProgram):
* html/canvas/WebGLRenderingContext.cpp:
(WebCore):
(WebCore::WebGLRenderingContext::linkProgram): Do not cache program info immediately.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113915 268f45cc-cd09-0410-ab3c-d52691b4dbfc
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=66bc9c1b9eb5151b1b236199d0eeb17df0557b47
Runtime enablement of WebGL
Hooks up with the Java side to enable/disable WebGL through the debug
menu.
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=75aab57859de45a0aaec5a7cad41a12111e9a82e
Support the usage of CORS for WebGL and the 2D canvas
Factor CORS request preparation out of DocumentThreadableLoader
https://bugs.webkit.org/show_bug.cgi?id=61209
2011-05-20 Adam Barth <abarth@webkit.org>
Reviewed by Alexey Proskuryakov.
Factor CORS request preparation out of DocumentThreadableLoader
https://bugs.webkit.org/show_bug.cgi?id=61209
DocumentThreadableLoader has two jobs:
1) Proxy loads between threads.
2) Run the CORS state machine.
This patch begins the work of separating those concerns, allowing CORS
to be used elsewhere in the loading pipeline. In particular, this
patch moves knowledge of how to prepare CORS requests out of
DocumentThreadableLoder.
* loader/CrossOriginAccessControl.cpp:
(WebCore::isOnAccessControlSimpleRequestHeaderWhitelist):
(WebCore::updateRequestForAccessControl):
(WebCore::createAccessControlPreflightRequest):
* loader/CrossOriginAccessControl.h:
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
(WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
(WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@86980 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Add rel type prerender to distinguish prerender from prefetch
https://bugs.webkit.org/show_bug.cgi?id=61079
2011-05-21 Gavin Peters <gavinp@chromium.org>
Reviewed by Adam Barth.
Add rel type prerender to distinguish prerender from prefetch
https://bugs.webkit.org/show_bug.cgi?id=61079
Chrome right now uses <link rel=prefetch ...> for one of two things,
to warm the cache in the same way as firefox, or to launch a speculative
rendering of a web page, for faster "loading" when the user navigates to it.
This new rel type will let us distinguish the two cases; the rel type prerender
isn't used on the web today, but the Google Web Search example prerendering application
is ready to experiment with it.
* fast/dom/HTMLLinkElement/prerender-expected.txt: Added.
* fast/dom/HTMLLinkElement/prerender.html: Added.
* platform/gtk/Skipped:
* platform/mac/Skipped:
* platform/qt/Skipped:
* platform/win/Skipped:
2011-05-21 Gavin Peters <gavinp@chromium.org>
Reviewed by Adam Barth.
Add rel type prerender to distinguish prerender from prefetch
https://bugs.webkit.org/show_bug.cgi?id=61079
Chrome right now uses <link rel=prefetch ...> for one of two things,
to warm the cache in the same way as firefox, or to launch a speculative
rendering of a web page, for faster "loading" when the user navigates to it.
This new rel type will let us distinguish the two cases; the rel type prerender
isn't used on the web today, but the Google Web Search example prerendering application
is ready to experiment with it.
Test: fast/dom/HTMLLinkElement/prerender.html
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::tokenizeRelAttribute):
(WebCore::HTMLLinkElement::process):
* html/HTMLLinkElement.h:
(WebCore::HTMLLinkElement::RelAttribute::RelAttribute):
* loader/cache/CachedResource.cpp:
(WebCore::defaultPriorityForResourceType):
* loader/cache/CachedResource.h:
(WebCore::CachedResource::isLinkResource):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::createResource):
(WebCore::CachedResourceLoader::requestLinkResource):
(WebCore::CachedResourceLoader::canRequest):
* loader/cache/CachedResourceLoader.h:
* loader/cache/CachedResourceRequest.cpp:
(WebCore::cachedResourceTypeToTargetType):
(WebCore::CachedResourceRequest::load):
* platform/network/ResourceRequestBase.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87020 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Make CachedResource take a ResourceRequest instead of just a url string.
2011-05-24 Nate Chapin <japhet@chromium.org>
Reviewed by Adam Barth.
Change CachedResources to take a ResourceRequest instead of
a url in their constructors and provide a very minimal set of
cases for avoiding reusing a CachedResource. The ResourceRequest
part of this change requires pushing responsibility
for calling Document::completeURL() to the caller, instead of
CachedResourceLoader, since ResourceRequest ASSERTs if it
is constructed with an invalid url.
https://bugs.webkit.org/show_bug.cgi?id=61318
Refactor, no new tests.
* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::addFontFaceRule):
* css/CSSImageValue.cpp:
(WebCore::CSSImageValue::cachedImage):
* css/CSSImportRule.cpp:
(WebCore::CSSImportRule::insertedIntoParent):
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::checkStyleSheet):
* dom/ScriptElement.cpp:
(WebCore::ScriptElement::requestScript):
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::process):
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement):
* loader/cache/CachedCSSStyleSheet.cpp:
(WebCore::CachedCSSStyleSheet::CachedCSSStyleSheet):
(WebCore::CachedCSSStyleSheet::didAddClient):
(WebCore::CachedCSSStyleSheet::checkNotify):
* loader/cache/CachedCSSStyleSheet.h:
* loader/cache/CachedFont.cpp:
(WebCore::CachedFont::CachedFont):
* loader/cache/CachedFont.h:
* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::CachedImage):
(WebCore::CachedImage::checkShouldPaintBrokenImage):
* loader/cache/CachedImage.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::CachedResource):
(WebCore::reuseRequest):
(WebCore::CachedResource::allowReuseOfRequest):
(WebCore::CachedResource::removeClient):
(WebCore::CachedResource::canUseCacheValidator):
* loader/cache/CachedResource.h:
(WebCore::CachedResource::resourceRequest):
(WebCore::CachedResource::url):
* loader/cache/CachedResourceLoader.cpp:
* loader/cache/CachedResourceLoader.h:
* loader/cache/CachedResourceRequest.cpp:
(WebCore::CachedResourceRequest::load):
* loader/cache/CachedScript.cpp:
(WebCore::CachedScript::CachedScript):
* loader/cache/CachedScript.h:
* loader/cache/CachedXSLStyleSheet.cpp:
(WebCore::CachedXSLStyleSheet::CachedXSLStyleSheet):
(WebCore::CachedXSLStyleSheet::didAddClient):
(WebCore::CachedXSLStyleSheet::checkNotify):
* loader/cache/CachedXSLStyleSheet.h:
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::requestImageResource):
* svg/SVGFontFaceUriElement.cpp:
(WebCore::SVGFontFaceUriElement::loadFont):
* xml/XSLImportRule.cpp:
(WebCore::XSLImportRule::loadSheet):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87239 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Support cross-origin property for images
2011-05-26 Adam Barth <abarth@webkit.org>
Reviewed by Eric Seidel.
Support cross-origin property for images
https://bugs.webkit.org/show_bug.cgi?id=61015
Test various cases involving CORS requests and canvas tainting.
* http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt: Added.
* http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt: Added.
* http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html: Added.
* http/tests/security/canvas-remote-read-remote-image-allowed.html: Added.
* http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Added.
* http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html: Added.
* http/tests/security/resources/abe-allow-credentials.php: Added.
* http/tests/security/resources/abe-allow-star.php: Added.
2011-05-26 Adam Barth <abarth@webkit.org>
Reviewed by Eric Seidel.
Support cross-origin property for images
https://bugs.webkit.org/show_bug.cgi?id=61015
This patch add support for the crossorigin attribute of images and
teaches 2D canvas to respect that flag and not taint a canvas if the
image drawn on the canvas is allowed by CORS.
While I was editing this code, I couldn't resist a couple touch-up
changes.
Tests: http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html
http/tests/security/canvas-remote-read-remote-image-allowed.html
http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html
* html/HTMLAttributeNames.in:
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::securityOrigin):
* html/HTMLCanvasElement.h:
* html/HTMLImageElement.idl:
* html/canvas/CanvasRenderingContext.cpp:
(WebCore::CanvasRenderingContext::checkOrigin):
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::createPattern):
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::passesAccessControlCheck):
* loader/cache/CachedResource.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87473 268f45cc-cd09-0410-ab3c-d52691b4dbfc
HTMLVideoElement::currentSrc() should return a KURL
2011-05-27 Adam Barth <abarth@webkit.org>
Reviewed by Eric Seidel.
HTMLVideoElement::currentSrc() should return a KURL
https://bugs.webkit.org/show_bug.cgi?id=61578
I suspect we got into this mess because the author of this code didn't
know about the URL attribute in WebKit IDL, which is super useful!
Bad news: The line of code in question seems to have another bug, which
I've documented in a FIXME. Let the yak shaving continue!
* html/HTMLMediaElement.cpp:
(WebCore::urlForLogging):
(WebCore::HTMLMediaElement::loadResource):
(WebCore::HTMLMediaElement::isSafeToLoadURL):
(WebCore::HTMLMediaElement::selectNextSourceChild):
(WebCore::HTMLMediaElement::getPluginProxyParams):
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::currentSrc):
(WebCore::HTMLMediaElement::currentURL):
* html/canvas/CanvasRenderingContext.cpp:
(WebCore::CanvasRenderingContext::checkOrigin):
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::absoluteMediaURL):
- This complete URL call was unnecessary because currentSrc is
already absolute.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87539 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Disallow use of cross-domain media (images, video) in WebGL
2011-06-09 Kenneth Russell <kbr@google.com>
Reviewed by Adam Barth.
Disallow use of cross-domain media (images, video) in WebGL
https://bugs.webkit.org/show_bug.cgi?id=62257
Updated WebGL implementation to track recent spec updates in this area.
Tests: http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
http/tests/security/webgl-remote-read-remote-image-allowed.html
http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html
* html/canvas/CanvasRenderingContext.cpp:
(WebCore::CanvasRenderingContext::wouldTaintOrigin):
(WebCore::CanvasRenderingContext::checkOrigin):
* html/canvas/CanvasRenderingContext.h:
(WebCore::CanvasRenderingContext::checkOrigin):
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::readPixels):
(WebCore::WebGLRenderingContext::texImage2D):
(WebCore::WebGLRenderingContext::videoFrameToImage):
(WebCore::WebGLRenderingContext::texSubImage2D):
* html/canvas/WebGLRenderingContext.h:
2011-06-09 Kenneth Russell <kbr@google.com>
Reviewed by Adam Barth.
Disallow use of cross-domain media (images, video) in WebGL
https://bugs.webkit.org/show_bug.cgi?id=62257
Updated origin-clean-conformance.html to track upstream version in
Khronos repository. Added new layout tests mirroring those added
in bug 61015 which verify that new CORS support for images is
working in the context of WebGL.
Verified new tests in WebKit and Chromium. Skipped tests on
platforms where WebGL is disabled.
* http/tests/canvas/webgl/origin-clean-conformance-expected.txt:
* http/tests/canvas/webgl/origin-clean-conformance.html:
* http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt: Added.
* http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt: Added.
* http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html: Added.
* http/tests/security/webgl-remote-read-remote-image-allowed.html: Added.
* http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Added.
* http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html: Added.
* platform/gtk/Skipped:
* platform/mac-leopard/Skipped:
* platform/mac-wk2/Skipped:
* platform/qt/Skipped:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@88489 268f45cc-cd09-0410-ab3c-d52691b4dbfc
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=0ddd7c1d91c08fbee6c99b79fa9971a7ac914384
Runtime enablement of WebGL logs
Allows enabling WebGL method level logging using:
adb shell setprop debug.webgl 1
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=307d4a2b5b20f2609497ceaea1eca2e29a8a781f
Adding WebGL FPS timing to logs
Samples WebGL average FPS every 15 frames and outputs to WebGL debug log.
TODO: Add setting to browser debug settings that overlays FPS on web
pages.
Postpone deleteRenderbuffer/deleteTexture until all framebuffer attachment points are removed.
https://bugs.webkit.org/show_bug.cgi?id=74741
Reviewed by Kenneth Russell.
Source/WebCore:
Use WebGLObject's attachment count mechanism to track if a renderbuffer/texture
is still attached to framebuffers, and if its deletion should be delated or not.
* html/canvas/WebGLFramebuffer.cpp:
(WebCore::WebGLFramebuffer::setAttachmentForBoundFramebuffer):
(WebCore::WebGLFramebuffer::getAttachment):
(WebCore::WebGLFramebuffer::removeAttachmentFromBoundFramebuffer):
(WebCore::WebGLFramebuffer::deleteObjectImpl):
(WebCore::WebGLFramebuffer::isBound):
* html/canvas/WebGLFramebuffer.h:
LayoutTests:
* fast/canvas/webgl/object-deletion-behaviour-expected.txt:
* fast/canvas/webgl/object-deletion-behaviour.html: synced with khronos side.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@103272 268f45cc-cd09-0410-ab3c-d52691b4dbfc
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=9def386340c74f2a745fb041b1cb11daa30d1a82
-----------------------------------------------------------
(cherry-picked from commit 6d9d732ff06a6b265d02b18d7034068a68ef0fde)
Conflicts:
Android.mk
Source/WebCore/ChangeLog
Change-Id: I3bbf993fe5a3d6cea53e019c8fa3912ecd2bd429
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 |