1a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// 2a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Use of this source code is governed by a BSD-style license that can be 4a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// found in the LICENSE file. 5a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// 6a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 7a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Surface.cpp: Implements the egl::Surface class, representing a drawing surface 8a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// such as the client area of a window, including any back buffers. 9a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3. 10a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 11ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include <tchar.h> 12ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 13a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "libEGL/Surface.h" 14a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 15a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "common/debug.h" 16a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 17a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "libEGL/main.h" 18a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "libEGL/Display.h" 19a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 20a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blocknamespace egl 21a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickSurface::Surface(Display *display, const Config *config, HWND window) 235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick : mDisplay(display), mConfig(config), mWindow(window) 24a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mSwapChain = NULL; 265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mDepthStencil = NULL; 27a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mBackBuffer = NULL; 28a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mFlipTexture = NULL; 29a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mFlipState = NULL; 30a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipState = NULL; 31a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 32a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio 33a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mRenderBuffer = EGL_BACK_BUFFER; 34a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSwapBehavior = EGL_BUFFER_PRESERVED; 35ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mSwapInterval = -1; 36ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch setSwapInterval(1); 37a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 38ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch subclassWindow(); 395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick resetSwapChain(); 40a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 41a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 42a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockSurface::~Surface() 43a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 44ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch unsubclassWindow(); 45ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch release(); 46ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 47ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 48ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Surface::release() 49ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 50a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSwapChain) 51a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 52a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSwapChain->Release(); 53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mSwapChain = NULL; 54a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 55a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 56a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mBackBuffer) 57a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 58a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mBackBuffer->Release(); 59ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mBackBuffer = NULL; 60a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 61a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 62a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mDepthStencil) 63a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 64a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDepthStencil->Release(); 65ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mDepthStencil = NULL; 66a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 67a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 68a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mFlipTexture) 69a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 70a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mFlipTexture->Release(); 71ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mFlipTexture = NULL; 72a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 73a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 74a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mFlipState) 75a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 76a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mFlipState->Release(); 77ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mFlipState = NULL; 78a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 79a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 80a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mPreFlipState) 81a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 82a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipState->Release(); 83ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mPreFlipState = NULL; 84a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 85a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 86a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid Surface::resetSwapChain() 88a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 89ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch RECT windowRect; 90ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!GetClientRect(getWindowHandle(), &windowRect)) 91ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 92ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(false); 93ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 94ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ERR("Could not retrieve the window dimensions"); 95ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 96ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 97ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 98ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); 99ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 100ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 101ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) 102ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 1035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick IDirect3DDevice9 *device = mDisplay->getDevice(); 1045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 105ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (device == NULL) 106ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 107ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 108ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 109ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 110ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Evict all non-render target textures to system memory and release all resources 111ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // before reallocating them to free up as much video memory as possible. 112ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->EvictManagedResources(); 113ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch release(); 114ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 1155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick D3DPRESENT_PARAMETERS presentParameters = {0}; 1165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; 1185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.BackBufferCount = 1; 1195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; 1205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.EnableAutoDepthStencil = FALSE; 1215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.Flags = 0; 1225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.hDeviceWindow = getWindowHandle(); 1235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented 1245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented 125ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch presentParameters.PresentationInterval = mPresentInterval; 1265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; 1275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.Windowed = TRUE; 128ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch presentParameters.BackBufferWidth = backbufferWidth; 129ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch presentParameters.BackBufferHeight = backbufferHeight; 1305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 131ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); 1325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (FAILED(result)) 1345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick { 1355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ERR("Could not create additional swap chains: %08lX", result); 138ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch release(); 1395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return error(EGL_BAD_ALLOC); 1405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, 144ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); 1455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (FAILED(result)) 1475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick { 1485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ERR("Could not create depthstencil surface for new swap chain: %08lX", result); 151ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch release(); 1525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return error(EGL_BAD_ALLOC); 1535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(SUCCEEDED(result)); 1565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, 158ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mFlipTexture, NULL); 1595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1605abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (FAILED(result)) 161a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 1625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ERR("Could not create flip texture for new swap chain: %08lX", result); 165ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch release(); 1665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return error(EGL_BAD_ALLOC); 167a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 168a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 169ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); 1705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mWidth = presentParameters.BackBufferWidth; 1715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mHeight = presentParameters.BackBufferHeight; 1725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 173ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mPresentIntervalDirty = false; 174ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 175ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch InvalidateRect(mWindow, NULL, FALSE); 1765abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // The flip state block recorded mFlipTexture so it is now invalid. 1785abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick releaseRecordedState(device); 1795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickHWND Surface::getWindowHandle() 1825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 1835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return mWindow; 184a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 185a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 1865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid Surface::writeRecordableFlipState(IDirect3DDevice9 *device) 187a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 188a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Disable all pipeline operations 189a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); 190a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 191a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 192a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 193a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 194a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_STENCILENABLE, FALSE); 195a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); 196a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); 197a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); 198ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 199a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetPixelShader(NULL); 200a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetVertexShader(NULL); 201a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 202a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Just sample the texture 203a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); 204a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 205a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); 206ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture. 207a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 208a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); 209a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); 2105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); 2115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); 212a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); 213a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 214ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle 215ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->SetScissorRect(&scissorRect); 216ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; 217ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->SetViewport(&viewport); 218a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 219a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 2205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid Surface::applyFlipState(IDirect3DDevice9 *device) 221a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 222a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT hr; 223a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 224a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mFlipState == NULL) 225a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 226a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Create two state blocks both recording the states that are changed when swapping. 227a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 228a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // mPreFlipState will record the original state each entry. 229a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->BeginStateBlock(); 230a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr)); 2315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick writeRecordableFlipState(device); 232a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->EndStateBlock(&mPreFlipState); 233a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 234a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 235a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (SUCCEEDED(hr)) 236a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 237a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipState->Capture(); 238a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 239a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 240a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // mFlipState will record the state for the swap operation. 241a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->BeginStateBlock(); 242a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr)); 243a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 2445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick writeRecordableFlipState(device); 245a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 246a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->EndStateBlock(&mFlipState); 247a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 248a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 249a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(hr)) 250a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 251a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mFlipState = NULL; 252a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipState->Release(); 253a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipState = NULL; 254a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 255a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 256a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 257a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = mFlipState->Apply(); 258a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr)); 259a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 260a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 261a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 262a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 263a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = mPreFlipState->Capture(); 264a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr)); 265a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = mFlipState->Apply(); 266a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr)); 267a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 268a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 269a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->GetRenderTarget(0, &mPreFlipBackBuffer); 270a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->GetDepthStencilSurface(&mPreFlipDepthStencil); 271a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 272a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderTarget(0, mBackBuffer); 273a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetDepthStencilSurface(NULL); 274a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 275a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 276a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Surface::restoreState(IDirect3DDevice9 *device) 277a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 278a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderTarget(0, mPreFlipBackBuffer); 279a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetDepthStencilSurface(mPreFlipDepthStencil); 280a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 281a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mPreFlipBackBuffer) 282a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 283a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipBackBuffer->Release(); 284a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipBackBuffer = NULL; 285a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 286a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 287a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mPreFlipDepthStencil) 288a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 289a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipDepthStencil->Release(); 290a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mPreFlipDepthStencil = NULL; 291a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 292ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 293ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mPreFlipState->Apply(); 294a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 295a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 2965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// On the next flip, this will cause the state to be recorded from scratch. 2975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// In particular we need to do this if the flip texture changes. 2985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid Surface::releaseRecordedState(IDirect3DDevice9 *device) 2995abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 3005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (mFlipState) 3015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick { 3025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mFlipState->Release(); 3035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mFlipState = NULL; 3045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 3055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 3065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (mPreFlipState) 3075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick { 3085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mPreFlipState->Release(); 3095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick mPreFlipState = NULL; 3105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 3115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 312ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#define kSurfaceProperty _TEXT("Egl::SurfaceOwner") 313ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") 314ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 315ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstatic LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { 316ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (message == WM_SIZE) { 317ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty)); 318ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if(surf) { 319ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch surf->checkForOutOfDateSwapChain(); 320ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 321ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 322ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc)); 323ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); 324ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 3255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 326ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Surface::subclassWindow() 327ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 328ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch SetLastError(0); 329ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc)); 330ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) { 331ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mWindowSubclassed = false; 332ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 333ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 334ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 335ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this)); 336ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc)); 337ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mWindowSubclassed = true; 338ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 339ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 340ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Surface::unsubclassWindow() 341ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 342ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if(!mWindowSubclassed) 343ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 344ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 345ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // un-subclass 346ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc)); 347ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 348ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Check the windowproc is still SurfaceWindowProc. 349ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // If this assert fails, then it is likely the application has subclassed the 350ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // hwnd as well and did not unsubclass before destroying its EGL context. The 351ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // application should be modified to either subclass before initializing the 352ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // EGL context, or to unsubclass before destroying the EGL context. 353ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if(parentWndFunc) { 354ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc); 355ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc)); 356ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 357ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 358ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch RemoveProp(mWindow, kSurfaceProperty); 359ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch RemoveProp(mWindow, kParentWndProc); 360ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mWindowSubclassed = false; 361ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 362ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 363ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochbool Surface::checkForOutOfDateSwapChain() 3645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 3655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick RECT client; 3665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!GetClientRect(getWindowHandle(), &client)) 3675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick { 3685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(false); 3695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 3705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 3715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 372ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information. 373ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch int clientWidth = client.right - client.left; 374ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch int clientHeight = client.bottom - client.top; 375ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); 3765abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 377ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (sizeDirty || mPresentIntervalDirty) 378ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 379ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch resetSwapChain(clientWidth, clientHeight); 3805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this) 3815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick { 3825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this); 3835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 3845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 3855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return true; 3865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 3875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 3885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 3895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 390ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochDWORD Surface::convertInterval(EGLint interval) 391a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 392ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch switch(interval) 393a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 394ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case 0: return D3DPRESENT_INTERVAL_IMMEDIATE; 395ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case 1: return D3DPRESENT_INTERVAL_ONE; 396ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case 2: return D3DPRESENT_INTERVAL_TWO; 397ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case 3: return D3DPRESENT_INTERVAL_THREE; 398ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case 4: return D3DPRESENT_INTERVAL_FOUR; 399ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch default: UNREACHABLE(); 400ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 4015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 402ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return D3DPRESENT_INTERVAL_DEFAULT; 403ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 4045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 4055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 406ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochbool Surface::swap() 407ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 408ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mSwapChain) 409ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 410a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = mDisplay->getDevice(); 411a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 4125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick applyFlipState(device); 413ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->SetTexture(0, mFlipTexture); 414a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 415a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Render the texture upside down into the back buffer 416ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Texcoords are chosen to flip the renderTarget about its Y axis. 417ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch float w = static_cast<float>(getWidth()); 418ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch float h = static_cast<float>(getHeight()); 419ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch float quad[4][6] = {{0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f}, 420ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch {w - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f}, 421ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch {w - 0.5f, h - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f}, 422ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch {0 - 0.5f, h - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}}; // x, y, z, rhw, u, v 423a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 424a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDisplay->startScene(); 425a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); 426a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 427a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block restoreState(device); 428a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 429a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDisplay->endScene(); 430ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 431ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); 432a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 433a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) 434a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 435a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(EGL_BAD_ALLOC, false); 436a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 437a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 438a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (result == D3DERR_DEVICELOST) 439a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 440a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(EGL_CONTEXT_LOST, false); 441a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 442a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 443a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(result)); 4445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 445ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch checkForOutOfDateSwapChain(); 446a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 447a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 448a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 449a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 450a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 451a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockEGLint Surface::getWidth() const 452a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 453a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return mWidth; 454a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 455a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 456a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockEGLint Surface::getHeight() const 457a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 458a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return mHeight; 459a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 460a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 461a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockIDirect3DSurface9 *Surface::getRenderTarget() 462a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 463ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch IDirect3DSurface9 *textureSurface = NULL; 464ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 465ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mFlipTexture) 466a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 467ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mFlipTexture->GetSurfaceLevel(0, &textureSurface); 468a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 469a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 470ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return textureSurface; 471a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 472a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 473a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockIDirect3DSurface9 *Surface::getDepthStencil() 474a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 475a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mDepthStencil) 476a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 477a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDepthStencil->AddRef(); 478a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 479a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 480a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return mDepthStencil; 481a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 482ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 483ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Surface::setSwapInterval(EGLint interval) 484ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 485ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mSwapInterval == interval) 486ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 487ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 488ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 489ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 490ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mSwapInterval = interval; 491ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval()); 492ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval()); 493ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 494ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mPresentInterval = convertInterval(mSwapInterval); 495ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mPresentIntervalDirty = true; 496ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 497a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 498