Remove dos-style line-endings (EOL changes only)

git-svn-id: https://angleproject.googlecode.com/svn/trunk@1218 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 9fba10e9
//
// 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
// found in the LICENSE file.
//
// debug.cpp: Debugging utilities.
#include "common/debug.h"
#include <stdio.h>
#include <stdarg.h>
#include <d3d9.h>
#include <windows.h>
namespace gl
{
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
{
#if !defined(ANGLE_DISABLE_PERF)
if (perfActive())
{
char message[32768];
int len = vsprintf_s(message, format, vararg);
if (len < 0)
{
return;
}
// There are no ASCII variants of these D3DPERF functions.
wchar_t wideMessage[32768];
for (int i = 0; i < len; ++i)
{
wideMessage[i] = message[i];
}
wideMessage[len] = 0;
perfFunc(0, wideMessage);
}
#endif
#if !defined(ANGLE_DISABLE_TRACE)
#if defined(NDEBUG)
if (traceFileDebugOnly)
{
return;
}
#endif
FILE* file = fopen(TRACE_OUTPUT_FILE, "a");
if (file)
{
vfprintf(file, format, vararg);
fclose(file);
}
#endif
}
void trace(bool traceFileDebugOnly, const char *format, ...)
{
va_list vararg;
va_start(vararg, format);
#if defined(ANGLE_DISABLE_PERF)
output(traceFileDebugOnly, NULL, format, vararg);
#else
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
#endif
va_end(vararg);
}
bool perfActive()
{
#if defined(ANGLE_DISABLE_PERF)
return false;
#else
static bool active = D3DPERF_GetStatus() != 0;
return active;
#endif
}
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
#if !defined(ANGLE_DISABLE_PERF)
va_list vararg;
va_start(vararg, format);
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
va_end(vararg);
#endif
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
#if !defined(ANGLE_DISABLE_PERF)
if (perfActive())
{
D3DPERF_EndEvent();
}
#endif
}
}
//
// 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
// found in the LICENSE file.
//
// debug.cpp: Debugging utilities.
#include "common/debug.h"
#include <stdio.h>
#include <stdarg.h>
#include <d3d9.h>
#include <windows.h>
namespace gl
{
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
{
#if !defined(ANGLE_DISABLE_PERF)
if (perfActive())
{
char message[32768];
int len = vsprintf_s(message, format, vararg);
if (len < 0)
{
return;
}
// There are no ASCII variants of these D3DPERF functions.
wchar_t wideMessage[32768];
for (int i = 0; i < len; ++i)
{
wideMessage[i] = message[i];
}
wideMessage[len] = 0;
perfFunc(0, wideMessage);
}
#endif
#if !defined(ANGLE_DISABLE_TRACE)
#if defined(NDEBUG)
if (traceFileDebugOnly)
{
return;
}
#endif
FILE* file = fopen(TRACE_OUTPUT_FILE, "a");
if (file)
{
vfprintf(file, format, vararg);
fclose(file);
}
#endif
}
void trace(bool traceFileDebugOnly, const char *format, ...)
{
va_list vararg;
va_start(vararg, format);
#if defined(ANGLE_DISABLE_PERF)
output(traceFileDebugOnly, NULL, format, vararg);
#else
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
#endif
va_end(vararg);
}
bool perfActive()
{
#if defined(ANGLE_DISABLE_PERF)
return false;
#else
static bool active = D3DPERF_GetStatus() != 0;
return active;
#endif
}
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
#if !defined(ANGLE_DISABLE_PERF)
va_list vararg;
va_start(vararg, format);
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
va_end(vararg);
#endif
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
#if !defined(ANGLE_DISABLE_PERF)
if (perfActive())
{
D3DPERF_EndEvent();
}
#endif
}
}
//
// 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
// found in the LICENSE file.
//
// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// 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.
#include <tchar.h>
#include "libEGL/Surface.h"
#include "common/debug.h"
#include "libGLESv2/Texture.h"
#include "libEGL/main.h"
#include "libEGL/Display.h"
#include <dwmapi.h>
namespace egl
{
namespace
{
const int versionWindowsVista = MAKEWORD(0x00, 0x06);
const int versionWindows7 = MAKEWORD(0x01, 0x06);
// Return the version of the operating system in a format suitable for ordering
// comparison.
int getComparableOSVersion()
{
DWORD version = GetVersion();
int majorVersion = LOBYTE(LOWORD(version));
int minorVersion = HIBYTE(LOWORD(version));
return MAKEWORD(minorVersion, majorVersion);
}
}
Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL;
mRenderTarget = NULL;
mOffscreenTexture = NULL;
mShareHandle = NULL;
mTexture = NULL;
mTextureFormat = EGL_NO_TEXTURE;
mTextureTarget = EGL_NO_TEXTURE;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
mSwapInterval = -1;
setSwapInterval(1);
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)
{
mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL;
mRenderTarget = NULL;
mOffscreenTexture = NULL;
mWindowSubclassed = false;
mTexture = NULL;
mTextureFormat = textureFormat;
mTextureTarget = textureType;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
mSwapInterval = -1;
setSwapInterval(1);
}
Surface::~Surface()
{
unsubclassWindow();
release();
}
bool Surface::initialize()
{
ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
if (!resetSwapChain())
return false;
// Modify present parameters for this window, if we are composited,
// to minimize the amount of queuing done by DWM between our calls to
// present and the actual screen.
if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) {
BOOL isComposited;
HRESULT result = DwmIsCompositionEnabled(&isComposited);
if (SUCCEEDED(result) && isComposited) {
DWM_PRESENT_PARAMETERS presentParams;
memset(&presentParams, 0, sizeof(presentParams));
presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
presentParams.cBuffer = 2;
result = DwmSetPresentParameters(mWindow, &presentParams);
if (FAILED(result))
ERR("Unable to set present parameters: 0x%08X", result);
}
}
return true;
}
void Surface::release()
{
if (mSwapChain)
{
mSwapChain->Release();
mSwapChain = NULL;
}
if (mBackBuffer)
{
mBackBuffer->Release();
mBackBuffer = NULL;
}
if (mDepthStencil)
{
mDepthStencil->Release();
mDepthStencil = NULL;
}
if (mRenderTarget)
{
mRenderTarget->Release();
mRenderTarget = NULL;
}
if (mOffscreenTexture)
{
mOffscreenTexture->Release();
mOffscreenTexture = NULL;
}
if (mTexture)
{
mTexture->releaseTexImage();
mTexture = NULL;
}
mShareHandle = NULL;
}
bool Surface::resetSwapChain()
{
if (!mWindow)
{
return resetSwapChain(mWidth, mHeight);
}
RECT windowRect;
if (!GetClientRect(getWindowHandle(), &windowRect))
{
ASSERT(false);
ERR("Could not retrieve the window dimensions");
return false;
}
return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
}
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
IDirect3DDevice9 *device = mDisplay->getDevice();
if (device == NULL)
{
return false;
}
// Evict all non-render target textures to system memory and release all resources
// before reallocating them to free up as much video memory as possible.
device->EvictManagedResources();
D3DPRESENT_PARAMETERS presentParameters = {0};
HRESULT result;
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
// We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX.
// We do this because DirectX docs are a bit vague whether to set this to 1
// or 2. The runtime seems to accept 1, so we speculate that either it is
// forcing it to 2 without telling us, or better, doing something smart
// behind the scenes knowing that we don't need more.
presentParameters.BackBufferCount = 1;
presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
presentParameters.hDeviceWindow = getWindowHandle();
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
presentParameters.PresentationInterval = mPresentInterval;
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
presentParameters.Windowed = TRUE;
presentParameters.BackBufferWidth = backbufferWidth;
presentParameters.BackBufferHeight = backbufferHeight;
// Release specific resources to free up memory for the new render target, while the
// old render target still exists for the purpose of preserving its contents.
if (mSwapChain)
{
mSwapChain->Release();
mSwapChain = NULL;
}
if (mBackBuffer)
{
mBackBuffer->Release();
mBackBuffer = NULL;
}
if (mOffscreenTexture)
{
mOffscreenTexture->Release();
mOffscreenTexture = NULL;
}
if (mDepthStencil)
{
mDepthStencil->Release();
mDepthStencil = NULL;
}
mShareHandle = NULL;
HANDLE *pShareHandle = NULL;
if (!mWindow && mDisplay->shareHandleSupported())
{
pShareHandle = &mShareHandle;
}
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
if (FAILED(result))
{
ERR("Could not create offscreen texture: %08lX", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
ASSERT(SUCCEEDED(result));
if (oldRenderTarget)
{
RECT rect =
{
0, 0,
mWidth, mHeight
};
if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth))
{
rect.right = presentParameters.BackBufferWidth;
}
if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight))
{
rect.bottom = presentParameters.BackBufferHeight;
}
mDisplay->endScene();
result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
ASSERT(SUCCEEDED(result));
oldRenderTarget->Release();
}
if (mWindow)
{
result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
ASSERT(SUCCEEDED(result));
}
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
{
result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
}
mWidth = presentParameters.BackBufferWidth;
mHeight = presentParameters.BackBufferHeight;
mPresentIntervalDirty = false;
return true;
}
bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
return true;
}
if (x + width > mWidth)
{
width = mWidth - x;
}
if (y + height > mHeight)
{
height = mHeight - y;
}
if (width == 0 || height == 0)
{
return true;
}
IDirect3DDevice9 *device = mDisplay->getDevice();
// Disable all pipeline operations
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetRenderTarget(0, mBackBuffer);
device->SetDepthStencilSurface(NULL);
device->SetTexture(0, mOffscreenTexture);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
device->SetViewport(&viewport);
float x1 = x - 0.5f;
float y1 = (mHeight - y - height) - 0.5f;
float x2 = (x + width) - 0.5f;
float y2 = (mHeight - y) - 0.5f;
float u1 = x / float(mWidth);
float v1 = y / float(mHeight);
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
{x2, y1, 0.0f, 1.0f, u2, v2},
{x2, y2, 0.0f, 1.0f, u2, v1},
{x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
mDisplay->endScene();
device->SetTexture(0, NULL);
RECT rect =
{
x, mHeight - y - height,
x + width, mHeight - y
};
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
if (context)
{
context->markAllStateDirty();
}
if (isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{
return error(EGL_BAD_ALLOC, false);
}
ASSERT(SUCCEEDED(result));
checkForOutOfDateSwapChain();
return true;
}
HWND Surface::getWindowHandle()
{
return mWindow;
}
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
{
Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
if(surf)
{
surf->checkForOutOfDateSwapChain();
}
}
WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
void Surface::subclassWindow()
{
if (!mWindow)
{
return;
}
DWORD processId;
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
{
return;
}
SetLastError(0);
LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
{
mWindowSubclassed = false;
return;
}
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
}
void Surface::unsubclassWindow()
{
if(!mWindowSubclassed)
{
return;
}
// un-subclass
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
// Check the windowproc is still SurfaceWindowProc.
// If this assert fails, then it is likely the application has subclassed the
// hwnd as well and did not unsubclass before destroying its EGL context. The
// application should be modified to either subclass before initializing the
// EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc)
{
LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
}
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
mWindowSubclassed = false;
}
bool Surface::checkForOutOfDateSwapChain()
{
RECT client;
if (!GetClientRect(getWindowHandle(), &client))
{
ASSERT(false);
return false;
}
// Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
int clientWidth = client.right - client.left;
int clientHeight = client.bottom - client.top;
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
if (sizeDirty || mPresentIntervalDirty)
{
resetSwapChain(clientWidth, clientHeight);
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
}
return true;
}
return false;
}
DWORD Surface::convertInterval(EGLint interval)
{
switch(interval)
{
case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
case 1: return D3DPRESENT_INTERVAL_ONE;
case 2: return D3DPRESENT_INTERVAL_TWO;
case 3: return D3DPRESENT_INTERVAL_THREE;
case 4: return D3DPRESENT_INTERVAL_FOUR;
default: UNREACHABLE();
}
return D3DPRESENT_INTERVAL_DEFAULT;
}
bool Surface::swap()
{
return swapRect(0, 0, mWidth, mHeight);
}
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mPostSubBufferSupported)
{
// Spec is not clear about how this should be handled.
return true;
}
return swapRect(x, y, width, height);
}
EGLint Surface::getWidth() const
{
return mWidth;
}
EGLint Surface::getHeight() const
{
return mHeight;
}
EGLint Surface::isPostSubBufferSupported() const
{
return mPostSubBufferSupported;
}
// Increments refcount on surface.
// caller must Release() the returned surface
IDirect3DSurface9 *Surface::getRenderTarget()
{
if (mRenderTarget)
{
mRenderTarget->AddRef();
}
return mRenderTarget;
}
// Increments refcount on surface.
// caller must Release() the returned surface
IDirect3DSurface9 *Surface::getDepthStencil()
{
if (mDepthStencil)
{
mDepthStencil->AddRef();
}
return mDepthStencil;
}
IDirect3DTexture9 *Surface::getOffscreenTexture()
{
if (mOffscreenTexture)
{
mOffscreenTexture->AddRef();
}
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;
}
}
//
// 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
// found in the LICENSE file.
//
// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// 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.
#include <tchar.h>
#include "libEGL/Surface.h"
#include "common/debug.h"
#include "libGLESv2/Texture.h"
#include "libEGL/main.h"
#include "libEGL/Display.h"
#include <dwmapi.h>
namespace egl
{
namespace
{
const int versionWindowsVista = MAKEWORD(0x00, 0x06);
const int versionWindows7 = MAKEWORD(0x01, 0x06);
// Return the version of the operating system in a format suitable for ordering
// comparison.
int getComparableOSVersion()
{
DWORD version = GetVersion();
int majorVersion = LOBYTE(LOWORD(version));
int minorVersion = HIBYTE(LOWORD(version));
return MAKEWORD(minorVersion, majorVersion);
}
}
Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL;
mRenderTarget = NULL;
mOffscreenTexture = NULL;
mShareHandle = NULL;
mTexture = NULL;
mTextureFormat = EGL_NO_TEXTURE;
mTextureTarget = EGL_NO_TEXTURE;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
mSwapInterval = -1;
setSwapInterval(1);
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)
{
mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL;
mRenderTarget = NULL;
mOffscreenTexture = NULL;
mWindowSubclassed = false;
mTexture = NULL;
mTextureFormat = textureFormat;
mTextureTarget = textureType;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
mSwapInterval = -1;
setSwapInterval(1);
}
Surface::~Surface()
{
unsubclassWindow();
release();
}
bool Surface::initialize()
{
ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
if (!resetSwapChain())
return false;
// Modify present parameters for this window, if we are composited,
// to minimize the amount of queuing done by DWM between our calls to
// present and the actual screen.
if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) {
BOOL isComposited;
HRESULT result = DwmIsCompositionEnabled(&isComposited);
if (SUCCEEDED(result) && isComposited) {
DWM_PRESENT_PARAMETERS presentParams;
memset(&presentParams, 0, sizeof(presentParams));
presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
presentParams.cBuffer = 2;
result = DwmSetPresentParameters(mWindow, &presentParams);
if (FAILED(result))
ERR("Unable to set present parameters: 0x%08X", result);
}
}
return true;
}
void Surface::release()
{
if (mSwapChain)
{
mSwapChain->Release();
mSwapChain = NULL;
}
if (mBackBuffer)
{
mBackBuffer->Release();
mBackBuffer = NULL;
}
if (mDepthStencil)
{
mDepthStencil->Release();
mDepthStencil = NULL;
}
if (mRenderTarget)
{
mRenderTarget->Release();
mRenderTarget = NULL;
}
if (mOffscreenTexture)
{
mOffscreenTexture->Release();
mOffscreenTexture = NULL;
}
if (mTexture)
{
mTexture->releaseTexImage();
mTexture = NULL;
}
mShareHandle = NULL;
}
bool Surface::resetSwapChain()
{
if (!mWindow)
{
return resetSwapChain(mWidth, mHeight);
}
RECT windowRect;
if (!GetClientRect(getWindowHandle(), &windowRect))
{
ASSERT(false);
ERR("Could not retrieve the window dimensions");
return false;
}
return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
}
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
IDirect3DDevice9 *device = mDisplay->getDevice();
if (device == NULL)
{
return false;
}
// Evict all non-render target textures to system memory and release all resources
// before reallocating them to free up as much video memory as possible.
device->EvictManagedResources();
D3DPRESENT_PARAMETERS presentParameters = {0};
HRESULT result;
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
// We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX.
// We do this because DirectX docs are a bit vague whether to set this to 1
// or 2. The runtime seems to accept 1, so we speculate that either it is
// forcing it to 2 without telling us, or better, doing something smart
// behind the scenes knowing that we don't need more.
presentParameters.BackBufferCount = 1;
presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
presentParameters.hDeviceWindow = getWindowHandle();
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
presentParameters.PresentationInterval = mPresentInterval;
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
presentParameters.Windowed = TRUE;
presentParameters.BackBufferWidth = backbufferWidth;
presentParameters.BackBufferHeight = backbufferHeight;
// Release specific resources to free up memory for the new render target, while the
// old render target still exists for the purpose of preserving its contents.
if (mSwapChain)
{
mSwapChain->Release();
mSwapChain = NULL;
}
if (mBackBuffer)
{
mBackBuffer->Release();
mBackBuffer = NULL;
}
if (mOffscreenTexture)
{
mOffscreenTexture->Release();
mOffscreenTexture = NULL;
}
if (mDepthStencil)
{
mDepthStencil->Release();
mDepthStencil = NULL;
}
mShareHandle = NULL;
HANDLE *pShareHandle = NULL;
if (!mWindow && mDisplay->shareHandleSupported())
{
pShareHandle = &mShareHandle;
}
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
if (FAILED(result))
{
ERR("Could not create offscreen texture: %08lX", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
ASSERT(SUCCEEDED(result));
if (oldRenderTarget)
{
RECT rect =
{
0, 0,
mWidth, mHeight
};
if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth))
{
rect.right = presentParameters.BackBufferWidth;
}
if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight))
{
rect.bottom = presentParameters.BackBufferHeight;
}
mDisplay->endScene();
result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
ASSERT(SUCCEEDED(result));
oldRenderTarget->Release();
}
if (mWindow)
{
result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
ASSERT(SUCCEEDED(result));
}
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
{
result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
}
mWidth = presentParameters.BackBufferWidth;
mHeight = presentParameters.BackBufferHeight;
mPresentIntervalDirty = false;
return true;
}
bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
return true;
}
if (x + width > mWidth)
{
width = mWidth - x;
}
if (y + height > mHeight)
{
height = mHeight - y;
}
if (width == 0 || height == 0)
{
return true;
}
IDirect3DDevice9 *device = mDisplay->getDevice();
// Disable all pipeline operations
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetRenderTarget(0, mBackBuffer);
device->SetDepthStencilSurface(NULL);
device->SetTexture(0, mOffscreenTexture);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
device->SetViewport(&viewport);
float x1 = x - 0.5f;
float y1 = (mHeight - y - height) - 0.5f;
float x2 = (x + width) - 0.5f;
float y2 = (mHeight - y) - 0.5f;
float u1 = x / float(mWidth);
float v1 = y / float(mHeight);
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
{x2, y1, 0.0f, 1.0f, u2, v2},
{x2, y2, 0.0f, 1.0f, u2, v1},
{x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
mDisplay->endScene();
device->SetTexture(0, NULL);
RECT rect =
{
x, mHeight - y - height,
x + width, mHeight - y
};
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
if (context)
{
context->markAllStateDirty();
}
if (isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{
return error(EGL_BAD_ALLOC, false);
}
ASSERT(SUCCEEDED(result));
checkForOutOfDateSwapChain();
return true;
}
HWND Surface::getWindowHandle()
{
return mWindow;
}
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
{
Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
if(surf)
{
surf->checkForOutOfDateSwapChain();
}
}
WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
void Surface::subclassWindow()
{
if (!mWindow)
{
return;
}
DWORD processId;
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
{
return;
}
SetLastError(0);
LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
{
mWindowSubclassed = false;
return;
}
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
}
void Surface::unsubclassWindow()
{
if(!mWindowSubclassed)
{
return;
}
// un-subclass
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
// Check the windowproc is still SurfaceWindowProc.
// If this assert fails, then it is likely the application has subclassed the
// hwnd as well and did not unsubclass before destroying its EGL context. The
// application should be modified to either subclass before initializing the
// EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc)
{
LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
}
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
mWindowSubclassed = false;
}
bool Surface::checkForOutOfDateSwapChain()
{
RECT client;
if (!GetClientRect(getWindowHandle(), &client))
{
ASSERT(false);
return false;
}
// Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
int clientWidth = client.right - client.left;
int clientHeight = client.bottom - client.top;
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
if (sizeDirty || mPresentIntervalDirty)
{
resetSwapChain(clientWidth, clientHeight);
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
}
return true;
}
return false;
}
DWORD Surface::convertInterval(EGLint interval)
{
switch(interval)
{
case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
case 1: return D3DPRESENT_INTERVAL_ONE;
case 2: return D3DPRESENT_INTERVAL_TWO;
case 3: return D3DPRESENT_INTERVAL_THREE;
case 4: return D3DPRESENT_INTERVAL_FOUR;
default: UNREACHABLE();
}
return D3DPRESENT_INTERVAL_DEFAULT;
}
bool Surface::swap()
{
return swapRect(0, 0, mWidth, mHeight);
}
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mPostSubBufferSupported)
{
// Spec is not clear about how this should be handled.
return true;
}
return swapRect(x, y, width, height);
}
EGLint Surface::getWidth() const
{
return mWidth;
}
EGLint Surface::getHeight() const
{
return mHeight;
}
EGLint Surface::isPostSubBufferSupported() const
{
return mPostSubBufferSupported;
}
// Increments refcount on surface.
// caller must Release() the returned surface
IDirect3DSurface9 *Surface::getRenderTarget()
{
if (mRenderTarget)
{
mRenderTarget->AddRef();
}
return mRenderTarget;
}
// Increments refcount on surface.
// caller must Release() the returned surface
IDirect3DSurface9 *Surface::getDepthStencil()
{
if (mDepthStencil)
{
mDepthStencil->AddRef();
}
return mDepthStencil;
}
IDirect3DTexture9 *Surface::getOffscreenTexture()
{
if (mOffscreenTexture)
{
mOffscreenTexture->AddRef();
}
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;
}
}
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.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Texture.h: Defines the abstract gl::Texture class and its concrete derived
// classes Texture2D and TextureCubeMap. Implements GL texture objects and
// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
#ifndef LIBGLESV2_TEXTURE_H_
#define LIBGLESV2_TEXTURE_H_
#include <vector>
#define GL_APICALL
#include <GLES2/gl2.h>
#include <d3d9.h>
#include "common/debug.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/utilities.h"
namespace egl
{
class Surface;
}
namespace gl
{
class Blit;
class Framebuffer;
enum
{
// These are the maximums the implementation can support
// The actual GL caps are limited by the device caps
// and should be queried from the Context
IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
};
class Image
{
public:
Image();
~Image();
bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease);
void markDirty() {mDirty = true;}
void markClean() {mDirty = false;}
bool isRenderableFormat() const;
D3DFORMAT getD3DFormat() const;
GLsizei getWidth() const {return mWidth;}
GLsizei getHeight() const {return mHeight;}
GLenum getFormat() const {return mFormat;}
GLenum getType() const {return mType;}
bool isDirty() const {return mSurface && mDirty;}
IDirect3DSurface9 *getSurface();
void setManagedSurface(IDirect3DSurface9 *surface);
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input);
void loadAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
const void *input);
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
private:
DISALLOW_COPY_AND_ASSIGN(Image);
void createSurface();
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
void unlock();
GLsizei mWidth;
GLsizei mHeight;
GLenum mFormat;
GLenum mType;
bool mDirty;
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
D3DFORMAT mD3DFormat;
IDirect3DSurface9 *mSurface;
};
class TextureStorage
{
public:
explicit TextureStorage(DWORD usage);
virtual ~TextureStorage();
bool isRenderTarget() const;
bool isManaged() const;
D3DPOOL getPool() const;
DWORD getUsage() const;
unsigned int getTextureSerial() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
const DWORD mD3DUsage;
const D3DPOOL mD3DPool;
const unsigned int mTextureSerial;
static unsigned int issueTextureSerial();
static unsigned int mCurrentTextureSerial;
};
class Texture : public RefCountObject
{
public:
explicit Texture(GLuint id);
virtual ~Texture();
virtual void addProxyRef(const Renderbuffer *proxy) = 0;
virtual void releaseProxy(const Renderbuffer *proxy) = 0;
virtual GLenum getTarget() const = 0;
bool setMinFilter(GLenum filter);
bool setMagFilter(GLenum filter);
bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
bool setUsage(GLenum usage);
GLenum getMinFilter() const;
GLenum getMagFilter() const;
GLenum getWrapS() const;
GLenum getWrapT() const;
GLenum getUsage() const;
virtual bool isSamplerComplete() const = 0;
IDirect3DBaseTexture9 *getTexture();
virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
bool hasDirtyParameters() const;
bool hasDirtyImages() const;
void resetDirty();
unsigned int getTextureSerial();
unsigned int getRenderTargetSerial(GLenum target);
bool isImmutable() const;
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.
protected:
void setImage(GLint unpackAlignment, const void *pixels, Image *image);
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);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
GLint creationLevels(GLsizei width, GLsizei height) const;
GLint creationLevels(GLsizei size) const;
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual void createTexture() = 0;
virtual void updateTexture() = 0;
virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
int levelCount() const;
static Blit *getBlitter();
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
GLenum mMinFilter;
GLenum mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
bool mDirtyParameters;
GLenum mUsage;
bool mDirtyImages;
bool mImmutable;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
virtual TextureStorage *getStorage(bool renderTarget) = 0;
};
class TextureStorage2D : public TextureStorage
{
public:
explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
virtual ~TextureStorage2D();
IDirect3DSurface9 *getSurfaceLevel(int level);
IDirect3DBaseTexture9 *getBaseTexture() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
IDirect3DTexture9 *mTexture;
const unsigned int mRenderTargetSerial;
};
class Texture2D : public Texture
{
public:
explicit Texture2D(GLuint id);
~Texture2D();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
virtual GLenum getTarget() const;
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
D3DFORMAT getD3DFormat(GLint level) const;
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
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);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
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 storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
virtual bool isSamplerComplete() const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
virtual Renderbuffer *getRenderbuffer(GLenum target);
protected:
friend class RenderbufferTexture2D;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
virtual TextureStorage *getStorage(bool renderTarget);
bool isMipmapComplete() const;
void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
TextureStorage2D *mTexStorage;
egl::Surface *mSurface;
// A specific internal reference count is kept for colorbuffer proxy references,
// 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 *mColorbufferProxy;
unsigned int mProxyRefs;
};
class TextureStorageCubeMap : public TextureStorage
{
public:
TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
virtual ~TextureStorageCubeMap();
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level);
IDirect3DBaseTexture9 *getBaseTexture() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
IDirect3DCubeTexture9 *mTexture;
const unsigned int mFirstRenderTargetSerial;
};
class TextureCubeMap : public Texture
{
public:
explicit TextureCubeMap(GLuint id);
~TextureCubeMap();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
virtual GLenum getTarget() const;
GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const;
GLenum getInternalFormat(GLenum target, GLint level) const;
D3DFORMAT getD3DFormat(GLenum target, GLint level) const;
bool isCompressed(GLenum target, GLint level) const;
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 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 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 setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, 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 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 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 bool isSamplerComplete() const;
virtual void generateMipmaps();
virtual Renderbuffer *getRenderbuffer(GLenum target);
static unsigned int faceIndex(GLenum face);
protected:
friend class RenderbufferTextureCubeMap;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
virtual TextureStorage *getStorage(bool renderTarget);
bool isCubeComplete() const;
bool isMipmapCubeComplete() const;
void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
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);
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
TextureStorageCubeMap *mTexStorage;
// A specific internal reference count is kept for colorbuffer proxy references,
// 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];
};
}
//
// 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
// found in the LICENSE file.
//
// Texture.h: Defines the abstract gl::Texture class and its concrete derived
// classes Texture2D and TextureCubeMap. Implements GL texture objects and
// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
#ifndef LIBGLESV2_TEXTURE_H_
#define LIBGLESV2_TEXTURE_H_
#include <vector>
#define GL_APICALL
#include <GLES2/gl2.h>
#include <d3d9.h>
#include "common/debug.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/utilities.h"
namespace egl
{
class Surface;
}
namespace gl
{
class Blit;
class Framebuffer;
enum
{
// These are the maximums the implementation can support
// The actual GL caps are limited by the device caps
// and should be queried from the Context
IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
};
class Image
{
public:
Image();
~Image();
bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease);
void markDirty() {mDirty = true;}
void markClean() {mDirty = false;}
bool isRenderableFormat() const;
D3DFORMAT getD3DFormat() const;
GLsizei getWidth() const {return mWidth;}
GLsizei getHeight() const {return mHeight;}
GLenum getFormat() const {return mFormat;}
GLenum getType() const {return mType;}
bool isDirty() const {return mSurface && mDirty;}
IDirect3DSurface9 *getSurface();
void setManagedSurface(IDirect3DSurface9 *surface);
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input);
void loadAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAData(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
const void *input);
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
private:
DISALLOW_COPY_AND_ASSIGN(Image);
void createSurface();
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
void unlock();
GLsizei mWidth;
GLsizei mHeight;
GLenum mFormat;
GLenum mType;
bool mDirty;
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
D3DFORMAT mD3DFormat;
IDirect3DSurface9 *mSurface;
};
class TextureStorage
{
public:
explicit TextureStorage(DWORD usage);
virtual ~TextureStorage();
bool isRenderTarget() const;
bool isManaged() const;
D3DPOOL getPool() const;
DWORD getUsage() const;
unsigned int getTextureSerial() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
const DWORD mD3DUsage;
const D3DPOOL mD3DPool;
const unsigned int mTextureSerial;
static unsigned int issueTextureSerial();
static unsigned int mCurrentTextureSerial;
};
class Texture : public RefCountObject
{
public:
explicit Texture(GLuint id);
virtual ~Texture();
virtual void addProxyRef(const Renderbuffer *proxy) = 0;
virtual void releaseProxy(const Renderbuffer *proxy) = 0;
virtual GLenum getTarget() const = 0;
bool setMinFilter(GLenum filter);
bool setMagFilter(GLenum filter);
bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
bool setUsage(GLenum usage);
GLenum getMinFilter() const;
GLenum getMagFilter() const;
GLenum getWrapS() const;
GLenum getWrapT() const;
GLenum getUsage() const;
virtual bool isSamplerComplete() const = 0;
IDirect3DBaseTexture9 *getTexture();
virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
bool hasDirtyParameters() const;
bool hasDirtyImages() const;
void resetDirty();
unsigned int getTextureSerial();
unsigned int getRenderTargetSerial(GLenum target);
bool isImmutable() const;
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.
protected:
void setImage(GLint unpackAlignment, const void *pixels, Image *image);
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);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
GLint creationLevels(GLsizei width, GLsizei height) const;
GLint creationLevels(GLsizei size) const;
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual void createTexture() = 0;
virtual void updateTexture() = 0;
virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
int levelCount() const;
static Blit *getBlitter();
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
GLenum mMinFilter;
GLenum mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
bool mDirtyParameters;
GLenum mUsage;
bool mDirtyImages;
bool mImmutable;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
virtual TextureStorage *getStorage(bool renderTarget) = 0;
};
class TextureStorage2D : public TextureStorage
{
public:
explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
virtual ~TextureStorage2D();
IDirect3DSurface9 *getSurfaceLevel(int level);
IDirect3DBaseTexture9 *getBaseTexture() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
IDirect3DTexture9 *mTexture;
const unsigned int mRenderTargetSerial;
};
class Texture2D : public Texture
{
public:
explicit Texture2D(GLuint id);
~Texture2D();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
virtual GLenum getTarget() const;
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
D3DFORMAT getD3DFormat(GLint level) const;
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
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);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
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 storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
virtual bool isSamplerComplete() const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
virtual Renderbuffer *getRenderbuffer(GLenum target);
protected:
friend class RenderbufferTexture2D;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
virtual TextureStorage *getStorage(bool renderTarget);
bool isMipmapComplete() const;
void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
TextureStorage2D *mTexStorage;
egl::Surface *mSurface;
// A specific internal reference count is kept for colorbuffer proxy references,
// 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 *mColorbufferProxy;
unsigned int mProxyRefs;
};
class TextureStorageCubeMap : public TextureStorage
{
public:
TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
virtual ~TextureStorageCubeMap();
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level);
IDirect3DBaseTexture9 *getBaseTexture() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
IDirect3DCubeTexture9 *mTexture;
const unsigned int mFirstRenderTargetSerial;
};
class TextureCubeMap : public Texture
{
public:
explicit TextureCubeMap(GLuint id);
~TextureCubeMap();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
virtual GLenum getTarget() const;
GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const;
GLenum getInternalFormat(GLenum target, GLint level) const;
D3DFORMAT getD3DFormat(GLenum target, GLint level) const;
bool isCompressed(GLenum target, GLint level) const;
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 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 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 setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, 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 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 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 bool isSamplerComplete() const;
virtual void generateMipmaps();
virtual Renderbuffer *getRenderbuffer(GLenum target);
static unsigned int faceIndex(GLenum face);
protected:
friend class RenderbufferTextureCubeMap;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
virtual TextureStorage *getStorage(bool renderTarget);
bool isCubeComplete() const;
bool isMipmapCubeComplete() const;
void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
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);
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
TextureStorageCubeMap *mTexStorage;
// A specific internal reference count is kept for colorbuffer proxy references,
// 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_
\ No newline at end of file
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