<commit_before>#include "camera.h"
#include "ces/ces_editor.h"
#include "ces/ces_resources.h"
#include "ces/ces_scene.h"
#include "ces/ces_utilities.h"
#include "debug_render.h"
#include "dev_ui.h"
#include "file_system.h"
#include "hash.h"
#include "input.h"
#include "loader.h"
#include "pen.h"
#include "pen_json.h"
#include "pen_string.h"
#include "pmfx.h"
#include "renderer.h"
#include "str_utilities.h"
#include "timer.h"
#include "forward_render.h"

using namespace put;
using namespace ces;

pen::window_creation_params pen_window{
    1280,           // width
    720,            // height
    4,              // MSAA samples
    "pmfx_renderer" // window title / process name
};

namespace physics
{
    extern PEN_TRV physics_thread_main(void* params);
}

namespace
{
    const s32 max_lights = 100;

    u32 lights_start = 0;
    f32 light_radius = 100.0f;
    s32 num_lights = max_lights;
    f32 scene_size = 200.0f;

    vec3f anim_dir[max_lights];

    const c8* render_methods[] =
    {
        "forward_render",
        "forward_render_zprepass",
        "deferred_render",
        "deferred_render_msaa"
    };
    s32 render_method = 0;

    f32 user_thread_time = 0.0f;

    void update_demo(ces::entity_scene* scene, f32 dt)
    {
        ImGui::Begin("Lighting", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
        ImGui::InputFloat("Light Radius", &light_radius);
        ImGui::SliderInt("Lights", &num_lights, 0, max_lights);

        if(ImGui::Combo("Method", &render_method, &render_methods[0], PEN_ARRAY_SIZE(render_methods)))
        {
            pmfx::set_view_set(render_methods[render_method]);
        }

        f32 render_gpu = 0.0f;
        f32 render_cpu = 0.0f;
        pen::renderer_get_present_time(render_cpu, render_gpu);

        ImGui::Separator();
        ImGui::Text("Stats:");
        ImGui::Text("User Thread: %2.2f ms", user_thread_time);
        ImGui::Text("Render Thread: %2.2f ms", render_cpu);
        ImGui::Text("GPU: %2.2f ms", render_gpu);
        ImGui::Separator();

        ImGui::End();

        static f32 t = 0.0f;
        t += dt * 0.01f;

        u32 lights_end = lights_start + num_lights;
        u32 light_nodes_end = lights_start + max_lights;
        u32 dir_index = 0;
        for(u32 i = lights_start; i < light_nodes_end; ++i)
        {
            if(i >= lights_end)
            {
                scene->entities[i] &= ~CMP_LIGHT;
                continue;
            }

            scene->transforms[i].translation += anim_dir[dir_index] * dt * 0.1f;
            scene->entities[i] |= CMP_TRANSFORM;

            for(u32 j = 0; j < 3; ++j)
            {
                if(fabs(scene->transforms[i].translation[j]) > scene_size)
                {
                    f32 rrx = (f32)(rand()%255) / 255.0f;
                    f32 rry = (f32)(rand()%255) / 255.0f;
                    f32 rrz = (f32)(rand()%255) / 255.0f;

                    anim_dir[dir_index] = vec3f(rrx, rry, rrz) * vec3f(2.0f) - vec3f(1.0);
                    anim_dir[dir_index] += normalised(vec3f(0.0f, scene_size / 2.0f, 0.0f) - scene->transforms[i].translation);
                }
            }

            scene->entities[i] |= CMP_LIGHT;
            scene->lights[i].radius = light_radius;

            dir_index++;
        }
    }
}

void create_scene_objects(ces::entity_scene* scene, camera& main_camera)
{
    clear_scene(scene);

    // set camera start pos
    main_camera.zoom = 495.0f;
    main_camera.rot = vec2f(-0.8f, 0.37f);

    material_resource* default_material = get_material_resource(PEN_HASH("default_material"));
    geometry_resource* box_resource = get_geometry_resource(PEN_HASH("cube"));

    // pbt textures for material
    u32 albedo_tex = put::load_texture("data/textures/pbr/metalgrid2_basecolor.dds");
    u32 normal_tex = put::load_texture("data/textures/pbr/metalgrid2_normal.dds");
    u32 matallic_tex = put::load_texture("data/textures/pbr/metalgrid2_metallic.dds");
    u32 roughness_tex = put::load_texture("data/textures/pbr/metalgrid2_roughness.dds");
    u32 wrap_linear = pmfx::get_render_state(PEN_HASH("wrap_linear"), pmfx::RS_SAMPLER);

    // add some pillars for overdraw and illumination
    f32   num_pillar_rows = 20;
    f32   pillar_size = 20.0f;
    f32   d = scene_size / num_pillar_rows;
    f32   s = -d * (f32)num_pillar_rows;
    vec3f start_pos = vec3f(s, pillar_size, s);
    vec3f pos = start_pos;
    for (s32 i = 0; i < num_pillar_rows; ++i)
    {
        pos.z = start_pos.z;

        for (s32 j = 0; j < num_pillar_rows; ++j)
        {
            f32 rx = 0.1f + (f32)(rand()%255) / 255.0f * pillar_size;
            f32 ry = 0.1f + (f32)(rand()%255) / 255.0f * pillar_size * 4.0f;
            f32 rz = 0.1f + (f32)(rand()%255) / 255.0f * pillar_size;

            pos.y = ry;

            u32 pillar = get_new_node(scene);
            scene->transforms[pillar].rotation = quat();
            scene->transforms[pillar].scale = vec3f(rx, ry, rz);
            scene->transforms[pillar].translation = pos;
            scene->parents[pillar] = pillar;
            scene->entities[pillar] |= CMP_TRANSFORM;
            scene->names[pillar] = "pillar";

            instantiate_geometry(box_resource, scene, pillar);
            instantiate_model_cbuffer(scene, pillar);

            // uv scale
            scene->material_permutation[pillar] |= FORWARD_LIT_UV_SCALE;
            instantiate_material(default_material, scene, pillar);

            forward_lit_uv_scale* m = (forward_lit_uv_scale*)&scene->material_data[pillar].data[0];
            m->m_albedo = vec4f::one();
            m->m_roughness = 0.1f;
            m->m_reflectivity = 0.3f;
            m->m_uv_scale = vec2f(0.5f, 0.5f);

            scene->samplers[pillar].sb[0].handle = albedo_tex;
            scene->samplers[pillar].sb[1].handle = normal_tex;
            scene->samplers[pillar].sb[2].handle = roughness_tex;
            scene->samplers[pillar].sb[3].handle = matallic_tex;

            for(u32 j = 0; j < 4; ++j)
                scene->samplers[pillar].sb[j].id_sampler_state = wrap_linear;

            pos.z += d * 2.0f;
        }

        pos.x += d * 2.0f;
    }

    for(s32 i = 0; i < max_lights; ++i)
    {
        f32 rx = (f32)(rand()%255) / 255.0f;
        f32 ry = (f32)(rand()%255) / 255.0f;
        f32 rz = (f32)(rand()%255) / 255.0f;

        f32 rrx = (f32)(rand()%255) / 255.0f;
        f32 rry = (f32)(rand()%255) / 255.0f;
        f32 rrz = (f32)(rand()%255) / 255.0f;

        ImColor ii = ImColor::HSV((rand() % 255) / 255.0f, (rand() % 255) / 255.0f, (rand() % 255) / 255.0f);
        vec4f col = normalised(vec4f(ii.Value.x, ii.Value.y, ii.Value.z, 1.0f));

        u32 light = get_new_node(scene);
        scene->names[light] = "light";
        scene->id_name[light] = PEN_HASH("light");

        scene->transforms[light].translation = (vec3f(rx, ry, rz) *
                                                vec3f(2.0f, 1.0f, 2.0f) +
                                                vec3f(-1.0f, 0.0f, -1.0f)) *
                                                vec3f(scene_size, scene_size * 0.1f, scene_size);

        scene->transforms[light].translation.y += scene_size;

        scene->transforms[light].rotation = quat();
        scene->transforms[light].rotation.euler_angles(rrx, rry, rrz);
        scene->transforms[light].scale = vec3f::one();
        scene->entities[light] |= CMP_TRANSFORM;

        scene->lights[light].colour = col.xyz;
        scene->lights[light].radius = light_radius;
        scene->lights[light].type = LIGHT_TYPE_POINT;
        instantiate_light(scene, light);

        anim_dir[i] = vec3f(rrx, rry, rrz) * vec3f(2.0f) - vec3f(1.0);

        if(i == 0)
            lights_start = light;
    }
}

PEN_TRV pen::user_entry(void* params)
{
    // unpack the params passed to the thread and signal to the engine it ok to proceed
    pen::job_thread_params* job_params = (pen::job_thread_params*)params;
    pen::job*               p_thread_info = job_params->job_info;
    pen::thread_semaphore_signal(p_thread_info->p_sem_continue, 1);

    pen::thread_create_job(physics::physics_thread_main, 1024 * 10, nullptr, pen::THREAD_START_DETACHED);

    put::dev_ui::init();
    put::dbg::init();

    // create main camera and controller
    put::camera main_camera;
    put::camera_create_perspective(&main_camera, 60.0f, put::k_use_window_aspect, 0.1f, 1000.0f);

    put::scene_controller cc;
    cc.camera = &main_camera;
    cc.update_function = &ces::update_model_viewer_camera;
    cc.name = "model_viewer_camera";
    cc.id_name = PEN_HASH(cc.name.c_str());

    // create the main scene and controller
    put::ces::entity_scene* main_scene = put::ces::create_scene("main_scene");
    put::ces::editor_init(main_scene);

    put::scene_controller sc;
    sc.scene = main_scene;
    sc.update_function = &ces::update_model_viewer_scene;
    sc.name = "main_scene";
    sc.camera = &main_camera;
    sc.id_name = PEN_HASH(sc.name.c_str());

    // create view renderers
    put::scene_view_renderer svr_main;
    svr_main.name = "ces_render_scene";
    svr_main.id_name = PEN_HASH(svr_main.name.c_str());
    svr_main.render_function = &ces::render_scene_view;

    put::scene_view_renderer svr_editor;
    svr_editor.name = "ces_render_editor";
    svr_editor.id_name = PEN_HASH(svr_editor.name.c_str());
    svr_editor.render_function = &ces::render_scene_editor;

    put::scene_view_renderer svr_light_volumes;
    svr_light_volumes.name = "ces_render_light_volumes";
    svr_light_volumes.id_name = PEN_HASH(svr_light_volumes.name.c_str());
    svr_light_volumes.render_function = &ces::render_light_volumes;

    pmfx::register_scene_view_renderer(svr_main);
    pmfx::register_scene_view_renderer(svr_editor);
    pmfx::register_scene_view_renderer(svr_light_volumes);

    pmfx::register_scene_controller(sc);
    pmfx::register_scene_controller(cc);

    pmfx::init("data/configs/pmfx_demo.jsn");

    create_scene_objects(main_scene, main_camera);

    f32 frame_time = 0.0f;

    while (1)
    {
        static u32 frame_timer = pen::timer_create("frame_timer");
        pen::timer_start(frame_timer);

        put::dev_ui::new_frame();

        update_demo(main_scene, (f32)frame_time);

        pmfx::update();

        pmfx::render();

        pmfx::show_dev_ui();

        put::dev_ui::render();

        frame_time = pen::timer_elapsed_ms(frame_timer);
        user_thread_time = frame_time;

        pen::renderer_present();
        pen::renderer_consume_cmd_buffer();

        pmfx::poll_for_changes();
        put::poll_hot_loader();

        // msg from the engine we want to terminate
        if (pen::thread_semaphore_try_wait(p_thread_info->p_sem_exit))
            break;
    }

    ces::destroy_scene(main_scene);
    ces::editor_shutdown();

    // clean up mem here
    put::pmfx::shutdown();
    put::dbg::shutdown();
    put::dev_ui::shutdown();

    pen::renderer_consume_cmd_buffer();

    // signal to the engine the thread has finished
    pen::thread_semaphore_signal(p_thread_info->p_sem_terminated, 1);

    return PEN_THREAD_OK;
}
<commit_msg>fix wrap mode in pmfx demo for d3d<commit_after>#include "camera.h"
#include "ces/ces_editor.h"
#include "ces/ces_resources.h"
#include "ces/ces_scene.h"
#include "ces/ces_utilities.h"
#include "debug_render.h"
#include "dev_ui.h"
#include "file_system.h"
#include "hash.h"
#include "input.h"
#include "loader.h"
#include "pen.h"
#include "pen_json.h"
#include "pen_string.h"
#include "pmfx.h"
#include "renderer.h"
#include "str_utilities.h"
#include "timer.h"
#include "forward_render.h"

using namespace put;
using namespace ces;

pen::window_creation_params pen_window{
    1280,           // width
    720,            // height
    4,              // MSAA samples
    "pmfx_renderer" // window title / process name
};

namespace physics
{
    extern PEN_TRV physics_thread_main(void* params);
}

namespace
{
    const s32 max_lights = 100;

    u32 lights_start = 0;
    f32 light_radius = 100.0f;
    s32 num_lights = max_lights;
    f32 scene_size = 200.0f;

    vec3f anim_dir[max_lights];

    const c8* render_methods[] =
    {
        "forward_render",
        "forward_render_zprepass",
        "deferred_render",
        "deferred_render_msaa"
    };
    s32 render_method = 0;

    f32 user_thread_time = 0.0f;

    void update_demo(ces::entity_scene* scene, f32 dt)
    {
        ImGui::Begin("Lighting", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
        ImGui::InputFloat("Light Radius", &light_radius);
        ImGui::SliderInt("Lights", &num_lights, 0, max_lights);

        if(ImGui::Combo("Method", &render_method, &render_methods[0], PEN_ARRAY_SIZE(render_methods)))
        {
            pmfx::set_view_set(render_methods[render_method]);
        }

        f32 render_gpu = 0.0f;
        f32 render_cpu = 0.0f;
        pen::renderer_get_present_time(render_cpu, render_gpu);

        ImGui::Separator();
        ImGui::Text("Stats:");
        ImGui::Text("User Thread: %2.2f ms", user_thread_time);
        ImGui::Text("Render Thread: %2.2f ms", render_cpu);
        ImGui::Text("GPU: %2.2f ms", render_gpu);
        ImGui::Separator();

        ImGui::End();

        static f32 t = 0.0f;
        t += dt * 0.01f;

        u32 lights_end = lights_start + num_lights;
        u32 light_nodes_end = lights_start + max_lights;
        u32 dir_index = 0;
        for(u32 i = lights_start; i < light_nodes_end; ++i)
        {
            if(i >= lights_end)
            {
                scene->entities[i] &= ~CMP_LIGHT;
                continue;
            }

            scene->transforms[i].translation += anim_dir[dir_index] * dt * 0.1f;
            scene->entities[i] |= CMP_TRANSFORM;

            for(u32 j = 0; j < 3; ++j)
            {
                if(fabs(scene->transforms[i].translation[j]) > scene_size)
                {
                    f32 rrx = (f32)(rand()%255) / 255.0f;
                    f32 rry = (f32)(rand()%255) / 255.0f;
                    f32 rrz = (f32)(rand()%255) / 255.0f;

                    anim_dir[dir_index] = vec3f(rrx, rry, rrz) * vec3f(2.0f) - vec3f(1.0);
                    anim_dir[dir_index] += normalised(vec3f(0.0f, scene_size / 2.0f, 0.0f) - scene->transforms[i].translation);
                }
            }

            scene->entities[i] |= CMP_LIGHT;
            scene->lights[i].radius = light_radius;

            dir_index++;
        }
    }
}

void create_scene_objects(ces::entity_scene* scene, camera& main_camera)
{
    clear_scene(scene);

    // set camera start pos
    main_camera.zoom = 495.0f;
    main_camera.rot = vec2f(-0.8f, 0.37f);

    material_resource* default_material = get_material_resource(PEN_HASH("default_material"));
    geometry_resource* box_resource = get_geometry_resource(PEN_HASH("cube"));

    // pbt textures for material
    u32 albedo_tex = put::load_texture("data/textures/pbr/metalgrid2_basecolor.dds");
    u32 normal_tex = put::load_texture("data/textures/pbr/metalgrid2_normal.dds");
    u32 matallic_tex = put::load_texture("data/textures/pbr/metalgrid2_metallic.dds");
    u32 roughness_tex = put::load_texture("data/textures/pbr/metalgrid2_roughness.dds");

    // add some pillars for overdraw and illumination
    f32   num_pillar_rows = 20;
    f32   pillar_size = 20.0f;
    f32   d = scene_size / num_pillar_rows;
    f32   s = -d * (f32)num_pillar_rows;
    vec3f start_pos = vec3f(s, pillar_size, s);
    vec3f pos = start_pos;
    for (s32 i = 0; i < num_pillar_rows; ++i)
    {
        pos.z = start_pos.z;

        for (s32 j = 0; j < num_pillar_rows; ++j)
        {
            f32 rx = 0.1f + (f32)(rand()%255) / 255.0f * pillar_size;
            f32 ry = 0.1f + (f32)(rand()%255) / 255.0f * pillar_size * 4.0f;
            f32 rz = 0.1f + (f32)(rand()%255) / 255.0f * pillar_size;

            pos.y = ry;

            u32 pillar = get_new_node(scene);
            scene->transforms[pillar].rotation = quat();
            scene->transforms[pillar].scale = vec3f(rx, ry, rz);
            scene->transforms[pillar].translation = pos;
            scene->parents[pillar] = pillar;
            scene->entities[pillar] |= CMP_TRANSFORM;
            scene->names[pillar] = "pillar";

            instantiate_geometry(box_resource, scene, pillar);
            instantiate_model_cbuffer(scene, pillar);

            // uv scale
            scene->material_permutation[pillar] |= FORWARD_LIT_UV_SCALE;
            instantiate_material(default_material, scene, pillar);

            forward_lit_uv_scale* m = (forward_lit_uv_scale*)&scene->material_data[pillar].data[0];
            m->m_albedo = vec4f::one();
            m->m_roughness = 0.1f;
            m->m_reflectivity = 0.3f;
            m->m_uv_scale = vec2f(0.5f, 0.5f);

            scene->samplers[pillar].sb[0].handle = albedo_tex;
            scene->samplers[pillar].sb[1].handle = normal_tex;
            scene->samplers[pillar].sb[2].handle = roughness_tex;
            scene->samplers[pillar].sb[3].handle = matallic_tex;

            for(u32 j = 0; j < 4; ++j)
                scene->samplers[pillar].sb[j].id_sampler_state = PEN_HASH("wrap_linear");

            pos.z += d * 2.0f;
        }

        pos.x += d * 2.0f;
    }

    for(s32 i = 0; i < max_lights; ++i)
    {
        f32 rx = (f32)(rand()%255) / 255.0f;
        f32 ry = (f32)(rand()%255) / 255.0f;
        f32 rz = (f32)(rand()%255) / 255.0f;

        f32 rrx = (f32)(rand()%255) / 255.0f;
        f32 rry = (f32)(rand()%255) / 255.0f;
        f32 rrz = (f32)(rand()%255) / 255.0f;

        ImColor ii = ImColor::HSV((rand() % 255) / 255.0f, (rand() % 255) / 255.0f, (rand() % 255) / 255.0f);
        vec4f col = normalised(vec4f(ii.Value.x, ii.Value.y, ii.Value.z, 1.0f));

        u32 light = get_new_node(scene);
        scene->names[light] = "light";
        scene->id_name[light] = PEN_HASH("light");

        scene->transforms[light].translation = (vec3f(rx, ry, rz) *
                                                vec3f(2.0f, 1.0f, 2.0f) +
                                                vec3f(-1.0f, 0.0f, -1.0f)) *
                                                vec3f(scene_size, scene_size * 0.1f, scene_size);

        scene->transforms[light].translation.y += scene_size;

        scene->transforms[light].rotation = quat();
        scene->transforms[light].rotation.euler_angles(rrx, rry, rrz);
        scene->transforms[light].scale = vec3f::one();
        scene->entities[light] |= CMP_TRANSFORM;

        scene->lights[light].colour = col.xyz;
        scene->lights[light].radius = light_radius;
        scene->lights[light].type = LIGHT_TYPE_POINT;
        instantiate_light(scene, light);

        anim_dir[i] = vec3f(rrx, rry, rrz) * vec3f(2.0f) - vec3f(1.0);

        if(i == 0)
            lights_start = light;
    }
}

PEN_TRV pen::user_entry(void* params)
{
    // unpack the params passed to the thread and signal to the engine it ok to proceed
    pen::job_thread_params* job_params = (pen::job_thread_params*)params;
    pen::job*               p_thread_info = job_params->job_info;
    pen::thread_semaphore_signal(p_thread_info->p_sem_continue, 1);

    pen::thread_create_job(physics::physics_thread_main, 1024 * 10, nullptr, pen::THREAD_START_DETACHED);

    put::dev_ui::init();
    put::dbg::init();

    // create main camera and controller
    put::camera main_camera;
    put::camera_create_perspective(&main_camera, 60.0f, put::k_use_window_aspect, 0.1f, 1000.0f);

    put::scene_controller cc;
    cc.camera = &main_camera;
    cc.update_function = &ces::update_model_viewer_camera;
    cc.name = "model_viewer_camera";
    cc.id_name = PEN_HASH(cc.name.c_str());

    // create the main scene and controller
    put::ces::entity_scene* main_scene = put::ces::create_scene("main_scene");
    put::ces::editor_init(main_scene);

    put::scene_controller sc;
    sc.scene = main_scene;
    sc.update_function = &ces::update_model_viewer_scene;
    sc.name = "main_scene";
    sc.camera = &main_camera;
    sc.id_name = PEN_HASH(sc.name.c_str());

    // create view renderers
    put::scene_view_renderer svr_main;
    svr_main.name = "ces_render_scene";
    svr_main.id_name = PEN_HASH(svr_main.name.c_str());
    svr_main.render_function = &ces::render_scene_view;

    put::scene_view_renderer svr_editor;
    svr_editor.name = "ces_render_editor";
    svr_editor.id_name = PEN_HASH(svr_editor.name.c_str());
    svr_editor.render_function = &ces::render_scene_editor;

    put::scene_view_renderer svr_light_volumes;
    svr_light_volumes.name = "ces_render_light_volumes";
    svr_light_volumes.id_name = PEN_HASH(svr_light_volumes.name.c_str());
    svr_light_volumes.render_function = &ces::render_light_volumes;

    pmfx::register_scene_view_renderer(svr_main);
    pmfx::register_scene_view_renderer(svr_editor);
    pmfx::register_scene_view_renderer(svr_light_volumes);

    pmfx::register_scene_controller(sc);
    pmfx::register_scene_controller(cc);

    pmfx::init("data/configs/pmfx_demo.jsn");

    create_scene_objects(main_scene, main_camera);

    f32 frame_time = 0.0f;

    while (1)
    {
        static u32 frame_timer = pen::timer_create("frame_timer");
        pen::timer_start(frame_timer);

        put::dev_ui::new_frame();

        update_demo(main_scene, (f32)frame_time);

        pmfx::update();

        pmfx::render();

        pmfx::show_dev_ui();

        put::dev_ui::render();

        frame_time = pen::timer_elapsed_ms(frame_timer);
        user_thread_time = frame_time;

        pen::renderer_present();
        pen::renderer_consume_cmd_buffer();

        pmfx::poll_for_changes();
        put::poll_hot_loader();

        // msg from the engine we want to terminate
        if (pen::thread_semaphore_try_wait(p_thread_info->p_sem_exit))
            break;
    }

    ces::destroy_scene(main_scene);
    ces::editor_shutdown();

    // clean up mem here
    put::pmfx::shutdown();
    put::dbg::shutdown();
    put::dev_ui::shutdown();

    pen::renderer_consume_cmd_buffer();

    // signal to the engine the thread has finished
    pen::thread_semaphore_signal(p_thread_info->p_sem_terminated, 1);

    return PEN_THREAD_OK;
}
<|endoftext|>


<commit_before>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
// (C) 2005 Mike Weiblen http://mew.cx/ released under the OSGPL.
// Simple example using GLUT to create an OpenGL window and OSG for rendering.
// Derived from osgGLUTsimple.cpp and osgkeyboardmouse.cpp

#include <osgGA/SimpleViewer>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>

#include <QtCore/QTimer>
#include <QtGui/QKeyEvent>
#include <QtGui/QApplication>
#include <QtOpenGL/QGLWidget>

#include <iostream>

class OSGWidget : public QGLWidget, public osgGA::SimpleViewer
{
public:

    OSGWidget( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, Qt::WFlags f = 0 );
    virtual ~OSGWidget() {}

protected:

    virtual void initializeGL();
    virtual void paintGL();

    virtual void resizeGL( int width, int height );
    virtual void keyPressEvent( QKeyEvent* event );
    virtual void keyReleaseEvent( QKeyEvent* event );
    virtual void mousePressEvent( QMouseEvent* event );
    virtual void mouseReleaseEvent( QMouseEvent* event );
    virtual void mouseMoveEvent( QMouseEvent* event );

    QTimer _timer;
};

OSGWidget::OSGWidget( QWidget * parent, const char * /*name*/, const QGLWidget * shareWidget, Qt::WFlags f):
    QGLWidget(parent, shareWidget, f)
{
    connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
    _timer.start(10);
}

void OSGWidget::initializeGL()
{
    QGLWidget::initializeGL();
}

void OSGWidget::paintGL()
{
    frame();
}

void OSGWidget::resizeGL( int width, int height )
{
    getEventQueue()->windowResize(0, 0, width, height );
}

void OSGWidget::keyPressEvent( QKeyEvent* event )
{
    getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) event->key() );
}

void OSGWidget::keyReleaseEvent( QKeyEvent* event )
{
    getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) event->key() );
}

void OSGWidget::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void OSGWidget::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}

void OSGWidget::mouseMoveEvent( QMouseEvent* event )
{
    getEventQueue()->mouseMotion(event->x(), event->y());
}

int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    OSGWidget* viewerWindow = new OSGWidget;

    viewerWindow->setSceneData(loadedModel.get());
    viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);

    viewerWindow->show();
    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );

    return a.exec();
}

/*EOF*/
<commit_msg>Refactored osgsimpleviewerQT4 to implement a GraphicsWindowQT, and then use multiple inheritance to build the final SimpleViewerQT.<commit_after>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
// (C) 2005 Mike Weiblen http://mew.cx/ released under the OSGPL.
// Simple example using GLUT to create an OpenGL window and OSG for rendering.
// Derived from osgGLUTsimple.cpp and osgkeyboardmouse.cpp

#include <osgGA/SimpleViewer>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>

#include <QtCore/QTimer>
#include <QtGui/QKeyEvent>
#include <QtGui/QApplication>
#include <QtOpenGL/QGLWidget>

#include <iostream>

class GraphicsWindowQT : public QGLWidget,  virtual osgGA::GraphicsWindow
{
public:

    GraphicsWindowQT( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, Qt::WFlags f = 0 );
    virtual ~GraphicsWindowQT() {}

protected:

    virtual void resizeGL( int width, int height );
    virtual void keyPressEvent( QKeyEvent* event );
    virtual void keyReleaseEvent( QKeyEvent* event );
    virtual void mousePressEvent( QMouseEvent* event );
    virtual void mouseReleaseEvent( QMouseEvent* event );
    virtual void mouseMoveEvent( QMouseEvent* event );

    QTimer _timer;
};

GraphicsWindowQT::GraphicsWindowQT( QWidget * parent, const char * /*name*/, const QGLWidget * shareWidget, Qt::WFlags f):
    QGLWidget(parent, shareWidget, f)
{
    connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
    _timer.start(10);
}

void GraphicsWindowQT::resizeGL( int width, int height )
{
    getEventQueue()->windowResize(0, 0, width, height );
}

void GraphicsWindowQT::keyPressEvent( QKeyEvent* event )
{
    getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) event->key() );
}

void GraphicsWindowQT::keyReleaseEvent( QKeyEvent* event )
{
    getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) event->key() );
}

void GraphicsWindowQT::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void GraphicsWindowQT::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}

void GraphicsWindowQT::mouseMoveEvent( QMouseEvent* event )
{
    getEventQueue()->mouseMotion(event->x(), event->y());
}

class SimpleViewerQT : public osgGA::SimpleViewer, public GraphicsWindowQT
{
    public:
        SimpleViewerQT() {}

        virtual void initializeGL()
        {
            QGLWidget::initializeGL();
        }

        virtual void paintGL()
        {
            frame();
        }

};

int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    SimpleViewerQT* viewerWindow = new SimpleViewerQT;

    viewerWindow->setSceneData(loadedModel.get());
    viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);

    viewerWindow->show();
    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );

    return a.exec();
}

/*EOF*/
<|endoftext|>


<commit_before>#pragma once
// quire_operators.hpp: definition of quire operators
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include <limits>

#define NOW 0

#if NOW
// QUIRE BINARY ARITHMETIC OPERATORS
template<size_t nbits, size_t es, size_t capacity>
inline quire<nbits,es,capacity> operator+(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) {
	quire<nbits, es> sum = lhs;
	sum += rhs;
	return sum;
}

template<size_t nbits, size_t es, size_t capacity>
inline quire<nbits, es, capacity> operator-(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) {
	quire<nbits, es, capacity> diff = lhs;
	diff -= rhs;
	return diff;
}

template<size_t nbits, size_t es, size_t capacity>
inline quire<nbits, es, capacity> operator*(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) {
	quire<nbits, es, capacity> mul = lhs;
	mul *= rhs;
	return mul;
}

template<size_t nbits, size_t es, size_t capacity>
inline quire<nbits, es, capacity> operator/(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) {
	quire<nbits, es, capacity> ratio = lhs;
	ratio /= rhs;
	return ratio;
}
#endif

////////////////// QUIRE
template<size_t nbits, size_t es, size_t capacity>
inline std::ostream& operator<<(std::ostream& ostr, const quire<nbits, es, capacity>& q) {
	ostr << q.sign_value << ": " << q._accu;
	return ostr;
}

template<size_t nbits, size_t es, size_t capacity>
inline std::istream& operator>> (std::istream& istr, const quire<nbits, es, capacity>& q) {
	istr >> q._accu;
	return istr;
}

template<size_t nbits, size_t es, size_t capacity>
inline bool operator==(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) { return lhs._accu == rhs._accu; }
template<size_t nbits, size_t es, size_t capacity>
inline bool operator!=(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) { return !operator==(lhs, rhs); }
template<size_t nbits, size_t es, size_t capacity>
inline bool operator< (const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) { return lhs._accu < rhs._accu; }
template<size_t nbits, size_t es, size_t capacity>
inline bool operator> (const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) { return  operator< (rhs, lhs); }
template<size_t nbits, size_t es, size_t capacity>
inline bool operator<=(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) { return !operator> (lhs, rhs); }
template<size_t nbits, size_t es, size_t capacity>
inline bool operator>=(const quire<nbits, es, capacity>& lhs, const quire<nbits, es, capacity>& rhs) { return !operator< (lhs, rhs); }
<commit_msg>Restructuring quire operators to be usable as stand-alone type<commit_after>#pragma once
// quire_operators.hpp: definition of quire operators
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include <limits><|endoftext|>


<commit_before>#include <iostream>
#include <vector>
using namespace std;
/*
the number of elements (n) and
the length of the range of possible key values (Range)
are approximately the same
Ex: if n=10, min=90, max=100, Range = max-min-1 = 100-90-1= 9
so, n & Range are approximately the same
It requires O(n + Range) time
*/

/* Sorts the array using pigeonhole algorithm */
void pigeonholeSort(int arr[], int n)
{
	// step-1: find max,min in the input array
	int max=arr[0];
	int min=arr[0];
	for(int i=0; i<n; i++){
		if(arr[i]<min)
			min = arr[i];
		if(arr[i]>max)
			max = arr[i];
	}

	// step-2: find range from max,min
	/*
		to index from 0......to [max-min] = max-min+1
		that is why range = max-min+1;
	*/
	int range = max-min+1;

	// step-3 create pigeonhole of size range
	vector<int>pigeonhole[range];

	/* Traverse through input array and put every
       element in its respective hole
       arr[i]-min is mapping from min-based index into 0-based index

    */
	for(int i=0; i<n; i++){
		pigeonhole[arr[i]-min].push_back(arr[i]);
	}

	/* Traverse through all holes one by one. For
       every hole, take its elements and put in array.
    */
	int index = 0;
	for(int i=0; i<range; i++){
		vector<int>::iterator it; // :: is for global scope
		for(it=pigeonhole[i].begin(); it !=pigeonhole[i].end();  it++)
			arr[index++] = *it;
	}
}
int main() {
	// your code goes here
	int arr[] = {8, 3, 2, 7, 4, 6, 8};
	int size = sizeof(arr)/sizeof(arr[0]);
	pigeonholeSort(arr, size);
	cout<<"Sorted order is : ";
    for (int i = 0; i < size; i++)
    	cout<<arr[i]<<" ";

	return 0;
}<commit_msg>Delete pigeonholeSort.cpp<commit_after><|endoftext|>


<commit_before>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "cinder/gl/Texture.h"
#include "cinder/gl/GlslProg.h"
#include "cinder/Log.h"
#include "cinder/gl/Fbo.h"
#include "cinder/gl/Shader.h"
#include "cinder/Timer.h"

#include "IntroSequence.h"
#include "SelfieExperience.h"

#include "cinder/MotionManager.h"
#include "cinder/Timeline.h"
#include "asio/asio.hpp"

#if defined(CINDER_ANDROID)
	#include "cinder/android/CinderAndroid.h"
#elsif defined(CINDER_COCOA_TOUCH)
	#include "cinder/cocoa/CinderCocoaTouch.h"
#endif

using namespace ci;
using namespace ci::app;
using namespace std;

using namespace soso;

class SelfieSelfieApp : public App {
public:
	SelfieSelfieApp();

	void setup() override;
	void playIntroAndGetOrientation();
	void determineSizeIndicator();
	void update() override;
	void draw() override;

  void focusGained();
  void focusLost();

	void updateCamera();
	void updateOrientationOffset();
	void showLandscape();

	void touchesBegan(TouchEvent event) override;
	void touchesEnded(TouchEvent event) override;

private:
	IntroSequence											introduction;
	std::unique_ptr<SelfieExperience> selfieExperience;
	std::string												sizeIndicator = "xhdpi";
	ci::Timer													touchTimer;
	uint32_t													touchId = 0;
	bool															doSaveImage = false;
	std::vector<std::future<void>>		saveActions;

	void saveComplete(bool success);
};

SelfieSelfieApp::SelfieSelfieApp()
{
	#ifdef CINDER_ANDROID
		ci::android::setActivityGainedFocusCallback( [this] { focusGained(); } );
		ci::android::setActivityLostFocusCallback( [this] { focusLost(); } );
	#endif
}

void SelfieSelfieApp::touchesBegan(cinder::app::TouchEvent event)
{
	touchId = event.getTouches().back().getId();
	touchTimer.start();
}

void SelfieSelfieApp::touchesEnded(cinder::app::TouchEvent event)
{
	if (touchId == event.getTouches().back().getId())
	{
		touchTimer.stop();
		if (touchTimer.getSeconds() < 0.16f) {
			doSaveImage = true;
		}
	}
}

void SelfieSelfieApp::setup()
{
  CI_LOG_I("Setting up selfie_x_selfie");

	determineSizeIndicator();
	auto image_path = fs::path("img") / sizeIndicator;
	introduction.setup( image_path );
	introduction.setFinishFn( [this] { showLandscape(); } );
}

void SelfieSelfieApp::focusGained()
{
	CI_LOG_I("Focus Gained");
	if( selfieExperience ) {
		selfieExperience->resume();
	}
}

void SelfieSelfieApp::focusLost()
{
	CI_LOG_I("Focus Lost");
	if( selfieExperience ) {
		selfieExperience->pause();
	}
}

void SelfieSelfieApp::determineSizeIndicator()
{
	auto large_side = toPixels( max( getWindowWidth(), getWindowHeight() ) );

	if( large_side <= 1280 ) {
		sizeIndicator = "xhdpi";
	}
	else if( large_side <= 1920 ) {
		sizeIndicator = "xxhdpi";
	}
	else {
		sizeIndicator = "xxxhdpi";
	}

	CI_LOG_I( "Device size: " << large_side << " using images for: " << sizeIndicator );
}

void SelfieSelfieApp::update()
{
	if( selfieExperience )
	{
		selfieExperience->update();
	}
	else
	{
		io_service().post( [this] {
			auto image_path = fs::path("img") / sizeIndicator;
			selfieExperience = unique_ptr<SelfieExperience>( new SelfieExperience( image_path ) );
			introduction.start();
		} );
	}
}

void SelfieSelfieApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );

	if( selfieExperience )
	{
		selfieExperience->draw();
	}

	if( doSaveImage )
	{
		doSaveImage = false;

		auto future = std::async(std::launch::async, [this] (const Surface &s) {
			bool success = false;
			try {
				cocoa::writeToSavedPhotosAlbum(s);
				success = true;
			} catch (std::exception &exc) {
				CI_LOG_W("Exception saving image: " << exc.what());
			}

			io_service().post([this, success] {
				saveComplete(success);
			});
		}, copyWindowSurface());

		saveActions.emplace_back(std::move(future));
	}

	introduction.draw();

	#if DEBUG
		auto err = gl::getError();
		if( err ) {
			CI_LOG_E( "Draw gl error: " << gl::getErrorString(err) );
		}
	#endif
}

void SelfieSelfieApp::saveComplete(bool success)
{
	saveActions.erase(std::remove_if(saveActions.begin(), saveActions.end(), [] (const std::future<void> &fut) {
		return ! fut.valid();
	}), saveActions.end());
	CI_LOG_I( (success ? "Saved Screenshot" : "Failed to save image") );
}

void SelfieSelfieApp::showLandscape()
{
	if( ! selfieExperience ) {
		auto image_path = fs::path("img") / sizeIndicator;
		selfieExperience = unique_ptr<SelfieExperience>( new SelfieExperience( image_path ) );
	}
	selfieExperience->showLandscape();
}

inline void prepareSettings( app::App::Settings *iSettings )
{
  iSettings->setMultiTouchEnabled();
	iSettings->setHighDensityDisplayEnabled();
	#ifdef CINDER_ANDROID
		iSettings->setKeepScreenOn(true);
	#endif
}

CINDER_APP( SelfieSelfieApp, RendererGl, &prepareSettings )
<commit_msg>Measure save time.<commit_after>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "cinder/gl/Texture.h"
#include "cinder/gl/GlslProg.h"
#include "cinder/Log.h"
#include "cinder/gl/Fbo.h"
#include "cinder/gl/Shader.h"
#include "cinder/Timer.h"

#include "IntroSequence.h"
#include "SelfieExperience.h"

#include "cinder/MotionManager.h"
#include "cinder/Timeline.h"
#include "asio/asio.hpp"

#if defined(CINDER_ANDROID)
	#include "cinder/android/CinderAndroid.h"
#elsif defined(CINDER_COCOA_TOUCH)
	#include "cinder/cocoa/CinderCocoaTouch.h"
#endif

using namespace ci;
using namespace ci::app;
using namespace std;

using namespace soso;

class SelfieSelfieApp : public App {
public:
	SelfieSelfieApp();

	void setup() override;
	void playIntroAndGetOrientation();
	void determineSizeIndicator();
	void update() override;
	void draw() override;

  void focusGained();
  void focusLost();

	void updateCamera();
	void updateOrientationOffset();
	void showLandscape();

	void touchesBegan(TouchEvent event) override;
	void touchesEnded(TouchEvent event) override;

private:
	IntroSequence											introduction;
	std::unique_ptr<SelfieExperience> selfieExperience;
	std::string												sizeIndicator = "xhdpi";
	ci::Timer													touchTimer;
	uint32_t													touchId = 0;
	bool															doSaveImage = false;
	std::vector<std::future<void>>		saveActions;

	void saveComplete(bool success);
};

SelfieSelfieApp::SelfieSelfieApp()
{
	#ifdef CINDER_ANDROID
		ci::android::setActivityGainedFocusCallback( [this] { focusGained(); } );
		ci::android::setActivityLostFocusCallback( [this] { focusLost(); } );
	#endif
}

void SelfieSelfieApp::touchesBegan(cinder::app::TouchEvent event)
{
	touchId = event.getTouches().back().getId();
	touchTimer.start();
}

void SelfieSelfieApp::touchesEnded(cinder::app::TouchEvent event)
{
	if (touchId == event.getTouches().back().getId())
	{
		touchTimer.stop();
		if (touchTimer.getSeconds() < 0.16f) {
			doSaveImage = true;
		}
	}
}

void SelfieSelfieApp::setup()
{
  CI_LOG_I("Setting up selfie_x_selfie");

	determineSizeIndicator();
	auto image_path = fs::path("img") / sizeIndicator;
	introduction.setup( image_path );
	introduction.setFinishFn( [this] { showLandscape(); } );
}

void SelfieSelfieApp::focusGained()
{
	CI_LOG_I("Focus Gained");
	if( selfieExperience ) {
		selfieExperience->resume();
	}
}

void SelfieSelfieApp::focusLost()
{
	CI_LOG_I("Focus Lost");
	if( selfieExperience ) {
		selfieExperience->pause();
	}
}

void SelfieSelfieApp::determineSizeIndicator()
{
	auto large_side = toPixels( max( getWindowWidth(), getWindowHeight() ) );

	if( large_side <= 1280 ) {
		sizeIndicator = "xhdpi";
	}
	else if( large_side <= 1920 ) {
		sizeIndicator = "xxhdpi";
	}
	else {
		sizeIndicator = "xxxhdpi";
	}

	CI_LOG_I( "Device size: " << large_side << " using images for: " << sizeIndicator );
}

void SelfieSelfieApp::update()
{
	if( selfieExperience )
	{
		selfieExperience->update();
	}
	else
	{
		io_service().post( [this] {
			auto image_path = fs::path("img") / sizeIndicator;
			selfieExperience = unique_ptr<SelfieExperience>( new SelfieExperience( image_path ) );
			introduction.start();
		} );
	}
}

void SelfieSelfieApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );

	if( selfieExperience )
	{
		selfieExperience->draw();
	}

	if( doSaveImage )
	{
		ci::Timer timer(true);
		doSaveImage = false;

		auto future = std::async(std::launch::async, [this] (const Surface &s) {
			bool success = false;
			try {
				cocoa::writeToSavedPhotosAlbum(s);
				success = true;
			} catch (std::exception &exc) {
				CI_LOG_W("Exception saving image: " << exc.what());
			}

			io_service().post([this, success] {
				saveComplete(success);
			});
		}, copyWindowSurface());

		saveActions.emplace_back(std::move(future));

		timer.stop();
		CI_LOG_I( "Save time on main thread: " << timer.getSeconds() * 1000 << "ms" );
	}

	introduction.draw();

	#if DEBUG
		auto err = gl::getError();
		if( err ) {
			CI_LOG_E( "Draw gl error: " << gl::getErrorString(err) );
		}
	#endif
}

void SelfieSelfieApp::saveComplete(bool success)
{
	saveActions.erase(std::remove_if(saveActions.begin(), saveActions.end(), [] (const std::future<void> &fut) {
		return ! fut.valid();
	}), saveActions.end());
	CI_LOG_I( (success ? "Saved Screenshot" : "Failed to save image") );
}

void SelfieSelfieApp::showLandscape()
{
	if( ! selfieExperience ) {
		auto image_path = fs::path("img") / sizeIndicator;
		selfieExperience = unique_ptr<SelfieExperience>( new SelfieExperience( image_path ) );
	}
	selfieExperience->showLandscape();
}

inline void prepareSettings( app::App::Settings *iSettings )
{
  iSettings->setMultiTouchEnabled();
	iSettings->setHighDensityDisplayEnabled();
	#ifdef CINDER_ANDROID
		iSettings->setKeepScreenOn(true);
	#endif
}

CINDER_APP( SelfieSelfieApp, RendererGl, &prepareSettings )
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file ccs.C
/// @brief Run and manage the CCS engine
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Craig Hamilton <cchamilt@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include "../mss.H"
#include "ccs.H"

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{
namespace ccs
{

///
/// @brief Start or stop the CCS engine
/// @param[in] i_target The MCBIST containing the CCS engine
/// @param[in] i_start_stop bool MSS_CCS_START for starting, MSS_CCS_STOP otherwise
/// @return FAPI2_RC_SUCCESS iff success
///
template<>
fapi2::ReturnCode start_stop( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, bool i_start_stop )
{
    typedef ccsTraits<TARGET_TYPE_MCBIST> TT;

    fapi2::buffer<uint64_t> l_buf;

    // Do we need to read this? We are setting the only bit defined in the scomdef? BRS
    FAPI_TRY(fapi2::getScom(i_target, TT::CNTLQ_REG, l_buf));

    FAPI_TRY( fapi2::putScom(i_target, TT::CNTLQ_REG,
                             i_start_stop ? l_buf.setBit<TT::CCS_START>() : l_buf.setBit<TT::CCS_STOP>()) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Determine the CCS failure type
/// @tparam T the fapi2 target type of the target for this error
/// @param[in] the failure type
/// @return ReturnCode associated with the fail.
/// @note FFDC is handled here, caller doesn't need to do it
///
template< fapi2::TargetType T >
fapi2::ReturnCode fail_type( const fapi2::Target<T>& i_target, const uint64_t& i_type )
{
    FAPI_ASSERT(STAT_READ_MISCOMPARE != i_type,
                fapi2::MSS_CCS_READ_MISCOMPARE().set_TARGET_IN_ERROR(i_target),
                "CCS FAIL Read Miscompare");

    FAPI_ASSERT(STAT_UE_SUE != i_type,
                fapi2::MSS_CCS_UE_SUE().set_TARGET_IN_ERROR(i_target),
                "CCS FAIL UE or SUE Error");

    FAPI_ASSERT(STAT_CAL_TIMEOUT != i_type,
                fapi2::MSS_CCS_CAL_TIMEOUT().set_TARGET_IN_ERROR(i_target),
                "CCS FAIL Calibration Operation Time Out");

    FAPI_ASSERT(STAT_HUNG != i_type,
                fapi2::MSS_CCS_HUNG().set_TARGET_IN_ERROR(i_target),
                "CCS appears hung");
fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Execute the contents of the CCS array
/// @param[in] i_target The MCBIST containing the array
/// @param[in] the MCBIST ccs program - to get the polling parameters
/// @return FAPI2_RC_SUCCESS iff success
///
template<>
fapi2::ReturnCode execute_inst_array(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
                                     ccs::program<TARGET_TYPE_MCBIST>& i_program)
{
    typedef ccsTraits<TARGET_TYPE_MCBIST> TT;

    fapi2::buffer<uint64_t> status;

    FAPI_TRY(start_stop(i_target, mss::START));

    mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
              [&status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
    {
        FAPI_DBG("ccs statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
        status = stat_reg;
        return status.getBit<TT::CCS_IN_PROGRESS>() != 1;
    });

    // Check for done and success. DONE being the only bit set.
    if (status == STAT_QUERY_SUCCESS)
    {
        FAPI_DBG("CCS Executed Successfully.");
        goto fapi_try_exit;
    }

    // So we failed or we're still in progress. Mask off the fail bits
    // and run this through the FFDC generator.
    FAPI_TRY( fail_type(i_target, status & 0x1C00000000000000) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Execute a set of CCS instructions
/// @tparam T, the fapi2::TargetType - derived
/// @tparam TT, the ccsTraits associated with T - derived
/// @param[in] the target to effect
/// @param[in] the vector of instructions
/// @param[in] the vector of ports
/// @return FAPI2_RC_SUCCSS iff ok
/// @note assumes the CCS engine has been configured.
///
template<>
fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
                           ccs::program<TARGET_TYPE_MCBIST>& i_program,
                           const std::vector< fapi2::Target<TARGET_TYPE_MCA> >& i_ports)
{
    // Subtract one for the idle we insert at the end
    static const size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
    static const uint64_t CCS_ARR0_ZERO = MCBIST_CCS_INST_ARR0_00;
    static const uint64_t CCS_ARR1_ZERO = MCBIST_CCS_INST_ARR1_00;

    ccs::instruction_t<TARGET_TYPE_MCBIST> l_des = ccs::des_command<TARGET_TYPE_MCBIST>();

    FAPI_DBG("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));

    auto l_inst_iter = i_program.iv_instructions.begin();

    while (l_inst_iter != i_program.iv_instructions.end())
    {
        size_t l_inst_count = 0;

        uint64_t l_total_delay = 0;
        uint64_t l_delay = 0;
        uint64_t l_repeat = 0;

        // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
        for (; l_inst_iter != i_program.iv_instructions.end()
             && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
        {
            // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
            // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
            l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
                        MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
            FAPI_TRY( fapi2::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0) );
            FAPI_TRY( fapi2::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1) );

            // arr1 contains a specification of the delay and repeat after this instruction, as well
            // as a repeat. Total up the delays as we go so we know how long to wait before polling
            // the CCS engine for completion
            l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
            l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
                        MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);

            l_total_delay += l_delay * (l_repeat + 1);

            FAPI_DBG("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
                     l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
                     CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
                     l_delay, l_total_delay, mss::c_str(i_target));
        }

        // Check our program for any delays. If there isn't a iv_initial_delay configured, then
        // we use the delay we just summed from the instructions.
        if (i_program.iv_poll.iv_initial_delay == 0)
        {
            i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
        }

        if (i_program.iv_poll.iv_initial_sim_delay == 0)
        {
            i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
        }

        FAPI_DBG("executing ccs instructions (%d:%d, %d) for %s",
                 i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));

        // Insert a DES as our last instruction. DES is idle state anyway and having this
        // here as an instruction forces the CCS engine to wait the delay specified in
        // the last instruction in this array (which it otherwise doesn't do.)
        l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
        FAPI_TRY( fapi2::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0) );
        FAPI_TRY( fapi2::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1) );

        FAPI_DBG("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
                 l_inst_count, l_des.arr0, l_des.arr1,
                 CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));

        // Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
        for (auto p : i_ports)
        {
            FAPI_DBG("executing CCS array for port %d (%s)", mss::pos(p), mss::c_str(p));
            FAPI_TRY( select_ports( i_target, mss::pos(p)) );
            FAPI_TRY( execute_inst_array(i_target, i_program) );
        }
    }

fapi_try_exit:
    i_program.iv_instructions.clear();
    return fapi2::current_err;
}

///
/// @brief Nimbus specialization for modeq_copy_cke_to_spare_cke
/// @tparam T, the fapi2::TargetType - derived
/// @tparam TT, the ccsTraits associated with T - derived
/// @param[in] the target to effect
/// @param[in] the buffer representing the mode register
/// @param[in] bool, true iff Copy CKE signals to CKE Spare on both ports
/// @return void
/// @note no-op for p9n
///
template<>
void copy_cke_to_spare_cke<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>&, fapi2::buffer<uint64_t>&,
        bool )
{
    return;
}

} // namespace
} // namespace
<commit_msg>Added mss::get/putScom<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file ccs.C
/// @brief Run and manage the CCS engine
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Craig Hamilton <cchamilt@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include "../mss.H"
#include "ccs.H"

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{
namespace ccs
{

///
/// @brief Start or stop the CCS engine
/// @param[in] i_target The MCBIST containing the CCS engine
/// @param[in] i_start_stop bool MSS_CCS_START for starting, MSS_CCS_STOP otherwise
/// @return FAPI2_RC_SUCCESS iff success
///
template<>
fapi2::ReturnCode start_stop( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, bool i_start_stop )
{
    typedef ccsTraits<TARGET_TYPE_MCBIST> TT;

    fapi2::buffer<uint64_t> l_buf;

    // Do we need to read this? We are setting the only bit defined in the scomdef? BRS
    FAPI_TRY(mss::getScom(i_target, TT::CNTLQ_REG, l_buf));

    FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG,
                           i_start_stop ? l_buf.setBit<TT::CCS_START>() : l_buf.setBit<TT::CCS_STOP>()) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Determine the CCS failure type
/// @tparam T the fapi2 target type of the target for this error
/// @param[in] the failure type
/// @return ReturnCode associated with the fail.
/// @note FFDC is handled here, caller doesn't need to do it
///
template< fapi2::TargetType T >
fapi2::ReturnCode fail_type( const fapi2::Target<T>& i_target, const uint64_t& i_type )
{
    FAPI_ASSERT(STAT_READ_MISCOMPARE != i_type,
                fapi2::MSS_CCS_READ_MISCOMPARE().set_TARGET_IN_ERROR(i_target),
                "CCS FAIL Read Miscompare");

    FAPI_ASSERT(STAT_UE_SUE != i_type,
                fapi2::MSS_CCS_UE_SUE().set_TARGET_IN_ERROR(i_target),
                "CCS FAIL UE or SUE Error");

    FAPI_ASSERT(STAT_CAL_TIMEOUT != i_type,
                fapi2::MSS_CCS_CAL_TIMEOUT().set_TARGET_IN_ERROR(i_target),
                "CCS FAIL Calibration Operation Time Out");

    FAPI_ASSERT(STAT_HUNG != i_type,
                fapi2::MSS_CCS_HUNG().set_TARGET_IN_ERROR(i_target),
                "CCS appears hung");
fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Execute the contents of the CCS array
/// @param[in] i_target The MCBIST containing the array
/// @param[in] the MCBIST ccs program - to get the polling parameters
/// @return FAPI2_RC_SUCCESS iff success
///
template<>
fapi2::ReturnCode execute_inst_array(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
                                     ccs::program<TARGET_TYPE_MCBIST>& i_program)
{
    typedef ccsTraits<TARGET_TYPE_MCBIST> TT;

    fapi2::buffer<uint64_t> status;

    FAPI_TRY(start_stop(i_target, mss::START));

    mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
              [&status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
    {
        FAPI_DBG("ccs statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
        status = stat_reg;
        return status.getBit<TT::CCS_IN_PROGRESS>() != 1;
    });

    // Check for done and success. DONE being the only bit set.
    if (status == STAT_QUERY_SUCCESS)
    {
        FAPI_DBG("CCS Executed Successfully.");
        goto fapi_try_exit;
    }

    // So we failed or we're still in progress. Mask off the fail bits
    // and run this through the FFDC generator.
    FAPI_TRY( fail_type(i_target, status & 0x1C00000000000000) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Execute a set of CCS instructions
/// @tparam T, the fapi2::TargetType - derived
/// @tparam TT, the ccsTraits associated with T - derived
/// @param[in] the target to effect
/// @param[in] the vector of instructions
/// @param[in] the vector of ports
/// @return FAPI2_RC_SUCCSS iff ok
/// @note assumes the CCS engine has been configured.
///
template<>
fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
                           ccs::program<TARGET_TYPE_MCBIST>& i_program,
                           const std::vector< fapi2::Target<TARGET_TYPE_MCA> >& i_ports)
{
    // Subtract one for the idle we insert at the end
    static const size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
    static const uint64_t CCS_ARR0_ZERO = MCBIST_CCS_INST_ARR0_00;
    static const uint64_t CCS_ARR1_ZERO = MCBIST_CCS_INST_ARR1_00;

    ccs::instruction_t<TARGET_TYPE_MCBIST> l_des = ccs::des_command<TARGET_TYPE_MCBIST>();

    FAPI_DBG("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));

    auto l_inst_iter = i_program.iv_instructions.begin();

    while (l_inst_iter != i_program.iv_instructions.end())
    {
        size_t l_inst_count = 0;

        uint64_t l_total_delay = 0;
        uint64_t l_delay = 0;
        uint64_t l_repeat = 0;

        // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
        for (; l_inst_iter != i_program.iv_instructions.end()
             && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
        {
            // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
            // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
            l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
                        MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
            FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0) );
            FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1) );

            // arr1 contains a specification of the delay and repeat after this instruction, as well
            // as a repeat. Total up the delays as we go so we know how long to wait before polling
            // the CCS engine for completion
            l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
            l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
                        MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);

            l_total_delay += l_delay * (l_repeat + 1);

            FAPI_DBG("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
                     l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
                     CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
                     l_delay, l_total_delay, mss::c_str(i_target));
        }

        // Check our program for any delays. If there isn't a iv_initial_delay configured, then
        // we use the delay we just summed from the instructions.
        if (i_program.iv_poll.iv_initial_delay == 0)
        {
            i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
        }

        if (i_program.iv_poll.iv_initial_sim_delay == 0)
        {
            i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
        }

        FAPI_DBG("executing ccs instructions (%d:%d, %d) for %s",
                 i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));

        // Insert a DES as our last instruction. DES is idle state anyway and having this
        // here as an instruction forces the CCS engine to wait the delay specified in
        // the last instruction in this array (which it otherwise doesn't do.)
        l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
        FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0) );
        FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1) );

        FAPI_DBG("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
                 l_inst_count, l_des.arr0, l_des.arr1,
                 CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));

        // Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
        for (auto p : i_ports)
        {
            FAPI_DBG("executing CCS array for port %d (%s)", mss::pos(p), mss::c_str(p));
            FAPI_TRY( select_ports( i_target, mss::pos(p)) );
            FAPI_TRY( execute_inst_array(i_target, i_program) );
        }
    }

fapi_try_exit:
    i_program.iv_instructions.clear();
    return fapi2::current_err;
}

///
/// @brief Nimbus specialization for modeq_copy_cke_to_spare_cke
/// @tparam T, the fapi2::TargetType - derived
/// @tparam TT, the ccsTraits associated with T - derived
/// @param[in] the target to effect
/// @param[in] the buffer representing the mode register
/// @param[in] bool, true iff Copy CKE signals to CKE Spare on both ports
/// @return void
/// @note no-op for p9n
///
template<>
void copy_cke_to_spare_cke<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>&, fapi2::buffer<uint64_t>&,
        bool )
{
    return;
}

} // namespace
} // namespace
<|endoftext|>


<commit_before>#include "pch.h"
#include "FrameCapturer.h"

#ifdef fcSupportEXR
#include <half.h>
#include <ImfRgbaFile.h>
#include <ImfOutputFile.h>
#include <ImfInputFile.h>
#include <ImfChannelList.h>
#include <ImfStringAttribute.h>
#include <ImfMatrixAttribute.h>
#include <ImfArray.h>
#include "fcFoundation.h"
#include "fcThreadPool.h"
#include "GraphicsDevice/fcGraphicsDevice.h"
#include "fcExrFile.h"

#if defined(fcWindows) && !defined(fcNoAutoLink)
#pragma comment(lib, "Half.lib")
#pragma comment(lib, "Iex-2_2.lib")
#pragma comment(lib, "IexMath-2_2.lib")
#pragma comment(lib, "IlmThread-2_2.lib")
#pragma comment(lib, "IlmImf-2_2.lib")
#pragma comment(lib, "zlibstatic.lib")
#endif

struct fcExrFrameData
{
    std::string path;
    int width, height;
    std::list<std::string> raw_frames;
    Imf::Header header;
    Imf::FrameBuffer frame_buffer;

    fcExrFrameData(const char *p, int w, int h)
        : path(p), width(w), height(h), header(w, h)
    {
        header.compression() = Imf::ZIPS_COMPRESSION;
    }
};

class fcExrContext : public fcIExrContext
{
public:
    fcExrContext(fcExrConfig &conf, fcIGraphicsDevice *dev);
    ~fcExrContext();
    void release() override;
    bool beginFrame(const char *path, int width, int height) override;
    bool addLayerTexture(void *tex, fcTextureFormat fmt, int channel, const char *name, bool flipY) override;
    bool addLayerPixels(const void *pixels, fcPixelFormat fmt, int channel, const char *name, bool flipY) override;
    bool endFrame() override;

private:
    void endFrameTask(fcExrFrameData *exr);

private:
    fcMagic m_magic; //  for debug
    fcExrConfig m_conf;
    fcIGraphicsDevice *m_dev;
    fcExrFrameData *m_exr;
    fcTaskGroup m_tasks;
    std::atomic<int> m_active_task_count;

    const void *m_tex_prev;
};

fcExrContext::fcExrContext(fcExrConfig &conf, fcIGraphicsDevice *dev)
    : m_magic(fcMagic_ExrContext)
    , m_conf(conf)
    , m_dev(dev)
    , m_exr(nullptr)
    , m_active_task_count(0)
    , m_tex_prev(nullptr)
{
}

fcExrContext::~fcExrContext()
{
    m_tasks.wait();
    m_magic = fcMagic_Deleted;
}

void fcExrContext::release()
{
    delete this;
}

bool fcExrContext::beginFrame(const char *path, int width, int height)
{
    if (m_exr != nullptr) { return false; } // beginFrame() されたまま endFrame() されてない

    // 実行中のタスクの数が上限に達している場合適当に待つ
    if (m_active_task_count >= m_conf.max_active_tasks)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        if (m_active_task_count >= m_conf.max_active_tasks)
        {
            m_tasks.wait();
        }
    }

    m_exr = new fcExrFrameData(path, width, height);
    return true;
}

bool fcExrContext::addLayerTexture(void *tex, fcTextureFormat fmt, int channel, const char *name, bool flipY)
{
    std::string *raw_frame = nullptr;

    // フレームバッファの内容取得
    if (tex == m_tex_prev)
    {
        // 前回取得した結果を使い回す
        raw_frame = &m_exr->raw_frames.back();
    }
    else
    {
        m_tex_prev = tex;
        m_exr->raw_frames.push_back(std::string());
        raw_frame = &m_exr->raw_frames.back();
        raw_frame->resize(m_exr->width * m_exr->height * fcGetPixelSize(fmt));
        if (!m_dev->readTexture(&(*raw_frame)[0], raw_frame->size(), tex, m_exr->width, m_exr->height, fmt))
        {
            m_exr->raw_frames.pop_back();
            return false;
        }
    }

    {
        char *raw_data = &(*raw_frame)[0];
        Imf::PixelType pixel_type = Imf::HALF;
        int channels = 0;
        int tsize = 0;
        switch (fmt)
        {
        case fcTextureFormat_ARGBHalf:  pixel_type = Imf::HALF; channels = 4; tsize = 2; break;
        case fcTextureFormat_RGHalf:    pixel_type = Imf::HALF; channels = 2; tsize = 2; break;
        case fcTextureFormat_RHalf:     pixel_type = Imf::HALF; channels = 1; tsize = 2; break;
        case fcTextureFormat_ARGBFloat: pixel_type = Imf::FLOAT; channels = 4; tsize = 4; break;
        case fcTextureFormat_RGFloat:   pixel_type = Imf::FLOAT; channels = 2; tsize = 4; break;
        case fcTextureFormat_RFloat:    pixel_type = Imf::FLOAT; channels = 1; tsize = 4; break;
        case fcTextureFormat_ARGBInt:   pixel_type = Imf::UINT; channels = 4; tsize = 4; break;
        case fcTextureFormat_RGInt:     pixel_type = Imf::UINT; channels = 2; tsize = 4; break;
        case fcTextureFormat_RInt:      pixel_type = Imf::UINT; channels = 1; tsize = 4; break;
        default:
        {
            m_exr->raw_frames.pop_back();
            return false;
        }
        }
        int psize = tsize * channels;

        m_exr->header.channels().insert(name, Imf::Channel(pixel_type));
        m_exr->frame_buffer.insert(name, Imf::Slice(pixel_type, raw_data + (tsize * channel), psize, psize * m_exr->width));
    }
    return true;
}

bool fcExrContext::addLayerPixels(const void *pixels, fcPixelFormat fmt, int channel, const char *name, bool flipY)
{
    std::string *raw_frame = nullptr;

    // フレームバッファの内容取得
    if (pixels == m_tex_prev)
    {
        // 前回取得した結果を使い回す
        raw_frame = &m_exr->raw_frames.back();
    }
    else
    {
        m_tex_prev = pixels;
        m_exr->raw_frames.push_back(std::string());
        raw_frame = &m_exr->raw_frames.back();
        raw_frame->resize(m_exr->width * m_exr->height * fcGetPixelSize(fmt));
        memcpy(&(*raw_frame)[0], pixels, raw_frame->size());
    }

    {
        char *raw_data = &(*raw_frame)[0];
        Imf::PixelType pixel_type = Imf::HALF;
        int channels = 0;
        int tsize = 0;
        switch (fmt)
        {
        case fcPixelFormat_RGBAHalf:  pixel_type = Imf::HALF; channels = 4; tsize = 2; break;
        case fcPixelFormat_RGBHalf:   pixel_type = Imf::HALF; channels = 3; tsize = 2; break;
        case fcPixelFormat_RGHalf:    pixel_type = Imf::HALF; channels = 2; tsize = 2; break;
        case fcPixelFormat_RHalf:     pixel_type = Imf::HALF; channels = 1; tsize = 2; break;
        case fcPixelFormat_RGBAFloat: pixel_type = Imf::FLOAT; channels = 4; tsize = 4; break;
        case fcPixelFormat_RGBFloat:  pixel_type = Imf::FLOAT; channels = 3; tsize = 4; break;
        case fcPixelFormat_RGFloat:   pixel_type = Imf::FLOAT; channels = 2; tsize = 4; break;
        case fcPixelFormat_RFloat:    pixel_type = Imf::FLOAT; channels = 1; tsize = 4; break;
        case fcPixelFormat_RGBAInt:   pixel_type = Imf::UINT; channels = 4; tsize = 4; break;
        case fcPixelFormat_RGBInt:    pixel_type = Imf::UINT; channels = 3; tsize = 4; break;
        case fcPixelFormat_RGInt:     pixel_type = Imf::UINT; channels = 2; tsize = 4; break;
        case fcPixelFormat_RInt:      pixel_type = Imf::UINT; channels = 1; tsize = 4; break;
        default:
        {
            m_exr->raw_frames.pop_back();
            return false;
        }
        }
        int psize = tsize * channels;

        m_exr->header.channels().insert(name, Imf::Channel(pixel_type));
        m_exr->frame_buffer.insert(name, Imf::Slice(pixel_type, raw_data + (tsize * channel), psize, psize * m_exr->width));
    }
    return true;
}

bool fcExrContext::endFrame()
{
    if (m_exr == nullptr) { return false; } // beginFrame() されてない
    m_tex_prev = nullptr;

    fcExrFrameData *exr = m_exr;
    m_exr = nullptr;
    ++m_active_task_count;
    m_tasks.run([this, exr](){
        endFrameTask(exr);
        --m_active_task_count;
    });
    return true;
}

void fcExrContext::endFrameTask(fcExrFrameData *exr)
{
    Imf::OutputFile fout(exr->path.c_str(), exr->header);
    fout.setFrameBuffer(exr->frame_buffer);
    fout.writePixels(exr->height);
    delete exr;
}

fcCLinkage fcExport fcIExrContext* fcExrCreateContextImpl(fcExrConfig &conf, fcIGraphicsDevice *dev)
{
    return new fcExrContext(conf, dev);
}
#endif // fcSupportEXR
<commit_msg>implemented flipY option for fcExrContext<commit_after>#include "pch.h"
#include "FrameCapturer.h"

#ifdef fcSupportEXR
#include <half.h>
#include <ImfRgbaFile.h>
#include <ImfOutputFile.h>
#include <ImfInputFile.h>
#include <ImfChannelList.h>
#include <ImfStringAttribute.h>
#include <ImfMatrixAttribute.h>
#include <ImfArray.h>
#include "fcFoundation.h"
#include "fcThreadPool.h"
#include "GraphicsDevice/fcGraphicsDevice.h"
#include "fcExrFile.h"

#if defined(fcWindows) && !defined(fcNoAutoLink)
#pragma comment(lib, "Half.lib")
#pragma comment(lib, "Iex-2_2.lib")
#pragma comment(lib, "IexMath-2_2.lib")
#pragma comment(lib, "IlmThread-2_2.lib")
#pragma comment(lib, "IlmImf-2_2.lib")
#pragma comment(lib, "zlibstatic.lib")
#endif

struct fcExrFrameData
{
    std::string path;
    int width, height;
    std::list<std::string> raw_frames;
    Imf::Header header;
    Imf::FrameBuffer frame_buffer;

    fcExrFrameData(const char *p, int w, int h)
        : path(p), width(w), height(h), header(w, h)
    {
        header.compression() = Imf::ZIPS_COMPRESSION;
    }
};

class fcExrContext : public fcIExrContext
{
public:
    fcExrContext(fcExrConfig &conf, fcIGraphicsDevice *dev);
    ~fcExrContext();
    void release() override;
    bool beginFrame(const char *path, int width, int height) override;
    bool addLayerTexture(void *tex, fcTextureFormat fmt, int channel, const char *name, bool flipY) override;
    bool addLayerPixels(const void *pixels, fcPixelFormat fmt, int channel, const char *name, bool flipY) override;
    bool endFrame() override;

private:
    void endFrameTask(fcExrFrameData *exr);

private:
    fcMagic m_magic; //  for debug
    fcExrConfig m_conf;
    fcIGraphicsDevice *m_dev;
    fcExrFrameData *m_exr;
    fcTaskGroup m_tasks;
    std::atomic<int> m_active_task_count;

    const void *m_tex_prev;
};

fcExrContext::fcExrContext(fcExrConfig &conf, fcIGraphicsDevice *dev)
    : m_magic(fcMagic_ExrContext)
    , m_conf(conf)
    , m_dev(dev)
    , m_exr(nullptr)
    , m_active_task_count(0)
    , m_tex_prev(nullptr)
{
}

fcExrContext::~fcExrContext()
{
    m_tasks.wait();
    m_magic = fcMagic_Deleted;
}

void fcExrContext::release()
{
    delete this;
}

bool fcExrContext::beginFrame(const char *path, int width, int height)
{
    if (m_exr != nullptr) { return false; } // beginFrame() されたまま endFrame() されてない

    // 実行中のタスクの数が上限に達している場合適当に待つ
    if (m_active_task_count >= m_conf.max_active_tasks)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        if (m_active_task_count >= m_conf.max_active_tasks)
        {
            m_tasks.wait();
        }
    }

    m_exr = new fcExrFrameData(path, width, height);
    return true;
}

// pitch: width * pixel size
static void fcImageFlipY(void *image_, int width, int height, int pitch)
{
    std::vector<char> buf_(pitch);
    char *image = (char*)image_;
    char *buf = &buf_[0];

    for (int y = 0; y < height / 2; ++y) {
        int iy = height - y - 1;
        memcpy(buf, image + (pitch*y), pitch);
        memcpy(image + (pitch*y), image + (pitch*iy), pitch);
        memcpy(image + (pitch*iy), buf, pitch);
    }
}

bool fcExrContext::addLayerTexture(void *tex, fcTextureFormat fmt, int channel, const char *name, bool flipY)
{
    std::string *raw_frame = nullptr;

    // フレームバッファの内容取得
    if (tex == m_tex_prev)
    {
        // 前回取得した結果を使い回す
        raw_frame = &m_exr->raw_frames.back();
    }
    else
    {
        m_tex_prev = tex;
        m_exr->raw_frames.push_back(std::string());
        raw_frame = &m_exr->raw_frames.back();
        raw_frame->resize(m_exr->width * m_exr->height * fcGetPixelSize(fmt));
        if (!m_dev->readTexture(&(*raw_frame)[0], raw_frame->size(), tex, m_exr->width, m_exr->height, fmt))
        {
            m_exr->raw_frames.pop_back();
            return false;
        }
        if (flipY) {
            fcImageFlipY(&(*raw_frame)[0], m_exr->width, m_exr->height, m_exr->width * fcGetPixelSize(fmt));
        }
    }

    {
        Imf::PixelType pixel_type = Imf::HALF;
        int channels = 0;
        int tsize = 0;
        switch (fmt)
        {
        case fcTextureFormat_ARGBHalf:  pixel_type = Imf::HALF; channels = 4; tsize = 2; break;
        case fcTextureFormat_RGHalf:    pixel_type = Imf::HALF; channels = 2; tsize = 2; break;
        case fcTextureFormat_RHalf:     pixel_type = Imf::HALF; channels = 1; tsize = 2; break;
        case fcTextureFormat_ARGBFloat: pixel_type = Imf::FLOAT; channels = 4; tsize = 4; break;
        case fcTextureFormat_RGFloat:   pixel_type = Imf::FLOAT; channels = 2; tsize = 4; break;
        case fcTextureFormat_RFloat:    pixel_type = Imf::FLOAT; channels = 1; tsize = 4; break;
        case fcTextureFormat_ARGBInt:   pixel_type = Imf::UINT; channels = 4; tsize = 4; break;
        case fcTextureFormat_RGInt:     pixel_type = Imf::UINT; channels = 2; tsize = 4; break;
        case fcTextureFormat_RInt:      pixel_type = Imf::UINT; channels = 1; tsize = 4; break;
        default:
            m_exr->raw_frames.pop_back();
            return false;
        }
        int psize = tsize * channels;

        char *raw_data = &(*raw_frame)[0];
        m_exr->header.channels().insert(name, Imf::Channel(pixel_type));
        m_exr->frame_buffer.insert(name, Imf::Slice(pixel_type, raw_data + (tsize * channel), psize, psize * m_exr->width));
    }
    return true;
}

bool fcExrContext::addLayerPixels(const void *pixels, fcPixelFormat fmt, int channel, const char *name, bool flipY)
{
    std::string *raw_frame = nullptr;

    // フレームバッファの内容取得
    if (pixels == m_tex_prev)
    {
        // 前回取得した結果を使い回す
        raw_frame = &m_exr->raw_frames.back();
    }
    else
    {
        m_tex_prev = pixels;
        m_exr->raw_frames.push_back(std::string());
        raw_frame = &m_exr->raw_frames.back();
        raw_frame->resize(m_exr->width * m_exr->height * fcGetPixelSize(fmt));
        memcpy(&(*raw_frame)[0], pixels, raw_frame->size());
        if (flipY) {
            fcImageFlipY(&(*raw_frame)[0], m_exr->width, m_exr->height, m_exr->width * fcGetPixelSize(fmt));
        }
    }

    {
        Imf::PixelType pixel_type = Imf::HALF;
        int channels = 0;
        int tsize = 0;
        switch (fmt)
        {
        case fcPixelFormat_RGBAHalf:  pixel_type = Imf::HALF; channels = 4; tsize = 2; break;
        case fcPixelFormat_RGBHalf:   pixel_type = Imf::HALF; channels = 3; tsize = 2; break;
        case fcPixelFormat_RGHalf:    pixel_type = Imf::HALF; channels = 2; tsize = 2; break;
        case fcPixelFormat_RHalf:     pixel_type = Imf::HALF; channels = 1; tsize = 2; break;
        case fcPixelFormat_RGBAFloat: pixel_type = Imf::FLOAT; channels = 4; tsize = 4; break;
        case fcPixelFormat_RGBFloat:  pixel_type = Imf::FLOAT; channels = 3; tsize = 4; break;
        case fcPixelFormat_RGFloat:   pixel_type = Imf::FLOAT; channels = 2; tsize = 4; break;
        case fcPixelFormat_RFloat:    pixel_type = Imf::FLOAT; channels = 1; tsize = 4; break;
        case fcPixelFormat_RGBAInt:   pixel_type = Imf::UINT; channels = 4; tsize = 4; break;
        case fcPixelFormat_RGBInt:    pixel_type = Imf::UINT; channels = 3; tsize = 4; break;
        case fcPixelFormat_RGInt:     pixel_type = Imf::UINT; channels = 2; tsize = 4; break;
        case fcPixelFormat_RInt:      pixel_type = Imf::UINT; channels = 1; tsize = 4; break;
        default:
            m_exr->raw_frames.pop_back();
            return false;
        }
        int psize = tsize * channels;

        char *raw_data = &(*raw_frame)[0];
        m_exr->header.channels().insert(name, Imf::Channel(pixel_type));
        m_exr->frame_buffer.insert(name, Imf::Slice(pixel_type, raw_data + (tsize * channel), psize, psize * m_exr->width));
    }
    return true;
}

bool fcExrContext::endFrame()
{
    if (m_exr == nullptr) { return false; } // beginFrame() されてない
    m_tex_prev = nullptr;

    fcExrFrameData *exr = m_exr;
    m_exr = nullptr;
    ++m_active_task_count;
    m_tasks.run([this, exr](){
        endFrameTask(exr);
        --m_active_task_count;
    });
    return true;
}

void fcExrContext::endFrameTask(fcExrFrameData *exr)
{
    Imf::OutputFile fout(exr->path.c_str(), exr->header);
    fout.setFrameBuffer(exr->frame_buffer);
    fout.writePixels(exr->height);
    delete exr;
}

fcCLinkage fcExport fcIExrContext* fcExrCreateContextImpl(fcExrConfig &conf, fcIGraphicsDevice *dev)
{
    return new fcExrContext(conf, dev);
}
#endif // fcSupportEXR
<|endoftext|>


<commit_before>/*
 * Otimizator.cpp
 *
 *  Created on: Jul 1, 2015
 *      Author: vader
 */

#include "Otimizator.h"

Otimizator::Otimizator(arma::Mat<int> matrix, vector<int> exp) {
	this->M = matrix;
	this->exp = exp;
	this->variable = exp[0] * 2 - 1;

}

arma::Mat<int> Otimizator::optimize() {
	bool isToStop = false;
	while (!isToStop) {

		std::pair<int,int> pair = this->generateAllPairs();
		if (pair.first == -1) {
			isToStop = true;
			break;
		}
		this->changePair(pair);

	}
	return this->M;
}

void Otimizator::changePair(std::pair<int,int> p) {

	this->m[this->variable] = p;
	this->findAndChange(p);
	this->variable++;
}

void Otimizator::findAndChange(std::pair<int,int> p) {
	int cols_size = this->M.n_cols;
	for (int i = 0; i < cols_size; i++) {
		vector<std::pair<int,int> > result = this->generatePairs(this->M.col(i));
		if (std::find(result.begin(), result.end(), p) != result.end()) {
			arma::Col<int> c = this->removePair(p, this->M.col(i));
			this->M.shed_col(i);
			this->M.insert_cols(i, c);
		}
	}
}

arma::Col<int> Otimizator::removePair(std::pair<int,int> p, arma::Col<int> column) {
	int col_size = column.size();
	for (int i = 0; i < col_size; i++) {
		if (column[i] == p.first) {
			column[i] = this->variable;
		}

	}
	for (int i = 0; i < col_size; i++) {
		if (column[i] == p.second) {
			column[i] = -1;
		}

	}

	return column;
}

std::pair<int,int> Otimizator::generateAllPairs() {
	std::map<std::pair<int,int>, int> allPairs;
	int cols_size = this->M.n_cols;
	for (int i = 0; i < cols_size; i++) {
		vector<std::pair<int,int> > pairs = this->generatePairs(this->M.col(i));
		vector<std::pair<int,int> >::const_iterator cii = pairs.begin();
		while (cii != pairs.end()) {
			std::pair<int,int> p = *cii;
			if (allPairs.count(p)) {
				allPairs[p] = allPairs[p] + 1;
			} else {
				allPairs[p] = 1;
			}
			cii++;
		}
	}
	std::pair<int,int> toReturn(-1, -1);
	int index = 0;
	std::map<std::pair<int,int>, int>::iterator iter;

	for (iter = allPairs.begin(); iter != allPairs.end(); ++iter) {
		if (iter->second > index) {
			toReturn = iter->first;
			index = iter->second;
		}
	}

	return toReturn;
}

vector<std::pair<int,int> > Otimizator::generatePairs(arma::Col<int> column) {
	vector<std::pair<int,int> > result;
	int column_size = column.size();
	for (int i = 1; i < column_size; i++) {
		if (column[i] != -1) {
			int p1 = column[i];
			for (int j = i + 1; j < column_size; j++) {
				int p2 = column[j];
				if (p2 != -1) {
					if (p1 > p2) {
						result.push_back(std::pair<int,int>(p1, p2));
					} else {
						result.push_back(std::pair<int,int>(p2, p1));
					}
				}
			}
		}
	}
	return result;
}
<commit_msg>Corrigido<commit_after>/*
 * Otimizator.cpp
 *
 *  Created on: Jul 1, 2015
 *      Author: vader
 */

#include "Otimizator.h"

Otimizator::Otimizator(arma::Mat<int> matrix, vector<int> exp) {
	this->M = matrix;
	this->exp = exp;
	this->variable = exp[0] * 2 - 1;

}

arma::Mat<int> Otimizator::optimize() {
	bool isToStop = false;
	while (!isToStop) {

		std::pair<int, int> pair = this->generateAllPairs();
		if (pair.first == -1) {
			isToStop = true;
			break;
		}
		this->changePair(pair);

	}

	std::map<int, std::pair<int, int> >::iterator iter;

	for (iter = this->m.begin(); iter != this->m.end(); ++iter) {
		cout << " variavel " << iter->first << " pair : " << iter->second.first
				<< "," << iter->second.second << endl;
	}

	return this->M;
}

void Otimizator::changePair(std::pair<int, int> p) {

	this->m[this->variable] = p;
	this->findAndChange(p);
	this->variable++;
}

void Otimizator::findAndChange(std::pair<int, int> p) {
	int cols_size = this->M.n_cols;
	for (int i = 0; i < cols_size; i++) {
		vector<std::pair<int, int> > result = this->generatePairs(
				this->M.col(i));
		if (std::find(result.begin(), result.end(), p) != result.end()) {
			arma::Col<int> c = this->removePair(p, this->M.col(i));
			this->M.shed_col(i);
			this->M.insert_cols(i, c);
		}
	}
}

arma::Col<int> Otimizator::removePair(std::pair<int, int> p,
		arma::Col<int> column) {
	int col_size = column.size();
	for (int i = 0; i < col_size; i++) {
		if (column[i] == p.first) {
			column[i] = this->variable;
		}

	}
	for (int i = 0; i < col_size; i++) {
		if (column[i] == p.second) {
			column[i] = -1;
		}

	}

	return column;
}

std::pair<int, int> Otimizator::generateAllPairs() {
	std::map<std::pair<int, int>, int> allPairs;
	int cols_size = this->M.n_cols;
	for (int i = 0; i < cols_size; i++) {
		vector<std::pair<int, int> > pairs = this->generatePairs(
				this->M.col(i));
		vector<std::pair<int, int> >::const_iterator cii = pairs.begin();
		while (cii != pairs.end()) {
			std::pair<int, int> p = *cii;
			if (allPairs.count(p)) {
				allPairs[p] = allPairs[p] + 1;
			} else {
				allPairs[p] = 1;
			}
			cii++;
		}
	}
	std::pair<int, int> toReturn(-1, -1);
	int index = 0;
	std::map<std::pair<int, int>, int>::iterator iter;

	for (iter = allPairs.begin(); iter != allPairs.end(); ++iter) {
		if (iter->second > index) {
			toReturn = iter->first;
			index = iter->second;
		}
	}

	return toReturn;
}

vector<std::pair<int, int> > Otimizator::generatePairs(arma::Col<int> column) {
	vector<std::pair<int, int> > result;
	int column_size = column.size();
	for (int i = 1; i < column_size; i++) {
		if (column[i] != -1) {
			int p1 = column[i];
			for (int j = i + 1; j < column_size; j++) {
				int p2 = column[j];
				if (p2 != -1) {
					if (p1 > p2) {
						result.push_back(std::pair<int, int>(p1, p2));
					} else {
						result.push_back(std::pair<int, int>(p2, p1));
					}
				}
			}
		}
	}
	return result;
}
<|endoftext|>