Пример #1
0
void
eecs467_default_display_started (vx_application_t *app, vx_display_t *disp)
{
    eecs467_default_implementation_t *impl = app->impl;

    vx_layer_t *layer = vx_layer_create (impl->world);
    vx_layer_set_background_color (layer, vx_black);
    vx_layer_set_display (layer, disp);

    pthread_mutex_lock (&impl->mutex);
    // store a reference to the world and layer that we associate with each vx_display_t
    zhash_put (impl->layers, &disp, &layer, NULL, NULL);
    pthread_mutex_unlock (&impl->mutex);

    if (impl->vxeh != NULL)
        vx_layer_add_event_handler (layer, impl->vxeh);

    vx_layer_camera_op (layer, OP_PROJ_PERSPECTIVE);
    float eye[3]    = {  0,  0,  1 };
    float lookat[3] = {  0,  0,  0 };
    float up[3]     = {  0,  1,  0 };
    vx_layer_camera_lookat (layer, eye, lookat, up, 1);

    vx_code_output_stream_t *couts = vx_code_output_stream_create (128);
    couts->write_uint32 (couts, OP_LAYER_CAMERA);
    couts->write_uint32 (couts, vx_layer_id (layer));
    couts->write_uint32 (couts, OP_INTERFACE_MODE);
    couts->write_float  (couts, 2.5f);
    disp->send_codes (disp, couts->data, couts->pos);
    vx_code_output_stream_destroy (couts);
}
Пример #2
0
static void send_buffer_resource_codes(vx_buffer_t * buffer, zhash_t * resources)
{
    vx_code_output_stream_t * couts = make_buffer_resource_codes(buffer, resources);
    notify_listeners_codes(buffer->world, couts);

    vx_code_output_stream_destroy(couts);
}
Пример #3
0
static void vx_world_buffer_destroy(vx_buffer_t * buffer)
{
    vx_world_t * vw = buffer->world;

    pthread_mutex_lock(&vw->buffer_mutex);

    free(buffer->name);
    zarray_vmap(buffer->back_objs, vx_object_dec_destroy);
    zarray_destroy(buffer->back_objs);

    zarray_vmap(buffer->pending_objs, vx_object_dec_destroy);
    zarray_destroy(buffer->pending_objs);

    zarray_vmap(buffer->front_objs, vx_object_dec_destroy);
    zarray_destroy(buffer->front_objs);

    zhash_vmap_values(buffer->front_resc, vx_resc_dec_destroy);
    zhash_destroy(buffer->front_resc);

    vx_code_output_stream_destroy(buffer->front_codes);

    pthread_mutex_destroy(&buffer->mutex);
    free(buffer);

    pthread_mutex_unlock(&vw->buffer_mutex);
}
Пример #4
0
void buffer_checkbox_changed(GtkWidget * widget, gpointer userdata)
{
    buffer_info_t * buffer = userdata;

    int enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));

    vx_code_output_stream_t * outs = vx_code_output_stream_create(128);
    outs->write_uint32 (outs, OP_BUFFER_ENABLED);
    outs->write_uint32 (outs, buffer->layer_id);
    outs->write_str (outs, buffer->name);
    outs->write_uint8 (outs, enabled? 1 : 0); // convert to byte

    buffer->man->disp->send_codes(buffer->man->disp, outs->data, outs->pos);

    vx_code_output_stream_destroy(outs);
}
Пример #5
0
// Pass in a codes describing which resources are no longer in use. Decrement user counts,
// and return a list of all resources whos counts have reached zero, which therefore
// should be deleted from the display using a OP_DEALLOC_RESOURCES opcode
void vx_resc_manager_buffer_resources(vx_resc_manager_t * mgr, const uint8_t * data, int datalen)
{
    if (0) print_manager(mgr);

    vx_code_input_stream_t * cins = vx_code_input_stream_create(data, datalen);
    int code = cins->read_uint32(cins);
    assert(code == OP_BUFFER_RESOURCES);
    int worldID = cins->read_uint32(cins);
    char * name = strdup(cins->read_str(cins)); //freed when cur_resources is eventually removed from the buffer map
    int count = cins->read_uint32(cins);

    zhash_t * cur_resources = zhash_create(sizeof(uint64_t), sizeof(vx_resc_t*), zhash_uint64_hash, zhash_uint64_equals);
    vx_resc_t * vr = NULL;
    for (int i = 0; i < count; i++) {
        uint64_t id = cins->read_uint64(cins);
        zhash_put(cur_resources, &id, &vr, NULL, NULL);
    }
    assert(cins->pos == cins->len); // we've emptied the stream
    vx_code_input_stream_destroy(cins);

    // 1 Update our records
    zhash_t * worldBuffers = NULL;
    zhash_get(mgr->allLiveSets, &worldID, &worldBuffers);
    if (worldBuffers == NULL) {
        worldBuffers = zhash_create(sizeof(char*), sizeof(zhash_t*), zhash_str_hash, zhash_str_equals);
        zhash_put(mgr->allLiveSets, &worldID, &worldBuffers, NULL, NULL);
    }

    zhash_t * old_resources = NULL;
    char * old_name = NULL;
    zhash_put(worldBuffers, &name, &cur_resources, &old_name, &old_resources);
    free(old_name);

    // 2 Figure out which resources have become unused:
    if(old_resources != NULL) {
        removeAll(old_resources, cur_resources);

        zarray_t * dealloc = zarray_create(sizeof(uint64_t));

        // now 'old_resources' contains only the resources that are no longer referenced
        // iterate through each one, and see if there is a buffer somewhere that references it
        zhash_iterator_t prev_itr;
        zhash_iterator_init(old_resources, &prev_itr);
        uint64_t id = -1;
        vx_resc_t * vr = NULL;
        while(zhash_iterator_next(&prev_itr, &id, &vr)) {
            // Check all worlds
            zhash_iterator_t  world_itr;// gives us all worlds
            zhash_iterator_init(mgr->allLiveSets, &world_itr);
            uint32_t wIDl = -1;
            zhash_t * buffer_map = NULL;
            while(zhash_iterator_next(&world_itr, &wIDl, &buffer_map)) {
                zhash_iterator_t buffer_itr; // gives us all buffers
                zhash_iterator_init(buffer_map, &buffer_itr);
                char * bName = NULL;
                zhash_t * resc_map = NULL;
                while(zhash_iterator_next(&buffer_itr, &bName, &resc_map)) {
                    if (zhash_contains(resc_map, &id)) {
                        goto continue_outer_loop;
                    }
                }

            }

            // If none of the worlds have this resource, we need to flag removal
            zarray_add(dealloc, &id);

          continue_outer_loop:
            ;
        }


        // 3 Issue dealloc commands
        if (zarray_size(dealloc) > 0) {
            vx_code_output_stream_t * couts = vx_code_output_stream_create(512);
            couts->write_uint32(couts, OP_DEALLOC_RESOURCES);
            couts->write_uint32(couts, zarray_size(dealloc));
            for (int i = 0; i < zarray_size(dealloc); i++) {
                uint64_t id = 0;
                zarray_get(dealloc, i, &id);
                couts->write_uint64(couts, id);
            }

            mgr->disp->send_codes(mgr->disp, couts->data, couts->pos);

            vx_code_output_stream_destroy(couts);

            // Also remove the resources we deallocated from remoteResc
            for (int i = 0; i < zarray_size(dealloc); i++) {
                uint64_t id = 0;
                zarray_get(dealloc, i, &id);

                assert(zhash_contains(mgr->remoteResc, &id));
                zhash_remove(mgr->remoteResc, &id, NULL, NULL);
            }

        }
        zarray_destroy(dealloc);
        zhash_destroy(old_resources);

    }
    if (0) {
        print_manager(mgr);
        printf("\n\n");
    }
}
Пример #6
0
static void save_scene(state_t * state, vx_code_input_stream_t * cins)
{
    char * filename = NULL;
    if (vx_code_input_stream_available(cins) > 0) {
        const char * f2 = cins->read_str(cins);
        filename = strdup(f2);
    } else { // generate a unique ID

        uint64_t mtime = vx_mtime();
        time_t now  = time(NULL);
        struct tm * now2 = localtime(&now);

        filename=sprintf_alloc("v%4d%02d%02d_%02d%02d%02d_%03d.vxs",
                               now2->tm_year + 1900,
                               now2->tm_mon + 1,
                               now2->tm_mday,
                               now2->tm_hour,
                               now2->tm_min,
                               now2->tm_sec,
                               (int)(mtime % 1000));
    }

    vx_code_output_stream_t * couts = vx_gl_renderer_serialize(state->glrend);

    // Append camera positions
    if (state->last_render_info != NULL) {
        render_info_t *rinfo = state->last_render_info;

        for (int i = 0; i <4; i++)
            couts->write_uint32(couts, rinfo->viewport[i]);

        couts->write_uint32(couts, zarray_size(rinfo->layers));
        for (int i = 0; i < zarray_size(rinfo->layers); i++) {
            layer_info_t * linfo = NULL;
            zarray_get(rinfo->layers, i, &linfo);

            couts->write_uint32(couts, linfo->layer_id);

            vx_camera_pos_t * pos = NULL;
            int * viewport = NULL;
            zhash_get(rinfo->camera_positions, &linfo->layer_id, &pos);
            zhash_get(rinfo->layer_positions, &linfo->layer_id, &viewport);

            vx_tcp_util_pack_camera_pos(pos, couts);


            for (int i = 0; i < 4; i++)
                couts->write_uint32(couts, viewport[i]);
        }
    }



    FILE * fp = fopen(filename, "w");
    fwrite(couts->data, sizeof(uint8_t), couts->pos, fp);
    fclose(fp);
    printf("Wrote %d bytes to %s\n", couts->pos, filename);

    vx_code_output_stream_destroy(couts);
    free(filename);

}
Пример #7
0
static void menu_action(GtkWidget * menuitem, char * shortname, gpointer userdata)
{
    state_t * state = userdata;
    if (state->popup_layer_id == 0)
        return;

    vx_code_output_stream_t * couts = vx_code_output_stream_create(128);


    if (verbose) printf("DBG menu: Label %s shortname %s\n",
                        gtk_menu_item_get_label(GTK_MENU_ITEM(menuitem)), shortname);

    if (!strcmp(shortname,"reset_camera")) {
        couts->write_uint32(couts, OP_LAYER_CAMERA);
        couts->write_uint32(couts, state->popup_layer_id);
        couts->write_uint32(couts, OP_DEFAULTS);
    } else if (!strcmp(shortname,"ortho")) {
        couts->write_uint32(couts, OP_LAYER_CAMERA);
        couts->write_uint32(couts, state->popup_layer_id);
        couts->write_uint32(couts, OP_PROJ_ORTHO);
    } else if (!strcmp(shortname,"perspective")) {
        couts->write_uint32(couts, OP_LAYER_CAMERA);
        couts->write_uint32(couts, state->popup_layer_id);
        couts->write_uint32(couts, OP_PROJ_PERSPECTIVE);
    } else if (!strcmp(shortname,"iface2.0D")) {
        couts->write_uint32(couts, OP_LAYER_CAMERA);
        couts->write_uint32(couts, state->popup_layer_id);
        couts->write_uint32(couts, OP_INTERFACE_MODE);
        couts->write_float(couts, 2.0f);
    } else if (!strcmp(shortname,"iface2.5D")) {
        couts->write_uint32(couts, OP_LAYER_CAMERA);
        couts->write_uint32(couts, state->popup_layer_id);
        couts->write_uint32(couts, OP_INTERFACE_MODE);
        couts->write_float(couts, 2.5f);
    } else if (!strcmp(shortname,"iface3.0D")) {
        couts->write_uint32(couts, OP_LAYER_CAMERA);
        couts->write_uint32(couts, state->popup_layer_id);
        couts->write_uint32(couts, OP_INTERFACE_MODE);
        couts->write_float(couts, 3.0f);
    } else if (!strcmp(shortname,"buffer_manager")) {
        vx_gtk_buffer_manager_show(state->buffer_manager, 1);
    } else if (!strcmp(shortname,"scene")) {
        couts->write_uint32(couts, OP_WINDOW_SCENE);
        // optional, filled in automatically couts->write_str(couts, "test.vxs");
    } else if (!strcmp(shortname,"screen_shot")) {
        couts->write_uint32(couts, OP_WINDOW_SCREENSHOT);
        // optional, filled in automatically couts->write_str(couts, "test.png");
    } else if (!strcmp(shortname,"record_movie")) {
        couts->write_uint32(couts, OP_WINDOW_MOVIE_RECORD);
        // optional, filled in automatically couts->write_str(couts, "test.ppms.gz");
    } else if (!strcmp(shortname,"stop_movie")) {
        couts->write_uint32(couts, OP_WINDOW_MOVIE_STOP);
    }


    if (couts->pos != 0) {
        state->super->send_codes(state->super, couts->data, couts->pos);
    }

        /* pthread_mutex_lock(&state->mutex); */

        /* pthread_mutex_unlock(&state->mutex); */

    vx_code_output_stream_destroy(couts);
}
Пример #8
0
static void display_started(vx_application_t * app, vx_display_t * disp)
{
    state_t * state = app->impl;

    {
        vx_layer_t * layer = vx_layer_create(state->world);
        vx_layer_set_display(layer, disp);
        //vx_layer_camera_op(layer, OP_PROJ_ORTHO);

        if (1) {
            float view_rel[] = {0.0, 0.0, 1.0, 1.0};
            vx_layer_set_viewport_rel(layer, view_rel);
        }

        if (1) {
            float eye3[] = {CAM_RADIUS,0,45.0f};
            float lookat3[] = {CAM_RADIUS,0,0.0f};
            float up3[] = {0,1,0};
            vx_layer_camera_lookat(layer, eye3, lookat3, up3, 0);
        }

        if (1) {
            float xy0[] = {-10,-10};
            float xy1[] = {10,10};
            vx_layer_camera_fit2D(layer, xy0, xy1, 0);
        }


        pthread_mutex_lock(&state->mutex);
        // store a reference to the world and layer that we associate with each vx_display_t
        zhash_put(state->layers, &disp, &layer, NULL, NULL);
        pthread_mutex_unlock(&state->mutex);

        // must redraw after each new display connects

        draw(state, state->world);
    }

    {
        vx_layer_t * layer = vx_layer_create(state->world2);
        vx_layer_set_display(layer, disp);
        vx_layer_camera_op(layer, OP_PROJ_ORTHO);

        {
            vx_layer_set_viewport_abs(layer, OP_ANCHOR_TOP_RIGHT, 100, 100);
        }

        {
            float eye3[] = {10.0f,10.0f,100.0f};
            float lookat3[] = {10.0f,10.0f,0.0f};
            float up3[] = {0,1,0};
            vx_layer_camera_lookat(layer, eye3, lookat3, up3, 0);
        }

        {
            float xy0[] = {-10,-10};
            float xy1[] = {10,10};
            vx_layer_camera_fit2D(layer, xy0, xy1, 0);
        }

        vx_layer_add_event_handler(layer, &state->veh);
        vx_layer_add_camera_listener(layer, &state->cl);


        /*
        pthread_mutex_lock(&state->mutex);
        // store a reference to the world and layer that we associate with each vx_display_t
        zhash_put(state->layers, &disp, &layer, NULL, NULL);
        pthread_mutex_unlock(&state->mutex);
        */

        // must redraw after each new display connects

        draw(state, state->world2);
    }


    if (0) {
        vx_layer_t * layer = vx_layer_create(state->world3);
        vx_layer_set_display(layer, disp);
        vx_layer_set_background_color(layer, vx_green);

        // Manually send the codes for animating a layer (not in
        // vx_layer_api yet):

        {
            float viewport[] = {0, 0.5, 0.5, 0.5};

            vx_code_output_stream_t * couts = vx_code_output_stream_create(128);
            couts->write_uint32(couts, OP_LAYER_VIEWPORT_REL);
            couts->write_uint32(couts, vx_layer_id(layer));
            for (int i = 0; i < 4; i++)
                couts->write_float(couts, viewport[i]);
            couts->write_uint32(couts, 2000); // animate over 2 seconds

            disp->send_codes(disp, couts->data, couts->pos);

            vx_code_output_stream_destroy(couts);
        }

        draw(state, state->world3); // XXX Why is this required to get
        // the layer to show up?
    }


}
Пример #9
0
static void * run_process(void * data)
{
    vx_world_t * world = data;


    while (world->process_running) {
        vx_world_listener_t * listener = NULL;
        char * buffer_name = NULL;

        // 1) Wait until there's data
        pthread_mutex_lock(&world->queue_mutex);
        while (zarray_size(world->buffer_queue) == 0 && zarray_size(world->listener_queue) == 0 && world->process_running) {
            pthread_cond_wait(&world->queue_cond, &world->queue_mutex);
        }

        if (!world->process_running) { // XXX cleaning out the queue?
            pthread_mutex_unlock(&world->queue_mutex);
            break;
        }

        // Processing new listeners takes priority
        if ( zarray_size(world->listener_queue) > 0) {
            zarray_get(world->listener_queue, 0, &listener);
            zarray_remove_index(world->listener_queue, 0, 0);
        } else {
            assert(zarray_size(world->buffer_queue) > 0);
            zarray_get(world->buffer_queue, 0, &buffer_name);
            zarray_remove_index(world->buffer_queue, 0, 0);
        }
        pthread_mutex_unlock(&world->queue_mutex);

        // Operation A: New listener
        if (listener != NULL) {
            // re-transmit each buffer that has already been serialized
            pthread_mutex_lock(&world->buffer_mutex);
            zhash_iterator_t itr;
            zhash_iterator_init(world->buffer_map, &itr);
            char * name = NULL;
            vx_buffer_t * buffer = NULL;
            while(zhash_iterator_next(&itr, &name, &buffer)) {
                if (buffer->front_codes->pos != 0) {
                    vx_code_output_stream_t * bresc_codes = make_buffer_resource_codes(buffer, buffer->front_resc);

                    // Doing a swap in 3 steps (instead of 4) like this
                    // is only safe if the listener is brand new, which we are
                    // guaranteed is the case in this chunk of code
                    listener->send_codes(listener, bresc_codes->data, bresc_codes->pos);
                    listener->send_resources(listener, buffer->front_resc);
                    listener->send_codes(listener, buffer->front_codes->data, buffer->front_codes->pos);

                    vx_code_output_stream_destroy(bresc_codes);
                }
            }

            pthread_mutex_unlock(&world->buffer_mutex);
        }

        // Operation B: buffer swap
        if (buffer_name != NULL) {
            vx_buffer_t * buffer = NULL;
            pthread_mutex_lock(&world->buffer_mutex);
            zhash_get(world->buffer_map, &buffer_name, &buffer);
            pthread_mutex_unlock(&world->buffer_mutex);

            delayed_swap(buffer);
        }

    }

    pthread_exit(NULL);
}