char *strcpy_safe(char *pDst, uint32_t dst_len, const char *pSrc) { VOGL_ASSERT(pDst && pSrc && dst_len); if (!dst_len) return pDst; char *pCur_dst = pDst; char c; do { if (dst_len == 1) { *pCur_dst++ = '\0'; break; } c = *pSrc++; *pCur_dst++ = c; dst_len--; } while (c); VOGL_ASSERT((pCur_dst - pDst) <= (int)dst_len); return pDst; }
bool task_pool::init(uint num_threads) { VOGL_ASSERT(num_threads <= cMaxThreads); num_threads = math::minimum<uint>(num_threads, cMaxThreads); deinit(); bool succeeded = true; m_num_threads = 0; while (m_num_threads < num_threads) { m_threads[m_num_threads] = (HANDLE)_beginthreadex(NULL, 32768, thread_func, this, 0, NULL); VOGL_ASSERT(m_threads[m_num_threads] != 0); if (!m_threads[m_num_threads]) { succeeded = false; break; } m_num_threads++; } if (!succeeded) { deinit(); return false; } return true; }
void QTextureViewer::setTexture(const vogl::ktx_texture* pTexture, uint baseMipLevel, uint maxMipLevel) { m_mipmappedTexture.clear(); bool bStatus = m_mipmappedTexture.read_ktx(*pTexture); VOGL_ASSERT(bStatus); if (bStatus) { bStatus = m_mipmappedTexture.convert(vogl::PIXEL_FMT_A8R8G8B8, false, vogl::dxt_image::pack_params()); m_mipmappedTexture.unflip(true, true); VOGL_ASSERT(bStatus); } if (!bStatus) { return; } delete_pixmaps(); m_draw_enabled = true; m_pKtxTexture = pTexture; m_baseMipLevel = baseMipLevel; m_maxMipLevel = maxMipLevel; }
bool threaded_resampler::resample(const params &p) { free_contrib_lists(); m_pParams = &p; VOGL_ASSERT(m_pParams->m_src_width && m_pParams->m_src_height); VOGL_ASSERT(m_pParams->m_dst_width && m_pParams->m_dst_height); switch (p.m_fmt) { case cPF_Y_F32: m_bytes_per_pixel = 4; break; case cPF_RGBX_F32: case cPF_RGBA_F32: m_bytes_per_pixel = 16; break; default: VOGL_ASSERT(false); return false; } int filter_index = find_resample_filter(p.m_Pfilter_name); if (filter_index < 0) return false; const resample_filter &filter = g_resample_filters[filter_index]; m_pX_contribs = Resampler::make_clist(m_pParams->m_src_width, m_pParams->m_dst_width, m_pParams->m_boundary_op, filter.func, filter.support, p.m_filter_x_scale, p.m_x_ofs); if (!m_pX_contribs) return false; m_pY_contribs = Resampler::make_clist(m_pParams->m_src_height, m_pParams->m_dst_height, m_pParams->m_boundary_op, filter.func, filter.support, p.m_filter_y_scale, p.m_y_ofs); if (!m_pY_contribs) return false; if (!m_tmp_img.try_resize(m_pParams->m_dst_width * m_pParams->m_src_height)) return false; for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++) m_pTask_pool->queue_object_task(this, &threaded_resampler::resample_x_task, i, NULL); m_pTask_pool->join(); for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++) m_pTask_pool->queue_object_task(this, &threaded_resampler::resample_y_task, i, NULL); m_pTask_pool->join(); m_tmp_img.clear(); free_contrib_lists(); return true; }
// TODO: Requires GL >= 3.2 or extension GL_ARB_sync bool vogl_sync_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target) { VOGL_FUNC_TRACER VOGL_NOTE_UNUSED(context_info); VOGL_NOTE_UNUSED(target); VOGL_NOTE_UNUSED(remapper); VOGL_CHECK_GL_ERROR; clear(); m_snapshot_handle = handle; GLsync sync = vogl_handle_to_sync(handle); bool any_gl_errors = false; #define GET_INT(pname) \ do \ { \ GLint val = 0; \ GLsizei len = 0; \ GL_ENTRYPOINT(glGetSynciv)(sync, pname, sizeof(val), &len, &val); \ if (vogl_check_gl_error()) \ any_gl_errors = true; \ m_params.insert(pname, 0, &val, sizeof(val)); \ } while (0) GET_INT(GL_OBJECT_TYPE); GET_INT(GL_SYNC_STATUS); GET_INT(GL_SYNC_CONDITION); GET_INT(GL_SYNC_FLAGS); #undef GET_INT if (any_gl_errors) { clear(); vogl_error_printf("%s: GL error while enumerating sync %" PRIu64 "'s' params\n", VOGL_METHOD_NAME, (uint64_t)handle); return false; } VOGL_ASSERT(m_params.get_value<GLenum>(GL_OBJECT_TYPE) == GL_SYNC_FENCE); VOGL_ASSERT(m_params.get_value<GLenum>(GL_SYNC_CONDITION) == GL_SYNC_GPU_COMMANDS_COMPLETE); VOGL_ASSERT(m_params.get_value<uint>(GL_SYNC_FLAGS) == 0); m_is_valid = true; return true; }
static void lock_heap() { VOGL_ASSERT(g_pHeap); #ifndef _MSC_VER pthread_mutex_lock(&g_mutex); #else ::EnterCriticalSection( &g_mutex ); #endif VOGL_ASSERT(!g_allocating_flag); g_allocating_flag = true; }
semaphore::semaphore(uint32 initialCount, uint32 maximumCount, const char *pName) { VOGL_NOTE_UNUSED(maximumCount); VOGL_NOTE_UNUSED(pName); VOGL_ASSERT(maximumCount >= initialCount); VOGL_ASSERT(maximumCount >= 1); if (sem_init(&m_sem, 0, initialCount)) { VOGL_FAIL("semaphore: sem_init() failed"); } }
//---------------------------------------------------------------------------------------------------------------------- // Function vogl_does_entrypoint_refer_to_namespace //---------------------------------------------------------------------------------------------------------------------- bool vogl_does_entrypoint_refer_to_namespace(gl_entrypoint_id_t entrypoint_id, vogl_namespace_t namespace_id) { VOGL_ASSERT(entrypoint_id < VOGL_NUM_ENTRYPOINTS); VOGL_ASSERT(namespace_id < VOGL_TOTAL_NAMESPACES); const gl_entrypoint_desc_t &desc = g_vogl_entrypoint_descs[entrypoint_id]; if (desc.m_return_namespace == namespace_id) return true; for (uint32_t i = 0; i < desc.m_num_params; i++) if (g_vogl_entrypoint_param_descs[entrypoint_id][i].m_namespace == namespace_id) return true; return false; }
bool uint64_to_string(uint64_t value, char *pDst, uint32_t len) { VOGL_ASSERT(pDst); // really only 20 digits (plus \0 or 21), but whatever const uint32_t cBufSize = 32; char buf[cBufSize]; char *p = buf + cBufSize - 1; *p-- = '\0'; do { *p-- = static_cast<uint8_t>('0' + (value % 10U)); value /= 10U; } while (value); const size_t total_bytes = (buf + cBufSize - 1) - p; if (total_bytes > len) { if ((pDst) && (len)) *pDst = '\0'; return false; } for (size_t i = 0; i < total_bytes; i++) pDst[i] = p[1 + i]; return true; }
const char *get_vogl_format_string(vogl_format fmt) { switch (fmt) { case cCRNFmtDXT1: return "DXT1"; case cCRNFmtDXT3: return "DXT3"; case cCRNFmtDXT5: return "DXT5"; case cCRNFmtDXT5_CCxY: return "DXT5_CCxY"; case cCRNFmtDXT5_xGBR: return "DXT5_xGBR"; case cCRNFmtDXT5_AGBR: return "DXT5_AGBR"; case cCRNFmtDXT5_xGxR: return "DXT5_xGxR"; case cCRNFmtDXN_XY: return "DXN_XY"; case cCRNFmtDXN_YX: return "DXN_YX"; case cCRNFmtDXT5A: return "DXT5A"; case cCRNFmtETC1: return "ETC1"; default: break; } VOGL_ASSERT(false); return "?"; }
static DWORD get_alloc_flags_from_access(vogl::uint32 access_flags) { // Windows flags are specified here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx // It's not possible to write memory without also reading memory. This is true generally, but also windows doesn't // have a way to specify flags that would be 'write-only.' VOGL_ASSERT((access_flags & PLAT_WRITE) == 0 || (access_flags & PLAT_READ) != 0); // Windows flags for this are kinda dumb. DWORD ret_flags = 0; if ((access_flags & (PLAT_READ | PLAT_WRITE)) == (PLAT_READ | PLAT_WRITE)) { ret_flags |= PAGE_READWRITE; access_flags &= ~(PLAT_READ | PLAT_WRITE); } if ((access_flags & PLAT_READ) == PLAT_READ) { ret_flags |= PAGE_READONLY; access_flags &= ~PLAT_READ; } // If this fires, it means the code above needs to be updated to support the flag being passed in. VOGL_VERIFY(access_flags == 0); return ret_flags; }
// size_x/y should be odd void compute_gaussian_kernel(float *pDst, int size_x, int size_y, float sigma_sqr, uint flags) { VOGL_ASSERT(size_x & size_y & 1); if (!(size_x | size_y)) return; int mid_x = size_x / 2; int mid_y = size_y / 2; double sum = 0; for (int x = 0; x < size_x; x++) { for (int y = 0; y < size_y; y++) { float g; if ((x > mid_x) && (y < mid_y)) g = pDst[(size_x - x - 1) + y * size_x]; else if ((x < mid_x) && (y > mid_y)) g = pDst[x + (size_y - y - 1) * size_x]; else if ((x > mid_x) && (y > mid_y)) g = pDst[(size_x - x - 1) + (size_y - y - 1) * size_x]; else g = gauss(x - mid_x, y - mid_y, sigma_sqr); pDst[x + y * size_x] = g; sum += g; } } if (flags & cComputeGaussianFlagNormalizeCenterToOne) { sum = pDst[mid_x + mid_y * size_x]; } if (flags & (cComputeGaussianFlagNormalizeCenterToOne | cComputeGaussianFlagNormalize)) { double one_over_sum = 1.0f / sum; for (int i = 0; i < size_x * size_y; i++) pDst[i] = static_cast<float>(pDst[i] * one_over_sum); if (flags & cComputeGaussianFlagNormalizeCenterToOne) pDst[mid_x + mid_y * size_x] = 1.0f; } if (flags & cComputeGaussianFlagPrint) { printf("{\n"); for (int y = 0; y < size_y; y++) { printf(" "); for (int x = 0; x < size_x; x++) { printf("%f, ", pDst[x + y * size_x]); } printf("\n"); } printf("}"); } }
bool vogleditor_stateTreeStateVecMatrixRowItem::hasChanged() const { if (m_pDiffBaseState == NULL) { return false; } static float baseValues[16]; static float curValues[16]; VOGL_ASSERT(m_numComponents <= 16); if (m_pDiffBaseState->get<float>(m_name, m_index, baseValues, m_numComponents, m_isIndexed) && m_pState->get<float>(m_name, m_index, curValues, m_numComponents, m_isIndexed)) { for(unsigned int i = 0; i < 4; i++) { if (baseValues[i + (m_rowIndex*4)] != curValues[i + (m_rowIndex*4)]) { // one of the values has changed, so return early return true; } } } else { // the enum must have been added, so it is different return true; } return false; }
template <typename T> bool vogleditor_stateTreeDatatypeItem<T>::hasChanged() const { if (m_pDiffBaseState == NULL) return false; static T baseValues[4]; static T curValues[4]; VOGL_ASSERT(m_numComponents <= 4); bool bFoundInBase = m_pDiffBaseState->get<T>(m_name, m_index, baseValues, m_numComponents, m_isIndexed); bool bFoundInCurrent = m_pStateVec->get<T>(m_name, m_index, curValues, m_numComponents, m_isIndexed); if (bFoundInBase && bFoundInCurrent) { for (unsigned int i = 0; i < m_numComponents; i++) { if (baseValues[i] != curValues[i]) { // one of the values has changed, so return early return true; } } } if (bFoundInCurrent && !bFoundInBase) { // the enum must have been added, so it is different return true; } return false; }
bool string_ptr_to_bool(const char *&p, bool &value) { VOGL_ASSERT(p); value = false; if (vogl_stricmp(p, "false") == 0) { p += 5; return true; } if (vogl_stricmp(p, "true") == 0) { p += 4; value = true; return true; } uint32_t v; if (string_ptr_to_uint(p, v)) { if (!v) return true; else if (v == 1) { value = true; return true; } } return false; }
bool uint64_to_string_with_commas(uint64_t value, char *pDst, uint32_t len) { VOGL_ASSERT(pDst); const uint32_t cBufSize = 32; char buf[cBufSize]; char *p = buf + cBufSize - 1; *p-- = '\0'; uint32_t num_chars_until_comma = 3; do { if (!num_chars_until_comma) { *p-- = ','; num_chars_until_comma = 3; } *p-- = static_cast<uint8_t>('0' + (value % 10U)); num_chars_until_comma--; value /= 10U; } while (value); const size_t total_bytes = (buf + cBufSize - 1) - p; if (total_bytes > len) return false; for (size_t i = 0; i < total_bytes; i++) pDst[i] = p[1 + i]; return true; }
pixel_format convert_vogl_format_to_pixel_format(vogl_format fmt) { switch (fmt) { case cCRNFmtDXT1: return PIXEL_FMT_DXT1; case cCRNFmtDXT3: return PIXEL_FMT_DXT3; case cCRNFmtDXT5: return PIXEL_FMT_DXT5; case cCRNFmtDXT5_CCxY: return PIXEL_FMT_DXT5_CCxY; case cCRNFmtDXT5_xGxR: return PIXEL_FMT_DXT5_xGxR; case cCRNFmtDXT5_xGBR: return PIXEL_FMT_DXT5_xGBR; case cCRNFmtDXT5_AGBR: return PIXEL_FMT_DXT5_AGBR; case cCRNFmtDXN_XY: return PIXEL_FMT_DXN; case cCRNFmtDXN_YX: return PIXEL_FMT_3DC; case cCRNFmtDXT5A: return PIXEL_FMT_DXT5A; case cCRNFmtETC1: return PIXEL_FMT_ETC1; default: { VOGL_ASSERT(false); break; } } return PIXEL_FMT_INVALID; }
bool task_pool::init(uint num_threads) { VOGL_ASSERT(num_threads <= cMaxThreads); num_threads = math::minimum<uint>(num_threads, cMaxThreads); deinit(); bool succeeded = true; m_num_threads = 0; while (m_num_threads < num_threads) { int status = pthread_create(&m_threads[m_num_threads], NULL, thread_func, this); if (status) { succeeded = false; break; } m_num_threads++; } if (!succeeded) { deinit(); return false; } return true; }
uint vogleditor_QVertexArrayExplorer::set_vertexarray_objects(vogl_context_snapshot* pContext, vogl::vector<vogl_context_snapshot*> sharingContexts) { clear(); m_sharing_contexts = sharingContexts; uint vaoCount = 0; vogl_gl_object_state_ptr_vec vaoObjects; pContext->get_all_objects_of_category(cGLSTVertexArray, vaoObjects); vaoCount = vaoObjects.size(); for (vogl_gl_object_state_ptr_vec::iterator iter = vaoObjects.begin(); iter != vaoObjects.end(); iter++) { if ((*iter)->get_type() == cGLSTVertexArray) { vogl_vao_state* pState = static_cast<vogl_vao_state*>(*iter); QString valueStr; valueStr = valueStr.sprintf("VertexArray %" PRIu64 " - %u attributes", pState->get_snapshot_handle(), pState->get_vertex_attrib_count()); ui->vertexArrayComboBox->addItem(valueStr, QVariant::fromValue(pState)); } else { VOGL_ASSERT(!"Unhandled object type in vogleditor_QVertexArrayExplorer"); } } return vaoCount; }
void semaphore::release(uint32 releaseCount) { VOGL_ASSERT(releaseCount >= 1); int status = 0; #ifdef WIN32 if (1 == releaseCount) status = sem_post(&m_sem); else status = sem_post_multiple(&m_sem, releaseCount); #else while (releaseCount > 0) { status = sem_post(&m_sem); if (status) break; releaseCount--; } #endif if (status) { VOGL_FAIL("semaphore: sem_post() or sem_post_multiple() failed"); } }
bool vogl_renderbuffer_desc::snapshot(const vogl_context_info &context_info) { VOGL_FUNC_TRACER VOGL_ASSERT(context_info.get_version() >= VOGL_GL_VERSION_3_0); VOGL_NOTE_UNUSED(context_info); VOGL_CHECK_GL_ERROR; #define GET_STATE(e, x) \ do \ { \ GL_ENTRYPOINT(glGetRenderbufferParameteriv)(GL_RENDERBUFFER, e, reinterpret_cast<int *>(&x)); \ VOGL_CHECK_GL_ERROR; \ } while (0) GET_STATE(GL_RENDERBUFFER_WIDTH, m_width); GET_STATE(GL_RENDERBUFFER_HEIGHT, m_height); GET_STATE(GL_RENDERBUFFER_SAMPLES, m_samples); GET_STATE(GL_RENDERBUFFER_INTERNAL_FORMAT, m_internal_format); GET_STATE(GL_RENDERBUFFER_RED_SIZE, m_red_size); GET_STATE(GL_RENDERBUFFER_GREEN_SIZE, m_green_size); GET_STATE(GL_RENDERBUFFER_BLUE_SIZE, m_blue_size); GET_STATE(GL_RENDERBUFFER_ALPHA_SIZE, m_alpha_size); GET_STATE(GL_RENDERBUFFER_DEPTH_SIZE, m_depth_size); GET_STATE(GL_RENDERBUFFER_STENCIL_SIZE, m_stencil_size); #undef GET_STATE return true; }
spinlock::~spinlock() { #ifdef VOGL_BUILD_DEBUG VOGL_ASSERT(!m_in_lock); #endif pthread_spin_destroy(&m_spinlock); }
void vogl_display_list::end_gen() { VOGL_FUNC_TRACER VOGL_ASSERT(m_generating); m_generating = false; m_valid = true; }
void timer::stop() { VOGL_ASSERT(m_started); query_counter(&m_stop_time); m_stopped = true; }
dynamic_string::dynamic_string(const char *p, uint len) { VOGL_ASSERT(p); set_to_empty_small_string(); set_from_buf(p, len); }
//---------------------------------------------------------------------------------------------------------------------- // vogl_find_internal_texture_format //---------------------------------------------------------------------------------------------------------------------- const vogl_internal_tex_format *vogl_find_internal_texture_format(GLenum internal_format) { VOGL_FUNC_TRACER VOGL_ASSERT(get_internal_format_hash_map().size()); const vogl_internal_tex_format **ppFmt = get_internal_format_hash_map().find_value(internal_format); return ppFmt ? *ppFmt : NULL; }
vogl_format convert_pixel_format_to_best_vogl_format(pixel_format vogl_fmt) { vogl_format fmt = cCRNFmtDXT1; switch (vogl_fmt) { case PIXEL_FMT_DXT1: case PIXEL_FMT_DXT1A: fmt = cCRNFmtDXT1; break; case PIXEL_FMT_DXT2: case PIXEL_FMT_DXT3: case PIXEL_FMT_DXT4: case PIXEL_FMT_DXT5: fmt = cCRNFmtDXT5; break; case PIXEL_FMT_3DC: fmt = cCRNFmtDXN_YX; break; case PIXEL_FMT_DXN: fmt = cCRNFmtDXN_XY; break; case PIXEL_FMT_DXT5A: fmt = cCRNFmtDXT5A; break; case PIXEL_FMT_R8G8B8: case PIXEL_FMT_L8: fmt = cCRNFmtDXT1; break; case PIXEL_FMT_A8R8G8B8: case PIXEL_FMT_A8: case PIXEL_FMT_A8L8: fmt = cCRNFmtDXT5; break; case PIXEL_FMT_DXT5_CCxY: fmt = cCRNFmtDXT5_CCxY; break; case PIXEL_FMT_DXT5_xGBR: fmt = cCRNFmtDXT5_xGBR; break; case PIXEL_FMT_DXT5_AGBR: fmt = cCRNFmtDXT5_AGBR; break; case PIXEL_FMT_DXT5_xGxR: fmt = cCRNFmtDXT5_xGxR; break; case PIXEL_FMT_ETC1: fmt = cCRNFmtETC1; break; default: { VOGL_ASSERT(false); break; } } return fmt; }
bool vogl_vao_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target) { VOGL_FUNC_TRACER VOGL_NOTE_UNUSED(target); VOGL_NOTE_UNUSED(remapper); VOGL_CHECK_GL_ERROR; clear(); VOGL_ASSERT(handle <= cUINT32_MAX); m_snapshot_handle = static_cast<GLuint>(handle); // TODO: Core profile support m_has_been_bound = handle ? (GL_ENTRYPOINT(glIsVertexArray)(static_cast<GLuint>(handle)) != 0) : true; if (m_has_been_bound) { vogl_scoped_binding_state orig_binding(GL_VERTEX_ARRAY); GL_ENTRYPOINT(glBindVertexArray)(m_snapshot_handle); VOGL_CHECK_GL_ERROR; m_element_array_binding = vogl_get_gl_integer(GL_ELEMENT_ARRAY_BUFFER_BINDING); m_vertex_attribs.resize(context_info.get_max_vertex_attribs()); for (uint32_t i = 0; i < context_info.get_max_vertex_attribs(); i++) { vogl_vertex_attrib_desc &desc = m_vertex_attribs[i]; desc.m_array_binding = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); desc.m_enabled = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED) != 0; desc.m_size = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_SIZE); desc.m_type = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_TYPE); desc.m_normalized = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED) != 0; desc.m_stride = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE); desc.m_integer = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_INTEGER) != 0; desc.m_divisor = vogl_get_vertex_attrib_uint(i, GL_VERTEX_ATTRIB_ARRAY_DIVISOR); GLvoid *ptr = NULL; GL_ENTRYPOINT(glGetVertexAttribPointerv)(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr); desc.m_pointer = reinterpret_cast<vogl_trace_ptr_value>(ptr); VOGL_CHECK_GL_ERROR; } } m_is_valid = true; return true; }
bool vogl_renderbuffer_desc::restore(const vogl_context_info &context_info) const { VOGL_FUNC_TRACER VOGL_NOTE_UNUSED(context_info); if (!m_width) return false; VOGL_ASSERT(context_info.get_version() >= VOGL_GL_VERSION_3_0); VOGL_CHECK_GL_ERROR; GL_ENTRYPOINT(glRenderbufferStorageMultisample)(GL_RENDERBUFFER, m_samples, m_internal_format, m_width, m_height); bool prev_gl_error = vogl_check_gl_error(); VOGL_ASSERT(!prev_gl_error); return !prev_gl_error; }
static void check(const char *pFile_line) { VOGL_ASSERT(g_heap_initialized); VOGL_NOTE_UNUSED(pFile_line); #if VOGL_MALLOC_DEBUGGING lock_heap(); Rmalloc_test(pFile_line); unlock_heap(); #endif }