Example #1
0
static gboolean
_cogl_blit_framebuffer_begin (CoglBlitData *data)
{
  CoglHandle dst_fbo, src_fbo;
  gboolean ret;

  _COGL_GET_CONTEXT (ctx, FALSE);

  /* We can only blit between FBOs if both textures are the same
     format and the blit framebuffer extension is supported */
  if ((cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) !=
      (cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) ||
      !(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT))
    return FALSE;

  dst_fbo = _cogl_offscreen_new_to_texture_full
    (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);

  if (dst_fbo == COGL_INVALID_HANDLE)
    ret = FALSE;
  else
    {
      if (!cogl_framebuffer_allocate (dst_fbo, NULL))
        ret = FALSE;
      else
        {
          src_fbo = _cogl_offscreen_new_to_texture_full
            (data->src_tex,
             COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL,
             0 /* level */);

          if (src_fbo == COGL_INVALID_HANDLE)
            ret = FALSE;
          else
            {
              if (!cogl_framebuffer_allocate (src_fbo, NULL))
                ret = FALSE;
              else
                _cogl_push_framebuffers (dst_fbo, src_fbo);

              cogl_handle_unref (src_fbo);
            }
        }

      cogl_handle_unref (dst_fbo);
    }

  return ret;
}
Example #2
0
static gboolean
_cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
{
  CoglHandle fbo;

  _COGL_GET_CONTEXT (ctx, FALSE);

  /* This will only work if the target texture is a CoglTexture2D */
  if (!cogl_is_texture_2d (data->dst_tex))
    return FALSE;

  fbo = _cogl_offscreen_new_to_texture_full
    (data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);

  if (fbo == COGL_INVALID_HANDLE)
    return FALSE;

  if (!cogl_framebuffer_allocate (fbo, NULL))
    {
      cogl_handle_unref (fbo);
      return FALSE;
    }

  cogl_push_framebuffer (fbo);
  cogl_handle_unref (fbo);

  return TRUE;
}
Example #3
0
File: cogland.c Project: 3v1n0/cogl
static void
cogland_compositor_create_output (CoglandCompositor *compositor,
                                  int x,
                                  int y,
                                  int width_mm,
                                  int height_mm)
{
  CoglandOutput *output = g_slice_new0 (CoglandOutput);
  CoglFramebuffer *fb;
  CoglError *error = NULL;
  CoglandMode *mode;

  output->x = x;
  output->y = y;
  output->width_mm = width_mm;
  output->height_mm = height_mm;

  output->wayland_output.interface = &wl_output_interface;

  wl_display_add_global (compositor->wayland_display,
                         &wl_output_interface,
                         output,
                         bind_output);

  output->onscreen = cogl_onscreen_new (compositor->cogl_context,
                                        width_mm, height_mm);
  /* Eventually there will be an implicit allocate on first use so this
   * will become optional... */
  fb = output->onscreen;
  if (!cogl_framebuffer_allocate (fb, &error))
    g_error ("Failed to allocate framebuffer: %s\n", error->message);

  cogl_onscreen_add_dirty_callback (output->onscreen,
                                    dirty_cb,
                                    compositor,
                                    NULL /* destroy */);

  cogl_onscreen_show (output->onscreen);
  cogl_framebuffer_set_viewport (fb,
                                 -x, -y,
                                 compositor->virtual_width,
                                 compositor->virtual_height);

  mode = g_slice_new0 (CoglandMode);
  mode->flags = 0;
  mode->width = width_mm;
  mode->height = height_mm;
  mode->refresh = 60;

  output->modes = g_list_prepend (output->modes, mode);

  compositor->outputs = g_list_prepend (compositor->outputs, output);
}
struct wl_shell_surface *
cogl_wayland_onscreen_get_shell_surface (CoglOnscreen *onscreen)
{
  CoglOnscreenEGL *egl_onscreen;
  CoglOnscreenWayland *wayland_onscreen;

  cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), NULL);

  egl_onscreen = onscreen->winsys;
  wayland_onscreen = egl_onscreen->platform;

  return wayland_onscreen->wayland_shell_surface;
}
Example #5
0
SDL_Window *
cogl_sdl_onscreen_get_window (CoglOnscreen *onscreen)
{
  CoglOnscreenSdl2 *sdl_onscreen;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_onscreen (onscreen), NULL);

  if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), NULL))
    return NULL;

  sdl_onscreen = onscreen->winsys;

  return sdl_onscreen->window;
}
Example #6
0
static void
texture_tower_revalidate_fbo (MetaTextureTower *tower,
                              int               level)
{
  CoglTexture *source_texture = tower->textures[level - 1];
  int source_texture_width = cogl_texture_get_width (source_texture);
  int source_texture_height = cogl_texture_get_height (source_texture);
  CoglTexture *dest_texture = tower->textures[level];
  int dest_texture_width = cogl_texture_get_width (dest_texture);
  int dest_texture_height = cogl_texture_get_height (dest_texture);
  Box *invalid = &tower->invalid[level];
  CoglFramebuffer *fb;
  CoglError *catch_error = NULL;
  CoglPipeline *pipeline;

  if (tower->fbos[level] == NULL)
    tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);

  fb = COGL_FRAMEBUFFER (tower->fbos[level]);

  if (!cogl_framebuffer_allocate (fb, &catch_error))
    {
      cogl_error_free (catch_error);
      return;
    }

  cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.);

  if (!tower->pipeline_template)
    {
      CoglContext *ctx =
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
      tower->pipeline_template = cogl_pipeline_new (ctx);
      cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
    }

  pipeline = cogl_pipeline_copy (tower->pipeline_template);
  cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);

  cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
                                            invalid->x1, invalid->y1,
                                            invalid->x2, invalid->y2,
                                            (2. * invalid->x1) / source_texture_width,
                                            (2. * invalid->y1) / source_texture_height,
                                            (2. * invalid->x2) / source_texture_width,
                                            (2. * invalid->y2) / source_texture_height);

  cogl_object_unref (pipeline);
}
static void init()
{
    CoglError *error = NULL;
    CoglDisplay *display;
    CoglRenderer *renderer;
    CoglBool missing_requirement;

    //g_setenv ("COGL_X11_SYNC", "1", 0);

    test_ctx = cogl_context_new (NULL, &error);
    if (!test_ctx) {
        g_message ("Failed to create a CoglContext: %s", error->message);
        exit(1);
    }

    display = cogl_context_get_display (test_ctx);
    renderer = cogl_display_get_renderer (display);

    if (!check_flags (renderer)) {
        g_message ("WARNING: Missing required feature[s] for this test\n");
        exit(1);
    }

    {
        //TODO: get all monitors size to test
        CoglOffscreen *offscreen;
        CoglTexture2D *tex = cogl_texture_2d_new_with_size (test_ctx,
                FB_WIDTH, FB_HEIGHT);
        offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (tex));
        test_fb = COGL_FRAMEBUFFER (offscreen);
    }

    if (!cogl_framebuffer_allocate (test_fb, &error)) {
        g_message ("Failed to allocate framebuffer: %s", error->message);
        exit(1);
    }

    cogl_framebuffer_clear4f (test_fb,
            COGL_BUFFER_BIT_COLOR |
            COGL_BUFFER_BIT_DEPTH |
            COGL_BUFFER_BIT_STENCIL,
            0, 0, 0, 1);
}
Example #8
0
static int test_init (TestData* data)
{
  CoglOnscreen *onscreen;
  GError *error = NULL;
  CoglVertexP2C4 triangle_vertices[] = {
        {0, 0.7, 0xff, 0x00, 0x00, 0x80},
        {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
        {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
  };

  cogl_android_set_native_window (data->app->window);

  data->context = cogl_context_new (NULL, &error);
  if (!data->context)
    {
      g_critical ("Failed to create context: %s\n", error->message);
      return 1;
    }

  onscreen = cogl_onscreen_new (data->context, 320, 420);

  /* Eventually there will be an implicit allocate on first use so this
   * will become optional... */
  data->fb = COGL_FRAMEBUFFER (onscreen);
  if (!cogl_framebuffer_allocate (data->fb, &error))
    {
      if (error)
        g_critical ("Failed to allocate framebuffer: %s\n", error->message);
      else
        g_critical ("Failed to allocate framebuffer");
      return 1;
    }

  cogl_onscreen_show (onscreen);

  cogl_push_framebuffer (data->fb);

  data->triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
                                            3, triangle_vertices);

  return 0;
}
Example #9
0
void
_clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
{
  if (backend->dummy_onscreen == COGL_INVALID_HANDLE)
    {
      CoglError *internal_error = NULL;

      backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1);

      if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend->dummy_onscreen),
                                      &internal_error))
        {
          g_critical ("Unable to create dummy onscreen: %s", internal_error->message);
          cogl_error_free (internal_error);
          return;
        }
    }

  cogl_set_framebuffer (COGL_FRAMEBUFFER (backend->dummy_onscreen));
}
Example #10
0
static void
cogland_compositor_create_output (CoglandCompositor *compositor,
                                  int x,
                                  int y,
                                  int width,
                                  int height)
{
  CoglandOutput *output = g_slice_new0 (CoglandOutput);
  CoglFramebuffer *fb;
  GError *error = NULL;

  output->wayland_output.interface = &wl_output_interface;

  wl_display_add_object (compositor->wayland_display, &output->wayland_output);
  wl_display_add_global (compositor->wayland_display, &output->wayland_output,
                         cogland_output_post_geometry);

  output->onscreen = cogl_onscreen_new (compositor->cogl_context,
                                        width, height);
  /* Eventually there will be an implicit allocate on first use so this
   * will become optional... */
  fb = COGL_FRAMEBUFFER (output->onscreen);
  if (!cogl_framebuffer_allocate (fb, &error))
    g_error ("Failed to allocate framebuffer: %s\n", error->message);

  cogl_onscreen_show (output->onscreen);
#if 0
  cogl_framebuffer_set_viewport (fb, x, y, width, height);
#else
  cogl_push_framebuffer (fb);
  cogl_set_viewport (-x, -y,
                     compositor->virtual_width,
                     compositor->virtual_height);
  cogl_pop_framebuffer ();
#endif

  compositor->outputs = g_list_prepend (compositor->outputs, output);
}
Example #11
0
File: msaa.c Project: jsdir/_
int
main (int argc, char **argv)
{
    CoglOnscreenTemplate *onscreen_template;
    CoglDisplay *display;
    CoglContext *ctx;
    CoglOnscreen *onscreen;
    CoglFramebuffer *fb;
    CoglError *error = NULL;
    CoglVertexP2C4 triangle_vertices[] = {
        {0, 0.7, 0xff, 0x00, 0x00, 0x80},
        {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
        {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
    };
    CoglPrimitive *triangle;
    CoglTexture *tex;
    CoglOffscreen *offscreen;
    CoglFramebuffer *offscreen_fb;
    CoglPipeline *pipeline;

    onscreen_template = cogl_onscreen_template_new (NULL);
    cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4);
    display = cogl_display_new (NULL, onscreen_template);

    if (!cogl_display_setup (display, &error))
      {
        fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n",
                 error->message);
        return 1;
      }

    ctx = cogl_context_new (display, &error);
    if (!ctx)
      {
        fprintf (stderr, "Failed to create context: %s\n", error->message);
        return 1;
      }

    onscreen = cogl_onscreen_new (ctx, 640, 480);
    fb = COGL_FRAMEBUFFER (onscreen);

    cogl_framebuffer_set_samples_per_pixel (fb, 4);

    if (!cogl_framebuffer_allocate (fb, &error))
      {
        fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
                 "disabling msaa for onscreen rendering: %s\n", error->message);
        cogl_error_free (error);
        cogl_framebuffer_set_samples_per_pixel (fb, 0);

        error = NULL;
        if (!cogl_framebuffer_allocate (fb, &error))
          {
            fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
            return 1;
          }
      }

    cogl_onscreen_show (onscreen);

    tex = cogl_texture_new_with_size (ctx,
                                      320, 480,
                                      COGL_TEXTURE_NO_SLICING,
                                      COGL_PIXEL_FORMAT_ANY);
    offscreen = cogl_offscreen_new_to_texture (tex);
    offscreen_fb = COGL_FRAMEBUFFER (offscreen);
    cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4);
    if (!cogl_framebuffer_allocate (offscreen_fb, &error))
      {
        cogl_error_free (error);
        error = NULL;
        fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
                 "disabling msaa for offscreen rendering");
        cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0);
      }

    triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
                                        3, triangle_vertices);
    pipeline = cogl_pipeline_new (ctx);

    for (;;) {
        CoglPollFD *poll_fds;
        int n_poll_fds;
        int64_t timeout;
        CoglPipeline *texture_pipeline;

        cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

        cogl_framebuffer_push_matrix (fb);
        cogl_framebuffer_scale (fb, 0.5, 1, 1);
        cogl_framebuffer_translate (fb, -1, 0, 0);
        cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
        cogl_framebuffer_pop_matrix (fb);

        cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
        cogl_framebuffer_resolve_samples (offscreen_fb);

        texture_pipeline = cogl_pipeline_new (ctx);
        cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex);
        cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1);
        cogl_object_unref (texture_pipeline);

        cogl_onscreen_swap_buffers (onscreen);

        cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
        g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
        cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
    }

    return 0;
}
Example #12
0
CoglPipeline *
_st_create_shadow_pipeline_from_actor (StShadow     *shadow_spec,
                                       ClutterActor *actor)
{
    CoglPipeline *shadow_pipeline = NULL;

    if (CLUTTER_IS_TEXTURE (actor))
    {
        CoglTexture *texture;

        texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));
        shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture);
    }
    else
    {
        CoglTexture *buffer;
        CoglOffscreen *offscreen;
        CoglFramebuffer *fb;
        ClutterActorBox box;
        CoglColor clear_color;
        float width, height;
        CoglError *catch_error = NULL;

        clutter_actor_get_allocation_box (actor, &box);
        clutter_actor_box_get_size (&box, &width, &height);

        if (width == 0 || height == 0)
            return NULL;

        buffer = cogl_texture_new_with_size (width,
                                             height,
                                             COGL_TEXTURE_NO_SLICING,
                                             COGL_PIXEL_FORMAT_ANY);

        if (buffer == NULL)
            return NULL;

        offscreen = cogl_offscreen_new_with_texture (buffer);
        fb = COGL_FRAMEBUFFER (offscreen);

        if (!cogl_framebuffer_allocate (fb, &catch_error))
        {
            cogl_error_free (catch_error);
            cogl_object_unref (buffer);
            return NULL;
        }

        cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);

        /* XXX: There's no way to render a ClutterActor to an offscreen
         * as it uses the implicit API. */
        G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
        cogl_push_framebuffer (fb);
        G_GNUC_END_IGNORE_DEPRECATIONS;

        cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
        cogl_framebuffer_translate (fb, -box.x1, -box.y1, 0);
        cogl_framebuffer_orthographic (fb, 0, 0, width, height, 0, 1.0);

        clutter_actor_set_opacity_override (actor, 255);
        clutter_actor_paint (actor);
        clutter_actor_set_opacity_override (actor, -1);

        G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
        cogl_pop_framebuffer ();
        G_GNUC_END_IGNORE_DEPRECATIONS;

        cogl_object_unref (fb);

        shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, buffer);

        cogl_object_unref (buffer);
    }

    return shadow_pipeline;
}
Example #13
0
static CoglHandle
data_to_cogl_handle (const guchar *data,
                     gboolean      has_alpha,
                     int           width,
                     int           height,
                     int           rowstride,
                     gboolean      add_padding)
{
  CoglHandle texture, offscreen;
  CoglColor clear_color;
  guint size;
  GError *error;

  size = MAX (width, height);

  if (!add_padding || width == height)
    return cogl_texture_new_from_data (width,
                                       height,
                                       COGL_TEXTURE_NONE,
                                       has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                                       COGL_PIXEL_FORMAT_ANY,
                                       rowstride,
                                       data);

  texture = cogl_texture_new_with_size (size, size,
                                        COGL_TEXTURE_NO_SLICING,
                                        COGL_PIXEL_FORMAT_ANY);

  offscreen = cogl_offscreen_new_with_texture (texture);

  error = NULL;
  if (!cogl_framebuffer_allocate (offscreen, &error))
    {
      g_warning ("Failed to allocate FBO (sized %d): %s", size, error->message);

      cogl_object_unref (texture);
      cogl_object_unref (offscreen);
      g_clear_error (&error);

      return cogl_texture_new_from_data (width,
                                         height,
                                         COGL_TEXTURE_NONE,
                                         has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                                         COGL_PIXEL_FORMAT_ANY,
                                         rowstride,
                                         data);
  }

  cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
  cogl_push_framebuffer (offscreen);
  cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
  cogl_pop_framebuffer ();
  cogl_handle_unref (offscreen);

  cogl_texture_set_region (texture,
                           0, 0,
                           (size - width) / 2, (size - height) / 2,
                           width, height,
                           width, height,
                           has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                           rowstride,
                           data);
  return texture;
}
static gboolean
clutter_stage_win32_realize (ClutterStageWindow *stage_window)
{
  ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
  ClutterBackend *backend;
  ClutterBackendWin32 *backend_win32;
  CoglFramebuffer *framebuffer;
  gfloat width;
  gfloat height;
  GError *error = NULL;

  CLUTTER_NOTE (MISC, "Realizing main stage");

  backend = CLUTTER_BACKEND (stage_win32->backend);
  backend_win32 = CLUTTER_BACKEND_WIN32 (backend);

  clutter_actor_get_size (CLUTTER_ACTOR (stage_win32->wrapper),
                          &width, &height);

  stage_win32->onscreen = cogl_onscreen_new (backend->cogl_context,
                                             width, height);

  if (stage_win32->hwnd == NULL)
    {
      ATOM window_class = clutter_stage_win32_get_window_class ();
      int win_xpos, win_ypos, win_width, win_height;

      if (window_class == 0)
        {
          g_critical ("Unable to register window class");
          goto fail;
        }

      /* If we're in fullscreen mode then use the fullscreen rect
         instead */
      if (_clutter_stage_is_fullscreen (stage_win32->wrapper))
        {
          get_fullscreen_rect (stage_win32);
          win_xpos = stage_win32->fullscreen_rect.left;
          win_ypos = stage_win32->fullscreen_rect.top;
          win_width = stage_win32->fullscreen_rect.right - win_xpos;
          win_height = stage_win32->fullscreen_rect.bottom - win_ypos;
        }
      else
        {
          win_xpos = win_ypos = CW_USEDEFAULT;

          get_full_window_size (stage_win32,
                                stage_win32->win_width,
                                stage_win32->win_height,
                                &win_width, &win_height);
        }

      if (stage_win32->wtitle == NULL)
        stage_win32->wtitle = g_utf8_to_utf16 (".", -1, NULL, NULL, NULL);

      stage_win32->hwnd = CreateWindowW ((LPWSTR) MAKEINTATOM (window_class),
					 stage_win32->wtitle,
					 get_window_style (stage_win32),
					 win_xpos,
					 win_ypos,
					 win_width,
					 win_height,
					 NULL, NULL,
					 GetModuleHandle (NULL),
					 NULL);

      if (stage_win32->hwnd == NULL)
        {
          g_critical ("Unable to create stage window");
          goto fail;
        }

      /* Store a pointer to the actor in the extra bytes of the window
         so we can quickly access it in the window procedure */
      SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) stage_win32);
    }

  cogl_win32_onscreen_set_foreign_window (stage_win32->onscreen,
                                          stage_win32->hwnd);

  cogl_onscreen_set_swap_throttled (stage_win32->onscreen,
                                    _clutter_get_sync_to_vblank ());

  framebuffer = COGL_FRAMEBUFFER (stage_win32->onscreen);
  if (!cogl_framebuffer_allocate (framebuffer, &error))
    {
      g_warning ("Failed to allocate stage: %s", error->message);
      g_error_free (error);
      cogl_object_unref (stage_win32->onscreen);
      stage_win32->onscreen = NULL;
      goto fail;
    }

  /* Create a context. This will be a no-op if we already have one */
  if (!_clutter_backend_create_context (CLUTTER_BACKEND (backend_win32),
                                        &error))
    {
      g_critical ("Unable to realize stage: %s", error->message);
      g_error_free (error);
      goto fail;
    }

  CLUTTER_NOTE (BACKEND, "Successfully realized stage");

  return TRUE;

 fail:
  return FALSE;
}
Example #15
0
static gboolean
_cogl_blit_texture_render_begin (CoglBlitData *data)
{
  CoglHandle fbo;
  CoglPipeline *pipeline;
  unsigned int dst_width, dst_height;

  _COGL_GET_CONTEXT (ctx, FALSE);

  fbo = _cogl_offscreen_new_to_texture_full
    (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */);

  if (fbo == COGL_INVALID_HANDLE)
    return FALSE;

  if (!cogl_framebuffer_allocate (fbo, NULL))
    {
      cogl_handle_unref (fbo);
      return FALSE;
    }

  cogl_push_framebuffer (fbo);
  cogl_handle_unref (fbo);

  dst_width = cogl_texture_get_width (data->dst_tex);
  dst_height = cogl_texture_get_height (data->dst_tex);

  /* Set up an orthographic projection so we can use pixel
     coordinates to render to the texture */
  cogl_ortho (0, /* left */
              dst_width, /* right */
              dst_height, /* bottom */
              0, /* top */
              -1, /* near */
              1 /* far */);

  /* We cache a pipeline used for migrating on to the context so
     that it doesn't have to continuously regenerate a shader
     program */
  if (ctx->blit_texture_pipeline == NULL)
    {
      ctx->blit_texture_pipeline = cogl_pipeline_new ();

      cogl_pipeline_set_layer_filters (ctx->blit_texture_pipeline, 0,
                                       COGL_PIPELINE_FILTER_NEAREST,
                                       COGL_PIPELINE_FILTER_NEAREST);

      /* Disable blending by just directly taking the contents of the
         source texture */
      cogl_pipeline_set_blend (ctx->blit_texture_pipeline,
                               "RGBA = ADD(SRC_COLOR, 0)",
                               NULL);
    }

  pipeline = ctx->blit_texture_pipeline;

  cogl_pipeline_set_layer_texture (pipeline, 0, data->src_tex);

  _cogl_push_source (pipeline, FALSE);

  return TRUE;
}
Example #16
0
CoglOnscreen* ImGui_ImplGtk3Cogl_Init(GtkWidget* widget,
                                      void (*callback)(CoglOnscreen *onscreen, void *data),
                                      void *data)
{
    g_clear_pointer(&g_GtkWidget, g_object_unref);
    g_clear_pointer(&g_GdkWindow, g_object_unref);
    g_clear_pointer(&g_Framebuffer, cogl_object_unref);
    g_clear_pointer(&g_Context, cogl_object_unref);

    g_GtkWidget = GTK_WIDGET(g_object_ref(widget));
    gtk_widget_realize(widget);
    GdkWindow *parent_window = gtk_widget_get_window(widget);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);

    g_Callbacks = get_backend_callbacks(parent_window);

    GdkWindowAttr attributes;
    memset(&attributes, 0, sizeof(attributes));
    attributes.x = 0;
    attributes.y = 0;
    attributes.width = allocation.width;
    attributes.height = allocation.height;
    attributes.wclass = GDK_INPUT_OUTPUT;
    attributes.window_type = g_Callbacks->winsys == COGL_WINSYS_ID_EGL_WAYLAND ?
        GDK_WINDOW_SUBSURFACE : GDK_WINDOW_CHILD;

    GdkDisplay *display = gdk_window_get_display(parent_window);
    attributes.visual = gtk_widget_get_visual(widget);

    g_GdkWindow = gdk_window_new(parent_window, &attributes,
                                 GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
    gdk_window_set_transient_for(g_GdkWindow, parent_window);
    gdk_window_set_pass_through(g_GdkWindow, TRUE);

    cairo_rectangle_int_t empty_rect;
    memset(&empty_rect, 0, sizeof(empty_rect));
    cairo_region_t *input_region = cairo_region_create_rectangle(&empty_rect);
    gdk_window_input_shape_combine_region(g_GdkWindow, input_region, 0, 0);
    cairo_region_destroy(input_region);

    cairo_region_t *region = get_window_region(g_GdkWindow);
    gdk_window_set_opaque_region(g_GdkWindow, region);
    cairo_region_destroy(region);

    CoglRenderer *renderer = cogl_renderer_new();
    cogl_renderer_set_winsys_id(renderer, g_Callbacks->winsys);
    g_Callbacks->init(renderer, display, g_GdkWindow);

    gdk_window_ensure_native(g_GdkWindow);

    g_Context = cogl_context_new(cogl_display_new(renderer, NULL), NULL);
    CoglOnscreen *onscreen = cogl_onscreen_new(g_Context, 1, 1);
    cogl_object_unref(renderer);

    g_Callbacks->resize(g_GdkWindow, onscreen,
                        allocation.width, allocation.height,
                        allocation.x, allocation.y);

    gtk_widget_add_events(widget, EVENT_MASK);
    g_signal_connect(widget, "event", G_CALLBACK(handle_gdk_event), NULL);
    g_signal_connect(widget, "size-allocate", G_CALLBACK(handle_allocate), NULL);

    g_Callbacks->set_window(onscreen, g_GdkWindow);

    if (!cogl_framebuffer_allocate(COGL_FRAMEBUFFER(onscreen), NULL))
        g_warning("Unable to allocate framebuffer");

    g_Framebuffer = COGL_FRAMEBUFFER(onscreen);

    ImGuiIO& io = ImGui::GetIO();
    for (int i = 0; i < ImGuiKey_COUNT; i++)
    {
        io.KeyMap[i] = i;
    }

    io.SetClipboardTextFn = ImGui_ImplGtk3Cogl_SetClipboardText;
    io.GetClipboardTextFn = ImGui_ImplGtk3Cogl_GetClipboardText;
    io.ClipboardUserData = gtk_widget_get_clipboard(g_GtkWidget,
                                                    GDK_SELECTION_CLIPBOARD);

    g_Callback = callback;
    g_CallbackData = data;
    GdkFrameClock *clock = gdk_window_get_frame_clock(g_GdkWindow);
    g_signal_connect(clock, "paint", G_CALLBACK(handle_repaint), NULL);

    gdk_frame_clock_request_phase(clock, GDK_FRAME_CLOCK_PHASE_PAINT);

    gdk_window_show(g_GdkWindow);

    return COGL_ONSCREEN(g_Framebuffer);
}