Commit ae345807 by jbauman@chromium.org

Add support for eglBindTexImage and eglReleaseTexImage

With this patch we can bind pbuffers as textures. Once we add support for using a sharing handle to create a pbuffer we can use this to allow us to use it as a texture as well. BUG=129 TEST=modified Simple_Texture2D works Review URL: http://codereview.appspot.com/4291066/ git-svn-id: https://angleproject.googlecode.com/svn/trunk@604 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent b627699f
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 598 #define BUILD_REVISION 604
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -64,6 +64,8 @@ void Config::setDefaults() ...@@ -64,6 +64,8 @@ void Config::setDefaults()
void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
{ {
mBindToTextureRGB = EGL_FALSE;
mBindToTextureRGBA = EGL_FALSE;
switch (renderTargetFormat) switch (renderTargetFormat)
{ {
case D3DFMT_A1R5G5B5: case D3DFMT_A1R5G5B5:
...@@ -86,6 +88,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter ...@@ -86,6 +88,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mGreenSize = 8; mGreenSize = 8;
mBlueSize = 8; mBlueSize = 8;
mAlphaSize = 8; mAlphaSize = 8;
mBindToTextureRGBA = true;
break; break;
case D3DFMT_R5G6B5: case D3DFMT_R5G6B5:
mBufferSize = 16; mBufferSize = 16;
...@@ -100,6 +103,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter ...@@ -100,6 +103,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mGreenSize = 8; mGreenSize = 8;
mBlueSize = 8; mBlueSize = 8;
mAlphaSize = 0; mAlphaSize = 0;
mBindToTextureRGB = true;
break; break;
default: default:
UNREACHABLE(); // Other formats should not be valid UNREACHABLE(); // Other formats should not be valid
...@@ -107,8 +111,6 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter ...@@ -107,8 +111,6 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mLuminanceSize = 0; mLuminanceSize = 0;
mAlphaMaskSize = 0; mAlphaMaskSize = 0;
mBindToTextureRGB = EGL_FALSE;
mBindToTextureRGBA = EGL_FALSE;
mColorBufferType = EGL_RGB_BUFFER; mColorBufferType = EGL_RGB_BUFFER;
mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG; mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG;
mConfigID = 0; mConfigID = 0;
......
...@@ -412,11 +412,11 @@ Surface *Display::createWindowSurface(HWND window, EGLConfig config) ...@@ -412,11 +412,11 @@ Surface *Display::createWindowSurface(HWND window, EGLConfig config)
return surface; return surface;
} }
Surface *Display::createOffscreenSurface(int width, int height, EGLConfig config) Surface *Display::createOffscreenSurface(int width, int height, EGLConfig config, EGLenum textureFormat, EGLenum textureTarget)
{ {
const Config *configuration = mConfigSet.get(config); const Config *configuration = mConfigSet.get(config);
Surface *surface = new Surface(this, configuration, width, height); Surface *surface = new Surface(this, configuration, width, height, textureFormat, textureTarget);
mSurfaceSet.insert(surface); mSurfaceSet.insert(surface);
return surface; return surface;
...@@ -637,6 +637,11 @@ bool Display::getLuminanceAlphaTextureSupport() ...@@ -637,6 +637,11 @@ bool Display::getLuminanceAlphaTextureSupport()
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8)); return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
} }
bool Display::getNonPow2TextureSupport()
{
return !(mDeviceCaps.TextureCaps & (D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
}
D3DPOOL Display::getBufferPool(DWORD usage) const D3DPOOL Display::getBufferPool(DWORD usage) const
{ {
if (mD3d9Ex != NULL) if (mD3d9Ex != NULL)
......
...@@ -43,7 +43,7 @@ class Display ...@@ -43,7 +43,7 @@ class Display
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
egl::Surface *createWindowSurface(HWND window, EGLConfig config); egl::Surface *createWindowSurface(HWND window, EGLConfig config);
egl::Surface *createOffscreenSurface(int width, int height, EGLConfig config); egl::Surface *createOffscreenSurface(int width, int height, EGLConfig config, EGLenum textureFormat, EGLenum textureTarget);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext); EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
void destroySurface(egl::Surface *surface); void destroySurface(egl::Surface *surface);
...@@ -68,6 +68,7 @@ class Display ...@@ -68,6 +68,7 @@ class Display
virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable); virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
virtual bool getLuminanceTextureSupport(); virtual bool getLuminanceTextureSupport();
virtual bool getLuminanceAlphaTextureSupport(); virtual bool getLuminanceAlphaTextureSupport();
virtual bool getNonPow2TextureSupport();
virtual D3DPOOL getBufferPool(DWORD usage) const; virtual D3DPOOL getBufferPool(DWORD usage) const;
bool isD3d9ExDevice() { return mD3d9Ex != NULL; } bool isD3d9ExDevice() { return mD3d9Ex != NULL; }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
#include "common/debug.h" #include "common/debug.h"
#include "libGLESv2/Texture.h"
#include "libEGL/main.h" #include "libEGL/main.h"
#include "libEGL/Display.h" #include "libEGL/Display.h"
...@@ -27,6 +28,9 @@ Surface::Surface(Display *display, const Config *config, HWND window) ...@@ -27,6 +28,9 @@ Surface::Surface(Display *display, const Config *config, HWND window)
mRenderTarget = NULL; mRenderTarget = NULL;
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
mShareHandle = 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 mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER; mRenderBuffer = EGL_BACK_BUFFER;
...@@ -38,7 +42,7 @@ Surface::Surface(Display *display, const Config *config, HWND window) ...@@ -38,7 +42,7 @@ Surface::Surface(Display *display, const Config *config, HWND window)
resetSwapChain(); resetSwapChain();
} }
Surface::Surface(Display *display, const Config *config, EGLint width, EGLint height) Surface::Surface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
: mDisplay(display), mWindow(NULL), mConfig(config), mWidth(width), mHeight(height) : mDisplay(display), mWindow(NULL), mConfig(config), mWidth(width), mHeight(height)
{ {
mSwapChain = NULL; mSwapChain = NULL;
...@@ -47,6 +51,9 @@ Surface::Surface(Display *display, const Config *config, EGLint width, EGLint he ...@@ -47,6 +51,9 @@ Surface::Surface(Display *display, const Config *config, EGLint width, EGLint he
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
mShareHandle = NULL; mShareHandle = NULL;
mWindowSubclassed = false; mWindowSubclassed = false;
mTexture = NULL;
mTextureFormat = textureFormat;
mTextureTarget = textureType;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER; mRenderBuffer = EGL_BACK_BUFFER;
...@@ -88,6 +95,12 @@ void Surface::release() ...@@ -88,6 +95,12 @@ void Surface::release()
mOffscreenTexture->Release(); mOffscreenTexture->Release();
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
} }
if (mTexture)
{
mTexture->releaseTexImage();
mTexture = NULL;
}
} }
void Surface::resetSwapChain() void Surface::resetSwapChain()
...@@ -347,6 +360,16 @@ IDirect3DSurface9 *Surface::getDepthStencil() ...@@ -347,6 +360,16 @@ IDirect3DSurface9 *Surface::getDepthStencil()
return mDepthStencil; return mDepthStencil;
} }
IDirect3DTexture9 *Surface::getOffscreenTexture()
{
if (mOffscreenTexture)
{
mOffscreenTexture->AddRef();
}
return mOffscreenTexture;
}
void Surface::setSwapInterval(EGLint interval) void Surface::setSwapInterval(EGLint interval)
{ {
if (mSwapInterval == interval) if (mSwapInterval == interval)
...@@ -361,4 +384,29 @@ void Surface::setSwapInterval(EGLint interval) ...@@ -361,4 +384,29 @@ void Surface::setSwapInterval(EGLint interval)
mPresentInterval = convertInterval(mSwapInterval); mPresentInterval = convertInterval(mSwapInterval);
mPresentIntervalDirty = true; 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;
}
} }
...@@ -17,6 +17,11 @@ ...@@ -17,6 +17,11 @@
#include "common/angleutils.h" #include "common/angleutils.h"
namespace gl
{
class Texture2D;
}
namespace egl namespace egl
{ {
class Display; class Display;
...@@ -26,7 +31,7 @@ class Surface ...@@ -26,7 +31,7 @@ class Surface
{ {
public: public:
Surface(Display *display, const egl::Config *config, HWND window); Surface(Display *display, const egl::Config *config, HWND window);
Surface(Display *display, const egl::Config *config, EGLint width, EGLint height); Surface(Display *display, const egl::Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
~Surface(); ~Surface();
...@@ -41,12 +46,20 @@ class Surface ...@@ -41,12 +46,20 @@ class Surface
virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil(); virtual IDirect3DSurface9 *getDepthStencil();
virtual IDirect3DTexture9 *getOffscreenTexture();
HANDLE getShareHandle() { return mShareHandle; } HANDLE getShareHandle() { return mShareHandle; }
void setSwapInterval(EGLint interval); void setSwapInterval(EGLint interval);
bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update
virtual EGLenum getTextureFormat() const;
virtual EGLenum getTextureTarget() const;
virtual D3DFORMAT getFormat() const;
virtual void setBoundTexture(gl::Texture2D *texture);
virtual gl::Texture2D *getBoundTexture() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(Surface); DISALLOW_COPY_AND_ASSIGN(Surface);
...@@ -77,13 +90,14 @@ private: ...@@ -77,13 +90,14 @@ private:
EGLint mPixelAspectRatio; // Display aspect ratio EGLint mPixelAspectRatio; // Display aspect ratio
EGLenum mRenderBuffer; // Render buffer EGLenum mRenderBuffer; // Render buffer
EGLenum mSwapBehavior; // Buffer swap behavior EGLenum mSwapBehavior; // Buffer swap behavior
// EGLenum textureFormat; // Format of texture: RGB, RGBA, or no texture EGLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture
// EGLenum textureTarget; // Type of texture: 2D or no texture EGLenum mTextureTarget; // Type of texture: 2D or no texture
// EGLenum vgAlphaFormat; // Alpha format for OpenVG // EGLenum vgAlphaFormat; // Alpha format for OpenVG
// EGLenum vgColorSpace; // Color space for OpenVG // EGLenum vgColorSpace; // Color space for OpenVG
EGLint mSwapInterval; EGLint mSwapInterval;
DWORD mPresentInterval; DWORD mPresentInterval;
bool mPresentIntervalDirty; bool mPresentIntervalDirty;
gl::Texture2D *mTexture;
}; };
} }
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "common/debug.h" #include "common/debug.h"
#include "common/version.h" #include "common/version.h"
#include "libGLESv2/Context.h" #include "libGLESv2/Context.h"
#include "libGLESv2/mathutil.h"
#include "libGLESv2/Texture.h"
#include "libEGL/main.h" #include "libEGL/main.h"
#include "libEGL/Display.h" #include "libEGL/Display.h"
...@@ -392,6 +394,8 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c ...@@ -392,6 +394,8 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
{ {
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
EGLint width = 0, height = 0; EGLint width = 0, height = 0;
EGLenum textureFormat = EGL_NO_TEXTURE;
EGLenum textureTarget = EGL_NO_TEXTURE;
if (!validate(display, config)) if (!validate(display, config))
{ {
...@@ -415,10 +419,23 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c ...@@ -415,10 +419,23 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
UNIMPLEMENTED(); // FIXME UNIMPLEMENTED(); // FIXME
break; break;
case EGL_TEXTURE_FORMAT: case EGL_TEXTURE_FORMAT:
switch (attrib_list[1])
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
textureFormat = attrib_list[1];
break;
default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
break;
case EGL_TEXTURE_TARGET: case EGL_TEXTURE_TARGET:
switch (attrib_list[1]) switch (attrib_list[1])
{ {
case EGL_NO_TEXTURE: case EGL_NO_TEXTURE:
case EGL_TEXTURE_2D:
textureTarget = attrib_list[1];
break; break;
default: default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
...@@ -440,10 +457,47 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c ...@@ -440,10 +457,47 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
} }
} }
if (width < 0 || height < 0)
{
return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
}
if (width == 0 || height == 0) if (width == 0 || height == 0)
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); {
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
EGLSurface surface = (EGLSurface)display->createOffscreenSurface(width, height, config); if (textureFormat != EGL_NO_TEXTURE && !display->getNonPow2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
}
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
{
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
}
EGLint surfaceTypeValue;
EGLint bindToTextureRGBValue;
EGLint bindToTextureRGBAValue;
display->getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceTypeValue);
display->getConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, &bindToTextureRGBValue);
display->getConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBAValue);
if (!(surfaceTypeValue & EGL_PBUFFER_BIT))
{
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
}
if ((textureFormat == EGL_TEXTURE_RGB && bindToTextureRGBValue != EGL_TRUE) ||
(textureFormat == EGL_TEXTURE_RGBA && bindToTextureRGBAValue != EGL_TRUE))
{
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
EGLSurface surface = (EGLSurface)display->createOffscreenSurface(width, height, config, textureFormat, textureTarget);
return success(surface); return success(surface);
} }
...@@ -779,15 +833,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint ...@@ -779,15 +833,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
try try
{ {
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *surf = static_cast<egl::Surface*>(surface);
if (!validate(display)) if (!validate(display))
{ {
return EGL_FALSE; return EGL_FALSE;
} }
// FIXME - need implementation if (buffer != EGL_BACK_BUFFER)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE || surf->getWindowHandle())
{
return error(EGL_BAD_SURFACE, EGL_FALSE);
}
return success(EGL_FALSE); if (surf->getBoundTexture())
{
return error(EGL_BAD_ACCESS, EGL_FALSE);
}
if (surf->getTextureFormat() == EGL_NO_TEXTURE)
{
return error(EGL_BAD_MATCH, EGL_FALSE);
}
glBindTexImage(surf);
return success(EGL_TRUE);
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
{ {
...@@ -804,15 +879,36 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi ...@@ -804,15 +879,36 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
try try
{ {
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *surf = static_cast<egl::Surface*>(surface);
if (!validate(display)) if (!validate(display))
{ {
return EGL_FALSE; return EGL_FALSE;
} }
// FIXME - need implementation if (buffer != EGL_BACK_BUFFER)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE || surf->getWindowHandle())
{
return error(EGL_BAD_SURFACE, EGL_FALSE);
}
if (surf->getTextureFormat() == EGL_NO_TEXTURE)
{
return error(EGL_BAD_MATCH, EGL_FALSE);
}
return success(EGL_FALSE); gl::Texture2D *texture = surf->getBoundTexture();
if (texture)
{
texture->releaseTexImage();
}
return success(EGL_TRUE);
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
{ {
......
...@@ -539,6 +539,7 @@ void glDestroyContext(gl::Context *context); ...@@ -539,6 +539,7 @@ void glDestroyContext(gl::Context *context);
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface); void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
gl::Context *glGetCurrentContext(); gl::Context *glGetCurrentContext();
__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname); __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
void __stdcall glBindTexImage(egl::Surface *surface);
} }
#endif // INCLUDE_CONTEXT_H_ #endif // INCLUDE_CONTEXT_H_
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include "common/debug.h" #include "common/debug.h"
#include "libEGL/Display.h"
#include "libGLESv2/main.h" #include "libGLESv2/main.h"
#include "libGLESv2/mathutil.h" #include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h" #include "libGLESv2/utilities.h"
...@@ -1209,6 +1211,7 @@ unsigned int Texture::issueSerial() ...@@ -1209,6 +1211,7 @@ unsigned int Texture::issueSerial()
Texture2D::Texture2D(GLuint id) : Texture(id) Texture2D::Texture2D(GLuint id) : Texture(id)
{ {
mTexture = NULL; mTexture = NULL;
mSurface = NULL;
} }
Texture2D::~Texture2D() Texture2D::~Texture2D()
...@@ -1220,6 +1223,12 @@ Texture2D::~Texture2D() ...@@ -1220,6 +1223,12 @@ Texture2D::~Texture2D()
mTexture->Release(); mTexture->Release();
mTexture = NULL; mTexture = NULL;
} }
if (mSurface)
{
mSurface->setBoundTexture(NULL);
mSurface = NULL;
}
} }
GLenum Texture2D::getTarget() const GLenum Texture2D::getTarget() const
...@@ -1252,7 +1261,7 @@ D3DFORMAT Texture2D::getD3DFormat() const ...@@ -1252,7 +1261,7 @@ D3DFORMAT Texture2D::getD3DFormat() const
return mImageArray[0].getD3DFormat(); return mImageArray[0].getD3DFormat();
} }
void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type) void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRedefine)
{ {
GLsizei textureWidth = mImageArray[0].width; GLsizei textureWidth = mImageArray[0].width;
GLsizei textureHeight = mImageArray[0].height; GLsizei textureHeight = mImageArray[0].height;
...@@ -1273,7 +1282,7 @@ void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsiz ...@@ -1273,7 +1282,7 @@ void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsiz
bool heightOkay = (textureHeight >> level == height) || (textureHeight >> level == 0 && height == 1); bool heightOkay = (textureHeight >> level == height) || (textureHeight >> level == 0 && height == 1);
bool textureOkay = (widthOkay && heightOkay && textureFormat == format && textureType == type); bool textureOkay = (widthOkay && heightOkay && textureFormat == format && textureType == type);
if (!textureOkay) // Purge all the levels and the texture. if (!textureOkay || forceRedefine || mSurface) // Purge all the levels and the texture.
{ {
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{ {
...@@ -1292,19 +1301,58 @@ void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsiz ...@@ -1292,19 +1301,58 @@ void Texture2D::redefineTexture(GLint level, GLenum format, GLsizei width, GLsiz
mDirtyImage = true; mDirtyImage = true;
mIsRenderable = false; mIsRenderable = false;
} }
if (mSurface)
{
mSurface->setBoundTexture(NULL);
mSurface = NULL;
}
} }
} }
void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{ {
redefineTexture(level, format, width, height, type); redefineTexture(level, format, width, height, type, false);
Texture::setImage(unpackAlignment, pixels, &mImageArray[level]); Texture::setImage(unpackAlignment, pixels, &mImageArray[level]);
} }
void Texture2D::bindTexImage(egl::Surface *surface)
{
GLenum format;
switch(surface->getFormat())
{
case D3DFMT_A8R8G8B8:
format = GL_RGBA;
break;
case D3DFMT_X8R8G8B8:
format = GL_RGB;
break;
default:
UNIMPLEMENTED();
return;
}
redefineTexture(0, format, surface->getWidth(), surface->getHeight(), GL_UNSIGNED_BYTE, true);
IDirect3DTexture9 *texture = surface->getOffscreenTexture();
mTexture = texture;
mDirtyImage = true;
mIsRenderable = true;
mSurface = surface;
mSurface->setBoundTexture(this);
}
void Texture2D::releaseTexImage()
{
redefineTexture(0, GL_RGB, 0, 0, GL_UNSIGNED_BYTE, true);
}
void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{ {
redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE); redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE, false);
Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]); Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]);
} }
...@@ -1366,7 +1414,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1366,7 +1414,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE); redefineTexture(level, format, width, height, GL_UNSIGNED_BYTE, false);
if (!mImageArray[level].isRenderable()) if (!mImageArray[level].isRenderable())
{ {
...@@ -1413,7 +1461,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1413,7 +1461,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
redefineTexture(level, mImageArray[level].format, mImageArray[level].width, mImageArray[level].height, GL_UNSIGNED_BYTE); redefineTexture(level, mImageArray[level].format, mImageArray[level].width, mImageArray[level].height, GL_UNSIGNED_BYTE, false);
if (!mImageArray[level].isRenderable() || (!mTexture && !isComplete())) if (!mImageArray[level].isRenderable() || (!mTexture && !isComplete()))
{ {
......
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
#include "libGLESv2/utilities.h" #include "libGLESv2/utilities.h"
#include "common/debug.h" #include "common/debug.h"
namespace egl
{
class Surface;
}
namespace gl namespace gl
{ {
class Blit; class Blit;
...@@ -210,6 +215,8 @@ class Texture2D : public Texture ...@@ -210,6 +215,8 @@ class Texture2D : public Texture
virtual bool isComplete() const; virtual bool isComplete() const;
virtual bool isCompressed() const; virtual bool isCompressed() const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps(); virtual void generateMipmaps();
...@@ -224,12 +231,13 @@ class Texture2D : public Texture ...@@ -224,12 +231,13 @@ class Texture2D : public Texture
virtual void convertToRenderTarget(); virtual void convertToRenderTarget();
virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
void redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); void redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type, bool force);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
IDirect3DTexture9 *mTexture; IDirect3DTexture9 *mTexture;
egl::Surface *mSurface;
BindingPointer<Renderbuffer> mColorbufferProxy; BindingPointer<Renderbuffer> mColorbufferProxy;
}; };
......
...@@ -5701,4 +5701,29 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * ...@@ -5701,4 +5701,29 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
return NULL; return NULL;
} }
void __stdcall glBindTexImage(egl::Surface *surface)
{
EVENT("(egl::Surface* surface = 0x%0.8p)",
surface);
try
{
gl::Context *context = gl::getContext();
if (context)
{
gl::Texture2D *textureObject = context->getTexture2D();
if (textureObject)
{
textureObject->bindTexImage(surface);
}
}
}
catch(std::bad_alloc&)
{
return error(GL_OUT_OF_MEMORY);
}
}
} }
...@@ -160,4 +160,5 @@ EXPORTS ...@@ -160,4 +160,5 @@ EXPORTS
glDestroyContext @145 NONAME glDestroyContext @145 NONAME
glMakeCurrent @146 NONAME glMakeCurrent @146 NONAME
glGetCurrentContext @147 NONAME glGetCurrentContext @147 NONAME
glGetProcAddress @148 NONAME glGetProcAddress @148 NONAME
\ No newline at end of file glBindTexImage @158 NONAME
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