Пример #1
0
static cg_filter_return_t
sdl_window_event_filter(SDL_WindowEvent *event,
                        cg_device_t *dev)
{
    SDL_Window *window;
    cg_framebuffer_t *framebuffer;

    window = SDL_GetWindowFromID(event->windowID);

    if (window == NULL)
        return CG_FILTER_CONTINUE;

    framebuffer = SDL_GetWindowData(window, CG_SDL_WINDOW_DATA_KEY);

    if (framebuffer == NULL || framebuffer->dev != dev)
        return CG_FILTER_CONTINUE;

    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
        cg_display_t *display = dev->display;
        cg_renderer_t *renderer = display->renderer;
        cg_renderer_sdl2_t *sdl_renderer = renderer->winsys;
        float width = event->data1;
        float height = event->data2;
        cg_onscreen_sdl2_t *sdl_onscreen;

        _cg_framebuffer_winsys_update_size(framebuffer, width, height);

        /* We only want to notify that a resize happened when the
         * application calls cg_device_dispatch so instead of
         * immediately notifying we queue an idle callback */
        if (!sdl_renderer->resize_notify_idle) {
            sdl_renderer->resize_notify_idle = _cg_loop_add_idle(
                renderer,
                flush_pending_resize_notifications_idle,
                dev,
                NULL);
        }

        sdl_onscreen = CG_ONSCREEN(framebuffer)->winsys;
        sdl_onscreen->pending_resize_notify = true;
    } else if (event->event == SDL_WINDOWEVENT_EXPOSED) {
        cg_onscreen_dirty_info_t info;

        /* Sadly SDL doesn't seem to report the rectangle of the expose
         * event so we'll just queue the whole window */
        info.x = 0;
        info.y = 0;
        info.width = framebuffer->width;
        info.height = framebuffer->height;

        _cg_onscreen_queue_dirty(CG_ONSCREEN(framebuffer), &info);
    }

    return CG_FILTER_CONTINUE;
}
Пример #2
0
static bool
_cg_winsys_set_gles2_context(cg_gles2_context_t *gles2_ctx,
                             cg_error_t **error)
{
    cg_device_t *dev = gles2_ctx->dev;
    cg_display_egl_t *egl_display = dev->display->winsys;
    bool status;

    if (gles2_ctx->write_buffer && cg_is_onscreen(gles2_ctx->write_buffer))
        status = bind_onscreen_with_context(
            CG_ONSCREEN(gles2_ctx->write_buffer), gles2_ctx->winsys);
    else
        status = _cg_winsys_egl_make_current(dev->display,
                                             egl_display->dummy_surface,
                                             egl_display->dummy_surface,
                                             gles2_ctx->winsys);

    if (!status) {
        _cg_set_error(error,
                      CG_WINSYS_ERROR,
                      CG_WINSYS_ERROR_MAKE_CURRENT,
                      "Failed to make gles2 context current");
        return false;
    }

    return true;
}
Пример #3
0
static void
paint_cb(uv_idle_t *idle)
{
    Data *data = idle->data;
    cg_error_t *error = NULL;
    const cg_gles2_vtable_t *gles2 = data->gles2_vtable;

    /* Draw scene with GLES2 */
    if (!cg_push_gles2_context(
            data->dev, data->gles2_ctx, data->fb, data->fb, &error)) {
        c_error("Failed to push gles2 context: %s\n", error->message);
    }

    /* Clear offscreen framebuffer with a random color */
    gles2->glClearColor(
        c_random_double(), c_random_double(), c_random_double(), 1.0f);
    gles2->glClear(GL_COLOR_BUFFER_BIT);

    cg_pop_gles2_context(data->dev);

    /* Draw scene with Cogl */
    cg_primitive_draw(data->triangle, data->fb, data->pipeline);

    cg_onscreen_swap_buffers(CG_ONSCREEN(data->fb));

    uv_idle_stop(&data->idle);
}
Пример #4
0
static cg_onscreen_t *
find_onscreen_for_xid(cg_device_t *dev, uint32_t xid)
{
    c_llist_t *l;

    for (l = dev->framebuffers; l; l = l->next) {
        cg_framebuffer_t *framebuffer = l->data;
        cg_onscreen_egl_t *egl_onscreen;
        cg_onscreen_xlib_t *xlib_onscreen;

        if (!framebuffer->type == CG_FRAMEBUFFER_TYPE_ONSCREEN)
            continue;

        egl_onscreen = CG_ONSCREEN(framebuffer)->winsys;
        xlib_onscreen = egl_onscreen->platform;
        if (xlib_onscreen->xwin == (Window)xid)
            return CG_ONSCREEN(framebuffer);
    }

    return NULL;
}
Пример #5
0
static void
flush_pending_notifications_cb(void *data, void *user_data)
{
    cg_framebuffer_t *framebuffer = data;

    if (framebuffer->type == CG_FRAMEBUFFER_TYPE_ONSCREEN) {
        cg_onscreen_t *onscreen = CG_ONSCREEN(framebuffer);
        cg_onscreen_sdl2_t *sdl_onscreen = onscreen->winsys;

        if (sdl_onscreen->pending_resize_notify) {
            _cg_onscreen_notify_resize(onscreen);
            sdl_onscreen->pending_resize_notify = false;
        }
    }
}
Пример #6
0
static void
redraw(Data *data)
{
    cg_framebuffer_t *fb = data->fb;

    cg_framebuffer_clear4f(fb, CG_BUFFER_BIT_COLOR, 0, 0, 0, 1);

    cg_framebuffer_push_matrix(fb);
    cg_framebuffer_translate(fb, data->center_x, -data->center_y, 0.0f);

    cg_primitive_draw(data->triangle, fb, data->pipeline);
    cg_framebuffer_pop_matrix(fb);

    cg_onscreen_swap_buffers(CG_ONSCREEN(fb));
}
Пример #7
0
int
main(int argc, char **argv)
{
    Data data;
    cg_onscreen_t *onscreen;
    cg_error_t *error = NULL;
    cg_vertex_p2c4_t triangle_vertices[] = {
        { 0, 0.7, 0xff, 0x00, 0x00, 0xff },
        { -0.7, -0.7, 0x00, 0xff, 0x00, 0xff },
        { 0.7, -0.7, 0x00, 0x00, 0xff, 0xff }
    };
    cg_renderer_t *renderer;
    cg_display_t *display;
    uv_loop_t *loop = uv_default_loop();

    renderer = cg_renderer_new();
    cg_renderer_add_constraint(renderer,
                               CG_RENDERER_CONSTRAINT_SUPPORTS_CG_GLES2);

    if (!cg_renderer_connect(renderer, &error)) {
        c_error("%s", error->message);
        exit(1);
    }

    display = cg_display_new(renderer, NULL);
    data.dev = cg_device_new();
    cg_device_set_display(data.dev, display);

    if (!cg_device_connect(data.dev, &error)) {
        c_error("%s", error->message);
        exit(1);
    }

    onscreen = cg_onscreen_new(data.dev, 640, 480);
    cg_onscreen_show(onscreen);
    data.fb = onscreen;

    /* Prepare onscreen primitive */
    data.triangle = cg_primitive_new_p2c4(
        data.dev, CG_VERTICES_MODE_TRIANGLES, 3, triangle_vertices);
    data.pipeline = cg_pipeline_new(data.dev);

    data.offscreen_texture = cg_texture_2d_new_with_size(
        data.dev, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT);
    data.offscreen = cg_offscreen_new_with_texture(data.offscreen_texture);

    data.gles2_ctx = cg_gles2_context_new(data.dev, &error);
    if (!data.gles2_ctx) {
        c_error("Failed to create GLES2 context: %s\n", error->message);
    }

    data.gles2_vtable = cg_gles2_context_get_vtable(data.gles2_ctx);

    /* Draw scene with GLES2 */
    if (!cg_push_gles2_context(
            data.dev, data.gles2_ctx, data.fb, data.fb, &error)) {
        c_error("Failed to push gles2 context: %s\n", error->message);
    }

    cg_pop_gles2_context(data.dev);

    cg_onscreen_add_frame_callback(
        CG_ONSCREEN(data.fb), frame_event_cb, &data, NULL); /* destroy notify */

    uv_idle_init(loop, &data.idle);
    data.idle.data = &data;
    uv_idle_start(&data.idle, paint_cb);

    cg_uv_set_mainloop(data.dev, loop);
    uv_run(loop, UV_RUN_DEFAULT);

    return 0;
}