summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libEGL/Surface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libEGL/Surface.cpp')
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.cpp432
1 files changed, 85 insertions, 347 deletions
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
index d9e1887e85..5a62142b45 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.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.
//
@@ -14,6 +14,8 @@
#include "common/debug.h"
#include "libGLESv2/Texture.h"
+#include "libGLESv2/renderer/SwapChain.h"
+#include "libGLESv2/main.h"
#include "libEGL/main.h"
#include "libEGL/Display.h"
@@ -23,14 +25,11 @@
namespace egl
{
-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
+Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
+ mRenderer = mDisplay->getRenderer();
mSwapChain = NULL;
- mBackBuffer = NULL;
- mDepthStencil = NULL;
- mRenderTarget = NULL;
- mOffscreenTexture = NULL;
mShareHandle = NULL;
mTexture = NULL;
mTextureFormat = EGL_NO_TEXTURE;
@@ -40,6 +39,8 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
mSwapInterval = -1;
+ mWidth = -1;
+ mHeight = -1;
setSwapInterval(1);
subclassWindow();
@@ -48,11 +49,8 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos
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)
{
+ mRenderer = mDisplay->getRenderer();
mSwapChain = NULL;
- mBackBuffer = NULL;
- mDepthStencil = NULL;
- mRenderTarget = NULL;
- mOffscreenTexture = NULL;
mWindowSubclassed = false;
mTexture = NULL;
mTextureFormat = textureFormat;
@@ -76,8 +74,6 @@ bool Surface::initialize()
typedef HRESULT (STDAPICALLTYPE *PtrDwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (STDAPICALLTYPE *PtrDwmSetPresentParameters)(HWND, DWM_PRESENT_PARAMETERS *);
- ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
-
if (!resetSwapChain())
return false;
@@ -118,260 +114,106 @@ bool Surface::initialize()
void Surface::release()
{
- if (mSwapChain)
- {
- mSwapChain->Release();
- mSwapChain = NULL;
- }
-
- if (mBackBuffer)
- {
- mBackBuffer->Release();
- mBackBuffer = NULL;
- }
-
- if (mDepthStencil)
- {
- mDepthStencil->Release();
- mDepthStencil = NULL;
- }
-
- if (mRenderTarget)
- {
- mRenderTarget->Release();
- mRenderTarget = NULL;
- }
-
- if (mOffscreenTexture)
- {
- mOffscreenTexture->Release();
- mOffscreenTexture = NULL;
- }
+ delete mSwapChain;
+ mSwapChain = NULL;
if (mTexture)
{
mTexture->releaseTexImage();
mTexture = NULL;
}
-
- mShareHandle = NULL;
}
bool Surface::resetSwapChain()
{
- if (!mWindow)
- {
- return resetSwapChain(mWidth, mHeight);
- }
-
- RECT windowRect;
- if (!GetClientRect(getWindowHandle(), &windowRect))
- {
- ASSERT(false);
+ ASSERT(!mSwapChain);
- ERR("Could not retrieve the window dimensions");
- return false;
- }
-
- return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
-}
+ int width;
+ int height;
-bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
-{
- IDirect3DDevice9 *device = mDisplay->getDevice();
-
- if (device == NULL)
+ if (mWindow)
{
- return false;
- }
-
- // 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();
-
- HRESULT result;
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+ ASSERT(false);
- // Release specific resources to free up memory for the new render target, while the
- // old render target still exists for the purpose of preserving its contents.
- if (mSwapChain)
- {
- mSwapChain->Release();
- mSwapChain = NULL;
- }
+ ERR("Could not retrieve the window dimensions");
+ return error(EGL_BAD_SURFACE, false);
+ }
- if (mBackBuffer)
- {
- mBackBuffer->Release();
- mBackBuffer = NULL;
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
}
-
- if (mOffscreenTexture)
+ else
{
- mOffscreenTexture->Release();
- mOffscreenTexture = NULL;
+ // non-window surface - size is determined at creation
+ width = mWidth;
+ height = mHeight;
}
- if (mDepthStencil)
+ mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
+ mConfig->mRenderTargetFormat,
+ mConfig->mDepthStencilFormat);
+ if (!mSwapChain)
{
- mDepthStencil->Release();
- mDepthStencil = NULL;
+ return error(EGL_BAD_ALLOC, false);
}
- HANDLE *pShareHandle = NULL;
- if (!mWindow && mDisplay->shareHandleSupported())
+ if (!resetSwapChain(width, height))
{
- pShareHandle = &mShareHandle;
+ delete mSwapChain;
+ mSwapChain = NULL;
+ return false;
}
- // CreateTexture will fail on zero dimensions, so just release old target
- if (!backbufferWidth || !backbufferHeight)
- {
- if (mRenderTarget)
- {
- mRenderTarget->Release();
- mRenderTarget = NULL;
- }
+ return true;
+}
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
- mPresentIntervalDirty = false;
+bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
- return true;
- }
+ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
- result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
- mConfig->mRenderTargetFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
- if (FAILED(result))
+ if (status == EGL_CONTEXT_LOST)
{
- ERR("Could not create offscreen texture: %08lX", result);
- release();
-
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
+ mDisplay->notifyDeviceLost();
+ return false;
}
-
- IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
-
- result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
- ASSERT(SUCCEEDED(result));
-
- if (oldRenderTarget)
+ else if (status != EGL_SUCCESS)
{
- RECT rect =
- {
- 0, 0,
- mWidth, mHeight
- };
-
- if (rect.right > static_cast<LONG>(backbufferWidth))
- {
- rect.right = backbufferWidth;
- }
+ return error(status, false);
+ }
- if (rect.bottom > static_cast<LONG>(backbufferHeight))
- {
- rect.bottom = backbufferHeight;
- }
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
- mDisplay->endScene();
+ return true;
+}
- result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
- ASSERT(SUCCEEDED(result));
+bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
- oldRenderTarget->Release();
- }
+ EGLint status = mSwapChain->reset(backbufferWidth, backbufferHeight, mSwapInterval);
- if (mWindow)
+ if (status == EGL_CONTEXT_LOST)
{
- D3DPRESENT_PARAMETERS presentParameters = {0};
- presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
- presentParameters.BackBufferCount = 1;
- presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
- presentParameters.EnableAutoDepthStencil = FALSE;
- presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = getWindowHandle();
- presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
- presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
- presentParameters.PresentationInterval = mPresentInterval;
- presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
- presentParameters.Windowed = TRUE;
- presentParameters.BackBufferWidth = backbufferWidth;
- presentParameters.BackBufferHeight = backbufferHeight;
-
- // http://crbug.com/140239
- // http://crbug.com/143434
- //
- // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width
- // when using the integrated Intel. This rounds the width up rather than down.
- //
- // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID
- // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur.
- D3DADAPTER_IDENTIFIER9* adapterIdentifier = mDisplay->getAdapterIdentifier();
- if (adapterIdentifier->VendorId == VENDOR_ID_INTEL)
- {
- presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
- }
-
- result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
-
- ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
- release();
-
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
- }
-
- result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
- ASSERT(SUCCEEDED(result));
- InvalidateRect(mWindow, NULL, FALSE);
+ mRenderer->notifyDeviceLost();
+ return false;
}
-
- if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
+ else if (status != EGL_SUCCESS)
{
- result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, mConfig->mDepthStencilFormat, D3DMULTISAMPLE_NONE,
- 0, FALSE, &mDepthStencil, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
-
- ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
- release();
-
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
- }
+ return error(status, false);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
+ mSwapIntervalDirty = false;
- mPresentIntervalDirty = false;
return true;
}
@@ -397,86 +239,18 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
return true;
}
- IDirect3DDevice9 *device = mDisplay->getDevice();
-
- // 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);
-
- device->SetRenderTarget(0, mBackBuffer);
- device->SetDepthStencilSurface(NULL);
-
- device->SetTexture(0, mOffscreenTexture);
- device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
- device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
- device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
- device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
- device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
-
- D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
- device->SetViewport(&viewport);
-
- float x1 = x - 0.5f;
- float y1 = (mHeight - y - height) - 0.5f;
- float x2 = (x + width) - 0.5f;
- float y2 = (mHeight - y) - 0.5f;
-
- float u1 = x / float(mWidth);
- float v1 = y / float(mHeight);
- float u2 = (x + width) / float(mWidth);
- float v2 = (y + height) / float(mHeight);
-
- float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
- {x2, y1, 0.0f, 1.0f, u2, v2},
- {x2, y2, 0.0f, 1.0f, u2, v1},
- {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
-
- mDisplay->startScene();
- device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
- mDisplay->endScene();
-
- device->SetTexture(0, NULL);
-
- RECT rect =
- {
- x, mHeight - y - height,
- x + width, mHeight - y
- };
-
- HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
-
- gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
- if (context)
- {
- context->markAllStateDirty();
- }
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
- if (isDeviceLostError(result))
+ if (status == EGL_CONTEXT_LOST)
{
- mDisplay->notifyDeviceLost();
+ mRenderer->notifyDeviceLost();
return false;
}
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
+ else if (status != EGL_SUCCESS)
{
- return error(EGL_BAD_ALLOC, false);
+ return error(status, false);
}
- ASSERT(SUCCEEDED(result));
-
checkForOutOfDateSwapChain();
return true;
@@ -572,9 +346,17 @@ bool Surface::checkForOutOfDateSwapChain()
int clientHeight = client.bottom - client.top;
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
- if (sizeDirty || mPresentIntervalDirty)
+ if (mSwapIntervalDirty)
{
resetSwapChain(clientWidth, clientHeight);
+ }
+ else if (sizeDirty)
+ {
+ resizeSwapChain(clientWidth, clientHeight);
+ }
+
+ if (mSwapIntervalDirty || sizeDirty)
+ {
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
@@ -582,22 +364,8 @@ bool Surface::checkForOutOfDateSwapChain()
return true;
}
- return false;
-}
-
-DWORD Surface::convertInterval(EGLint 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;
+ return false;
}
bool Surface::swap()
@@ -631,38 +399,9 @@ EGLint Surface::isPostSubBufferSupported() const
return mPostSubBufferSupported;
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Surface::getRenderTarget()
-{
- if (mRenderTarget)
- {
- mRenderTarget->AddRef();
- }
-
- return mRenderTarget;
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Surface::getDepthStencil()
-{
- if (mDepthStencil)
- {
- mDepthStencil->AddRef();
- }
-
- return mDepthStencil;
-}
-
-IDirect3DTexture9 *Surface::getOffscreenTexture()
+rx::SwapChain *Surface::getSwapChain() const
{
- if (mOffscreenTexture)
- {
- mOffscreenTexture->AddRef();
- }
-
- return mOffscreenTexture;
+ return mSwapChain;
}
void Surface::setSwapInterval(EGLint interval)
@@ -673,11 +412,10 @@ void Surface::setSwapInterval(EGLint interval)
}
mSwapInterval = interval;
- mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
- mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
+ mSwapInterval = std::max(mSwapInterval, mRenderer->getMinSwapInterval());
+ mSwapInterval = std::min(mSwapInterval, mRenderer->getMaxSwapInterval());
- mPresentInterval = convertInterval(mSwapInterval);
- mPresentIntervalDirty = true;
+ mSwapIntervalDirty = true;
}
EGLenum Surface::getTextureFormat() const
@@ -700,7 +438,7 @@ gl::Texture2D *Surface::getBoundTexture() const
return mTexture;
}
-D3DFORMAT Surface::getFormat() const
+EGLenum Surface::getFormat() const
{
return mConfig->mRenderTargetFormat;
}