EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { CLIENT_THREAD_STATE_T *thread; CLIENT_PROCESS_STATE_T *process; EGLBoolean result; if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) { if (!value) { thread->error = EGL_BAD_PARAMETER; result = EGL_FALSE; } else if (egl_config_to_id(config) < 0 || egl_config_to_id(config) >= EGL_MAX_CONFIGS) { thread->error = EGL_BAD_CONFIG; result = EGL_FALSE; } else if (!egl_config_get_attrib(egl_config_to_id(config), attribute, value)) { thread->error = EGL_BAD_ATTRIBUTE; result = EGL_FALSE; } else { thread->error = EGL_SUCCESS; result = EGL_TRUE; } CLIENT_UNLOCK(); } else result = EGL_FALSE; return result; }
EGLAPI void EGLAPIENTRY eglGetDriverMonitorXMLBRCM(EGLDisplay dpy, EGLint bufSize, EGLint *length, char *xmlStats) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { if (process->driver_monitor_inited && xmlStats != NULL) { RPC_CALL2_OUT_BULK(eglGetDriverMonitorXMLBRCM_impl, thread, EGLGETDRIVERMONITORXMLBRCM_ID, bufSize, xmlStats); if (length != NULL) *length = strlen(xmlStats); } } } CLIENT_UNLOCK(); }
EGLAPI EGLBoolean EGLAPIENTRY eglTermDriverMonitorBRCM(EGLDisplay dpy) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLBoolean result; CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { egl_driver_monitor_term(process); thread->error = EGL_SUCCESS; result = EGL_TRUE; } else result = EGL_FALSE; } CLIENT_UNLOCK(); return result; }
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { CLIENT_THREAD_STATE_T *thread; CLIENT_PROCESS_STATE_T *process; EGLBoolean result; if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) { if (!num_config) { thread->error = EGL_BAD_PARAMETER; result = EGL_FALSE; } else if (!configs) { thread->error = EGL_SUCCESS; *num_config = EGL_MAX_CONFIGS; result = EGL_TRUE; } else { int i; for (i = 0; i < EGL_MAX_CONFIGS && i < config_size; i++) configs[i] = egl_config_from_id(i); thread->error = EGL_SUCCESS; *num_config = i; result = EGL_TRUE; } CLIENT_UNLOCK(); } else result = EGL_FALSE; return result; }
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR _sync) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLBoolean result; CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { EGL_SYNC_T *sync = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)_sync); if (sync) { thread->error = EGL_SUCCESS; khrn_pointer_map_delete(&process->syncs, (uint32_t)(uintptr_t)_sync); egl_sync_term(sync); khrn_platform_free(sync); } else thread->error = EGL_BAD_PARAMETER; result = (thread->error == EGL_SUCCESS ? EGL_TRUE : EGL_FALSE); } else { result = EGL_FALSE; } } CLIENT_UNLOCK(); return result; }
static bool check_global_image_egl_image(GLuint global_image_id[2], GLeglImageOES image, CLIENT_THREAD_STATE_T *thread, bool render) /* else texture */ { CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE(); uint64_t id; uint32_t format, width, height; CLIENT_LOCK(); id = process->inited ? khrn_global_image_map_lookup(&process->global_image_egl_images, (uint32_t)(uintptr_t)image) : 0; CLIENT_UNLOCK(); if (!id) { return false; } global_image_id[0] = (GLuint)id; global_image_id[1] = (GLuint)(id >> 32); platform_get_global_image_info(global_image_id[0], global_image_id[1], &format, &width, &height); if (!(format & ((thread->opengl.context->type == OPENGL_ES_11) ? (render ? EGL_PIXEL_FORMAT_RENDER_GLES_BRCM : EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM) : (render ? EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM : EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM))) || (width == 0) || (height == 0)) { return false; } /* format and max width/height checks done on server */ return true; }
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surf, const EGLint *attrib_list) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLBoolean result; CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (!process) result = 0; else { EGL_SURFACE_T *surface = client_egl_get_surface(thread, process, surf); if (surface) { bool preserve_pixels = false; uint32_t lock_usage_hint = EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR; /* we completely ignore this */ assert(!surface->is_locked); if (!lock_surface_check_attribs(attrib_list, &preserve_pixels, &lock_usage_hint)) { thread->error = EGL_BAD_ATTRIBUTE; result = EGL_FALSE; } else if (!egl_config_is_lockable((int)(intptr_t)surface->config - 1)) { /* Only lockable surfaces can be locked (obviously) */ thread->error = EGL_BAD_ACCESS; result = EGL_FALSE; } else if (surface->context_binding_count) { /* Cannot lock a surface if it is bound to a context */ thread->error = EGL_BAD_ACCESS; result = EGL_FALSE; } else if (preserve_pixels) { /* TODO: we don't need to support this. What error should we return? */ thread->error = EGL_BAD_ATTRIBUTE; return EGL_FALSE; } else { /* Don't allocate the buffer here. This happens during "mapping", in eglQuerySurface. */ surface->mapped_buffer = 0; surface->is_locked = true; thread->error = EGL_SUCCESS; result = EGL_TRUE; } } else result = EGL_FALSE; } } CLIENT_UNLOCK(); return result; }
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLSyncKHR result = EGL_NO_SYNC_KHR; UNUSED(type); CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); EGLint condition; EGLint threshold; if (process) { if (1) thread->error = EGL_BAD_ATTRIBUTE; else if (egl_sync_check_attribs(attrib_list, &condition, &threshold)) { EGL_SYNC_T *sync = egl_sync_create((EGLSyncKHR)(size_t)process->next_sync, condition, threshold); if (sync) { if (khrn_pointer_map_insert(&process->syncs, process->next_sync, sync)) { thread->error = EGL_SUCCESS; result = (EGLSurface)(size_t)process->next_sync++; } else { thread->error = EGL_BAD_ALLOC; egl_sync_term(sync); khrn_platform_free(sync); } } else thread->error = EGL_BAD_ALLOC; } } } CLIENT_UNLOCK(); return result; }
EGLAPI EGLBoolean EGLAPIENTRY eglInitDriverMonitorBRCM(EGLDisplay dpy, EGLint hw_bank, EGLint l3c_bank) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLBoolean result; CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { if (!process->driver_monitor_inited) process->driver_monitor_inited = RPC_BOOLEAN_RES(RPC_CALL2_RES(eglInitDriverMonitorBRCM_impl, thread, EGLINITDRIVERMONITORBRCM_ID, hw_bank, l3c_bank)); if (process->driver_monitor_inited) { thread->error = EGL_SUCCESS; result = EGL_TRUE; } else { thread->error = EGL_BAD_ALLOC; result = EGL_FALSE; } } else result = EGL_FALSE; } CLIENT_UNLOCK(); return result; }
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR _sync, EGLint attribute, EGLint *value) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLBoolean result = EGL_FALSE; CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { if (value) { EGL_SYNC_T *sync = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)_sync); if (sync) { if (egl_sync_get_attrib(sync, attribute, value)) { thread->error = EGL_SUCCESS; result = EGL_TRUE; } else thread->error = EGL_BAD_ATTRIBUTE; } else thread->error = EGL_BAD_PARAMETER; } else { thread->error = EGL_BAD_PARAMETER; } } } CLIENT_UNLOCK(); return result; }
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig_inner(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config, bool sane) { CLIENT_THREAD_STATE_T *thread; CLIENT_PROCESS_STATE_T *process; EGLBoolean result; if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) { if (!num_config) { thread->error = EGL_BAD_PARAMETER; result = EGL_FALSE; } else { /* check for invalid attributes, and find color components for which we have expressed a preference */ bool use_red = false; bool use_green = false; bool use_blue = false; bool use_alpha = false; if (!egl_config_check_attribs(attrib_list, &use_red, &use_green, &use_blue, &use_alpha)) { thread->error = EGL_BAD_ATTRIBUTE; result = EGL_FALSE; } else { /* sort configs */ int ids[EGL_MAX_CONFIGS]; int i, j; for (i = 0; i < EGL_MAX_CONFIGS; i++) ids[i] = i; // egl_config_sort(ids, use_red, use_green, use_blue, use_alpha); egl_config_sort(ids, !sane && use_red, !sane && use_green, !sane && use_blue, !sane && use_alpha); /* return configs */ j = 0; for (i = 0; i < EGL_MAX_CONFIGS; i++) { if (egl_config_filter(ids[i], attrib_list)) { if (configs && j < config_size) { configs[j] = egl_config_from_id(ids[i]); j++; } else if (!configs) { // If configs==NULL then we count all configs // Otherwise we only count the configs we return j++; } } } thread->error = EGL_SUCCESS; *num_config = j; result = EGL_TRUE; } } CLIENT_UNLOCK(); } else result = EGL_FALSE; return result; }
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surf) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGLBoolean result; CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (!process) result = 0; else { EGL_SURFACE_T *surface = client_egl_get_locked_surface(thread, process, surf); if (!surface) { result = EGL_FALSE; } else if (!surface->is_locked) { thread->error = EGL_BAD_ACCESS; result = EGL_FALSE; } else { assert(surface->is_locked); if (surface->mapped_buffer) { KHRN_IMAGE_FORMAT_T format = egl_config_get_mapped_format((int)(intptr_t)surface->config - 1); uint32_t stride = khrn_image_get_stride(format, surface->width); int lines, offset, height; lines = KHDISPATCH_WORKSPACE_SIZE / stride; offset = 0; height = surface->height; while (height > 0) { int batch = _min(lines, height); #ifndef RPC_DIRECT uint32_t len = batch * stride; #endif RPC_CALL7_IN_BULK(eglIntSetColorData_impl, EGLINTSETCOLORDATA_ID, surface->serverbuffer, format, surface->width, batch, stride, offset, (const char *)surface->mapped_buffer + offset * stride, len); offset += batch; height -= batch; } khrn_platform_free(surface->mapped_buffer); } surface->mapped_buffer = 0; surface->is_locked = false; thread->error = EGL_SUCCESS; result = EGL_TRUE; } } } CLIENT_UNLOCK(); return result; }
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR _sync, EGLint flags, EGLTimeKHR timeout) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); UNUSED(timeout); CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { EGL_SYNC_T *sync = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)_sync); if (sync) { #ifdef __SYMBIAN32__ //At present store semaphore Id in name so no need to call create again (not available in this platform) if(1) { #else PLATFORM_SEMAPHORE_T semaphore; if( khronos_platform_semaphore_create(&semaphore, sync->sem, 1) == KHR_SUCCESS) { #endif if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) RPC_FLUSH(); CLIENT_UNLOCK(); #ifdef __SYMBIAN32__ khronos_platform_semaphore_acquire_and_release(&sync->master); #else khronos_platform_semaphore_acquire(&semaphore); khronos_platform_semaphore_release(&semaphore); khronos_platform_semaphore_destroy(&semaphore); #endif return EGL_CONDITION_SATISFIED_KHR; } else thread->error = EGL_BAD_ALLOC; // not strictly allowed by the spec, but indicates that we failed to create a reference to the named semaphore } else thread->error = EGL_BAD_PARAMETER; } } CLIENT_UNLOCK(); return EGL_FALSE; } EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR _sync, EGLenum mode) { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); UNUSED(mode); CLIENT_LOCK(); { CLIENT_PROCESS_STATE_T *process = client_egl_get_process_state(thread, dpy, EGL_TRUE); if (process) { EGL_SYNC_T *sync = (EGL_SYNC_T *)khrn_pointer_map_lookup(&process->syncs, (uint32_t)(size_t)_sync); if (sync) thread->error = EGL_BAD_MATCH; else thread->error = EGL_BAD_PARAMETER; } } CLIENT_UNLOCK(); return EGL_FALSE; }