Add the ReadnPixelsEXT command

Trac #18608 Signed-off-by: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@865 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 9112d2a9
...@@ -2208,7 +2208,8 @@ void Context::applyTextures(SamplerType type) ...@@ -2208,7 +2208,8 @@ void Context::applyTextures(SamplerType type)
} }
} }
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{ {
Framebuffer *framebuffer = getReadFramebuffer(); Framebuffer *framebuffer = getReadFramebuffer();
...@@ -2222,6 +2223,17 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2222,6 +2223,17 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
// sized query sanity check
if (bufSize)
{
int requiredSize = outputPitch * height;
if (requiredSize > *bufSize)
{
return error(GL_INVALID_OPERATION);
}
}
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget(); IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
if (!renderTarget) if (!renderTarget)
...@@ -2286,7 +2298,6 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2286,7 +2298,6 @@ 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;
int inputPitch = -lock.Pitch; int inputPitch = -lock.Pitch;
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
for (int j = 0; j < rect.bottom - rect.top; j++) for (int j = 0; j < rect.bottom - rect.top; j++)
{ {
......
...@@ -420,7 +420,7 @@ class Context ...@@ -420,7 +420,7 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask); void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count); void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
......
...@@ -53,6 +53,46 @@ bool validImageSize(GLint level, GLsizei width, GLsizei height) ...@@ -53,6 +53,46 @@ bool validImageSize(GLint level, GLsizei width, GLsizei height)
return false; return false;
} }
// check for combinations of format and type that are valid for ReadPixels
bool validReadFormatType(GLenum format, GLenum type)
{
switch (format)
{
case GL_RGBA:
switch (type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return false;
}
break;
case GL_BGRA_EXT:
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
break;
default:
return false;
}
break;
case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
switch (type)
{
case gl::IMPLEMENTATION_COLOR_READ_TYPE:
break;
default:
return false;
}
break;
default:
return false;
}
return true;
}
extern "C" extern "C"
{ {
...@@ -4054,51 +4094,55 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) ...@@ -4054,51 +4094,55 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
} }
} }
void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei bufSize,
GLvoid *data)
{ {
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
"GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)", "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
x, y, width, height, format, type, pixels); x, y, width, height, format, type, bufSize, data);
try try
{ {
if (width < 0 || height < 0) if (width < 0 || height < 0 || bufSize < 0)
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
switch (format) if (!validReadFormatType(format, type))
{
case GL_RGBA:
switch (type)
{ {
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
break;
case GL_BGRA_EXT: gl::Context *context = gl::getNonLostContext();
switch (type)
if (context)
{ {
case GL_UNSIGNED_BYTE: context->readPixels(x, y, width, height, format, type, &bufSize, data);
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
break;
default:
return error(GL_INVALID_OPERATION);
} }
break; }
case gl::IMPLEMENTATION_COLOR_READ_FORMAT: catch(std::bad_alloc&)
switch (type)
{ {
case gl::IMPLEMENTATION_COLOR_READ_TYPE: return error(GL_OUT_OF_MEMORY);
break;
default:
return error(GL_INVALID_OPERATION);
} }
break; }
default:
void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid* pixels)
{
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
"GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
x, y, width, height, format, type, pixels);
try
{
if (width < 0 || height < 0)
{
return error(GL_INVALID_VALUE);
}
if (!validReadFormatType(format, type))
{
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4106,7 +4150,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe ...@@ -4106,7 +4150,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe
if (context) if (context)
{ {
context->readPixels(x, y, width, height, format, type, pixels); context->readPixels(x, y, width, height, format, type, NULL, pixels);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
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