Optimizes Texture::loadImageData

TRAC #13046 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Shannon Woods git-svn-id: https://angleproject.googlecode.com/svn/trunk@399 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 1dcea9f8
...@@ -200,119 +200,244 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei ...@@ -200,119 +200,244 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
{ {
GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment); GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
switch (format)
{
case GL_ALPHA:
loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_LUMINANCE:
loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_BYTE:
loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_UNSIGNED_SHORT_5_6_5:
loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
default: UNREACHABLE();
}
break;
case GL_RGBA:
switch (type)
{
case GL_UNSIGNED_BYTE:
loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_UNSIGNED_SHORT_5_5_5_1:
loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
default: UNREACHABLE();
}
break;
case GL_BGRA_EXT:
switch (type)
{
case GL_UNSIGNED_BYTE:
loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
default: UNREACHABLE();
}
break;
default: UNREACHABLE();
}
}
void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; source = static_cast<const unsigned char*>(input) + y * inputPitch;
const unsigned short *source16 = reinterpret_cast<const unsigned short*>(source); dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
unsigned char *dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
dest[4 * x + 1] = 0;
dest[4 * x + 2] = 0;
dest[4 * x + 3] = source[x];
}
}
}
// fast path for EXT_texture_format_BGRA8888 void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) { size_t inputPitch, const void *input, size_t outputPitch, void *output) const
memcpy(dest, source, width*4); {
continue; const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
dest[4 * x + 1] = source[x];
dest[4 * x + 2] = source[x];
dest[4 * x + 3] = 0xFF;
} }
}
}
void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
unsigned char r; dest[4 * x + 0] = source[2*x+0];
unsigned char g; dest[4 * x + 1] = source[2*x+0];
unsigned char b; dest[4 * x + 2] = source[2*x+0];
unsigned char a; dest[4 * x + 3] = source[2*x+1];
}
}
}
switch (format) void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
{ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
case GL_ALPHA: {
a = source[x]; const unsigned char *source = NULL;
r = 0; unsigned char *dest = NULL;
g = 0;
b = 0;
break;
case GL_LUMINANCE:
r = source[x];
g = source[x];
b = source[x];
a = 0xFF;
break;
case GL_LUMINANCE_ALPHA:
r = source[2*x+0];
g = source[2*x+0];
b = source[2*x+0];
a = source[2*x+1];
break;
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_BYTE:
r = source[x * 3 + 0];
g = source[x * 3 + 1];
b = source[x * 3 + 2];
a = 0xFF;
break;
case GL_UNSIGNED_SHORT_5_6_5:
{
unsigned short rgba = source16[x];
a = 0xFF; for (int y = 0; y < height; y++)
b = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2); {
g = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9); source = static_cast<const unsigned char*>(input) + y * inputPitch;
r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
} for (int x = 0; x < width; x++)
break; {
dest[4 * x + 0] = source[x * 3 + 2];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 0];
dest[4 * x + 3] = 0xFF;
}
}
}
default: UNREACHABLE(); void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
} size_t inputPitch, const void *input, size_t outputPitch, void *output) const
break; {
const unsigned short *source = NULL;
unsigned char *dest = NULL;
case GL_RGBA: for (int y = 0; y < height; y++)
switch (type) {
{ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
case GL_UNSIGNED_BYTE: dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
r = source[x * 4 + 0]; for (int x = 0; x < width; x++)
g = source[x * 4 + 1]; {
b = source[x * 4 + 2]; unsigned short rgba = source[x];
a = source[x * 4 + 3]; dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
break; dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
case GL_UNSIGNED_SHORT_4_4_4_4: dest[4 * x + 3] = 0xFF;
{ }
unsigned short rgba = source16[x]; }
}
a = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0); void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
b = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4); size_t inputPitch, const void *input, size_t outputPitch, void *output) const
g = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8); {
r = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12); const unsigned char *source = NULL;
} unsigned char *dest = NULL;
break;
case GL_UNSIGNED_SHORT_5_5_5_1: for (int y = 0; y < height; y++)
{ {
unsigned short rgba = source16[x]; source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 4 + 2];
dest[4 * x + 1] = source[x * 4 + 1];
dest[4 * x + 2] = source[x * 4 + 0];
dest[4 * x + 3] = source[x * 4 + 3];
}
}
}
a = (rgba & 0x0001) ? 0xFF : 0; void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
b = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3); size_t inputPitch, const void *input, size_t outputPitch, void *output) const
g = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8); {
r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); const unsigned short *source = NULL;
} unsigned char *dest = NULL;
break;
default: UNREACHABLE(); for (int y = 0; y < height; y++)
} {
break; source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
default: UNREACHABLE(); dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
} for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
}
}
}
dest[4 * x + 0] = b; void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
dest[4 * x + 1] = g; size_t inputPitch, const void *input, size_t outputPitch, void *output) const
dest[4 * x + 2] = r; {
dest[4 * x + 3] = a; const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
} }
} }
} }
void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
memcpy(dest, source, width*4);
}
}
void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img) void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img)
{ {
IDirect3DTexture9 *newTexture = NULL; IDirect3DTexture9 *newTexture = NULL;
......
...@@ -147,6 +147,25 @@ class Texture : public RefCountObject ...@@ -147,6 +147,25 @@ class Texture : public RefCountObject
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const; GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer. IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
bool mDirty; bool mDirty;
......
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