コード例 #1
0
ファイル: gdkglcontext-wayland.c プロジェクト: Distrotech/gtk
static void
gdk_x11_gl_context_dispose (GObject *gobject)
{
  GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (gobject);

  if (context_wayland->egl_context != NULL)
    {
      GdkGLContext *context = GDK_GL_CONTEXT (gobject);
      GdkWindow *window = gdk_gl_context_get_window (context);
      GdkDisplay *display = gdk_window_get_display (window);
      GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);

      if (eglGetCurrentContext () == context_wayland->egl_context)
        eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                       EGL_NO_CONTEXT);

      GDK_NOTE (OPENGL, g_print ("Destroying EGL context\n"));

      eglDestroyContext (display_wayland->egl_display,
                         context_wayland->egl_context);
      context_wayland->egl_context = NULL;
    }

  G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (gobject);
}
コード例 #2
0
ファイル: gdkmirdisplay.c プロジェクト: Therzok/gtk
static gboolean
gdk_mir_display_make_gl_context_current (GdkDisplay   *display,
                                         GdkGLContext *context)
{
  EGLDisplay egl_display = _gdk_mir_display_get_egl_display (display);
  GdkMirGLContext *mir_context;
  GdkWindow *window;
  EGLSurface egl_surface;

  if (context == NULL)
    {
      eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
      return TRUE;
    }

  mir_context = GDK_MIR_GL_CONTEXT (context);
  window = gdk_gl_context_get_window (context);

  if (mir_context->is_attached)
    {
      egl_surface = _gdk_mir_window_get_egl_surface (window,
                                                     mir_context->egl_config);
    }
  else
    {
      if (_gdk_mir_display_have_egl_surfaceless_context (display))
        egl_surface = EGL_NO_SURFACE;
      else
        egl_surface = _gdk_mir_window_get_dummy_egl_surface (window,
                                                             mir_context->egl_config);
    }

  if (!eglMakeCurrent (egl_display, egl_surface, egl_surface, mir_context->egl_context))
    {
      g_warning ("eglMakeCurrent failed");
      return FALSE;
    }

  return TRUE;
}
コード例 #3
0
ファイル: gdkglcontext-wayland.c プロジェクト: Distrotech/gtk
gboolean
gdk_wayland_display_make_gl_context_current (GdkDisplay   *display,
                                             GdkGLContext *context)
{
  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
  GdkWaylandGLContext *context_wayland;
  GdkWindow *window;
  EGLSurface egl_surface;

  if (context == NULL)
    {
      eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                     EGL_NO_CONTEXT);
      return TRUE;
    }

  context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
  window = gdk_gl_context_get_window (context);

  if (context_wayland->is_attached)
    egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config);
  else
    {
      if (display_wayland->have_egl_surfaceless_context)
	egl_surface = EGL_NO_SURFACE;
      else
	egl_surface = gdk_wayland_window_get_dummy_egl_surface (window->impl_window,
								context_wayland->egl_config);
    }

  if (!eglMakeCurrent (display_wayland->egl_display, egl_surface,
                       egl_surface, context_wayland->egl_context))
    {
      g_warning ("eglMakeCurrent failed");
      return FALSE;
    }

  return TRUE;
}
コード例 #4
0
ファイル: gdkglcontext-wayland.c プロジェクト: Distrotech/gtk
static void
gdk_wayland_gl_context_end_frame (GdkGLContext   *context,
                                  cairo_region_t *painted,
                                  cairo_region_t *damage)
{
  GdkWindow *window = gdk_gl_context_get_window (context);
  GdkDisplay *display = gdk_window_get_display (window);
  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
  GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
  EGLSurface egl_surface;

  gdk_gl_context_make_current (context);

  egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
                                                    context_wayland->egl_config);

  /* TODO: Use eglSwapBuffersWithDamageEXT if available */
  if (display_wayland->have_egl_swap_buffers_with_damage)
    {
      int i, j, n_rects = cairo_region_num_rectangles (damage);
      EGLint *rects = g_new (EGLint, n_rects * 4);
      cairo_rectangle_int_t rect;
      int window_height = gdk_window_get_height (window);

      for (i = 0, j = 0; i < n_rects; i++)
        {
          cairo_region_get_rectangle (damage, i, &rect);
          rects[j++] = rect.x;
          rects[j++] = window_height - rect.height - rect.y;
          rects[j++] = rect.width;
          rects[j++] = rect.height;
        }
      eglSwapBuffersWithDamageEXT (display_wayland->egl_display, egl_surface, rects, n_rects);
      g_free (rects);
    }
  else
    eglSwapBuffers (display_wayland->egl_display, egl_surface);
}
コード例 #5
0
ファイル: gdkgl.c プロジェクト: davidyang5405/gtk
/* This is always called with the paint context current */
void
gdk_gl_texture_from_surface (cairo_surface_t *surface,
                             cairo_region_t  *region)
{
    GdkGLContext *paint_context;
    cairo_surface_t *image;
    double device_x_offset, device_y_offset;
    cairo_rectangle_int_t rect, e;
    int n_rects, i;
    GdkWindow *window;
    int unscaled_window_height;
    unsigned int texture_id;
    int window_scale;
    double sx, sy;
    float umax, vmax;
    gboolean use_texture_rectangle;
    guint target;
    paint_context = gdk_gl_context_get_current ();
    if ((_gdk_gl_flags & GDK_GL_SOFTWARE_DRAW_SURFACE) == 0 &&
            paint_context &&
            GDK_GL_CONTEXT_GET_CLASS (paint_context)->texture_from_surface &&
            GDK_GL_CONTEXT_GET_CLASS (paint_context)->texture_from_surface (paint_context, surface, region))
        return;

    /* Software fallback */
    use_texture_rectangle = gdk_gl_context_use_texture_rectangle (paint_context);

    window = gdk_gl_context_get_window (paint_context);
    window_scale = gdk_window_get_scale_factor (window);
    gdk_window_get_unscaled_size (window, NULL, &unscaled_window_height);

    sx = sy = 1;
    cairo_surface_get_device_scale (window->current_paint.surface, &sx, &sy);

    cairo_surface_get_device_offset (surface,
                                     &device_x_offset, &device_y_offset);

    glGenTextures (1, &texture_id);
    if (use_texture_rectangle)
        target = GL_TEXTURE_RECTANGLE_ARB;
    else
        target = GL_TEXTURE_2D;

    glBindTexture (target, texture_id);
    glEnable (GL_SCISSOR_TEST);

    glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    n_rects = cairo_region_num_rectangles (region);

#define FLIP_Y(_y) (unscaled_window_height - (_y))

    for (i = 0; i < n_rects; i++)
    {
        cairo_region_get_rectangle (region, i, &rect);

        glScissor (rect.x * window_scale, FLIP_Y ((rect.y + rect.height) * window_scale),
                   rect.width * window_scale, rect.height * window_scale);

        e = rect;
        e.x *= sx;
        e.y *= sy;
        e.x += (int)device_x_offset;
        e.y += (int)device_y_offset;
        e.width *= sx;
        e.height *= sy;
        image = cairo_surface_map_to_image (surface, &e);

        gdk_gl_context_upload_texture (paint_context, image, e.width, e.height, target);

        cairo_surface_unmap_image (surface, image);

        if (use_texture_rectangle)
        {
            umax = rect.width * sx;
            vmax = rect.height * sy;
        }
        else
        {
            umax = 1.0;
            vmax = 1.0;
        }

        {
            GdkTexturedQuad quad = {
                rect.x * window_scale, FLIP_Y(rect.y * window_scale),
                (rect.x + rect.width) * window_scale, FLIP_Y((rect.y + rect.height) * window_scale),
                0, 0,
                umax, vmax,
            };

            /* We don't want to combine the quads here, because they have different textures.
             * And we don't want to upload the unused source areas to make it one texture. */
            gdk_gl_texture_quads (paint_context, target, 1, &quad);
        }
    }

#undef FLIP_Y

    glDisable (GL_SCISSOR_TEST);
    glDeleteTextures (1, &texture_id);
}
コード例 #6
0
ファイル: gdkgl.c プロジェクト: davidyang5405/gtk
void
gdk_gl_texture_quads (GdkGLContext *paint_context,
                      guint texture_target,
                      int n_quads,
                      GdkTexturedQuad *quads)
{
    GdkGLContextPaintData *paint_data  = gdk_gl_context_get_paint_data (paint_context);
    GdkGLContextProgram *program;
    GdkWindow *window = gdk_gl_context_get_window (paint_context);
    int window_scale = gdk_window_get_scale_factor (window);
    float w = gdk_window_get_width (window) * window_scale;
    float h = gdk_window_get_height (window) * window_scale;
    int i;
    float *vertex_buffer_data;

    bind_vao (paint_data);

    if (paint_data->tmp_vertex_buffer == 0)
        glGenBuffers(1, &paint_data->tmp_vertex_buffer);

    if (texture_target == GL_TEXTURE_RECTANGLE_ARB)
        use_texture_rect_program (paint_data);
    else
        use_texture_2d_program (paint_data);

    program = paint_data->current_program;

    glActiveTexture (GL_TEXTURE0);
    glUniform1i(program->map_location, 0); /* Use texture unit 0 */

    glEnableVertexAttribArray (program->position_location);
    glEnableVertexAttribArray (program->uv_location);
    glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_vertex_buffer);

    glVertexAttribPointer (program->position_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL);
    glVertexAttribPointer (program->uv_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void *) (sizeof(float) * 2));

#define VERTEX_SIZE 4

#define QUAD_N_VERTICES 6

#define QUAD_SIZE (VERTEX_SIZE * QUAD_N_VERTICES)

    vertex_buffer_data = g_new (float, n_quads * QUAD_SIZE);

    for (i = 0; i < n_quads; i++)
    {
        GdkTexturedQuad *quad = &quads[i];
        float vertex_data[] = {
            (quad->x1 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u1, quad->v1,
            (quad->x1 * 2) / w - 1, (quad->y2 * 2) / h - 1, quad->u1, quad->v2,
            (quad->x2 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u2, quad->v1,

            (quad->x2 * 2) / w - 1, (quad->y2 * 2) / h - 1, quad->u2, quad->v2,
            (quad->x1 * 2) / w - 1, (quad->y2 * 2) / h - 1, quad->u1, quad->v2,
            (quad->x2 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u2, quad->v1,
        };

        float *vertex = &vertex_buffer_data[i * QUAD_SIZE];
        memcpy (vertex, vertex_data, sizeof(vertex_data));
    }

    glBufferData (GL_ARRAY_BUFFER, sizeof(float) * n_quads * QUAD_SIZE, vertex_buffer_data, GL_STREAM_DRAW);
    glDrawArrays (GL_TRIANGLES, 0, n_quads * QUAD_N_VERTICES);

    g_free (vertex_buffer_data);

    glDisableVertexAttribArray (program->position_location);
    glDisableVertexAttribArray (program->uv_location);
}