/*
* Auxiliary functions to compute the size of array/blob arguments.
*/
+
#include <string.h>
-#include <map>
#include "os_thread.hpp"
#include "glimports.hpp"
#include "glproc.hpp"
+#include "glsize.hpp"
#include "eglsize.hpp"
#include "assert.h"
-static os::recursive_mutex image_map_mutex;
-static std::map<EGLImageKHR, struct image_info *>image_map;
-
static int
bisect_val(int min, int max, bool is_valid_val(int val))
{
static int
detect_size(int *width_ret, int *height_ret)
{
- static GLint max_tex_size;
+ GLint max_tex_size;
int width;
int height;
- if (!max_tex_size)
- _glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
+ 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 0;
}
-void
-_eglCreateImageKHR_get_image_info(EGLImageKHR image, struct image_info *info)
+/* 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;
_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
- memset(info, sizeof *info, 0);
+ info->width = 0;
+ info->height = 0;
_glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, texture, 0);
_glBindFramebuffer(GL_FRAMEBUFFER, orig_fbo);
_glDeleteFramebuffers(1, &fbo);
-
- return;
}
-static struct image_info *
-get_image_info(EGLImageKHR image)
-{
- struct image_info *info;
-
- image_map_mutex.lock();
- info = image_map[image];
- image_map_mutex.unlock();
-
- return info;
-}
-
-void
-_eglCreateImageKHR_epilog(EGLDisplay dpy, EGLContext ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attrib_list,
- EGLImageKHR image)
-{
- struct image_info *info;
-
- info = (struct image_info *)malloc(sizeof *info);
- _eglCreateImageKHR_get_image_info(image, info);
-
- image_map_mutex.lock();
- assert(image_map.find(image) == image_map.end());
- image_map[image] = info;
- image_map_mutex.unlock();
-}
-
-void
-_eglDestroyImageKHR_epilog(EGLImageKHR image)
-{
- struct image_info *info;
-
- info = get_image_info(image);
-
- image_map_mutex.lock();
- image_map.erase(image);
- image_map_mutex.unlock();
-
- free(info);
-}
-
-void
-get_texture_2d_image(struct image_blob *blob)
+static void
+get_texture_2d_image(image_info *info)
{
GLuint fbo = 0;
GLint prev_fbo = 0;
status = _glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
os::log("%s: error: %d\n", __func__, status);
- _glReadPixels(0, 0, blob->info.width, blob->info.height, GL_RGBA,
- GL_UNSIGNED_BYTE, blob->data);
+ _glReadPixels(0, 0, info->width, info->height, info->format, info->type, info->pixels);
/* Don't leak errors to the traced application. */
(void)_glGetError();
_glDeleteFramebuffers(1, &fbo);
}
-size_t
-_glEGLImageTargetTexture2DOES_size(GLint target, EGLImageKHR image)
+struct image_info *
+_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image)
{
+ GLuint tex;
+ GLuint bound_tex;
struct image_info *info;
- size_t size;
- info = get_image_info(image);
- size = sizeof(struct image_blob) - 1;
- /* We always read out the pixels in RGBA format */
- size += info->width * info->height * 4;
+ info = new image_info;
- return size;
-}
+ memset(info, 0, sizeof *info);
-void *
-_glEGLImageTargetTexture2DOES_get_ptr(GLenum target, EGLImageKHR image)
-{
- GLuint tex;
- GLuint bound_tex;
- size_t image_blob_size = _glEGLImageTargetTexture2DOES_size(target, image);
- struct image_blob *blob;
- struct image_info *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);
- blob = (struct image_blob *)malloc(image_blob_size);
- info = get_image_info(image);
- blob->info = *info;
- get_texture_2d_image(blob);
+
+ 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 (void *)blob;
+ return info;
}
void
-_glEGLImageTargetTexture2DOES_put_ptr(const void *buffer)
+_EGLImageKHR_free_image_info(struct image_info *info)
{
- free((void *)buffer);
+ free(info->pixels);
+ delete info;
}
+
#ifndef _EGLSIZE_HPP_
#define _EGLSIZE_HPP_
-struct image_info
-{
- int width;
- int height;
-};
-struct image_blob
+#include "glimports.hpp"
+
+
+struct image_info
{
- struct image_info info;
- char data[1];
+ GLint internalformat;
+ GLsizei width;
+ GLsizei height;
+ GLenum format;
+ GLenum type;
+ GLsizei size;
+ GLvoid * pixels;
};
-void
-_eglDestroyImageKHR_epilog(EGLImageKHR image);
+struct image_info *
+_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image);
void
-_eglCreateImageKHR_epilog(EGLDisplay dpy, EGLContext ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attrib_list,
- EGLImageKHR image);
-
-size_t
-_glEGLImageTargetTexture2DOES_size(GLint target, EGLImageKHR image);
+_EGLImageKHR_free_image_info(struct image_info *info);
-void *
-_glEGLImageTargetTexture2DOES_get_ptr(GLenum target, EGLImageKHR image);
-
-void
-_glEGLImageTargetTexture2DOES_put_ptr(const void *buffer);
#endif
#include <string.h>
+#include <algorithm>
+
#include "os.hpp"
#include "glimports.hpp"
}
}
-static void retrace_glEGLImageTargetTexture2DOES(trace::Call &call)
-{
- EGLenum target = call.arg(0).toUInt();
- struct image_blob *iblob;
- struct image_info *info;
-
- if (target != GL_TEXTURE_2D) {
- os::log("%s: target %d not supported\n", __func__, target);
- return;
- }
- iblob = static_cast<struct image_blob *>((call.arg(1)).toPointer());
- info = &iblob->info;
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info->width, info->height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, iblob->data);
-}
-
const retrace::Entry glretrace::egl_callbacks[] = {
{"eglGetError", &retrace::ignore},
{"eglGetDisplay", &retrace::ignore},
//{"eglCopyBuffers", &retrace::ignore},
{"eglGetProcAddress", &retrace::ignore},
{"eglCreateImageKHR", &retrace::ignore},
- {"glEGLImageTargetTexture2DOES", &retrace_glEGLImageTargetTexture2DOES},
+ {"eglDestroyImageKHR", &retrace::ignore},
+ {"glEGLImageTargetTexture2DOES", &retrace::ignore},
{NULL, NULL},
};
print ' gltrace::releaseContext((uintptr_t)ctx);'
print ' }'
- if function.name == 'eglCreateImageKHR':
- print ' _eglCreateImageKHR_epilog(dpy, ctx, target, buffer,'
- print ' attrib_list, _result);'
-
- if function.name == 'eglDestroyImageKHR':
- print ' _eglDestroyImageKHR_epilog(image);'
-
- def serializeArgValue(self, function, arg):
- if function.name == 'glEGLImageTargetTexture2DOES' and \
- arg.name == 'image':
- print ' GLsizei blob_size;'
- print ' GLvoid *blob_ptr;'
- print ' blob_size = _glEGLImageTargetTexture2DOES_size(target, image);'
- print ' blob_ptr = _glEGLImageTargetTexture2DOES_get_ptr(target, image);'
- print ' trace::localWriter.writeBlob(blob_ptr, blob_size);'
- print ' _glEGLImageTargetTexture2DOES_put_ptr(blob_ptr);'
-
- return
-
- GlTracer.serializeArgValue(self, function, arg)
+ 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 <stdlib.h>'
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();'
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();'