Commit 9616e583 by apatrick@chromium.org

Merge no-flip-rows r1142 to trunk.

Review URL: https://codereview.appspot.com/6304052 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1162 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e6357c0e
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1156 #define BUILD_REVISION 1162
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -219,25 +219,11 @@ void OutputHLSL::header() ...@@ -219,25 +219,11 @@ void OutputHLSL::header()
out << uniforms; out << uniforms;
out << "\n"; out << "\n";
// The texture fetch functions "flip" the Y coordinate in one way or another. This is because textures are stored
// according to the OpenGL convention, i.e. (0, 0) is "bottom left", rather than the D3D convention where (0, 0)
// is "top left". Since the HLSL texture fetch functions expect textures to be stored according to the D3D
// convention, the Y coordinate passed to these functions is adjusted to compensate.
//
// The simplest case is texture2D where the mapping is Y -> 1-Y, which maps [0, 1] -> [1, 0].
//
// The texture2DProj functions are more complicated because the projection divides by either Z or W. For the vec3
// case, the mapping is Y -> Z-Y or Y/Z -> 1-Y/Z, which again maps [0, 1] -> [1, 0].
//
// For cube textures the mapping is Y -> -Y, which maps [-1, 1] -> [1, -1]. This is not sufficient on its own for the
// +Y and -Y faces, which are now on the "wrong sides" of the cube. This is compensated for by exchanging the
// +Y and -Y faces everywhere else throughout the code.
if (mUsesTexture2D) if (mUsesTexture2D)
{ {
out << "float4 gl_texture2D(sampler2D s, float2 t)\n" out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
"{\n" "{\n"
" return tex2D(s, float2(t.x, 1 - t.y));\n" " return tex2D(s, t);\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -246,7 +232,7 @@ void OutputHLSL::header() ...@@ -246,7 +232,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n" out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n"
"{\n" "{\n"
" return tex2Dbias(s, float4(t.x, 1 - t.y, 0, bias));\n" " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -255,12 +241,12 @@ void OutputHLSL::header() ...@@ -255,12 +241,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
"{\n" "{\n"
" return tex2Dproj(s, float4(t.x, t.z - t.y, 0, t.z));\n" " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProj(sampler2D s, float4 t)\n" "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
"{\n" "{\n"
" return tex2Dproj(s, float4(t.x, t.w - t.y, t.z, t.w));\n" " return tex2Dproj(s, t);\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -269,12 +255,12 @@ void OutputHLSL::header() ...@@ -269,12 +255,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n" out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n"
"{\n" "{\n"
" return tex2Dbias(s, float4(t.x / t.z, 1 - (t.y / t.z), 0, bias));\n" " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n" "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n"
"{\n" "{\n"
" return tex2Dbias(s, float4(t.x / t.w, 1 - (t.y / t.w), 0, bias));\n" " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -283,7 +269,7 @@ void OutputHLSL::header() ...@@ -283,7 +269,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
"{\n" "{\n"
" return texCUBE(s, float3(t.x, -t.y, t.z));\n" " return texCUBE(s, t);\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -292,7 +278,7 @@ void OutputHLSL::header() ...@@ -292,7 +278,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n" out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n"
"{\n" "{\n"
" return texCUBEbias(s, float4(t.x, -t.y, t.z, bias));\n" " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -303,7 +289,7 @@ void OutputHLSL::header() ...@@ -303,7 +289,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n" out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x, 1 - t.y, 0, 0));\n" " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -312,7 +298,7 @@ void OutputHLSL::header() ...@@ -312,7 +298,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n" out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x, 1 - t.y, 0, 0));\n" " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -321,12 +307,12 @@ void OutputHLSL::header() ...@@ -321,12 +307,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n" out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProjLod(sampler2D s, float4 t)\n" "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -335,12 +321,12 @@ void OutputHLSL::header() ...@@ -335,12 +321,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n" out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n" "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -349,7 +335,7 @@ void OutputHLSL::header() ...@@ -349,7 +335,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n" out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n"
"{\n" "{\n"
" return texCUBElod(s, float4(t.x, -t.y, t.z, 0));\n" " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -358,7 +344,7 @@ void OutputHLSL::header() ...@@ -358,7 +344,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n" out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n"
"{\n" "{\n"
" return texCUBElod(s, float4(t.x, -t.y, t.z, 0));\n" " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -1232,7 +1218,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) ...@@ -1232,7 +1218,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
} }
else else
{ {
outputTriplet(visit, "(-ddy(", "", "))"); outputTriplet(visit, "ddy(", "", ")");
} }
break; break;
case EOpFwidth: case EOpFwidth:
......
// //
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Surface.cpp: Implements the egl::Surface class, representing a drawing surface // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// such as the client area of a window, including any back buffers. // such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3. // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
#include <tchar.h> #include <tchar.h>
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
#include "common/debug.h" #include "common/debug.h"
#include "libGLESv2/Texture.h" #include "libGLESv2/Texture.h"
#include "libEGL/main.h" #include "libEGL/main.h"
#include "libEGL/Display.h" #include "libEGL/Display.h"
#include <dwmapi.h> #include <dwmapi.h>
namespace egl namespace egl
{ {
namespace namespace
{ {
const int versionWindowsVista = MAKEWORD(0x00, 0x06); const int versionWindowsVista = MAKEWORD(0x00, 0x06);
const int versionWindows7 = MAKEWORD(0x01, 0x06); const int versionWindows7 = MAKEWORD(0x01, 0x06);
// Return the version of the operating system in a format suitable for ordering // Return the version of the operating system in a format suitable for ordering
// comparison. // comparison.
int getComparableOSVersion() int getComparableOSVersion()
{ {
DWORD version = GetVersion(); DWORD version = GetVersion();
int majorVersion = LOBYTE(LOWORD(version)); int majorVersion = LOBYTE(LOWORD(version));
int minorVersion = HIBYTE(LOWORD(version)); int minorVersion = HIBYTE(LOWORD(version));
return MAKEWORD(minorVersion, majorVersion); return MAKEWORD(minorVersion, majorVersion);
} }
} }
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) : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{ {
mSwapChain = NULL; mSwapChain = NULL;
mDepthStencil = NULL; mBackBuffer = NULL;
mRenderTarget = NULL; mDepthStencil = NULL;
mOffscreenTexture = NULL; mRenderTarget = NULL;
mShareHandle = NULL; mOffscreenTexture = NULL;
mTexture = NULL; mShareHandle = NULL;
mTextureFormat = EGL_NO_TEXTURE; mTexture = NULL;
mTextureTarget = EGL_NO_TEXTURE; 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; mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mSwapBehavior = EGL_BUFFER_PRESERVED; mRenderBuffer = EGL_BACK_BUFFER;
mSwapInterval = -1; mSwapBehavior = EGL_BUFFER_PRESERVED;
setSwapInterval(1); mSwapInterval = -1;
setSwapInterval(1);
subclassWindow();
} subclassWindow();
}
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) 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; mSwapChain = NULL;
mRenderTarget = NULL; mBackBuffer = NULL;
mOffscreenTexture = NULL; mDepthStencil = NULL;
mWindowSubclassed = false; mRenderTarget = NULL;
mTexture = NULL; mOffscreenTexture = NULL;
mTextureFormat = textureFormat; mWindowSubclassed = false;
mTextureTarget = textureType; mTexture = NULL;
mTextureFormat = textureFormat;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio mTextureTarget = textureType;
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED; mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mSwapInterval = -1; mRenderBuffer = EGL_BACK_BUFFER;
setSwapInterval(1); mSwapBehavior = EGL_BUFFER_PRESERVED;
} mSwapInterval = -1;
setSwapInterval(1);
Surface::~Surface() }
{
unsubclassWindow(); Surface::~Surface()
release(); {
} unsubclassWindow();
release();
bool Surface::initialize() }
{
ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil); bool Surface::initialize()
{
if (!resetSwapChain()) ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
return false;
if (!resetSwapChain())
// Modify present parameters for this window, if we are composited, return false;
// to minimize the amount of queuing done by DWM between our calls to
// present and the actual screen. // Modify present parameters for this window, if we are composited,
if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) { // to minimize the amount of queuing done by DWM between our calls to
BOOL isComposited; // present and the actual screen.
HRESULT result = DwmIsCompositionEnabled(&isComposited); if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) {
if (SUCCEEDED(result) && isComposited) { BOOL isComposited;
DWM_PRESENT_PARAMETERS presentParams; HRESULT result = DwmIsCompositionEnabled(&isComposited);
memset(&presentParams, 0, sizeof(presentParams)); if (SUCCEEDED(result) && isComposited) {
presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS); DWM_PRESENT_PARAMETERS presentParams;
presentParams.cBuffer = 2; memset(&presentParams, 0, sizeof(presentParams));
presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
result = DwmSetPresentParameters(mWindow, &presentParams); presentParams.cBuffer = 2;
if (FAILED(result))
ERR("Unable to set present parameters: 0x%08X", result); result = DwmSetPresentParameters(mWindow, &presentParams);
} if (FAILED(result))
} ERR("Unable to set present parameters: 0x%08X", result);
}
return true; }
}
return true;
void Surface::release() }
{
if (mSwapChain) void Surface::release()
{ {
mSwapChain->Release(); if (mSwapChain)
mSwapChain = NULL; {
} mSwapChain->Release();
mSwapChain = NULL;
if (mDepthStencil) }
{
mDepthStencil->Release(); if (mBackBuffer)
mDepthStencil = NULL; {
} mBackBuffer->Release();
mBackBuffer = NULL;
if (mRenderTarget) }
{
mRenderTarget->Release(); if (mDepthStencil)
mRenderTarget = NULL; {
} mDepthStencil->Release();
mDepthStencil = NULL;
if (mOffscreenTexture) }
{
mOffscreenTexture->Release(); if (mRenderTarget)
mOffscreenTexture = NULL; {
} mRenderTarget->Release();
mRenderTarget = NULL;
if (mTexture) }
{
mTexture->releaseTexImage(); if (mOffscreenTexture)
mTexture = NULL; {
} mOffscreenTexture->Release();
} mOffscreenTexture = NULL;
}
bool Surface::resetSwapChain()
{ if (mTexture)
if (!mWindow) {
{ mTexture->releaseTexImage();
return resetSwapChain(mWidth, mHeight); mTexture = NULL;
} }
RECT windowRect; mShareHandle = NULL;
if (!GetClientRect(getWindowHandle(), &windowRect)) }
{
ASSERT(false); bool Surface::resetSwapChain()
{
ERR("Could not retrieve the window dimensions"); if (!mWindow)
return false; {
} return resetSwapChain(mWidth, mHeight);
}
return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
} RECT windowRect;
if (!GetClientRect(getWindowHandle(), &windowRect))
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) {
{ ASSERT(false);
IDirect3DDevice9 *device = mDisplay->getDevice();
ERR("Could not retrieve the window dimensions");
if (device == NULL) return false;
{ }
return false;
} return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
}
IDirect3DSurface9* preservedRenderTarget = NULL;
if (mPostSubBufferSupported && mRenderTarget) bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{ {
preservedRenderTarget = mRenderTarget; IDirect3DDevice9 *device = mDisplay->getDevice();
preservedRenderTarget->AddRef();
} if (device == NULL)
{
// Evict all non-render target textures to system memory and release all resources return false;
// before reallocating them to free up as much video memory as possible. }
device->EvictManagedResources();
release(); // 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.
D3DPRESENT_PARAMETERS presentParameters = {0}; device->EvictManagedResources();
HRESULT result;
D3DPRESENT_PARAMETERS presentParameters = {0};
bool useFlipEx = (getComparableOSVersion() >= versionWindows7) && mDisplay->isD3d9ExDevice(); HRESULT result;
// FlipEx causes unseemly stretching when resizing windows AND when one presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
// draws outside of the WM_PAINT callback. While this is seldom a problem in // We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX.
// single process applications, it is particuarly noticeable in multiprocess // We do this because DirectX docs are a bit vague whether to set this to 1
// applications. Therefore, if the creator process of our window is not in // or 2. The runtime seems to accept 1, so we speculate that either it is
// the current process, disable use of FlipEx. // forcing it to 2 without telling us, or better, doing something smart
DWORD windowPID; // behind the scenes knowing that we don't need more.
GetWindowThreadProcessId(mWindow, &windowPID); presentParameters.BackBufferCount = 1;
if (windowPID != GetCurrentProcessId()) presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
{ presentParameters.EnableAutoDepthStencil = FALSE;
useFlipEx = false; presentParameters.Flags = 0;
} presentParameters.hDeviceWindow = getWindowHandle();
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
// Various hardware does not support D3DSWAPEFFECT_FLIPEX when either the presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
// device format or back buffer format is not 32-bit. presentParameters.PresentationInterval = mPresentInterval;
HDC deviceContext = GetDC(0); presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
int deviceFormatBits = GetDeviceCaps(deviceContext, BITSPIXEL); presentParameters.Windowed = TRUE;
ReleaseDC(0, deviceContext); presentParameters.BackBufferWidth = backbufferWidth;
if (mConfig->mBufferSize != 32 || deviceFormatBits != 32) presentParameters.BackBufferHeight = backbufferHeight;
{
useFlipEx = 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)
// D3DSWAPEFFECT_FLIPEX is always VSYNCed {
if (mSwapInterval == 0) mSwapChain->Release();
{ mSwapChain = NULL;
useFlipEx = false; }
}
if (mBackBuffer)
// D3DSWAPEFFECT_FLIPEX does not preserve the back buffer. {
if (mPostSubBufferSupported) mBackBuffer->Release();
{ mBackBuffer = NULL;
useFlipEx = false; }
}
if (mOffscreenTexture)
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; {
// We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX. mOffscreenTexture->Release();
// We do this because DirectX docs are a bit vague whether to set this to 1 mOffscreenTexture = NULL;
// 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. if (mDepthStencil)
presentParameters.BackBufferCount = 1; {
presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; mDepthStencil->Release();
presentParameters.EnableAutoDepthStencil = FALSE; mDepthStencil = NULL;
presentParameters.Flags = 0; }
presentParameters.hDeviceWindow = getWindowHandle();
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented mShareHandle = NULL;
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented HANDLE *pShareHandle = NULL;
presentParameters.PresentationInterval = mPresentInterval; if (!mWindow && mDisplay->shareHandleSupported())
// Use flipEx on Win7 or greater. {
if(useFlipEx) pShareHandle = &mShareHandle;
presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX; }
else
presentParameters.SwapEffect = mPostSubBufferSupported ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD; result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
presentParameters.Windowed = TRUE; presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
presentParameters.BackBufferWidth = backbufferWidth; if (FAILED(result))
presentParameters.BackBufferHeight = backbufferHeight; {
ERR("Could not create offscreen texture: %08lX", result);
if (mWindow) release();
{
result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); if(isDeviceLostError(result))
} else { {
HANDLE *pShareHandle = NULL; mDisplay->notifyDeviceLost();
if (mDisplay->shareHandleSupported()) { return false;
pShareHandle = &mShareHandle; }
} else
{
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, return error(EGL_BAD_ALLOC, false);
presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); }
} }
if (FAILED(result)) IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
ASSERT(SUCCEEDED(result));
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release(); if (oldRenderTarget)
{
RECT rect =
if (preservedRenderTarget) {
{ 0, 0,
preservedRenderTarget->Release(); mWidth, mHeight
preservedRenderTarget = NULL; };
}
if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth))
if(isDeviceLostError(result)) {
{ rect.right = presentParameters.BackBufferWidth;
mDisplay->notifyDeviceLost(); }
return false;
} if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight))
else {
{ rect.bottom = presentParameters.BackBufferHeight;
return error(EGL_BAD_ALLOC, false); }
}
} mDisplay->endScene();
if (mWindow) result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
{ ASSERT(SUCCEEDED(result));
mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
if (!preservedRenderTarget) oldRenderTarget->Release();
{ }
InvalidateRect(mWindow, NULL, FALSE);
} if (mWindow)
} {
else result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
{
mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); if (FAILED(result))
} {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
if (preservedRenderTarget)
{ ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
RECT rect = release();
{
0, 0, if(isDeviceLostError(result))
mWidth, mHeight {
}; mDisplay->notifyDeviceLost();
return false;
if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth)) }
{ else
rect.right = presentParameters.BackBufferWidth; {
} return error(EGL_BAD_ALLOC, false);
}
if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight)) }
{
rect.bottom = presentParameters.BackBufferHeight; result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
} ASSERT(SUCCEEDED(result));
}
mDisplay->endScene();
device->StretchRect(preservedRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
{
preservedRenderTarget->Release(); result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
preservedRenderTarget = NULL; presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
} presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) if (FAILED(result))
{ {
result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
} release();
if (FAILED(result)) if(isDeviceLostError(result))
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); mDisplay->notifyDeviceLost();
return false;
ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); }
release(); else
return error(EGL_BAD_ALLOC, false); {
} return error(EGL_BAD_ALLOC, false);
}
mWidth = presentParameters.BackBufferWidth; }
mHeight = presentParameters.BackBufferHeight; }
mPresentIntervalDirty = false; mWidth = presentParameters.BackBufferWidth;
return true; mHeight = presentParameters.BackBufferHeight;
}
mPresentIntervalDirty = false;
HWND Surface::getWindowHandle() return true;
{ }
return mWindow;
} bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner") {
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") return true;
}
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{ if (x + width > mWidth)
if (message == WM_SIZE) {
{ width = mWidth - x;
Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty)); }
if(surf)
{ if (y + height > mHeight)
surf->checkForOutOfDateSwapChain(); {
} height = mHeight - y;
} }
WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); if (width == 0 || height == 0)
} {
return true;
void Surface::subclassWindow() }
{
if (!mWindow) IDirect3DDevice9 *device = mDisplay->getDevice();
{
return; // Disable all pipeline operations
} device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
DWORD processId; device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId()) device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
{ device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
return; device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
} device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
SetLastError(0); device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); device->SetPixelShader(NULL);
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) device->SetVertexShader(NULL);
{
mWindowSubclassed = false; device->SetRenderTarget(0, mBackBuffer);
return; device->SetDepthStencilSurface(NULL);
}
device->SetTexture(0, mOffscreenTexture);
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this)); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc)); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
mWindowSubclassed = true; device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
} device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
void Surface::unsubclassWindow() device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
{ device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
if(!mWindowSubclassed) device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
{
return; D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
} device->SetViewport(&viewport);
// un-subclass float x1 = x - 0.5f;
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc)); float y1 = (mHeight - y - height) - 0.5f;
float x2 = (x + width) - 0.5f;
// Check the windowproc is still SurfaceWindowProc. float y2 = (mHeight - y) - 0.5f;
// 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 float u1 = x / float(mWidth);
// application should be modified to either subclass before initializing the float v1 = y / float(mHeight);
// EGL context, or to unsubclass before destroying the EGL context. float u2 = (x + width) / float(mWidth);
if(parentWndFunc) float v2 = (y + height) / float(mHeight);
{
LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc); float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); {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
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc); mDisplay->startScene();
mWindowSubclassed = false; device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
} mDisplay->endScene();
bool Surface::checkForOutOfDateSwapChain() device->SetTexture(0, NULL);
{
RECT client; RECT rect =
if (!GetClientRect(getWindowHandle(), &client)) {
{ x, mHeight - y - height,
ASSERT(false); x + width, mHeight - y
return false; };
}
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
// Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
int clientWidth = client.right - client.left; gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
int clientHeight = client.bottom - client.top; if (context)
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); {
context->markAllStateDirty();
if (sizeDirty || mPresentIntervalDirty) }
{
resetSwapChain(clientWidth, clientHeight); if (isDeviceLostError(result))
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this) {
{ mDisplay->notifyDeviceLost();
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this); return false;
} }
return true; if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
} {
return false; return error(EGL_BAD_ALLOC, false);
} }
DWORD Surface::convertInterval(EGLint interval) ASSERT(SUCCEEDED(result));
{
switch(interval) checkForOutOfDateSwapChain();
{
case 0: return D3DPRESENT_INTERVAL_IMMEDIATE; return true;
case 1: return D3DPRESENT_INTERVAL_ONE; }
case 2: return D3DPRESENT_INTERVAL_TWO;
case 3: return D3DPRESENT_INTERVAL_THREE; HWND Surface::getWindowHandle()
case 4: return D3DPRESENT_INTERVAL_FOUR; {
default: UNREACHABLE(); return mWindow;
} }
return D3DPRESENT_INTERVAL_DEFAULT;
} #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
bool Surface::swap()
{ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
if (mSwapChain) {
{ if (message == WM_SIZE)
mDisplay->endScene(); {
Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); if(surf)
{
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) surf->checkForOutOfDateSwapChain();
{ }
return error(EGL_BAD_ALLOC, false); }
} WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
if (isDeviceLostError(result)) }
{
mDisplay->notifyDeviceLost(); void Surface::subclassWindow()
return false; {
} if (!mWindow)
{
ASSERT(SUCCEEDED(result)); return;
}
checkForOutOfDateSwapChain();
} DWORD processId;
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
return true; if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
} {
return;
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) }
{
if (x < 0 || y < 0 || width < 0 || height < 0) SetLastError(0);
{ LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
return error(EGL_BAD_PARAMETER, false); if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
} {
mWindowSubclassed = false;
if (!mPostSubBufferSupported) return;
{ }
// Spec is not clear about how this should be handled.
return true; SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
} SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
if (mSwapChain) }
{
mDisplay->endScene(); void Surface::unsubclassWindow()
{
RECT rect = if(!mWindowSubclassed)
{ {
x, mHeight - y - height, return;
x + width, mHeight - y }
};
// un-subclass
if (rect.right > mWidth) LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
{
rect.right = mWidth; // 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
if (rect.bottom > mHeight) // application should be modified to either subclass before initializing the
{ // EGL context, or to unsubclass before destroying the EGL context.
rect.bottom = mHeight; if(parentWndFunc)
} {
LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
if (rect.left == rect.right || rect.top == rect.bottom) ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
{ }
return true;
} RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); mWindowSubclassed = false;
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{ bool Surface::checkForOutOfDateSwapChain()
return error(EGL_BAD_ALLOC, false); {
} RECT client;
if (!GetClientRect(getWindowHandle(), &client))
if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED) {
{ ASSERT(false);
return error(EGL_CONTEXT_LOST, false); return false;
} }
ASSERT(SUCCEEDED(result)); // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
int clientWidth = client.right - client.left;
checkForOutOfDateSwapChain(); int clientHeight = client.bottom - client.top;
} bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
return true; if (sizeDirty || mPresentIntervalDirty)
} {
resetSwapChain(clientWidth, clientHeight);
EGLint Surface::getWidth() const if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{ {
return mWidth; glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
} }
EGLint Surface::getHeight() const return true;
{ }
return mHeight; return false;
} }
EGLint Surface::isPostSubBufferSupported() const DWORD Surface::convertInterval(EGLint interval)
{ {
return mPostSubBufferSupported; switch(interval)
} {
case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
// Increments refcount on surface. case 1: return D3DPRESENT_INTERVAL_ONE;
// caller must Release() the returned surface case 2: return D3DPRESENT_INTERVAL_TWO;
IDirect3DSurface9 *Surface::getRenderTarget() case 3: return D3DPRESENT_INTERVAL_THREE;
{ case 4: return D3DPRESENT_INTERVAL_FOUR;
if (mRenderTarget) default: UNREACHABLE();
{ }
mRenderTarget->AddRef();
} return D3DPRESENT_INTERVAL_DEFAULT;
}
return mRenderTarget;
} bool Surface::swap()
{
// Increments refcount on surface. return swapRect(0, 0, mWidth, mHeight);
// caller must Release() the returned surface }
IDirect3DSurface9 *Surface::getDepthStencil()
{ bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
if (mDepthStencil) {
{ if (!mPostSubBufferSupported)
mDepthStencil->AddRef(); {
} // Spec is not clear about how this should be handled.
return true;
return mDepthStencil; }
}
return swapRect(x, y, width, height);
IDirect3DTexture9 *Surface::getOffscreenTexture() }
{
if (mOffscreenTexture) EGLint Surface::getWidth() const
{ {
mOffscreenTexture->AddRef(); return mWidth;
} }
return mOffscreenTexture; EGLint Surface::getHeight() const
} {
return mHeight;
void Surface::setSwapInterval(EGLint interval) }
{
if (mSwapInterval == interval) EGLint Surface::isPostSubBufferSupported() const
{ {
return; return mPostSubBufferSupported;
} }
mSwapInterval = interval; // Increments refcount on surface.
mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval()); // caller must Release() the returned surface
mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval()); IDirect3DSurface9 *Surface::getRenderTarget()
{
mPresentInterval = convertInterval(mSwapInterval); if (mRenderTarget)
mPresentIntervalDirty = true; {
} mRenderTarget->AddRef();
}
EGLenum Surface::getTextureFormat() const
{ return mRenderTarget;
return mTextureFormat; }
}
// Increments refcount on surface.
EGLenum Surface::getTextureTarget() const // caller must Release() the returned surface
{ IDirect3DSurface9 *Surface::getDepthStencil()
return mTextureTarget; {
} if (mDepthStencil)
{
void Surface::setBoundTexture(gl::Texture2D *texture) mDepthStencil->AddRef();
{ }
mTexture = texture;
} return mDepthStencil;
}
gl::Texture2D *Surface::getBoundTexture() const
{ IDirect3DTexture9 *Surface::getOffscreenTexture()
return mTexture; {
} if (mOffscreenTexture)
{
D3DFORMAT Surface::getFormat() const mOffscreenTexture->AddRef();
{ }
return mConfig->mRenderTargetFormat;
} return mOffscreenTexture;
} }
void Surface::setSwapInterval(EGLint interval)
{
if (mSwapInterval == interval)
{
return;
}
mSwapInterval = interval;
mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
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;
}
}
...@@ -69,6 +69,7 @@ private: ...@@ -69,6 +69,7 @@ private:
Display *const mDisplay; Display *const mDisplay;
IDirect3DSwapChain9 *mSwapChain; IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
IDirect3DSurface9 *mDepthStencil; IDirect3DSurface9 *mDepthStencil;
IDirect3DSurface9* mRenderTarget; IDirect3DSurface9* mRenderTarget;
IDirect3DTexture9* mOffscreenTexture; IDirect3DTexture9* mOffscreenTexture;
...@@ -78,6 +79,7 @@ private: ...@@ -78,6 +79,7 @@ private:
void subclassWindow(); void subclassWindow();
void unsubclassWindow(); void unsubclassWindow();
bool resetSwapChain(int backbufferWidth, int backbufferHeight); bool resetSwapChain(int backbufferWidth, int backbufferHeight);
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
static DWORD convertInterval(EGLint interval); static DWORD convertInterval(EGLint interval);
const HWND mWindow; // Window that the surface is created for. const HWND mWindow; // Window that the surface is created for.
......
...@@ -1108,6 +1108,11 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi ...@@ -1108,6 +1108,11 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
try try
{ {
if (x < 0 || y < 0 || width < 0 || height < 0)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -281,7 +281,7 @@ class Context ...@@ -281,7 +281,7 @@ class Context
void makeCurrent(egl::Display *display, egl::Surface *surface); void makeCurrent(egl::Display *display, egl::Surface *surface);
void markAllStateDirty(); virtual void markAllStateDirty();
void markDxUniformsDirty(); void markDxUniformsDirty();
virtual void markContextLost(); virtual void markContextLost();
......
...@@ -1391,7 +1391,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1391,7 +1391,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
"\n" "\n"
" VS_OUTPUT output;\n" " VS_OUTPUT output;\n"
" output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n" " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n"
" output.gl_Position.y = gl_Position.y - dx_HalfPixelSize.y * gl_Position.w;\n" " output.gl_Position.y = -(gl_Position.y + dx_HalfPixelSize.y * gl_Position.w);\n"
" output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.gl_Position.w = gl_Position.w;\n"; " output.gl_Position.w = gl_Position.w;\n";
...@@ -1524,15 +1524,14 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1524,15 +1524,14 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
if (sm3) if (sm3)
{ {
// dx_Coord.y contains the render target height. See Context::applyRenderTarget()
pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
" gl_FragCoord.y = dx_Coord.y - input.dx_VPos.y - 0.5;\n"; " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
} }
else else
{ {
// dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget() // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget()
pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n" pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n"
" gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n"; " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n";
} }
pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n" pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
...@@ -1541,7 +1540,8 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1541,7 +1540,8 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
if (fragmentShader->mUsesPointCoord && sm3) if (fragmentShader->mUsesPointCoord && sm3)
{ {
pixelHLSL += " gl_PointCoord = input.gl_PointCoord;\n"; pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n";
pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
} }
if (fragmentShader->mUsesFrontFacing) if (fragmentShader->mUsesFrontFacing)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
// //
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Texture.h: Defines the abstract gl::Texture class and its concrete derived // Texture.h: Defines the abstract gl::Texture class and its concrete derived
// classes Texture2D and TextureCubeMap. Implements GL texture objects and // classes Texture2D and TextureCubeMap. Implements GL texture objects and
// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63. // related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
#ifndef LIBGLESV2_TEXTURE_H_ #ifndef LIBGLESV2_TEXTURE_H_
#define LIBGLESV2_TEXTURE_H_ #define LIBGLESV2_TEXTURE_H_
#include <vector> #include <vector>
#define GL_APICALL #define GL_APICALL
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <d3d9.h> #include <d3d9.h>
#include "common/debug.h" #include "common/debug.h"
#include "common/RefCountObject.h" #include "common/RefCountObject.h"
#include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/utilities.h" #include "libGLESv2/utilities.h"
namespace egl namespace egl
{ {
class Surface; class Surface;
} }
namespace gl namespace gl
{ {
class Blit; class Blit;
class Framebuffer; class Framebuffer;
enum enum
{ {
// These are the maximums the implementation can support // These are the maximums the implementation can support
// The actual GL caps are limited by the device caps // The actual GL caps are limited by the device caps
// and should be queried from the Context // and should be queried from the Context
IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384, IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
}; };
class Image class Image
{ {
public: public:
Image(); Image();
~Image(); ~Image();
bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease); bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease);
void markDirty() {mDirty = true;} void markDirty() {mDirty = true;}
void markClean() {mDirty = false;} void markClean() {mDirty = false;}
bool isRenderableFormat() const; bool isRenderableFormat() const;
D3DFORMAT getD3DFormat() const; D3DFORMAT getD3DFormat() const;
GLsizei getWidth() const {return mWidth;} GLsizei getWidth() const {return mWidth;}
GLsizei getHeight() const {return mHeight;} GLsizei getHeight() const {return mHeight;}
GLenum getFormat() const {return mFormat;} GLenum getFormat() const {return mFormat;}
GLenum getType() const {return mType;} GLenum getType() const {return mType;}
bool isDirty() const {return mSurface && mDirty;} bool isDirty() const {return mSurface && mDirty;}
IDirect3DSurface9 *getSurface(); IDirect3DSurface9 *getSurface();
void setManagedSurface(IDirect3DSurface9 *surface); void setManagedSurface(IDirect3DSurface9 *surface);
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input); GLint unpackAlignment, const void *input);
void loadAlphaData(GLsizei width, GLsizei height, void loadAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaDataSSE2(GLsizei width, GLsizei height, void loadAlphaDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatData(GLsizei width, GLsizei height, void loadAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatData(GLsizei width, GLsizei height, void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceData(GLsizei width, GLsizei height, void loadLuminanceData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatData(GLsizei width, GLsizei height, void loadLuminanceFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatData(GLsizei width, GLsizei height, void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaData(GLsizei width, GLsizei height, void loadLuminanceAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height, void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height, void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteData(GLsizei width, GLsizei height, void loadRGBUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565Data(GLsizei width, GLsizei height, void loadRGB565Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatData(GLsizei width, GLsizei height, void loadRGBFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatData(GLsizei width, GLsizei height, void loadRGBHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height, void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteData(GLsizei width, GLsizei height, void loadRGBAUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444Data(GLsizei width, GLsizei height, void loadRGBA4444Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551Data(GLsizei width, GLsizei height, void loadRGBA5551Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatData(GLsizei width, GLsizei height, void loadRGBAFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatData(GLsizei width, GLsizei height, void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAData(GLsizei width, GLsizei height, void loadBGRAData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
const void *input); const void *input);
void loadDXT1Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
void loadDXT3Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const; private:
void loadDXT5Data(GLsizei width, GLsizei height, DISALLOW_COPY_AND_ASSIGN(Image);
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void createSurface();
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
private: void unlock();
DISALLOW_COPY_AND_ASSIGN(Image);
GLsizei mWidth;
void createSurface(); GLsizei mHeight;
GLenum mFormat;
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); GLenum mType;
void unlock();
bool mDirty;
GLsizei mWidth;
GLsizei mHeight; D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
GLenum mFormat; D3DFORMAT mD3DFormat;
GLenum mType;
IDirect3DSurface9 *mSurface;
bool mDirty; };
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. class TextureStorage
D3DFORMAT mD3DFormat; {
public:
IDirect3DSurface9 *mSurface; explicit TextureStorage(DWORD usage);
};
virtual ~TextureStorage();
class TextureStorage
{ bool isRenderTarget() const;
public: bool isManaged() const;
explicit TextureStorage(DWORD usage); D3DPOOL getPool() const;
DWORD getUsage() const;
virtual ~TextureStorage(); unsigned int getTextureSerial() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
bool isRenderTarget() const;
bool isManaged() const; private:
D3DPOOL getPool() const; DISALLOW_COPY_AND_ASSIGN(TextureStorage);
DWORD getUsage() const;
unsigned int getTextureSerial() const; const DWORD mD3DUsage;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0; const D3DPOOL mD3DPool;
private: const unsigned int mTextureSerial;
DISALLOW_COPY_AND_ASSIGN(TextureStorage); static unsigned int issueTextureSerial();
const DWORD mD3DUsage; static unsigned int mCurrentTextureSerial;
const D3DPOOL mD3DPool; };
const unsigned int mTextureSerial; class Texture : public RefCountObject
static unsigned int issueTextureSerial(); {
public:
static unsigned int mCurrentTextureSerial; explicit Texture(GLuint id);
};
virtual ~Texture();
class Texture : public RefCountObject
{ virtual void addProxyRef(const Renderbuffer *proxy) = 0;
public: virtual void releaseProxy(const Renderbuffer *proxy) = 0;
explicit Texture(GLuint id);
virtual GLenum getTarget() const = 0;
virtual ~Texture();
bool setMinFilter(GLenum filter);
virtual void addProxyRef(const Renderbuffer *proxy) = 0; bool setMagFilter(GLenum filter);
virtual void releaseProxy(const Renderbuffer *proxy) = 0; bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
virtual GLenum getTarget() const = 0; bool setUsage(GLenum usage);
bool setMinFilter(GLenum filter); GLenum getMinFilter() const;
bool setMagFilter(GLenum filter); GLenum getMagFilter() const;
bool setWrapS(GLenum wrap); GLenum getWrapS() const;
bool setWrapT(GLenum wrap); GLenum getWrapT() const;
bool setUsage(GLenum usage); GLenum getUsage() const;
GLenum getMinFilter() const; virtual bool isSamplerComplete() const = 0;
GLenum getMagFilter() const;
GLenum getWrapS() const; IDirect3DBaseTexture9 *getTexture();
GLenum getWrapT() const; virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
GLenum getUsage() const;
virtual void generateMipmaps() = 0;
virtual bool isSamplerComplete() const = 0; virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
IDirect3DBaseTexture9 *getTexture(); bool hasDirtyParameters() const;
virtual Renderbuffer *getRenderbuffer(GLenum target) = 0; bool hasDirtyImages() const;
void resetDirty();
virtual void generateMipmaps() = 0; unsigned int getTextureSerial();
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; unsigned int getRenderTargetSerial(GLenum target);
bool hasDirtyParameters() const; bool isImmutable() const;
bool hasDirtyImages() const;
void resetDirty(); static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
unsigned int getTextureSerial();
unsigned int getRenderTargetSerial(GLenum target); protected:
void setImage(GLint unpackAlignment, const void *pixels, Image *image);
bool isImmutable() const; bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
protected: GLint creationLevels(GLsizei width, GLsizei height) const;
void setImage(GLint unpackAlignment, const void *pixels, Image *image); GLint creationLevels(GLsizei size) const;
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image); virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image); virtual void createTexture() = 0;
virtual void updateTexture() = 0;
GLint creationLevels(GLsizei width, GLsizei height) const; virtual void convertToRenderTarget() = 0;
GLint creationLevels(GLsizei size) const; virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; int levelCount() const;
virtual void createTexture() = 0;
virtual void updateTexture() = 0; static Blit *getBlitter();
virtual void convertToRenderTarget() = 0; static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
GLenum mMinFilter;
int levelCount() const; GLenum mMagFilter;
GLenum mWrapS;
static Blit *getBlitter(); GLenum mWrapT;
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); bool mDirtyParameters;
GLenum mUsage;
GLenum mMinFilter;
GLenum mMagFilter; bool mDirtyImages;
GLenum mWrapS;
GLenum mWrapT; bool mImmutable;
bool mDirtyParameters;
GLenum mUsage; private:
DISALLOW_COPY_AND_ASSIGN(Texture);
bool mDirtyImages;
virtual TextureStorage *getStorage(bool renderTarget) = 0;
bool mImmutable; };
private: class TextureStorage2D : public TextureStorage
DISALLOW_COPY_AND_ASSIGN(Texture); {
public:
virtual TextureStorage *getStorage(bool renderTarget) = 0; explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
}; TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
class TextureStorage2D : public TextureStorage virtual ~TextureStorage2D();
{
public: IDirect3DSurface9 *getSurfaceLevel(int level);
explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture); IDirect3DBaseTexture9 *getBaseTexture() const;
TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
virtual unsigned int getRenderTargetSerial(GLenum target) const;
virtual ~TextureStorage2D();
private:
IDirect3DSurface9 *getSurfaceLevel(int level); DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
IDirect3DBaseTexture9 *getBaseTexture() const;
IDirect3DTexture9 *mTexture;
virtual unsigned int getRenderTargetSerial(GLenum target) const; const unsigned int mRenderTargetSerial;
};
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage2D); class Texture2D : public Texture
{
IDirect3DTexture9 *mTexture; public:
const unsigned int mRenderTargetSerial; explicit Texture2D(GLuint id);
};
~Texture2D();
class Texture2D : public Texture
{ void addProxyRef(const Renderbuffer *proxy);
public: void releaseProxy(const Renderbuffer *proxy);
explicit Texture2D(GLuint id);
virtual GLenum getTarget() const;
~Texture2D();
GLsizei getWidth(GLint level) const;
void addProxyRef(const Renderbuffer *proxy); GLsizei getHeight(GLint level) const;
void releaseProxy(const Renderbuffer *proxy); GLenum getInternalFormat(GLint level) const;
D3DFORMAT getD3DFormat(GLint level) const;
virtual GLenum getTarget() const; bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
GLenum getInternalFormat(GLint level) const; void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
D3DFORMAT getD3DFormat(GLint level) const; void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
bool isCompressed(GLint level) const; void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
bool isDepth(GLint level) const; void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); virtual bool isSamplerComplete() const;
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); virtual void bindTexImage(egl::Surface *surface);
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); virtual void releaseTexImage();
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); virtual void generateMipmaps();
virtual bool isSamplerComplete() const; virtual Renderbuffer *getRenderbuffer(GLenum target);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage(); protected:
friend class RenderbufferTexture2D;
virtual void generateMipmaps(); virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
virtual Renderbuffer *getRenderbuffer(GLenum target);
private:
protected: DISALLOW_COPY_AND_ASSIGN(Texture2D);
friend class RenderbufferTexture2D;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual IDirect3DSurface9 *getDepthStencil(GLenum target); virtual void createTexture();
virtual void updateTexture();
private: virtual void convertToRenderTarget();
DISALLOW_COPY_AND_ASSIGN(Texture2D); virtual TextureStorage *getStorage(bool renderTarget);
virtual IDirect3DBaseTexture9 *getBaseTexture() const; bool isMipmapComplete() const;
virtual void createTexture();
virtual void updateTexture(); void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
virtual void convertToRenderTarget(); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
virtual TextureStorage *getStorage(bool renderTarget);
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
bool isMipmapComplete() const;
TextureStorage2D *mTexStorage;
void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); egl::Surface *mSurface;
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
// A specific internal reference count is kept for colorbuffer proxy references,
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; // because, as the renderbuffer acting as proxy will maintain a binding pointer
// back to this texture, there would be a circular reference if we used a binding
TextureStorage2D *mTexStorage; // pointer here. This reference count will cause the pointer to be set to NULL if
egl::Surface *mSurface; // the count drops to zero, but will not cause deletion of the Renderbuffer.
Renderbuffer *mColorbufferProxy;
// A specific internal reference count is kept for colorbuffer proxy references, unsigned int mProxyRefs;
// because, as the renderbuffer acting as proxy will maintain a binding pointer };
// back to this texture, there would be a circular reference if we used a binding
// pointer here. This reference count will cause the pointer to be set to NULL if class TextureStorageCubeMap : public TextureStorage
// the count drops to zero, but will not cause deletion of the Renderbuffer. {
Renderbuffer *mColorbufferProxy; public:
unsigned int mProxyRefs; TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
};
virtual ~TextureStorageCubeMap();
class TextureStorageCubeMap : public TextureStorage
{ IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level);
public: IDirect3DBaseTexture9 *getBaseTexture() const;
TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
virtual unsigned int getRenderTargetSerial(GLenum target) const;
virtual ~TextureStorageCubeMap();
private:
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level); DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
IDirect3DBaseTexture9 *getBaseTexture() const;
IDirect3DCubeTexture9 *mTexture;
virtual unsigned int getRenderTargetSerial(GLenum target) const; const unsigned int mFirstRenderTargetSerial;
};
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap); class TextureCubeMap : public Texture
{
IDirect3DCubeTexture9 *mTexture; public:
const unsigned int mFirstRenderTargetSerial; explicit TextureCubeMap(GLuint id);
};
~TextureCubeMap();
class TextureCubeMap : public Texture
{ void addProxyRef(const Renderbuffer *proxy);
public: void releaseProxy(const Renderbuffer *proxy);
explicit TextureCubeMap(GLuint id);
virtual GLenum getTarget() const;
~TextureCubeMap();
GLsizei getWidth(GLenum target, GLint level) const;
void addProxyRef(const Renderbuffer *proxy); GLsizei getHeight(GLenum target, GLint level) const;
void releaseProxy(const Renderbuffer *proxy); GLenum getInternalFormat(GLenum target, GLint level) const;
D3DFORMAT getD3DFormat(GLenum target, GLint level) const;
virtual GLenum getTarget() const; bool isCompressed(GLenum target, GLint level) const;
GLsizei getWidth(GLenum target, GLint level) const; void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
GLsizei getHeight(GLenum target, GLint level) const; void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
GLenum getInternalFormat(GLenum target, GLint level) const; void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
D3DFORMAT getD3DFormat(GLenum target, GLint level) const; void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
bool isCompressed(GLenum target, GLint level) const; void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void storage(GLsizei levels, GLenum internalformat, GLsizei size);
void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); virtual bool isSamplerComplete() const;
void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); virtual void generateMipmaps();
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei size); virtual Renderbuffer *getRenderbuffer(GLenum target);
virtual bool isSamplerComplete() const; static unsigned int faceIndex(GLenum face);
virtual void generateMipmaps(); protected:
friend class RenderbufferTextureCubeMap;
virtual Renderbuffer *getRenderbuffer(GLenum target); virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
static unsigned int faceIndex(GLenum face); private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
protected:
friend class RenderbufferTextureCubeMap; virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual void createTexture();
virtual void updateTexture();
private: virtual void convertToRenderTarget();
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); virtual TextureStorage *getStorage(bool renderTarget);
virtual IDirect3DBaseTexture9 *getBaseTexture() const; bool isCubeComplete() const;
virtual void createTexture(); bool isMipmapCubeComplete() const;
virtual void updateTexture();
virtual void convertToRenderTarget(); void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
virtual TextureStorage *getStorage(bool renderTarget); void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void redefineImage(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
bool isCubeComplete() const;
bool isMipmapCubeComplete() const; Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); TextureStorageCubeMap *mTexStorage;
void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void redefineImage(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); // A specific internal reference count is kept for colorbuffer proxy references,
// because, as the renderbuffer acting as proxy will maintain a binding pointer
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; // back to this texture, there would be a circular reference if we used a binding
// pointer here. This reference count will cause the pointer to be set to NULL if
TextureStorageCubeMap *mTexStorage; // the count drops to zero, but will not cause deletion of the Renderbuffer.
Renderbuffer *mFaceProxies[6];
// A specific internal reference count is kept for colorbuffer proxy references, unsigned int *mFaceProxyRefs[6];
// because, as the renderbuffer acting as proxy will maintain a binding pointer };
// back to this texture, there would be a circular reference if we used a binding }
// pointer here. This reference count will cause the pointer to be set to NULL if
// the count drops to zero, but will not cause deletion of the Renderbuffer.
Renderbuffer *mFaceProxies[6];
unsigned int *mFaceProxyRefs[6];
};
}
#endif // LIBGLESV2_TEXTURE_H_ #endif // LIBGLESV2_TEXTURE_H_
\ No newline at end of file
...@@ -70,26 +70,6 @@ inline unsigned int unorm(float x) ...@@ -70,26 +70,6 @@ inline unsigned int unorm(float x)
} }
} }
inline RECT transformPixelRect(GLint x, GLint y, GLint w, GLint h, GLint surfaceHeight)
{
RECT rect = {x,
surfaceHeight - y - h,
x + w,
surfaceHeight - y};
return rect;
}
inline int transformPixelYOffset(GLint yoffset, GLint h, GLint surfaceHeight)
{
return surfaceHeight - yoffset - h;
}
inline GLenum adjustWinding(GLenum winding)
{
ASSERT(winding == GL_CW || winding == GL_CCW);
return winding == GL_CW ? GL_CCW : GL_CW;
}
inline bool supportsSSE2() inline bool supportsSSE2()
{ {
static bool checked = false; static bool checked = false;
......
...@@ -612,9 +612,6 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) ...@@ -612,9 +612,6 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
{ {
D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
// Map a cube map texture target to the corresponding D3D surface index. Note that the
// Y faces are swapped because the Y coordinate to the texture lookup intrinsic functions
// are negated in the pixel shader.
switch (cubeFace) switch (cubeFace)
{ {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
...@@ -624,10 +621,10 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) ...@@ -624,10 +621,10 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
face = D3DCUBEMAP_FACE_NEGATIVE_X; face = D3DCUBEMAP_FACE_NEGATIVE_X;
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
face = D3DCUBEMAP_FACE_NEGATIVE_Y; face = D3DCUBEMAP_FACE_POSITIVE_Y;
break; break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
face = D3DCUBEMAP_FACE_POSITIVE_Y; face = D3DCUBEMAP_FACE_NEGATIVE_Y;
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
face = D3DCUBEMAP_FACE_POSITIVE_Z; face = D3DCUBEMAP_FACE_POSITIVE_Z;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment