int cache_create(size_t concurrency, size_t capacity, uint64_t duration, void (*destroy_cb)(h2o_iovec_t value), cache_t *cache) { memset(cache, 0, sizeof(*cache)); assert(is_power_of_2(CONCURRENCY_FACTOR)); // Rounding up to a power of 2 simplifies the calculations a little bit, and, as any increase in // the number of caches, potentially reduces thread contention. cache->cache_num = CONCURRENCY_FACTOR * round_up_to_power_of_2(concurrency); cache->cache_num = MAX(cache->cache_num, 1); capacity = (capacity + cache->cache_num - 1) / cache->cache_num; pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr)) return EXIT_FAILURE; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP)) goto error; cache->cache = malloc(cache->cache_num * sizeof(*cache->cache)); if (!cache->cache) goto error; cache->cache_lock = malloc(cache->cache_num * sizeof(*cache->cache_lock)); if (!cache->cache_lock) goto error_malloc; for (size_t i = 0; i < cache->cache_num; i++) { cache->cache[i] = h2o_cache_create(0, capacity, duration, destroy_cb); if (!cache->cache[i] || pthread_mutex_init(cache->cache_lock + i, &attr)) { if (cache->cache[i]) h2o_cache_destroy(cache->cache[i]); cache->cache_num = i; cache_destroy(cache); goto error; } } pthread_mutexattr_destroy(&attr); return EXIT_SUCCESS; error_malloc: free(cache->cache); error: pthread_mutexattr_destroy(&attr); return EXIT_FAILURE; }
struct htable *htable_alloc(uint32_t size, htable_hash_fn_t hash_fun, htable_eq_fn_t eq_fun) { struct htable *htable; htable = calloc(1, sizeof(*htable)); if (!htable) { return NULL; } size = round_up_to_power_of_2(size); if (size < HTABLE_MIN_SIZE) { size = HTABLE_MIN_SIZE; } htable->hash_fun = hash_fun; htable->eq_fun = eq_fun; htable->used = 0; if (htable_realloc(htable, size)) { free(htable); return NULL; } return htable; }
int32_t graphics_3d_subinit(uint32_t *Rmask, uint32_t *Gmask, uint32_t *Bmask, uint32_t *Amask) { /* Pepper Graphics3D setup. */ PPB_Instance *ppb_instance_interface = (PPB_Instance *) NaCl_GetInterface(PPB_INSTANCE_INTERFACE); if (!ppb_instance_interface) { write_log("Could not acquire PPB_Instance interface.\n"); return 0; } ppb_g3d_interface = (PPB_Graphics3D *) NaCl_GetInterface(PPB_GRAPHICS_3D_INTERFACE); if (!ppb_g3d_interface) { write_log("Could not acquire PPB_Graphics3D interface.\n"); return 0; } pp_instance = NaCl_GetInstance(); if (!pp_instance) { write_log("Could not find current Pepper instance.\n"); return 0; } int32_t attribs[] = { PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24, PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8, PP_GRAPHICS3DATTRIB_SAMPLES, 0, PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, PP_GRAPHICS3DATTRIB_WIDTH, gfxvidinfo.width, PP_GRAPHICS3DATTRIB_HEIGHT, gfxvidinfo.height, PP_GRAPHICS3DATTRIB_GPU_PREFERENCE, PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_PERFORMANCE, PP_GRAPHICS3DATTRIB_NONE }; graphics_context = ppb_g3d_interface->Create( pp_instance, 0 /* share_context */, attribs); if (!graphics_context) { write_log("Could not obtain a PPB_Graphics3D context.\n"); return 0; } if (!ppb_instance_interface->BindGraphics(pp_instance, graphics_context)) { write_log("Failed to bind context to instance.\n"); return 0; } glSetCurrentContextPPAPI(graphics_context); /* UAE gfxvidinfo setup. */ /* TODO(cstefansen): Implement gfx double-buffering if perf. mandates it. */ gfxvidinfo.pixbytes = 2; /* 16-bit graphics */ gfxvidinfo.rowbytes = gfxvidinfo.width * gfxvidinfo.pixbytes; gfxvidinfo.bufmem = (uint8_t *) calloc(round_up_to_power_of_2(gfxvidinfo.rowbytes), round_up_to_power_of_2(gfxvidinfo.height)); gfxvidinfo.flush_screen = pepper_graphics3d_flush_screen; *Rmask = 0x0000F800, *Gmask = 0x000007E0, *Bmask = 0x0000001F, *Amask = 0; /* OpenGL ES setup. */ glViewport(0, 0, gfxvidinfo.width, gfxvidinfo.height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glDisable(GL_DEPTH_TEST); /* Uniform index. */ enum { UNIFORM_VIDEOFRAME, UNIFORM_INPUTCOLOR, UNIFORM_THRESHOLD, NUM_UNIFORMS }; GLint uniforms[NUM_UNIFORMS]; /* Attribute index. */ enum { ATTRIB_VERTEX, ATTRIB_TEXTUREPOSITON, NUM_ATTRIBUTES }; static GLuint g_programObj; static GLuint g_textureID; char *g_VShaderData = "attribute vec4 position;" "attribute vec4 inputTextureCoordinate;" "varying vec2 textureCoordinate;" "void main()" "{" "gl_Position = position;" "textureCoordinate = inputTextureCoordinate.xy;" "}"; char *g_FShaderData = "varying highp vec2 textureCoordinate;" "uniform sampler2D videoFrame;" "void main()" "{" "gl_FragColor = texture2D(videoFrame, textureCoordinate);" "}"; GLuint g_vertexShader; GLuint g_fragmentShader; g_vertexShader = compileShader(GL_VERTEX_SHADER, g_VShaderData); g_fragmentShader = compileShader(GL_FRAGMENT_SHADER, g_FShaderData); g_programObj = glCreateProgram(); glAttachShader(g_programObj, g_vertexShader); glAttachShader(g_programObj, g_fragmentShader); glBindAttribLocation(g_programObj, ATTRIB_VERTEX, "position"); glBindAttribLocation(g_programObj, ATTRIB_TEXTUREPOSITON, "inputTextureCoordinate"); glLinkProgram(g_programObj); uniforms[UNIFORM_VIDEOFRAME] = glGetUniformLocation(g_programObj, "videoFrame"); uniforms[UNIFORM_INPUTCOLOR] = glGetUniformLocation(g_programObj, "inputColor"); uniforms[UNIFORM_THRESHOLD] = glGetUniformLocation(g_programObj, "threshold"); glGenTextures(1, &g_textureID); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, g_textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); GLint textureWidth = round_up_to_power_of_2(gfxvidinfo.width); GLint textureHeight = round_up_to_power_of_2(gfxvidinfo.height); glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGB, textureWidth, textureHeight, 0, GL_RGB, pixel_data_type, gfxvidinfo.bufmem); static const GLfloat squareVertices[] = { -1.0f, -1.0, 1.0f, -1.0, -1.0f, 1.0, 1.0f, 1.0, }; GLfloat xFraction = ((GLfloat) gfxvidinfo.width) / (GLfloat) textureWidth; GLfloat yFraction = ((GLfloat) gfxvidinfo.height) / (GLfloat) textureHeight; static GLfloat textureVertices[] = { 0.0f, 0.0f /* yFraction */, 0.0f /* xFraction */, 0.0f /* yFraction */, 0.0f, 0.0f, 0.0f /* xFraction */, 0.0f, }; textureVertices[1] = yFraction; textureVertices[2] = xFraction; textureVertices[3] = yFraction; textureVertices[6] = xFraction; glUseProgram(g_programObj); glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0); glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices); glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); DEBUG_LOG("Shaders compiled and program linked.\n"); GLenum glErrorStatus = glGetError(); if (glErrorStatus) { write_log("GL error %d while initializing.\n", glErrorStatus); return 0; } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); ppb_g3d_interface->SwapBuffers(graphics_context, PP_BlockUntilComplete()); gettimeofday(&tv_prev, NULL); return 1; /* Success! */ }