struct fv_array_object * fv_array_object_new(void) { struct fv_array_object *array; GLuint vao; if (fv_gl.have_vertex_array_objects) { fv_gl.glGenVertexArrays(1, &vao); array = FV_ARRAY_OBJECT_TO_POINTER(vao); } else { array = fv_alloc(sizeof *array); array->enabled_attribs = 0; array->element_buffer = 0; } return array; }
/* * red support routines */ red_t * red_alloc(int weight, int inv_pmax, int th_min, int th_max, int flags, int pkttime) { red_t *rp; int w, i; int npkts_per_sec; rp = malloc(sizeof(red_t), M_DEVBUF, M_WAITOK|M_ZERO); if (rp == NULL) return (NULL); rp->red_avg = 0; rp->red_idle = 1; if (weight == 0) rp->red_weight = W_WEIGHT; else rp->red_weight = weight; if (inv_pmax == 0) rp->red_inv_pmax = default_inv_pmax; else rp->red_inv_pmax = inv_pmax; if (th_min == 0) rp->red_thmin = default_th_min; else rp->red_thmin = th_min; if (th_max == 0) rp->red_thmax = default_th_max; else rp->red_thmax = th_max; rp->red_flags = flags; if (pkttime == 0) /* default packet time: 1000 bytes / 10Mbps * 8 * 1000000 */ rp->red_pkttime = 800; else rp->red_pkttime = pkttime; if (weight == 0) { /* when the link is very slow, adjust red parameters */ npkts_per_sec = 1000000 / rp->red_pkttime; if (npkts_per_sec < 50) { /* up to about 400Kbps */ rp->red_weight = W_WEIGHT_2; } else if (npkts_per_sec < 300) { /* up to about 2.4Mbps */ rp->red_weight = W_WEIGHT_1; } } /* calculate wshift. weight must be power of 2 */ w = rp->red_weight; for (i = 0; w > 1; i++) w = w >> 1; rp->red_wshift = i; w = 1 << rp->red_wshift; if (w != rp->red_weight) { printf("invalid weight value %d for red! use %d\n", rp->red_weight, w); rp->red_weight = w; } /* * thmin_s and thmax_s are scaled versions of th_min and th_max * to be compared with avg. */ rp->red_thmin_s = rp->red_thmin << (rp->red_wshift + FP_SHIFT); rp->red_thmax_s = rp->red_thmax << (rp->red_wshift + FP_SHIFT); /* * precompute probability denominator * probd = (2 * (TH_MAX-TH_MIN) / pmax) in fixed-point */ rp->red_probd = (2 * (rp->red_thmax - rp->red_thmin) * rp->red_inv_pmax) << FP_SHIFT; /* allocate weight table */ rp->red_wtab = wtab_alloc(rp->red_weight); microtime(&rp->red_last); #ifdef ALTQ3_COMPAT #ifdef ALTQ_FLOWVALVE if (flags & REDF_FLOWVALVE) rp->red_flowvalve = fv_alloc(rp); /* if fv_alloc failes, flowvalve is just disabled */ #endif #endif /* ALTQ3_COMPAT */ return (rp); }
struct fv_map_painter * fv_map_painter_new(struct fv_image_data *image_data, struct fv_shader_data *shader_data) { struct fv_map_painter *painter; struct tile_data data; struct fv_map_painter_tile *tile; int first, tx, ty; int tex_width, tex_height; GLuint tex_uniform; painter = fv_alloc(sizeof *painter); if (fv_gl.have_instanced_arrays) { fv_gl.glGenBuffers(1, &painter->instance_buffer); fv_gl.glBindBuffer(GL_ARRAY_BUFFER, painter->instance_buffer); fv_gl.glBufferData(GL_ARRAY_BUFFER, sizeof (struct instance) * FV_MAP_PAINTER_MAX_SPECIALS, NULL, /* data */ GL_DYNAMIC_DRAW); } init_programs(painter, shader_data); if (!load_models(painter, image_data)) goto error_instance_buffer; fv_image_data_get_size(image_data, FV_IMAGE_DATA_MAP_TEXTURE, &tex_width, &tex_height); if (!fv_gl.have_npot_mipmaps) { painter->texture_width = smallest_pot(tex_width); painter->texture_height = smallest_pot(tex_height); } else { painter->texture_width = tex_width; painter->texture_height = tex_height; } fv_gl.glGenTextures(1, &painter->texture); fv_gl.glBindTexture(GL_TEXTURE_2D, painter->texture); fv_gl.glTexImage2D(GL_TEXTURE_2D, 0, /* level */ GL_RGB, painter->texture_width, painter->texture_height, 0, /* border */ GL_RGB, GL_UNSIGNED_BYTE, NULL); fv_image_data_set_sub_2d(image_data, GL_TEXTURE_2D, 0, /* level */ 0, 0, /* x/y offset */ FV_IMAGE_DATA_MAP_TEXTURE); fv_gl.glGenerateMipmap(GL_TEXTURE_2D); fv_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); fv_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); fv_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); fv_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); tex_uniform = fv_gl.glGetUniformLocation(painter->map_program.id, "tex"); fv_gl.glUseProgram(painter->map_program.id); fv_gl.glUniform1i(tex_uniform, 0); tex_uniform = fv_gl.glGetUniformLocation(painter->texture_program.id, "tex"); fv_gl.glUseProgram(painter->texture_program.id); fv_gl.glUniform1i(tex_uniform, 0); fv_buffer_init(&data.vertices); fv_buffer_init(&data.indices); tile = painter->tiles; for (ty = 0; ty < FV_MAP_TILES_Y; ty++) { for (tx = 0; tx < FV_MAP_TILES_X; tx++) { first = data.indices.length / sizeof (uint16_t); tile->min = (data.vertices.length / sizeof (struct vertex)); tile->offset = data.indices.length; generate_tile(painter, &data, tx, ty); tile->max = (data.vertices.length / sizeof (struct vertex)) - 1; tile->count = (data.indices.length / sizeof (uint16_t) - first); tile++; } } assert(data.vertices.length / sizeof (struct vertex) < 65536); painter->array = fv_array_object_new(); fv_gl.glGenBuffers(1, &painter->vertices_buffer); fv_gl.glBindBuffer(GL_ARRAY_BUFFER, painter->vertices_buffer); fv_gl.glBufferData(GL_ARRAY_BUFFER, data.vertices.length, data.vertices.data, GL_STATIC_DRAW); fv_array_object_set_attribute(painter->array, FV_SHADER_DATA_ATTRIB_POSITION, 4, /* size */ GL_UNSIGNED_BYTE, GL_FALSE, /* normalized */ sizeof (struct vertex), 0, /* divisor */ painter->vertices_buffer, offsetof(struct vertex, x)); fv_array_object_set_attribute(painter->array, FV_SHADER_DATA_ATTRIB_TEX_COORD, 2, /* size */ GL_UNSIGNED_SHORT, GL_TRUE, /* normalized */ sizeof (struct vertex), 0, /* divisor */ painter->vertices_buffer, offsetof(struct vertex, s)); fv_gl.glGenBuffers(1, &painter->indices_buffer); fv_array_object_set_element_buffer(painter->array, painter->indices_buffer); fv_gl.glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices.length, data.indices.data, GL_STATIC_DRAW); fv_buffer_destroy(&data.indices); fv_buffer_destroy(&data.vertices); return painter; error_instance_buffer: if (fv_gl.have_instanced_arrays) fv_gl.glDeleteBuffers(1, &painter->instance_buffer); fv_free(painter); return NULL; }