From: José Fonseca Date: Sun, 5 Aug 2012 09:24:28 +0000 (+0100) Subject: Merge branch 'egl-image' X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=b14eab55d848d5c0055c4c512c36248e9578ce24;hp=67e00fdd5bdf596c9468d29ad99e7eba646cd02a;p=apitrace Merge branch 'egl-image' Conflicts: wrappers/egltrace.py --- diff --git a/helpers/eglsize.cpp b/helpers/eglsize.cpp new file mode 100644 index 0000000..4f2dfdc --- /dev/null +++ b/helpers/eglsize.cpp @@ -0,0 +1,217 @@ +/********************************************************************* + * + * Copyright 2012 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *********************************************************************/ + +/* + * Auxiliary functions to compute the size of array/blob arguments. + */ + +#include + +#include "os_thread.hpp" +#include "glimports.hpp" +#include "glproc.hpp" +#include "glsize.hpp" +#include "eglsize.hpp" +#include "assert.h" + + +static int +bisect_val(int min, int max, bool is_valid_val(int val)) +{ + bool valid; + + while (1) { + int try_val = min + (max - min + 1) / 2; + + valid = is_valid_val(try_val); + if (min == max) + break; + + if (valid) + min = try_val; + else + max = try_val - 1; + } + + return valid ? min : -1; +} + +static bool +is_valid_width(int val) +{ + _glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, val, 1); + return _glGetError() == GL_NO_ERROR; +} + +static bool +is_valid_height(int val) +{ + _glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, val); + return _glGetError() == GL_NO_ERROR; +} + +static int +detect_size(int *width_ret, int *height_ret) +{ + GLint max_tex_size; + int width; + int height; + + max_tex_size = 0; + _glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); + + width = bisect_val(1, max_tex_size, is_valid_width); + if (width < 0) + return -1; + + height = bisect_val(1, max_tex_size, is_valid_height); + if (height < 0) + return -1; + + *width_ret = width; + *height_ret = height; + + return 0; +} + +/* XXX */ +static inline bool +can_unpack_subimage(void) { + return false; +} + +static void +_eglCreateImageKHR_get_image_size(EGLImageKHR image, image_info *info) +{ + GLuint fbo = 0; + GLuint orig_fbo = 0; + GLuint texture = 0; + GLuint orig_texture; + GLenum status; + + _glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&orig_fbo); + _glGenFramebuffers(1, &fbo); + _glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + _glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&orig_texture); + _glGenTextures(1, &texture); + _glBindTexture(GL_TEXTURE_2D, texture); + + _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + info->width = 0; + info->height = 0; + + _glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, texture, 0); + status = _glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status == GL_FRAMEBUFFER_COMPLETE) { + if (detect_size(&info->width, &info->height) != 0) + os::log("%s: can't detect image size\n", __func__); + } else { + os::log("%s: error: %x\n", __func__, status); + } + + /* Don't leak errors to the traced application. */ + (void)_glGetError(); + + _glBindTexture(GL_TEXTURE_2D, orig_texture); + _glDeleteTextures(1, &texture); + + _glBindFramebuffer(GL_FRAMEBUFFER, orig_fbo); + _glDeleteFramebuffers(1, &fbo); +} + +static void +get_texture_2d_image(image_info *info) +{ + GLuint fbo = 0; + GLint prev_fbo = 0; + GLint texture; + GLenum status; + + _glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); + if (!texture) + return; + + _glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fbo); + _glGenFramebuffers(1, &fbo); + _glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + _glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + texture, 0); + status = _glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + os::log("%s: error: %d\n", __func__, status); + _glReadPixels(0, 0, info->width, info->height, info->format, info->type, info->pixels); + /* Don't leak errors to the traced application. */ + (void)_glGetError(); + + _glBindFramebuffer(GL_FRAMEBUFFER, prev_fbo); + _glDeleteFramebuffers(1, &fbo); +} + +struct image_info * +_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image) +{ + GLuint tex; + GLuint bound_tex; + struct image_info *info; + + info = new image_info; + + memset(info, 0, sizeof *info); + + info->internalformat = GL_RGBA; + info->format = GL_RGBA; + info->type = GL_UNSIGNED_BYTE; + + _eglCreateImageKHR_get_image_size(image, info); + + _glGenTextures(1, &tex); + _glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&bound_tex); + _glBindTexture(GL_TEXTURE_2D, tex); + _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + info->size = _glTexImage2D_size(info->format, info->type, info->width, info->height); + info->pixels = malloc(info->size); + + get_texture_2d_image(info); + _glBindTexture(GL_TEXTURE_2D, bound_tex); + _glDeleteBuffers(1, &tex); + + return info; +} + +void +_EGLImageKHR_free_image_info(struct image_info *info) +{ + free(info->pixels); + delete info; +} + + diff --git a/helpers/eglsize.hpp b/helpers/eglsize.hpp new file mode 100644 index 0000000..a2014f6 --- /dev/null +++ b/helpers/eglsize.hpp @@ -0,0 +1,57 @@ + +/********************************************************************* + * + * Copyright 2012 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *********************************************************************/ + +/* + * Auxiliary functions to compute the size of array/blob arguments. + */ +#ifndef _EGLSIZE_HPP_ +#define _EGLSIZE_HPP_ + + +#include "glimports.hpp" + + +struct image_info +{ + GLint internalformat; + GLsizei width; + GLsizei height; + GLenum format; + GLenum type; + GLsizei size; + GLvoid * pixels; +}; + +struct image_info * +_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image); + +void +_EGLImageKHR_free_image_info(struct image_info *info); + + +#endif diff --git a/helpers/glsize.hpp b/helpers/glsize.hpp index 5c646fd..e686140 100644 --- a/helpers/glsize.hpp +++ b/helpers/glsize.hpp @@ -37,6 +37,8 @@ #include +#include + #include "os.hpp" #include "glimports.hpp" diff --git a/retrace/glretrace_egl.cpp b/retrace/glretrace_egl.cpp index 70fe354..43e8169 100644 --- a/retrace/glretrace_egl.cpp +++ b/retrace/glretrace_egl.cpp @@ -32,6 +32,7 @@ #include "retrace.hpp" #include "glretrace.hpp" #include "os.hpp" +#include "eglsize.hpp" #ifndef EGL_OPENGL_ES_API #define EGL_OPENGL_ES_API 0x30A0 @@ -259,5 +260,8 @@ const retrace::Entry glretrace::egl_callbacks[] = { {"eglSwapBuffers", &retrace_eglSwapBuffers}, //{"eglCopyBuffers", &retrace::ignore}, {"eglGetProcAddress", &retrace::ignore}, + {"eglCreateImageKHR", &retrace::ignore}, + {"eglDestroyImageKHR", &retrace::ignore}, + {"glEGLImageTargetTexture2DOES", &retrace::ignore}, {NULL, NULL}, }; diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index 17aff4c..a2bcfff 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -376,6 +376,7 @@ if (ENABLE_EGL AND NOT WIN32 AND NOT APPLE) egltrace.cpp glcaps.cpp gltrace_state.cpp + ${CMAKE_SOURCE_DIR}/helpers/eglsize.cpp ) add_dependencies (egltrace glproc) diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py index 4330581..a6ff17f 100644 --- a/wrappers/egltrace.py +++ b/wrappers/egltrace.py @@ -81,6 +81,33 @@ class EglTracer(GlTracer): print ' gltrace::releaseContext((uintptr_t)ctx);' print ' }' + if function.name == 'glEGLImageTargetTexture2DOES': + print ' image_info *info = _EGLImageKHR_get_image_info(target, image);' + print ' if (info) {' + print ' GLint level = 0;' + print ' GLint internalformat = info->internalformat;' + print ' GLsizei width = info->width;' + print ' GLsizei height = info->height;' + print ' GLint border = 0;' + print ' GLenum format = info->format;' + print ' GLenum type = info->type;' + print ' const GLvoid * pixels = info->pixels;' + self.emitFakeTexture2D() + print ' _EGLImageKHR_free_image_info(info);' + print ' }' + + def emitFakeTexture2D(self): + function = glapi.getFunctionByName('glTexImage2D') + instances = function.argNames() + print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,) + for arg in function.args: + assert not arg.output + self.serializeArg(function, arg) + print ' trace::localWriter.endEnter();' + print ' trace::localWriter.beginLeave(_fake_call);' + print ' trace::localWriter.endLeave();' + + if __name__ == '__main__': print '#include ' @@ -95,6 +122,7 @@ if __name__ == '__main__': print print '#include "glproc.hpp"' print '#include "glsize.hpp"' + print '#include "eglsize.hpp"' print api = API() diff --git a/wrappers/gltrace.py b/wrappers/gltrace.py index 901e9d7..411a19b 100644 --- a/wrappers/gltrace.py +++ b/wrappers/gltrace.py @@ -1016,16 +1016,6 @@ class GlTracer(Tracer): function = api.getFunctionByName('glClientActiveTexture') self.fake_call(function, [texture]) - def fake_call(self, function, args): - print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,) - for arg, instance in zip(function.args, args): - assert not arg.output - print ' trace::localWriter.beginArg(%u);' % (arg.index,) - self.serializeValue(arg.type, instance) - print ' trace::localWriter.endArg();' - print ' trace::localWriter.endEnter();' - print ' trace::localWriter.beginLeave(_fake_call);' - print ' trace::localWriter.endLeave();' diff --git a/wrappers/trace.py b/wrappers/trace.py index 958c072..2146f68 100644 --- a/wrappers/trace.py +++ b/wrappers/trace.py @@ -695,4 +695,15 @@ class Tracer: print ' trace::localWriter.endEnter();' print ' trace::localWriter.beginLeave(_call);' print ' trace::localWriter.endLeave();' + + def fake_call(self, function, args): + print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,) + for arg, instance in zip(function.args, args): + assert not arg.output + print ' trace::localWriter.beginArg(%u);' % (arg.index,) + self.serializeValue(arg.type, instance) + print ' trace::localWriter.endArg();' + print ' trace::localWriter.endEnter();' + print ' trace::localWriter.beginLeave(_fake_call);' + print ' trace::localWriter.endLeave();'