diff options
Diffstat (limited to 'opengl/libagl/texture.cpp')
-rw-r--r-- | opengl/libagl/texture.cpp | 97 |
1 files changed, 86 insertions, 11 deletions
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 13d078e..9407bd5 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -24,6 +24,7 @@ #include "TextureObjectManager.h" #include <private/ui/android_natives_priv.h> +#include <ETC1/etc1.h> #ifdef LIBAGL_USE_GRALLOC_COPYBITS #include "copybit.h" @@ -583,7 +584,7 @@ static void decodePalette4(const GLvoid *data, int level, int width, int height, static __attribute__((noinline)) -void set_depth_and_fog(ogles_context_t* c, GLint z) +void set_depth_and_fog(ogles_context_t* c, GGLfixed z) { const uint32_t enables = c->rasterizer.state.enables; // we need to compute Zw @@ -592,8 +593,8 @@ void set_depth_and_fog(ogles_context_t* c, GLint z) GGLfixed Zw; GGLfixed n = gglFloatToFixed(c->transforms.vpt.zNear); GGLfixed f = gglFloatToFixed(c->transforms.vpt.zFar); - if (z<=0) Zw = n; - else if (z>=1) Zw = f; + if (z<=0) Zw = n; + else if (z>=0x10000) Zw = f; else Zw = gglMulAddx(z, (f-n), n); if (enables & GGL_ENABLE_FOG) { // set up fog if needed... @@ -836,7 +837,7 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte c->rasterizer.procs.texCoord2i(c, s0, t0); const uint32_t enables = c->rasterizer.state.enables; if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG))) - set_depth_and_fog(c, z); + set_depth_and_fog(c, gglIntToFixed(z)); c->rasterizer.procs.color4xv(c, c->currentColorClamped.v); c->rasterizer.procs.disable(c, GGL_W_LERP); @@ -1081,11 +1082,6 @@ void glCompressedTexImage2D( ogles_error(c, GL_INVALID_ENUM); return; } - if ((internalformat < GL_PALETTE4_RGB8_OES || - internalformat > GL_PALETTE8_RGB5_A1_OES)) { - ogles_error(c, GL_INVALID_ENUM); - return; - } if (width<0 || height<0 || border!=0) { ogles_error(c, GL_INVALID_VALUE); return; @@ -1121,6 +1117,12 @@ void glCompressedTexImage2D( format = GL_RGBA; type = GL_UNSIGNED_SHORT_5_5_5_1; break; +#ifdef GL_OES_compressed_ETC1_RGB8_texture + case GL_ETC1_RGB8_OES: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; +#endif default: ogles_error(c, GL_INVALID_ENUM); return; @@ -1133,6 +1135,30 @@ void glCompressedTexImage2D( int32_t size; GGLSurface* surface; + +#ifdef GL_OES_compressed_ETC1_RGB8_texture + if (internalformat == GL_ETC1_RGB8_OES) { + GLsizei compressedSize = etc1_get_encoded_data_size(width, height); + if (compressedSize > imageSize) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + int error = createTextureSurface(c, &surface, &size, + level, format, type, width, height); + if (error) { + ogles_error(c, error); + return; + } + if (etc1_decode_image( + (const etc1_byte*)data, + (etc1_byte*)surface->data, + width, height, 3, surface->stride*3) != 0) { + ogles_error(c, GL_INVALID_OPERATION); + } + return; + } +#endif + // all mipmap levels are specified at once. const int numLevels = level<0 ? -level : 1; @@ -1389,9 +1415,20 @@ void glCopyTexImage2D( // (x,y) is the lower-left corner of colorBuffer y = cbSurface.height - (y + height); + /* The GLES spec says: + * If any of the pixels within the specified rectangle are outside + * the framebuffer associated with the current rendering context, + * then the values obtained for those pixels are undefined. + */ + if (x+width > GLint(cbSurface.width)) + width = cbSurface.width - x; + + if (y+height > GLint(cbSurface.height)) + height = cbSurface.height - y; + int err = copyPixels(c, txSurface, 0, 0, - cbSurface, x, y, cbSurface.width, cbSurface.height); + cbSurface, x, y, width, height); if (err) { ogles_error(c, err); } @@ -1439,8 +1476,19 @@ void glCopyTexSubImage2D( const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = cbSurface.height - (y + height); + /* The GLES spec says: + * If any of the pixels within the specified rectangle are outside + * the framebuffer associated with the current rendering context, + * then the values obtained for those pixels are undefined. + */ + if (x+width > GLint(cbSurface.width)) + width = cbSurface.width - x; + + if (y+height > GLint(cbSurface.height)) + height = cbSurface.height - y; + int err = copyPixels(c, - surface, xoffset, yoffset, + txSurface, xoffset, yoffset, cbSurface, x, y, width, height); if (err) { ogles_error(c, err); @@ -1580,6 +1628,11 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) return; } + if (image == EGL_NO_IMAGE_KHR) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { ogles_error(c, GL_INVALID_VALUE); @@ -1604,4 +1657,26 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) { + ogles_context_t* c = ogles_context_t::get(); + if (target != GL_RENDERBUFFER_OES) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + + if (image == EGL_NO_IMAGE_KHR) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + + // well, we're not supporting this extension anyways } |