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
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 7f50c5b..2e0b1e3 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -200,119 +200,244 @@
{
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++)
{
- const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
- const unsigned short *source16 = reinterpret_cast<const unsigned short*>(source);
- unsigned char *dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
-
- // fast path for EXT_texture_format_BGRA8888
- if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) {
- memcpy(dest, source, width*4);
- continue;
- }
-
+ 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++)
{
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
-
- switch (format)
- {
- case GL_ALPHA:
- a = source[x];
- r = 0;
- 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;
- b = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
- g = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
- r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- }
- break;
-
- default: UNREACHABLE();
- }
- break;
-
- case GL_RGBA:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- r = source[x * 4 + 0];
- g = source[x * 4 + 1];
- b = source[x * 4 + 2];
- a = source[x * 4 + 3];
- break;
-
- case GL_UNSIGNED_SHORT_4_4_4_4:
- {
- unsigned short rgba = source16[x];
-
- a = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
- b = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
- g = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
- r = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
- }
- break;
-
- case GL_UNSIGNED_SHORT_5_5_5_1:
- {
- unsigned short rgba = source16[x];
-
- a = (rgba & 0x0001) ? 0xFF : 0;
- b = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
- g = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
- r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- }
- break;
-
- default: UNREACHABLE();
- }
- break;
- default: UNREACHABLE();
- }
-
- dest[4 * x + 0] = b;
- dest[4 * x + 1] = g;
- dest[4 * x + 2] = r;
- dest[4 * x + 3] = a;
+ dest[4 * x + 0] = 0;
+ dest[4 * x + 1] = 0;
+ dest[4 * x + 2] = 0;
+ dest[4 * x + 3] = source[x];
}
}
}
+void Texture::loadLuminanceImageData(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++)
+ {
+ 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++)
+ {
+ dest[4 * x + 0] = source[2*x+0];
+ dest[4 * x + 1] = source[2*x+0];
+ dest[4 * x + 2] = source[2*x+0];
+ dest[4 * x + 3] = source[2*x+1];
+ }
+ }
+}
+
+void Texture::loadRGBUByteImageData(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++)
+ {
+ 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;
+ }
+ }
+}
+
+void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ 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 & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
+ dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
+
+void Texture::loadRGBAUByteImageData(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++)
+ {
+ 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];
+ }
+ }
+}
+
+void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ 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 & 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);
+ }
+ }
+}
+
+void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ 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)
{
IDirect3DTexture9 *newTexture = NULL;