Mostly eliminates usage of getD3DFormat in Texture.

TRAC #21906 Signed-off-by: Daniel Koch Author: Shannon Woods git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1367 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 5ac99789
...@@ -3547,11 +3547,8 @@ bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type) ...@@ -3547,11 +3547,8 @@ bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
return error(GL_INVALID_OPERATION, false); return error(GL_INVALID_OPERATION, false);
} }
if(!dx2es::ConvertReadBufferFormat(renderbuffer->getD3DFormat(), format, type)) *format = gl::ExtractFormat(renderbuffer->getActualFormat());
{ *type = gl::ExtractType(renderbuffer->getActualFormat());
ASSERT(false);
return false;
}
return true; return true;
} }
...@@ -4071,7 +4068,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -4071,7 +4068,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
if (!validReadType || !validDrawType || if (!validReadType || !validDrawType ||
readFramebuffer->getColorbuffer()->getD3DFormat() != drawFramebuffer->getColorbuffer()->getD3DFormat()) readFramebuffer->getColorbuffer()->getActualFormat() != drawFramebuffer->getColorbuffer()->getActualFormat())
{ {
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation"); ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
...@@ -4099,7 +4096,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -4099,7 +4096,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{ {
if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() || if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
readFramebuffer->getDepthbuffer()->getD3DFormat() != drawFramebuffer->getDepthbuffer()->getD3DFormat()) readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4115,7 +4112,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -4115,7 +4112,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{ {
if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() || if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
readFramebuffer->getStencilbuffer()->getD3DFormat() != drawFramebuffer->getStencilbuffer()->getD3DFormat()) readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
......
...@@ -35,32 +35,32 @@ void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy) ...@@ -35,32 +35,32 @@ void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
GLuint RenderbufferInterface::getRedSize() const GLuint RenderbufferInterface::getRedSize() const
{ {
return dx2es::GetRedSize(getD3DFormat()); return gl::GetRedSize(getActualFormat());
} }
GLuint RenderbufferInterface::getGreenSize() const GLuint RenderbufferInterface::getGreenSize() const
{ {
return dx2es::GetGreenSize(getD3DFormat()); return gl::GetGreenSize(getActualFormat());
} }
GLuint RenderbufferInterface::getBlueSize() const GLuint RenderbufferInterface::getBlueSize() const
{ {
return dx2es::GetBlueSize(getD3DFormat()); return gl::GetBlueSize(getActualFormat());
} }
GLuint RenderbufferInterface::getAlphaSize() const GLuint RenderbufferInterface::getAlphaSize() const
{ {
return dx2es::GetAlphaSize(getD3DFormat()); return gl::GetAlphaSize(getActualFormat());
} }
GLuint RenderbufferInterface::getDepthSize() const GLuint RenderbufferInterface::getDepthSize() const
{ {
return dx2es::GetDepthSize(getD3DFormat()); return gl::GetDepthSize(getActualFormat());
} }
GLuint RenderbufferInterface::getStencilSize() const GLuint RenderbufferInterface::getStencilSize() const
{ {
return dx2es::GetStencilSize(getD3DFormat()); return gl::GetStencilSize(getActualFormat());
} }
///// RenderbufferTexture2D Implementation //////// ///// RenderbufferTexture2D Implementation ////////
...@@ -116,9 +116,9 @@ GLenum RenderbufferTexture2D::getInternalFormat() const ...@@ -116,9 +116,9 @@ GLenum RenderbufferTexture2D::getInternalFormat() const
return mTexture2D->getInternalFormat(0); return mTexture2D->getInternalFormat(0);
} }
D3DFORMAT RenderbufferTexture2D::getD3DFormat() const GLenum RenderbufferTexture2D::getActualFormat() const
{ {
return mTexture2D->getD3DFormat(0); return mTexture2D->getActualFormat(0);
} }
GLsizei RenderbufferTexture2D::getSamples() const GLsizei RenderbufferTexture2D::getSamples() const
...@@ -184,9 +184,9 @@ GLenum RenderbufferTextureCubeMap::getInternalFormat() const ...@@ -184,9 +184,9 @@ GLenum RenderbufferTextureCubeMap::getInternalFormat() const
return mTextureCubeMap->getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); return mTextureCubeMap->getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
} }
D3DFORMAT RenderbufferTextureCubeMap::getD3DFormat() const GLenum RenderbufferTextureCubeMap::getActualFormat() const
{ {
return mTextureCubeMap->getD3DFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); return mTextureCubeMap->getActualFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
} }
GLsizei RenderbufferTextureCubeMap::getSamples() const GLsizei RenderbufferTextureCubeMap::getSamples() const
...@@ -257,9 +257,9 @@ GLenum Renderbuffer::getInternalFormat() const ...@@ -257,9 +257,9 @@ GLenum Renderbuffer::getInternalFormat() const
return mInstance->getInternalFormat(); return mInstance->getInternalFormat();
} }
D3DFORMAT Renderbuffer::getD3DFormat() const GLenum Renderbuffer::getActualFormat() const
{ {
return mInstance->getD3DFormat(); return mInstance->getActualFormat();
} }
GLuint Renderbuffer::getRedSize() const GLuint Renderbuffer::getRedSize() const
...@@ -316,6 +316,7 @@ RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) ...@@ -316,6 +316,7 @@ RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
mHeight = 0; mHeight = 0;
mInternalFormat = GL_RGBA4; mInternalFormat = GL_RGBA4;
mD3DFormat = D3DFMT_A8R8G8B8; mD3DFormat = D3DFMT_A8R8G8B8;
mActualFormat = GL_RGBA8_OES;
mSamples = 0; mSamples = 0;
} }
...@@ -352,9 +353,9 @@ GLenum RenderbufferStorage::getInternalFormat() const ...@@ -352,9 +353,9 @@ GLenum RenderbufferStorage::getInternalFormat() const
return mInternalFormat; return mInternalFormat;
} }
D3DFORMAT RenderbufferStorage::getD3DFormat() const GLenum RenderbufferStorage::getActualFormat() const
{ {
return mD3DFormat; return mActualFormat;
} }
GLsizei RenderbufferStorage::getSamples() const GLsizei RenderbufferStorage::getSamples() const
...@@ -391,6 +392,7 @@ Colorbuffer::Colorbuffer(renderer::SwapChain *swapChain) ...@@ -391,6 +392,7 @@ Colorbuffer::Colorbuffer(renderer::SwapChain *swapChain)
mHeight = description.Height; mHeight = description.Height;
mInternalFormat = dx2es::ConvertBackBufferFormat(description.Format); mInternalFormat = dx2es::ConvertBackBufferFormat(description.Format);
mD3DFormat = description.Format; mD3DFormat = description.Format;
mActualFormat = dx2es::GetEquivalentFormat(mD3DFormat);
mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType); mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
} }
} }
...@@ -429,6 +431,7 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) ...@@ -429,6 +431,7 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
mHeight = height; mHeight = height;
mInternalFormat = format; mInternalFormat = format;
mD3DFormat = requestedFormat; mD3DFormat = requestedFormat;
mActualFormat = dx2es::GetEquivalentFormat(mD3DFormat);
mSamples = supportedSamples; mSamples = supportedSamples;
} }
...@@ -465,6 +468,7 @@ DepthStencilbuffer::DepthStencilbuffer(renderer::SwapChain *swapChain) ...@@ -465,6 +468,7 @@ DepthStencilbuffer::DepthStencilbuffer(renderer::SwapChain *swapChain)
mInternalFormat = dx2es::ConvertDepthStencilFormat(description.Format); mInternalFormat = dx2es::ConvertDepthStencilFormat(description.Format);
mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType); mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
mD3DFormat = description.Format; mD3DFormat = description.Format;
mActualFormat = dx2es::GetEquivalentFormat(mD3DFormat);
} }
} }
...@@ -503,6 +507,7 @@ DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) ...@@ -503,6 +507,7 @@ DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
mHeight = height; mHeight = height;
mInternalFormat = GL_DEPTH24_STENCIL8_OES; mInternalFormat = GL_DEPTH24_STENCIL8_OES;
mD3DFormat = D3DFMT_D24S8; mD3DFormat = D3DFMT_D24S8;
mActualFormat = GL_DEPTH24_STENCIL8_OES;
mSamples = supportedSamples; mSamples = supportedSamples;
} }
......
...@@ -45,7 +45,7 @@ class RenderbufferInterface ...@@ -45,7 +45,7 @@ class RenderbufferInterface
virtual GLsizei getWidth() const = 0; virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0; virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0; virtual GLenum getInternalFormat() const = 0;
virtual D3DFORMAT getD3DFormat() const = 0; virtual GLenum getActualFormat() const = 0;
virtual GLsizei getSamples() const = 0; virtual GLsizei getSamples() const = 0;
GLuint getRedSize() const; GLuint getRedSize() const;
...@@ -77,7 +77,7 @@ class RenderbufferTexture2D : public RenderbufferInterface ...@@ -77,7 +77,7 @@ class RenderbufferTexture2D : public RenderbufferInterface
virtual GLsizei getWidth() const; virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const; virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const; virtual GLenum getInternalFormat() const;
virtual D3DFORMAT getD3DFormat() const; virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const; virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const; virtual unsigned int getSerial() const;
...@@ -105,7 +105,7 @@ class RenderbufferTextureCubeMap : public RenderbufferInterface ...@@ -105,7 +105,7 @@ class RenderbufferTextureCubeMap : public RenderbufferInterface
virtual GLsizei getWidth() const; virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const; virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const; virtual GLenum getInternalFormat() const;
virtual D3DFORMAT getD3DFormat() const; virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const; virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const; virtual unsigned int getSerial() const;
...@@ -133,7 +133,7 @@ class RenderbufferStorage : public RenderbufferInterface ...@@ -133,7 +133,7 @@ class RenderbufferStorage : public RenderbufferInterface
virtual GLsizei getWidth() const; virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const; virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const; virtual GLenum getInternalFormat() const;
virtual D3DFORMAT getD3DFormat() const; virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const; virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const; virtual unsigned int getSerial() const;
...@@ -145,6 +145,7 @@ class RenderbufferStorage : public RenderbufferInterface ...@@ -145,6 +145,7 @@ class RenderbufferStorage : public RenderbufferInterface
GLsizei mWidth; GLsizei mWidth;
GLsizei mHeight; GLsizei mHeight;
GLenum mInternalFormat; GLenum mInternalFormat;
GLenum mActualFormat;
D3DFORMAT mD3DFormat; D3DFORMAT mD3DFormat;
GLsizei mSamples; GLsizei mSamples;
...@@ -179,7 +180,7 @@ class Renderbuffer : public RefCountObject ...@@ -179,7 +180,7 @@ class Renderbuffer : public RefCountObject
GLsizei getWidth() const; GLsizei getWidth() const;
GLsizei getHeight() const; GLsizei getHeight() const;
GLenum getInternalFormat() const; GLenum getInternalFormat() const;
D3DFORMAT getD3DFormat() const; GLenum getActualFormat() const;
GLuint getRedSize() const; GLuint getRedSize() const;
GLuint getGreenSize() const; GLuint getGreenSize() const;
GLuint getBlueSize() const; GLuint getBlueSize() const;
......
...@@ -708,10 +708,10 @@ GLenum Texture2D::getInternalFormat(GLint level) const ...@@ -708,10 +708,10 @@ GLenum Texture2D::getInternalFormat(GLint level) const
return GL_NONE; return GL_NONE;
} }
D3DFORMAT Texture2D::getD3DFormat(GLint level) const GLenum Texture2D::getActualFormat(GLint level) const
{ {
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
return mImageArray[level].getD3DFormat(); return mImageArray[level].getActualFormat();
else else
return D3DFMT_UNKNOWN; return D3DFMT_UNKNOWN;
} }
...@@ -1360,10 +1360,10 @@ GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const ...@@ -1360,10 +1360,10 @@ GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
return GL_NONE; return GL_NONE;
} }
D3DFORMAT TextureCubeMap::getD3DFormat(GLenum target, GLint level) const GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
{ {
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
return mImageArray[faceIndex(target)][level].getD3DFormat(); return mImageArray[faceIndex(target)][level].getActualFormat();
else else
return D3DFMT_UNKNOWN; return D3DFMT_UNKNOWN;
} }
......
...@@ -154,7 +154,7 @@ class Texture2D : public Texture ...@@ -154,7 +154,7 @@ class Texture2D : public Texture
GLsizei getWidth(GLint level) const; GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const; GLenum getInternalFormat(GLint level) const;
D3DFORMAT getD3DFormat(GLint level) const; GLenum getActualFormat(GLint level) const;
bool isCompressed(GLint level) const; bool isCompressed(GLint level) const;
bool isDepth(GLint level) const; bool isDepth(GLint level) const;
...@@ -222,7 +222,7 @@ class TextureCubeMap : public Texture ...@@ -222,7 +222,7 @@ class TextureCubeMap : public Texture
GLsizei getWidth(GLenum target, GLint level) const; GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const; GLsizei getHeight(GLenum target, GLint level) const;
GLenum getInternalFormat(GLenum target, GLint level) const; GLenum getInternalFormat(GLenum target, GLint level) const;
D3DFORMAT getD3DFormat(GLenum target, GLint level) const; GLenum getActualFormat(GLenum target, GLint level) const;
bool isCompressed(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 setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
......
...@@ -30,6 +30,7 @@ Image::Image() ...@@ -30,6 +30,7 @@ Image::Image()
mD3DPool = D3DPOOL_SYSTEMMEM; mD3DPool = D3DPOOL_SYSTEMMEM;
mD3DFormat = D3DFMT_UNKNOWN; mD3DFormat = D3DFMT_UNKNOWN;
mActualFormat = GL_NONE;
} }
Image::~Image() Image::~Image()
...@@ -80,6 +81,7 @@ bool Image::redefine(GLint internalformat, GLsizei width, GLsizei height, bool f ...@@ -80,6 +81,7 @@ bool Image::redefine(GLint internalformat, GLsizei width, GLsizei height, bool f
mInternalFormat = internalformat; mInternalFormat = internalformat;
// compute the d3d format that will be used // compute the d3d format that will be used
mD3DFormat = Texture::ConvertTextureInternalFormat(internalformat); mD3DFormat = Texture::ConvertTextureInternalFormat(internalformat);
mActualFormat = dx2es::GetEquivalentFormat(mD3DFormat);
if (mSurface) if (mSurface)
{ {
...@@ -165,6 +167,11 @@ bool Image::isRenderableFormat() const ...@@ -165,6 +167,11 @@ bool Image::isRenderableFormat() const
return Texture::IsTextureFormatRenderable(getD3DFormat()); return Texture::IsTextureFormatRenderable(getD3DFormat());
} }
GLenum Image::getActualFormat() const
{
return mActualFormat;
}
D3DFORMAT Image::getD3DFormat() const D3DFORMAT Image::getD3DFormat() const
{ {
// this should only happen if the image hasn't been redefined first // this should only happen if the image hasn't been redefined first
......
...@@ -32,6 +32,7 @@ class Image ...@@ -32,6 +32,7 @@ class Image
bool isRenderableFormat() const; bool isRenderableFormat() const;
D3DFORMAT getD3DFormat() const; D3DFORMAT getD3DFormat() const;
GLenum getActualFormat() const;
GLsizei getWidth() const {return mWidth;} GLsizei getWidth() const {return mWidth;}
GLsizei getHeight() const {return mHeight;} GLsizei getHeight() const {return mHeight;}
...@@ -108,6 +109,7 @@ class Image ...@@ -108,6 +109,7 @@ class Image
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
D3DFORMAT mD3DFormat; D3DFORMAT mD3DFormat;
GLenum mActualFormat;
IDirect3DSurface9 *mSurface; IDirect3DSurface9 *mSurface;
}; };
......
...@@ -1273,6 +1273,35 @@ GLenum ConvertDepthStencilFormat(D3DFORMAT format) ...@@ -1273,6 +1273,35 @@ GLenum ConvertDepthStencilFormat(D3DFORMAT format)
return GL_DEPTH24_STENCIL8_OES; return GL_DEPTH24_STENCIL8_OES;
} }
GLenum GetEquivalentFormat(D3DFORMAT format)
{
if (format == D3DFMT_INTZ)
return GL_DEPTH24_STENCIL8_OES;
if (format == D3DFMT_NULL)
return GL_NONE;
switch (format)
{
case D3DFMT_A4R4G4B4: return GL_RGBA4;
case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
case D3DFMT_R5G6B5: return GL_RGB565;
case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
case D3DFMT_D16: return GL_DEPTH_COMPONENT16;
case D3DFMT_D24S8: return GL_DEPTH24_STENCIL8_OES;
case D3DFMT_UNKNOWN: return GL_NONE;
case D3DFMT_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
case D3DFMT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
case D3DFMT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
case D3DFMT_A32B32G32R32F: return GL_RGBA32F_EXT;
case D3DFMT_A16B16G16R16F: return GL_RGBA16F_EXT;
case D3DFMT_L8: return GL_LUMINANCE8_EXT;
case D3DFMT_A8L8: return GL_LUMINANCE8_ALPHA8_EXT;
default: UNREACHABLE();
return GL_NONE;
}
}
} }
namespace dx namespace dx
......
...@@ -100,6 +100,7 @@ bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); ...@@ -100,6 +100,7 @@ bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
bool ConvertReadBufferFormat(D3DFORMAT d3dformat, GLenum *format, GLenum *type); bool ConvertReadBufferFormat(D3DFORMAT d3dformat, GLenum *format, GLenum *type);
GLenum ConvertBackBufferFormat(D3DFORMAT format); GLenum ConvertBackBufferFormat(D3DFORMAT format);
GLenum ConvertDepthStencilFormat(D3DFORMAT format); GLenum ConvertDepthStencilFormat(D3DFORMAT format);
GLenum GetEquivalentFormat(D3DFORMAT format);
} }
......
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