Implements PACK_ALIGNMENT for ReadPixels

TRAC #11484 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Shannon Woods git-svn-id: https://angleproject.googlecode.com/svn/trunk@224 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent ce3d0f2f
...@@ -1589,6 +1589,8 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -1589,6 +1589,8 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
unsigned char *dest = (unsigned char*)pixels; unsigned char *dest = (unsigned char*)pixels;
unsigned short *dest16 = (unsigned short*)pixels; unsigned short *dest16 = (unsigned short*)pixels;
GLsizei outputPitch = ComputePitch(width, format, type, packAlignment);
for (int j = 0; j < rect.bottom - rect.top; j++) for (int j = 0; j < rect.bottom - rect.top; j++)
{ {
for (int i = 0; i < rect.right - rect.left; i++) for (int i = 0; i < rect.right - rect.left; i++)
...@@ -1671,10 +1673,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -1671,10 +1673,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
dest[4 * (i + j * width) + 0] = (unsigned char)(255 * r + 0.5f); dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
dest[4 * (i + j * width) + 1] = (unsigned char)(255 * g + 0.5f); dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * (i + j * width) + 2] = (unsigned char)(255 * b + 0.5f); dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
dest[4 * (i + j * width) + 3] = (unsigned char)(255 * a + 0.5f); dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
...@@ -1683,9 +1685,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -1683,9 +1685,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
switch (type) switch (type)
{ {
case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE
dest16[i + j * width] = ((unsigned short)(31 * b + 0.5f) << 0) | dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(63 * g + 0.5f) << 5) | ((unsigned short)(31 * b + 0.5f) << 0) |
((unsigned short)(31 * r + 0.5f) << 11); ((unsigned short)(63 * g + 0.5f) << 5) |
((unsigned short)(31 * r + 0.5f) << 11);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
......
...@@ -150,51 +150,17 @@ D3DFORMAT Texture::selectFormat(GLenum format) ...@@ -150,51 +150,17 @@ D3DFORMAT Texture::selectFormat(GLenum format)
return D3DFMT_A8R8G8B8; return D3DFMT_A8R8G8B8;
} }
// Returns the size, in bytes, of a single texel in an Image
int Texture::pixelSize(GLenum format, GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
switch (format)
{
case GL_ALPHA: return sizeof(unsigned char);
case GL_LUMINANCE: return sizeof(unsigned char);
case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
case GL_RGB: return sizeof(unsigned char) * 3;
case GL_RGBA: return sizeof(unsigned char) * 4;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5:
return sizeof(unsigned short);
default: UNREACHABLE();
}
return 0;
}
int Texture::imagePitch(const Image &img) const int Texture::imagePitch(const Image &img) const
{ {
return img.width * 4; return img.width * 4;
} }
GLsizei Texture::computePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) const
{
ASSERT(alignment > 0 && isPow2(alignment));
GLsizei rawPitch = pixelSize(format, type) * width;
return (rawPitch + alignment - 1) & ~(alignment - 1);
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line. // into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line.
void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const
{ {
GLsizei inputPitch = computePitch(width, format, type, unpackAlignment); GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
......
...@@ -96,7 +96,6 @@ class Texture ...@@ -96,7 +96,6 @@ class Texture
}; };
static D3DFORMAT selectFormat(GLenum format); static D3DFORMAT selectFormat(GLenum format);
static int pixelSize(GLenum format, GLenum type);
int imagePitch(const Image& img) const; int imagePitch(const Image& img) const;
GLenum mMinFilter; GLenum mMinFilter;
...@@ -136,8 +135,6 @@ class Texture ...@@ -136,8 +135,6 @@ class Texture
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;
GLsizei computePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) const;
}; };
class Texture2D : public Texture class Texture2D : public Texture
......
...@@ -144,6 +144,40 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig ...@@ -144,6 +144,40 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
return -1; return -1;
} }
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
{
ASSERT(alignment > 0 && isPow2(alignment));
GLsizei rawPitch = ComputePixelSize(format, type) * width;
return (rawPitch + alignment - 1) & ~(alignment - 1);
}
// Returns the size, in bytes, of a single texel in an Image
int ComputePixelSize(GLenum format, GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
switch (format)
{
case GL_ALPHA: return sizeof(unsigned char);
case GL_LUMINANCE: return sizeof(unsigned char);
case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
case GL_RGB: return sizeof(unsigned char) * 3;
case GL_RGBA: return sizeof(unsigned char) * 4;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5:
return sizeof(unsigned short);
default: UNREACHABLE();
}
return 0;
}
} }
namespace es2dx namespace es2dx
......
...@@ -25,6 +25,9 @@ int AttributeVectorCount(GLenum type); ...@@ -25,6 +25,9 @@ int AttributeVectorCount(GLenum type);
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize); int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
int ComputePixelSize(GLenum format, GLenum type);
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
} }
namespace es2dx namespace es2dx
......
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