X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glretrace_egl.cpp;h=d7b14ecad6c5e7db5861b42083e1b6b5fd3be2d5;hb=452d3256a3ba7f249222ef857d69c8caaaa753f3;hp=1c7697a0c6c88dfc4acfd0c1384e78a0a8c99420;hpb=3984ad2eba8decfcfab3da10964746e0ef8720c7;p=apitrace diff --git a/glretrace_egl.cpp b/glretrace_egl.cpp index 1c7697a..d7b14ec 100644 --- a/glretrace_egl.cpp +++ b/glretrace_egl.cpp @@ -37,6 +37,7 @@ #define EGL_OPENGL_ES_API 0x30A0 #define EGL_OPENVG_API 0x30A1 #define EGL_OPENGL_API 0x30A2 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 #endif @@ -45,10 +46,16 @@ using namespace glretrace; typedef std::map DrawableMap; typedef std::map ContextMap; +typedef std::map ProfileMap; static DrawableMap drawable_map; static ContextMap context_map; +static ProfileMap profile_map; static unsigned int current_api = EGL_OPENGL_ES_API; +static glws::Profile last_profile = glws::PROFILE_COMPAT; + +static void +createDrawable(unsigned long long orig_config, unsigned long long orig_surface); static glws::Drawable * getDrawable(unsigned long long surface_ptr) { @@ -58,6 +65,13 @@ getDrawable(unsigned long long surface_ptr) { DrawableMap::const_iterator it; it = drawable_map.find(surface_ptr); + if (it == drawable_map.end()) { + // In Fennec we get the egl window surface from Java which isn't + // traced, so just create a drawable if it doesn't exist in here + createDrawable(0, surface_ptr); + it = drawable_map.find(surface_ptr); + assert(it != drawable_map.end()); + } return (it != drawable_map.end()) ? it->second : NULL; } @@ -74,11 +88,37 @@ getContext(unsigned long long context_ptr) { return (it != context_map.end()) ? it->second : NULL; } +static void createDrawable(unsigned long long orig_config, unsigned long long orig_surface) +{ + ProfileMap::iterator it = profile_map.find(orig_config); + glws::Profile profile; + + // If the requested config is associated with a profile, use that + // profile. Otherwise, assume that the last used profile is what + // the user wants. + if (it != profile_map.end()) { + profile = it->second; + } else { + profile = last_profile; + } + + glws::Visual *visual = glretrace::visual[profile]; + + glws::Drawable *drawable = glws::createDrawable(visual); + drawable_map[orig_surface] = drawable; +} + static void retrace_eglCreateWindowSurface(trace::Call &call) { + unsigned long long orig_config = call.arg(1).toUIntPtr(); unsigned long long orig_surface = call.ret->toUIntPtr(); + createDrawable(orig_config, orig_surface); +} - glws::Drawable *drawable = glws::createDrawable(glretrace::visual); - drawable_map[orig_surface] = drawable; +static void retrace_eglCreatePbufferSurface(trace::Call &call) { + unsigned long long orig_config = call.arg(1).toUIntPtr(); + unsigned long long orig_surface = call.ret->toUIntPtr(); + createDrawable(orig_config, orig_surface); + // TODO: Respect the pbuffer dimensions too } static void retrace_eglDestroySurface(trace::Call &call) { @@ -88,7 +128,10 @@ static void retrace_eglDestroySurface(trace::Call &call) { it = drawable_map.find(orig_surface); if (it != drawable_map.end()) { - delete it->second; + if (it->second != drawable) { + // TODO: reference count + delete it->second; + } drawable_map.erase(it); } } @@ -98,17 +141,59 @@ static void retrace_eglBindAPI(trace::Call &call) { } static void retrace_eglCreateContext(trace::Call &call) { - if (current_api != EGL_OPENGL_API) { - retrace::warning(call) << "only OpenGL is supported. Aborting...\n"; - os::abort(); - return; - } - unsigned long long orig_context = call.ret->toUIntPtr(); + unsigned long long orig_config = call.arg(1).toUIntPtr(); glws::Context *share_context = getContext(call.arg(2).toUIntPtr()); + trace::Array *attrib_array = dynamic_cast(&call.arg(3)); + glws::Profile profile; + + switch (current_api) { + case EGL_OPENGL_API: + profile = glws::PROFILE_COMPAT; + break; + case EGL_OPENGL_ES_API: + default: + profile = glws::PROFILE_ES1; + if (attrib_array) { + for (int i = 0; i < attrib_array->values.size(); i += 2) { + int v = attrib_array->values[i]->toSInt(); + if (v == EGL_CONTEXT_CLIENT_VERSION) { + v = attrib_array->values[i + 1]->toSInt(); + if (v == 2) + profile = glws::PROFILE_ES2; + break; + } + } + } + break; + } + + + glws::Context *context = glws::createContext(glretrace::visual[profile], share_context, profile); + if (!context) { + const char *name; + switch (profile) { + case glws::PROFILE_COMPAT: + name = "OpenGL"; + break; + case glws::PROFILE_ES1: + name = "OpenGL ES 1.1"; + break; + case glws::PROFILE_ES2: + name = "OpenGL ES 2.0"; + break; + default: + name = "unknown"; + break; + } + + retrace::warning(call) << "Failed to create " << name << " context.\n"; + os::abort(); + } - glws::Context *context = glws::createContext(glretrace::visual, share_context); context_map[orig_context] = context; + profile_map[orig_config] = profile; + last_profile = profile; } static void retrace_eglDestroyContext(trace::Call &call) { @@ -153,7 +238,7 @@ static void retrace_eglMakeCurrent(trace::Call &call) { static void retrace_eglSwapBuffers(trace::Call &call) { frame_complete(call); - if (double_buffer) { + if (double_buffer && drawable) { drawable->swapBuffers(); } else { glFlush(); @@ -170,7 +255,7 @@ const retrace::Entry glretrace::egl_callbacks[] = { {"eglChooseConfig", &retrace::ignore}, {"eglGetConfigAttrib", &retrace::ignore}, {"eglCreateWindowSurface", &retrace_eglCreateWindowSurface}, - //{"eglCreatePbufferSurface", &retrace::ignore}, + {"eglCreatePbufferSurface", &retrace_eglCreatePbufferSurface}, //{"eglCreatePixmapSurface", &retrace::ignore}, {"eglDestroySurface", &retrace_eglDestroySurface}, {"eglQuerySurface", &retrace::ignore},