diff options
Diffstat (limited to 'opengl/libs/GLES2_dbg/src/texture.cpp')
-rw-r--r-- | opengl/libs/GLES2_dbg/src/texture.cpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/opengl/libs/GLES2_dbg/src/texture.cpp b/opengl/libs/GLES2_dbg/src/texture.cpp new file mode 100644 index 0000000..3aa0aab --- /dev/null +++ b/opengl/libs/GLES2_dbg/src/texture.cpp @@ -0,0 +1,265 @@ +/* + ** Copyright 2011, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ + +#include "header.h" + +namespace android +{ +unsigned GetBytesPerPixel(const GLenum format, const GLenum type) +{ + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + return 2; + case GL_UNSIGNED_SHORT_4_4_4_4: + return 2; + case GL_UNSIGNED_SHORT_5_5_5_1: + return 2; + case GL_UNSIGNED_BYTE: + break; + default: + assert(0); + } + + switch (format) { + case GL_ALPHA: + return 1; + case GL_LUMINANCE: + return 1; + break; + case GL_LUMINANCE_ALPHA: + return 2; + case GL_RGB: + return 3; + case GL_RGBA: + return 4; + default: + assert(0); + return 0; + } +} + +#define USE_RLE 0 +#if USE_RLE +export template<typename T> +void * RLEEncode(const void * pixels, unsigned count, unsigned * encodedSize) +{ + // first is a byte indicating data size [1,2,4] bytes + // then an unsigned indicating decompressed size + // then a byte of header: MSB == 1 indicates run, else literal + // LSB7 is run or literal length (actual length - 1) + + const T * data = (T *)pixels; + unsigned bufferSize = sizeof(T) * count / 2 + 8; + unsigned char * buffer = (unsigned char *)malloc(bufferSize); + buffer[0] = sizeof(T); + unsigned bufferWritten = 1; // number of bytes written + *(unsigned *)(buffer + bufferWritten) = count; + bufferWritten += sizeof(count); + while (count) { + unsigned char run = 1; + bool repeat = true; + for (run = 1; run < count; run++) + if (data[0] != data[run]) { + repeat = false; + break; + } else if (run > 126) + break; + if (!repeat) { + // find literal length + for (run = 1; run < count; run++) + if (data[run - 1] == data[run]) + break; + else if (run > 126) + break; + unsigned bytesToWrite = 1 + sizeof(T) * run; + if (bufferWritten + bytesToWrite > bufferSize) { + bufferSize += sizeof(T) * run + 256; + buffer = (unsigned char *)realloc(buffer, bufferSize); + } + buffer[bufferWritten++] = run - 1; + for (unsigned i = 0; i < run; i++) { + *(T *)(buffer + bufferWritten) = *data; + bufferWritten += sizeof(T); + data++; + } + count -= run; + } else { + unsigned bytesToWrite = 1 + sizeof(T); + if (bufferWritten + bytesToWrite > bufferSize) { + bufferSize += 256; + buffer = (unsigned char *)realloc(buffer, bufferSize); + } + buffer[bufferWritten++] = (run - 1) | 0x80; + *(T *)(buffer + bufferWritten) = data[0]; + bufferWritten += sizeof(T); + data += run; + count -= run; + } + } + if (encodedSize) + *encodedSize = bufferWritten; + return buffer; +} + +void * RLEEncode(const void * pixels, const unsigned bytesPerPixel, const unsigned count, unsigned * encodedSize) +{ + switch (bytesPerPixel) { + case 4: + return RLEEncode<int>(pixels, count, encodedSize); + case 2: + return RLEEncode<short>(pixels, count, encodedSize); + case 1: + return RLEEncode<char>(pixels, count, encodedSize); + default: + assert(0); + return NULL; + } +} +#endif +}; // namespace android + +void Debug_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +{ + glesv2debugger::Message msg; + const bool expectResponse = false; + struct : public FunctionCall { + GLenum target; + GLint level; + GLint internalformat; + GLsizei width; + GLsizei height; + GLint border; + GLenum format; + GLenum type; + const GLvoid* pixels; + + const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) { + nsecs_t c0 = systemTime(timeMode); + _c->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + msg.set_time((systemTime(timeMode) - c0) * 1e-6f); + return 0; + } + } caller; + caller.target = target; + caller.level = level; + caller.internalformat = internalformat; + caller.width = width; + caller.height = height; + caller.border = border; + caller.format = format; + caller.type = type; + caller.pixels = pixels; + + msg.set_arg0(target); + msg.set_arg1(level); + msg.set_arg2(internalformat); + msg.set_arg3(width); + msg.set_arg4(height); + msg.set_arg5(border); + msg.set_arg6(format); + msg.set_arg7(type); + msg.set_arg8(reinterpret_cast<int>(pixels)); + + if (pixels) { + assert(internalformat == format); + assert(0 == border); + + unsigned bytesPerPixel = GetBytesPerPixel(format, type); + assert(0 < bytesPerPixel); + +// LOGD("GLESv2_dbg: glTexImage2D width=%d height=%d level=%d bytesPerPixel=%d", +// width, height, level, bytesPerPixel); +#if USE_RLE + unsigned encodedSize = 0; + void * data = RLEEncode(pixels, bytesPerPixel, width * height, &encodedSize); + msg.set_data(data, encodedSize); + free(data); + if (encodedSize > bytesPerPixel * width * height) + LOGD("GLESv2_dbg: glTexImage2D sending data encodedSize=%d size=%d", encodedSize, bytesPerPixel * width * height); +#else + msg.set_data(pixels, bytesPerPixel * width * height); +#endif + } + + int * ret = MessageLoop(caller, msg, expectResponse, + glesv2debugger::Message_Function_glTexImage2D); +} + +void Debug_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) +{ + glesv2debugger::Message msg; + const bool expectResponse = false; + struct : public FunctionCall { + GLenum target; + GLint level; + GLint xoffset; + GLint yoffset; + GLsizei width; + GLsizei height; + GLenum format; + GLenum type; + const GLvoid* pixels; + + const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) { + nsecs_t c0 = systemTime(timeMode); + _c->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + msg.set_time((systemTime(timeMode) - c0) * 1e-6f); + return 0; + } + } caller; + caller.target = target; + caller.level = level; + caller.xoffset = xoffset; + caller.yoffset = yoffset; + caller.width = width; + caller.height = height; + caller.format = format; + caller.type = type; + caller.pixels = pixels; + + msg.set_arg0(target); + msg.set_arg1(level); + msg.set_arg2(xoffset); + msg.set_arg3(yoffset); + msg.set_arg4(width); + msg.set_arg5(height); + msg.set_arg6(format); + msg.set_arg7(type); + msg.set_arg8(reinterpret_cast<int>(pixels)); + + assert(pixels); + if (pixels) { + unsigned bytesPerPixel = GetBytesPerPixel(format, type); + assert(0 < bytesPerPixel); + +// LOGD("GLESv2_dbg: glTexSubImage2D width=%d height=%d level=%d bytesPerPixel=%d", +// width, height, level, bytesPerPixel); + +#if USE_RLE + unsigned encodedSize = 0; + void * data = RLEEncode(pixels, bytesPerPixel, width * height, &encodedSize); + msg.set_data(data, encodedSize); + free(data); + if (encodedSize > bytesPerPixel * width * height) + LOGD("GLESv2_dbg: glTexImage2D sending data encodedSize=%d size=%d", encodedSize, bytesPerPixel * width * height); +#else + msg.set_data(pixels, bytesPerPixel * width * height); +#endif + } + + int * ret = MessageLoop(caller, msg, expectResponse, + glesv2debugger::Message_Function_glTexSubImage2D); +}
\ No newline at end of file |