From: Stanislav Vorobiov Date: Fri, 29 Jun 2012 13:28:21 +0000 (+0400) Subject: eglGetDisplay now returns the same display handle for every call. X-Git-Tag: TizenStudio_2.0_p2.3~1273^2~77 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8cc2e6f6c37665b2e7ae21c090004b5810731c8d;p=sdk%2Femulator%2Fqemu.git eglGetDisplay now returns the same display handle for every call. Fixed races in gles. Replaced unpack alignment with pack/unpack alignment. --- diff --git a/hw/gles2.c b/hw/gles2.c index 00928a7..82cbcf8 100644 --- a/hw/gles2.c +++ b/hw/gles2.c @@ -535,6 +535,7 @@ void *gles2_init(CPUArchState *env) s->env = env; s->abi = gles2_abi_arm_hardfp; s->quality = gles2_quality; + pthread_mutex_init(&s->m, NULL); GLES2_PRINT("GLES2 quality: %d\n", s->quality); @@ -593,6 +594,7 @@ gles2_ebo* gles2_ebo_find(unsigned int name, gles2_ebo* list) gles2_ebo* gles2_ebo_add(unsigned int name, gles2_ebo* list) { gles2_ebo* ebo = malloc(sizeof(gles2_ebo)); + memset(ebo, 0, sizeof(*ebo)); ebo->name = name; ebo->data = NULL; ebo->next = NULL; diff --git a/hw/gles2.h b/hw/gles2.h index e653bec..76af97f 100644 --- a/hw/gles2.h +++ b/hw/gles2.h @@ -250,6 +250,7 @@ struct gles2_State MemoryRegion io_egl; MemoryRegion io_es11; MemoryRegion io_es20; + pthread_mutex_t m; }; #if(GLES2_DEBUG==1) diff --git a/hw/gles2_egl_calls.c b/hw/gles2_egl_calls.c index d29c7b7..5db62ad 100644 --- a/hw/gles2_egl_calls.c +++ b/hw/gles2_egl_calls.c @@ -108,9 +108,23 @@ GLES2_CB(eglGetDisplay) GLES2_PRINT("\tGot host display %p...\n", dpy); GLES2_BARRIER_RET; - gles2_ret_TEGLDisplay(s, gles2_handle_create(s, dpy)); - dpy_updatecaption(get_displaystate()); + pthread_mutex_lock(&s->m); + + uint32_t handle = gles2_handle_find(s, dpy); + + if (!handle) + { + handle = gles2_handle_create(s, dpy); + gles2_ret_TEGLDisplay(s, handle); + dpy_updatecaption(get_displaystate()); + } + else + { + gles2_ret_TEGLDisplay(s, handle); + } + + pthread_mutex_unlock(&s->m); } GLES2_CB(eglInitialize) @@ -119,16 +133,20 @@ GLES2_CB(eglInitialize) GLES2_ARG(Tptr, majorp); GLES2_ARG(Tptr, minorp); - GLES2_BARRIER_ARG_NORET; + GLES2_BARRIER_ARG; + + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); + pthread_mutex_unlock(&s->m); + GLES2_PRINT("Request to initialize display %p...\n", dpy); EGLint major, minor; if (eglInitialize(dpy, &major, &minor)) { GLES2_PRINT("Display initialized (EGL %d.%d)!\n", major, minor); - //GLES2_BARRIER_RET; + GLES2_BARRIER_RET; gles2_put_TEGLint(s, majorp, major); gles2_put_TEGLint(s, minorp, minor); gles2_ret_TEGLBoolean(s, EGL_TRUE); @@ -136,7 +154,7 @@ GLES2_CB(eglInitialize) } GLES2_PRINT("Failed to initialize...\n"); - //GLES2_BARRIER_RET; + GLES2_BARRIER_RET; gles2_ret_TEGLBoolean(s, EGL_FALSE); } @@ -149,8 +167,12 @@ GLES2_CB(eglGetConfigs) GLES2_BARRIER_ARG; + pthread_mutex_lock(&s->m); + EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); + pthread_mutex_unlock(&s->m); + EGLConfig* configs = configsp ? malloc(sizeof(EGLConfig)*config_size) : NULL; EGLint num_config; @@ -160,6 +182,7 @@ GLES2_CB(eglGetConfigs) if (configs) { EGLint i; + pthread_mutex_lock(&s->m); for (i = 0; i < num_config; ++i) { uint32_t handle; if (!(handle = gles2_handle_find(s, configs[i]))) { @@ -167,6 +190,7 @@ GLES2_CB(eglGetConfigs) } gles2_put_TEGLConfig(s, configsp + i*sizeof(TEGLConfig), handle); } + pthread_mutex_unlock(&s->m); free(configs); } @@ -199,18 +223,24 @@ GLES2_CB(eglChooseConfig) } attrib_list[attrib_list_n] = EGL_NONE; + pthread_mutex_lock(&s->m); + EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - GLES2_BARRIER_ARG_NORET; + pthread_mutex_unlock(&s->m); + + GLES2_BARRIER_ARG; EGLConfig* configs = configsp ? malloc(sizeof(EGLConfig)*config_size) : NULL; EGLint num_config; EGLBoolean ret = eglChooseConfig(dpy, attrib_list, configs, config_size, &num_config); free(attrib_list); - //GLES2_BARRIER_RET; + GLES2_BARRIER_RET; if (configs) { EGLint i; + pthread_mutex_lock(&s->m); + for (i = 0; i < num_config; ++i) { uint32_t handle; if (!(handle = gles2_handle_find(s, configs[i]))) { @@ -219,6 +249,8 @@ GLES2_CB(eglChooseConfig) gles2_put_TEGLConfig(s, configsp + i*sizeof(TEGLConfig), handle); } + pthread_mutex_unlock(&s->m); + free(configs); } gles2_put_TEGLint(s, num_configp, num_config); @@ -234,12 +266,15 @@ GLES2_CB(eglGetConfigAttrib) GLES2_ARG(Tptr, valuep); GLES2_BARRIER_ARG; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); EGLint value; EGLBoolean ret = eglGetConfigAttrib(dpy, gles2_handle_get(s, config), attribute, &value); + pthread_mutex_unlock(&s->m); + GLES2_BARRIER_RET; gles2_put_TEGLint(s, valuep, value); @@ -253,9 +288,13 @@ GLES2_CB(eglCreateWindowSurface) GLES2_ARG(Tptr, winp); GLES2_ARG(Tptr, attrib_listp); + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); + + pthread_mutex_unlock(&s->m); + (void)attrib_listp; gles2_Surface* fsurf; @@ -268,6 +307,8 @@ GLES2_CB(eglCreateWindowSurface) return; } + memset(fsurf, 0, sizeof(*fsurf)); + fsurf->id = surf_id++; fsurf->ddrawp = winp; @@ -299,7 +340,11 @@ GLES2_CB(eglCreateWindowSurface) GLES2_PRINT("Created at %p!\n", fsurf); GLES2_BARRIER_RET; gles2_transfer_compile(&fsurf->tfr, s, fsurf->pixelsp, nbytes); + pthread_mutex_lock(&s->m); + gles2_ret_TEGLSurface(s, gles2_handle_create(s, fsurf)); + + pthread_mutex_unlock(&s->m); } GLES2_CB(eglCreatePixmapSurface) @@ -309,8 +354,13 @@ GLES2_CB(eglCreatePixmapSurface) GLES2_ARG(Tptr, pixmapp); GLES2_ARG(Tptr, attrib_listp); + pthread_mutex_lock(&s->m); + EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); + + pthread_mutex_unlock(&s->m); + (void)attrib_listp; gles2_Surface* fsurf; @@ -323,6 +373,8 @@ GLES2_CB(eglCreatePixmapSurface) return; } + memset(fsurf, 0, sizeof(*fsurf)); + fsurf->id = surf_id++; fsurf->ddrawp = pixmapp; fsurf->pixmap = 1; @@ -354,7 +406,9 @@ GLES2_CB(eglCreatePixmapSurface) GLES2_PRINT("Created at %p!\n", fsurf); GLES2_BARRIER_RET; gles2_transfer_compile(&fsurf->tfr, s, fsurf->pixelsp, nbytes); + pthread_mutex_lock(&s->m); gles2_ret_TEGLSurface(s, gles2_handle_create(s, fsurf)); + pthread_mutex_unlock(&s->m); } GLES2_CB(eglCreatePbufferSurface) @@ -363,8 +417,10 @@ GLES2_CB(eglCreatePbufferSurface) GLES2_ARG(TEGLConfig, config_); GLES2_ARG(Tptr, attrib_listp); + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); + pthread_mutex_unlock(&s->m); EGLint attrib_list_n = 0; while (gles2_get_TEGLint(s, attrib_listp + attrib_list_n*sizeof(EGLint)) != EGL_NONE) { @@ -389,6 +445,8 @@ GLES2_CB(eglCreatePbufferSurface) return; } + memset(fsurf, 0, sizeof(*fsurf)); + fsurf->id = surf_id++; fsurf->ddrawp = 0; @@ -407,7 +465,9 @@ GLES2_CB(eglCreatePbufferSurface) GLES2_PRINT("Created at %p!\n", fsurf); GLES2_BARRIER_RET; + pthread_mutex_lock(&s->m); gles2_ret_TEGLSurface(s, gles2_handle_create(s, fsurf)); + pthread_mutex_unlock(&s->m); } GLES2_CB(eglDestroySurface) @@ -416,9 +476,11 @@ GLES2_CB(eglDestroySurface) GLES2_ARG(TEGLSurface, surface_); GLES2_BARRIER_ARG_NORET; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); gles2_Surface* fsurf = (EGLSurface)gles2_handle_get(s, surface_); gles2_handle_free(s, surface_); + pthread_mutex_unlock(&s->m); GLES2_PRINT("Destroyed surface ID = %d...\n", fsurf->id); fsurf->id = -1; @@ -440,8 +502,10 @@ GLES2_CB(eglBindTexImage) GLES2_ARG(TEGLint, buffer); gles2_CompiledTransfer tfr; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); gles2_Surface* fsurf = (gles2_Surface*)gles2_handle_get(s, surface_); + pthread_mutex_unlock(&s->m); // FIXME: Not a very clean way.. uint32_t pixelsp = gles2_get_dword(s, fsurf->ddrawp + 4*sizeof(uint32_t)); @@ -475,8 +539,10 @@ GLES2_CB(eglReleaseTexImage) GLES2_ARG(TEGLint, buffer); GLES2_BARRIER_ARG; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); gles2_Surface* fsurf = (gles2_Surface*)gles2_handle_get(s, surface_); + pthread_mutex_unlock(&s->m); GLES2_PRINT("Unbinding surface ID = %d!\n", fsurf->id); @@ -491,11 +557,12 @@ GLES2_CB(eglCreateContext) GLES2_ARG(TEGLConfig, config_); GLES2_ARG(TEGLContext, share_context_); GLES2_ARG(Tptr, attrib_listp); - GLES2_BARRIER_ARG; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); gles2_Context* share_context = gles2_handle_get(s, share_context_); + pthread_mutex_unlock(&s->m); EGLint *attribs= NULL; @@ -516,7 +583,7 @@ GLES2_CB(eglCreateContext) + i*sizeof(EGLint)); } } - + GLES2_BARRIER_ARG; GLES2_PRINT("Host context creation requested...\n"); EGLContext hctx = eglCreateContext(dpy, config, share_context?share_context->hctx:NULL, attribs); GLES2_BARRIER_RET; @@ -527,6 +594,7 @@ GLES2_CB(eglCreateContext) gles2_ret_TEGLContext(s, 0); } else { gles2_Context * ctx = malloc(sizeof(gles2_Context)); + memset(ctx, 0, sizeof(*ctx)); ctx->hctx = hctx; int version = 1; //if OpenGL ES check for client version from attrib_list @@ -556,8 +624,11 @@ GLES2_CB(eglCreateContext) ctx->ebo_list->next = NULL; if (attribs) free(attribs); + memset(ctx->ebo_list, 0, sizeof(*ctx->ebo_list)); GLES2_PRINT("Created at %p!\n", ctx); + pthread_mutex_lock(&s->m); gles2_ret_TEGLContext(s, gles2_handle_create(s, ctx)); + pthread_mutex_unlock(&s->m); } } @@ -567,6 +638,7 @@ GLES2_CB(eglDestroyContext) GLES2_ARG(TEGLContext, ctx_); GLES2_BARRIER_ARG; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); gles2_Context* ctx = (gles2_Context*) gles2_handle_get(s, ctx_); EGLBoolean ret = eglDestroyContext(dpy, ctx->hctx); @@ -578,6 +650,7 @@ GLES2_CB(eglDestroyContext) gles2_handle_free(s, ctx_); GLES2_PRINT("Destroyed %p!\n", ctx); } + pthread_mutex_unlock(&s->m); GLES2_BARRIER_RET; gles2_ret_TEGLBoolean(s,ret); @@ -591,10 +664,21 @@ GLES2_CB(eglMakeCurrent) GLES2_ARG(TEGLContext, ctx_); GLES2_BARRIER_ARG; + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); gles2_Surface* draw = (EGLSurface)gles2_handle_get(s, draw_); gles2_Surface* read = (EGLSurface)gles2_handle_get(s, read_); gles2_Context* ctx = (gles2_Context*)gles2_handle_get(s, ctx_); + pthread_mutex_unlock(&s->m); + + if (!dpy) + { + /* + * Evas sets 'dpy' to NULL and calls this function after it + * destroys a context + */ + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + } GLES2_PRINT("Making host context current...\n"); @@ -623,11 +707,7 @@ GLES2_CB(eglMakeCurrent) } int i; for (i = 0; i < ctx->narrays; ++i) { - ctx->arrays[i].type = GL_NONE; - ctx->arrays[i].enabled = 0; - ctx->arrays[i].ptr = 0; - ctx->arrays[i].apply = 0; - ctx->arrays[i].tptr = 0; + memset(&ctx->arrays[i], 0, sizeof(ctx->arrays[i])); } } } @@ -645,8 +725,10 @@ GLES2_CB(eglSwapBuffers) GLES2_ARG(TEGLDisplay, dpy_); GLES2_ARG(TEGLSurface, surface_); + pthread_mutex_lock(&s->m); EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); gles2_Surface* fsurf = (EGLSurface)gles2_handle_get(s, surface_); + pthread_mutex_unlock(&s->m); if (!fsurf) { fprintf(stderr, "ERROR: Trying to swap NULL surface!\n"); GLES2_BARRIER_ARG; diff --git a/hw/gles2_escommon_calls.c b/hw/gles2_escommon_calls.c index 7e31424..3aafdfe 100644 --- a/hw/gles2_escommon_calls.c +++ b/hw/gles2_escommon_calls.c @@ -16,11 +16,11 @@ static unsigned gles2_glTexParameterCount(TGLenum pname) return count; } -static unsigned gles2_get_stride(unsigned width, unsigned bpp) +static unsigned gles2_get_stride(GLuint alignment_type, unsigned width, unsigned bpp) { unsigned alignment = 0; - hgl.glGetIntegerv(GL_UNPACK_ALIGNMENT, (GLint *)&alignment); + hgl.glGetIntegerv(alignment_type, (GLint *)&alignment); if (!alignment) { @@ -845,7 +845,7 @@ GLES2_CB(glReadPixels) GLES2_PRINT("Reading %dx%dx%d image at %d,%d...\n", width, height, bpp, x, y); - nbytes = height*gles2_get_stride(width, bpp); + nbytes = height*gles2_get_stride(GL_PACK_ALIGNMENT, width, bpp); pixels = malloc(nbytes); } hgl.glReadPixels(x, y, width, height, format, type, pixels); @@ -933,7 +933,7 @@ GLES2_CB(glTexImage2D) GLES2_PRINT("Uploading %dx%dx%d image...\n", width, height, bpp); char* pixels = NULL; if (pixelsp && width > 0 && height > 0) { - TGLsizei nbytes = height*gles2_get_stride(width, bpp); + TGLsizei nbytes = height*gles2_get_stride(GL_UNPACK_ALIGNMENT, width, bpp); pixels = malloc(nbytes); gles2_transfer(s, pixelsp, nbytes, pixels, 0); } @@ -1039,7 +1039,7 @@ GLES2_CB(glTexSubImage2D) char *pixels = NULL; if (pixelsp && width > 0 && height > 0) { - TGLsizei nbytes = height*gles2_get_stride(width, bpp); + TGLsizei nbytes = height*gles2_get_stride(GL_UNPACK_ALIGNMENT, width, bpp); pixels = malloc(nbytes); gles2_transfer(s, pixelsp, nbytes, pixels, 0); } diff --git a/hw/gles2_kernel_calls.c b/hw/gles2_kernel_calls.c index 0b2a425..e995be9 100644 --- a/hw/gles2_kernel_calls.c +++ b/hw/gles2_kernel_calls.c @@ -48,6 +48,7 @@ GLES2_CB(init) GLES2_PRINT("Selected ABI %d\n", s->abi); client = malloc(sizeof(*client)); + memset(client, 0, sizeof(*client)); client->s = s; client->nr = i + 1; client->rendering_api = EGL_OPENGL_ES_API;