From b6bd727d23c16a4b1c96634d65b3c1548ecb5bae Mon Sep 17 00:00:00 2001 From: "daniel@transgaming.com" Date: Wed, 5 May 2010 18:48:22 +0000 Subject: [PATCH] Implemented eglSwapInterval TRAC #12137 Signed-off-by: Andrew Lewycky Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@235 736b8ea6-26fd-11df-bfd4-992fa37f6226 --- src/libEGL/Display.cpp | 35 ++++++++++++++++++++++++++++++----- src/libEGL/Display.h | 4 ++++ src/libEGL/Surface.cpp | 6 +++--- src/libEGL/Surface.h | 5 +++-- src/libEGL/libEGL.cpp | 2 +- 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp index 6276452ba..175cb175c 100644 --- a/src/libEGL/Display.cpp +++ b/src/libEGL/Display.cpp @@ -26,6 +26,7 @@ Display::Display(HDC deviceContext) : mDc(deviceContext) mAdapter = D3DADAPTER_DEFAULT; mDeviceType = D3DDEVTYPE_HAL; + mSwapInterval = 1; } Display::~Display() @@ -224,7 +225,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) case EGL_ALPHA_MASK_SIZE: *value = configuration->mAlphaMaskSize; break; case EGL_COLOR_BUFFER_TYPE: *value = configuration->mColorBufferType; break; case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break; - case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break; + case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break; case EGL_CONFORMANT: *value = configuration->mConformant; break; default: return false; @@ -233,9 +234,9 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) return true; } -egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config) +Surface *Display::createWindowSurface(HWND window, EGLConfig config) { - const egl::Config *configuration = mConfigSet.get(config); + const Config *configuration = mConfigSet.get(config); D3DPRESENT_PARAMETERS presentParameters = {0}; @@ -249,7 +250,7 @@ egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config) presentParameters.hDeviceWindow = window; presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented - presentParameters.PresentationInterval = configuration->mMinSwapInterval; + presentParameters.PresentationInterval = getPresentInterval(configuration, true); presentParameters.SwapEffect = D3DSWAPEFFECT_COPY; presentParameters.Windowed = TRUE; // FIXME @@ -345,7 +346,7 @@ egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config) if (swapChain) { - surface = new Surface(this, swapChain, depthStencilSurface, configuration->mConfigID); + surface = new Surface(this, swapChain, depthStencilSurface, configuration); mSurfaceSet.insert(surface); swapChain->Release(); @@ -409,6 +410,30 @@ bool Display::hasExistingWindowSurface(HWND window) return false; } +void Display::setSwapInterval(GLint interval) +{ + mSwapInterval = interval; +} + +DWORD Display::getPresentInterval(const egl::Config *config, bool maximumRate) +{ + GLint interval = maximumRate ? 0 : mSwapInterval; + interval = interval < config->mMinSwapInterval ? config->mMinSwapInterval : interval; + interval = interval > config->mMaxSwapInterval ? config->mMaxSwapInterval : interval; + + switch(interval) + { + case 0: return D3DPRESENT_INTERVAL_IMMEDIATE; + case 1: return D3DPRESENT_INTERVAL_ONE; + case 2: return D3DPRESENT_INTERVAL_TWO; + case 3: return D3DPRESENT_INTERVAL_THREE; + case 4: return D3DPRESENT_INTERVAL_FOUR; + default: UNREACHABLE(); + } + + return D3DPRESENT_INTERVAL_DEFAULT; +} + IDirect3DDevice9 *Display::getDevice() { return mDevice; diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h index 2876c4a92..1c46e0c6a 100644 --- a/src/libEGL/Display.h +++ b/src/libEGL/Display.h @@ -54,6 +54,9 @@ class Display bool isValidSurface(egl::Surface *surface); bool hasExistingWindowSurface(HWND window); + void setSwapInterval(GLint interval); + DWORD getPresentInterval(const egl::Config *config, bool maximumRate); + virtual IDirect3DDevice9 *getDevice(); private: @@ -66,6 +69,7 @@ class Display IDirect3DDevice9 *mDevice; bool mSceneStarted; + GLint mSwapInterval; typedef std::set SurfaceSet; SurfaceSet mSurfaceSet; diff --git a/src/libEGL/Surface.cpp b/src/libEGL/Surface.cpp index d1e7eecce..1dd88a2bb 100644 --- a/src/libEGL/Surface.cpp +++ b/src/libEGL/Surface.cpp @@ -17,8 +17,8 @@ namespace egl { -Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, EGLint configID) - : mDisplay(display), mSwapChain(swapChain), mConfigID(configID), mDepthStencil(depthStencil) +Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, const Config *config) + : mDisplay(display), mSwapChain(swapChain), mDepthStencil(depthStencil), mConfig(config) { mBackBuffer = NULL; mRenderTarget = NULL; @@ -150,7 +150,7 @@ void Surface::swap() texture->Release(); mDisplay->endScene(); - result = mSwapChain->Present(NULL, NULL, NULL, NULL, D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_DONOTWAIT); // FIXME: Get the swap interval from the associated Display + result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval(mConfig, false)); if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) { diff --git a/src/libEGL/Surface.h b/src/libEGL/Surface.h index 8953834f0..0422843f7 100644 --- a/src/libEGL/Surface.h +++ b/src/libEGL/Surface.h @@ -20,11 +20,12 @@ namespace egl { class Display; +class Config; class Surface { public: - Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9* depthStencil, EGLint configID); + Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9* depthStencil, const egl::Config *config); ~Surface(); @@ -45,7 +46,7 @@ class Surface IDirect3DSurface9 *mRenderTarget; IDirect3DSurface9 *mDepthStencil; - const EGLint mConfigID; // ID of EGLConfig surface was created with + const egl::Config *mConfig; // EGL config surface was created with EGLint mHeight; // Height of surface EGLint mWidth; // Width of surface // EGLint horizontalResolution; // Horizontal dot pitch diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp index 3c58f23a4..a98a34c6d 100644 --- a/src/libEGL/libEGL.cpp +++ b/src/libEGL/libEGL.cpp @@ -746,7 +746,7 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) return EGL_FALSE; } - // UNIMPLEMENTED(); // FIXME + display->setSwapInterval(interval); return success(EGL_TRUE); }