Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* cairo - a vector graphics library with display and print output
  2.  *
  3.  * Copyright © 2009 Eric Anholt
  4.  * Copyright © 2009 Chris Wilson
  5.  * Copyright © 2005,2010 Red Hat, Inc
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it either under the terms of the GNU Lesser General Public
  9.  * License version 2.1 as published by the Free Software Foundation
  10.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  11.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  12.  * notice, a recipient may use your version of this file under either
  13.  * the MPL or the LGPL.
  14.  *
  15.  * You should have received a copy of the LGPL along with this library
  16.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  18.  * You should have received a copy of the MPL along with this library
  19.  * in the file COPYING-MPL-1.1
  20.  *
  21.  * The contents of this file are subject to the Mozilla Public License
  22.  * Version 1.1 (the "License"); you may not use this file except in
  23.  * compliance with the License. You may obtain a copy of the License at
  24.  * http://www.mozilla.org/MPL/
  25.  *
  26.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  27.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  28.  * the specific language governing rights and limitations.
  29.  *
  30.  * The Original Code is the cairo graphics library.
  31.  *
  32.  * The Initial Developer of the Original Code is Red Hat, Inc.
  33.  *
  34.  * Contributor(s):
  35.  *      Benjamin Otte <otte@gnome.org>
  36.  *      Carl Worth <cworth@cworth.org>
  37.  *      Chris Wilson <chris@chris-wilson.co.uk>
  38.  *      Eric Anholt <eric@anholt.net>
  39.  *      T. Zachary Laine <whatwasthataddress@gmail.com>
  40.  */
  41.  
  42. #ifndef CAIRO_GL_PRIVATE_H
  43. #define CAIRO_GL_PRIVATE_H
  44.  
  45. #include "cairoint.h"
  46.  
  47. #include "cairo-gl-gradient-private.h"
  48.  
  49. #include "cairo-device-private.h"
  50. #include "cairo-error-private.h"
  51. #include "cairo-rtree-private.h"
  52.  
  53. #include <assert.h>
  54.  
  55. #include <GL/glew.h>
  56.  
  57. #include "cairo-gl.h"
  58.  
  59. #include <GL/gl.h>
  60. #define GL_GLEXT_PROTOTYPES
  61. #include <GL/glext.h>
  62.  
  63. #define DEBUG_GL 0
  64.  
  65. #if DEBUG_GL && __GNUC__
  66. #define UNSUPPORTED(reason) ({ \
  67.     fprintf (stderr, \
  68.              "cairo-gl: hit unsupported operation in %s(), line %d: %s\n", \
  69.              __FUNCTION__, __LINE__, reason); \
  70.     CAIRO_INT_STATUS_UNSUPPORTED; \
  71. })
  72. #else
  73. #define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
  74. #endif
  75.  
  76. /* maximal number of shaders we keep in the cache.
  77.  * Random number that is hopefully big enough to not cause many cache evictions. */
  78. #define CAIRO_GL_MAX_SHADERS_PER_CONTEXT 64
  79.  
  80. /* VBO size that we allocate, smaller size means we gotta flush more often */
  81. #define CAIRO_GL_VBO_SIZE 16384
  82.  
  83. typedef struct _cairo_gl_surface {
  84.     cairo_surface_t base;
  85.  
  86.     int width, height;
  87.  
  88.     GLuint tex; /* GL texture object containing our data. */
  89.     GLuint fb; /* GL framebuffer object wrapping our data. */
  90.     GLuint depth; /* GL framebuffer object holding depth */
  91.     int owns_tex;
  92. } cairo_gl_surface_t;
  93.  
  94. typedef struct cairo_gl_glyph_cache {
  95.     cairo_rtree_t rtree;
  96.     cairo_surface_pattern_t pattern;
  97. } cairo_gl_glyph_cache_t;
  98.  
  99. typedef enum cairo_gl_tex {
  100.     CAIRO_GL_TEX_SOURCE = 0,
  101.     CAIRO_GL_TEX_MASK = 1,
  102.     CAIRO_GL_TEX_TEMP = 2
  103. } cairo_gl_tex_t;
  104.  
  105. typedef enum cairo_gl_operand_type {
  106.     CAIRO_GL_OPERAND_NONE,
  107.     CAIRO_GL_OPERAND_CONSTANT,
  108.     CAIRO_GL_OPERAND_TEXTURE,
  109.     CAIRO_GL_OPERAND_LINEAR_GRADIENT,
  110.     CAIRO_GL_OPERAND_RADIAL_GRADIENT,
  111.     CAIRO_GL_OPERAND_SPANS,
  112.  
  113.     CAIRO_GL_OPERAND_COUNT
  114. } cairo_gl_operand_type_t;
  115.  
  116. typedef struct cairo_gl_shader_impl cairo_gl_shader_impl_t;
  117.  
  118. typedef struct cairo_gl_shader {
  119.     GLuint fragment_shader;
  120.     GLuint program;
  121. } cairo_gl_shader_t;
  122.  
  123. typedef enum cairo_gl_shader_in {
  124.     CAIRO_GL_SHADER_IN_NORMAL,
  125.     CAIRO_GL_SHADER_IN_CA_SOURCE,
  126.     CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
  127.  
  128.     CAIRO_GL_SHADER_IN_COUNT
  129. } cairo_gl_shader_in_t;
  130.  
  131. typedef enum cairo_gl_var_type {
  132.   CAIRO_GL_VAR_NONE,
  133.   CAIRO_GL_VAR_TEXCOORDS,
  134.   CAIRO_GL_VAR_COVERAGE
  135. } cairo_gl_var_type_t;
  136.  
  137. #define cairo_gl_var_type_hash(src,mask,dest) ((mask) << 2 | (src << 1) | (dest))
  138. #define CAIRO_GL_VAR_TYPE_MAX ((CAIRO_GL_VAR_COVERAGE << 2) | (CAIRO_GL_VAR_TEXCOORDS << 1) | CAIRO_GL_VAR_TEXCOORDS)
  139.  
  140. /* This union structure describes a potential source or mask operand to the
  141.  * compositing equation.
  142.  */
  143. typedef struct cairo_gl_operand {
  144.     cairo_gl_operand_type_t type;
  145.     union {
  146.         struct {
  147.             GLuint tex;
  148.             cairo_gl_surface_t *surface;
  149.             cairo_surface_attributes_t attributes;
  150.         } texture;
  151.         struct {
  152.             GLfloat color[4];
  153.         } constant;
  154.         struct {
  155.             cairo_gl_gradient_t *gradient;
  156.             cairo_matrix_t m;
  157.             float segment_x;
  158.             float segment_y;
  159.             cairo_extend_t extend;
  160.         } linear;
  161.         struct {
  162.             cairo_gl_gradient_t *gradient;
  163.             cairo_matrix_t m;
  164.             float circle_1_x;
  165.             float circle_1_y;
  166.             float radius_0;
  167.             float radius_1;
  168.             cairo_extend_t extend;
  169.         } radial;
  170.     };
  171.     unsigned int vertex_offset;
  172. } cairo_gl_operand_t;
  173.  
  174. struct _cairo_gl_context {
  175.     cairo_device_t base;
  176.  
  177.     GLuint dummy_tex;
  178.     GLuint texture_load_pbo;
  179.     GLuint vbo;
  180.     GLint max_framebuffer_size;
  181.     GLint max_texture_size;
  182.     GLint max_textures;
  183.     GLenum tex_target;
  184.  
  185.     const cairo_gl_shader_impl_t *shader_impl;
  186.  
  187.     GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX + 1];
  188.     cairo_gl_shader_t fill_rectangles_shader;
  189.     cairo_cache_t shaders;
  190.  
  191.     cairo_cache_t gradients;
  192.  
  193.     cairo_gl_glyph_cache_t glyph_cache[2];
  194.     cairo_list_t fonts;
  195.  
  196.     cairo_gl_surface_t *current_target;
  197.     cairo_operator_t current_operator;
  198.     cairo_gl_shader_t *pre_shader; /* for component alpha */
  199.     cairo_gl_shader_t *current_shader;
  200.  
  201.     cairo_gl_operand_t operands[2];
  202.  
  203.     char *vb;
  204.     unsigned int vb_offset;
  205.     unsigned int vertex_size;
  206.     cairo_region_t *clip_region;
  207.  
  208.     void (*acquire) (void *ctx);
  209.     void (*release) (void *ctx);
  210.  
  211.     void (*make_current) (void *ctx, cairo_gl_surface_t *surface);
  212.     void (*swap_buffers)(void *ctx, cairo_gl_surface_t *surface);
  213.     void (*destroy) (void *ctx);
  214. };
  215.  
  216. typedef struct _cairo_gl_composite {
  217.     cairo_gl_surface_t *dst;
  218.     cairo_operator_t op;
  219.     cairo_region_t *clip_region;
  220.  
  221.     cairo_gl_operand_t src;
  222.     cairo_gl_operand_t mask;
  223. } cairo_gl_composite_t;
  224.  
  225. cairo_private extern const cairo_surface_backend_t _cairo_gl_surface_backend;
  226.  
  227. static cairo_always_inline GLenum
  228. _cairo_gl_get_error (void)
  229. {
  230.     GLenum err = glGetError();
  231.  
  232.     if (unlikely (err))
  233.         while (glGetError ());
  234.  
  235.     return err;
  236. }
  237.  
  238. static inline cairo_device_t *
  239. _cairo_gl_context_create_in_error (cairo_status_t status)
  240. {
  241.     return (cairo_device_t *) _cairo_device_create_in_error (status);
  242. }
  243.  
  244. cairo_private cairo_status_t
  245. _cairo_gl_context_init (cairo_gl_context_t *ctx);
  246.  
  247. cairo_private void
  248. _cairo_gl_surface_init (cairo_device_t *device,
  249.                         cairo_gl_surface_t *surface,
  250.                         cairo_content_t content,
  251.                         int width, int height);
  252.  
  253. static cairo_always_inline cairo_bool_t cairo_warn
  254. _cairo_gl_surface_is_texture (cairo_gl_surface_t *surface)
  255. {
  256.     return surface->tex != 0;
  257. }
  258.  
  259. cairo_private cairo_status_t
  260. _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
  261.                               cairo_image_surface_t *src,
  262.                               int src_x, int src_y,
  263.                               int width, int height,
  264.                               int dst_x, int dst_y);
  265.  
  266. static cairo_always_inline cairo_bool_t
  267. _cairo_gl_device_has_glsl (cairo_device_t *device)
  268. {
  269.     return ((cairo_gl_context_t *) device)->shader_impl != NULL;
  270. }
  271.  
  272. static cairo_always_inline cairo_bool_t
  273. _cairo_gl_device_requires_power_of_two_textures (cairo_device_t *device)
  274. {
  275.     return ((cairo_gl_context_t *) device)->tex_target == GL_TEXTURE_RECTANGLE_EXT;
  276. }
  277.  
  278. static cairo_always_inline cairo_status_t cairo_warn
  279. _cairo_gl_context_acquire (cairo_device_t *device,
  280.                            cairo_gl_context_t **ctx)
  281. {
  282.     cairo_status_t status;
  283.  
  284.     status = cairo_device_acquire (device);
  285.     if (unlikely (status))
  286.         return status;
  287.  
  288.     /* clear potential previous GL errors */
  289.     _cairo_gl_get_error ();
  290.  
  291.     *ctx = (cairo_gl_context_t *) device;
  292.     return CAIRO_STATUS_SUCCESS;
  293. }
  294.  
  295. static cairo_always_inline cairo_warn cairo_status_t
  296. _cairo_gl_context_release (cairo_gl_context_t *ctx, cairo_status_t status)
  297. {
  298.     GLenum err;
  299.  
  300.     err = _cairo_gl_get_error ();
  301.  
  302.     if (unlikely (err)) {
  303.         cairo_status_t new_status;
  304.         new_status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
  305.         if (status == CAIRO_STATUS_SUCCESS)
  306.             status = new_status;
  307.     }
  308.  
  309.     cairo_device_release (&(ctx)->base);
  310.  
  311.     return status;
  312. }
  313.  
  314. cairo_private void
  315. _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface);
  316.  
  317. cairo_private void
  318. _cairo_gl_context_activate (cairo_gl_context_t *ctx,
  319.                             cairo_gl_tex_t      tex_unit);
  320.  
  321. cairo_private cairo_bool_t
  322. _cairo_gl_operator_is_supported (cairo_operator_t op);
  323.  
  324. cairo_private cairo_status_t
  325. _cairo_gl_composite_init (cairo_gl_composite_t *setup,
  326.                           cairo_operator_t op,
  327.                           cairo_gl_surface_t *dst,
  328.                           cairo_bool_t has_component_alpha,
  329.                           const cairo_rectangle_int_t *rect);
  330.  
  331. cairo_private void
  332. _cairo_gl_composite_fini (cairo_gl_composite_t *setup);
  333.  
  334. cairo_private void
  335. _cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup,
  336.                                      cairo_region_t *clip_region);
  337.  
  338. cairo_private cairo_int_status_t
  339. _cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
  340.                                 const cairo_pattern_t *pattern,
  341.                                 int src_x, int src_y,
  342.                                 int dst_x, int dst_y,
  343.                                 int width, int height);
  344.  
  345. cairo_private cairo_int_status_t
  346. _cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
  347.                               const cairo_pattern_t *pattern,
  348.                               int src_x, int src_y,
  349.                               int dst_x, int dst_y,
  350.                               int width, int height);
  351.  
  352. cairo_private void
  353. _cairo_gl_composite_set_mask_spans (cairo_gl_composite_t *setup);
  354.  
  355. cairo_private cairo_status_t
  356. _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
  357.                            cairo_gl_context_t **ctx);
  358.  
  359. cairo_private void
  360. _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
  361.                                GLfloat x1,
  362.                                GLfloat y1,
  363.                                GLfloat x2,
  364.                                GLfloat y2,
  365.                                uint8_t alpha);
  366.  
  367. cairo_private void
  368. _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
  369.                                 GLfloat x1,
  370.                                 GLfloat y1,
  371.                                 GLfloat x2,
  372.                                 GLfloat y2,
  373.                                 GLfloat glyph_x1,
  374.                                 GLfloat glyph_y1,
  375.                                 GLfloat glyph_x2,
  376.                                 GLfloat glyph_y2);
  377.  
  378. cairo_private void
  379. _cairo_gl_composite_flush (cairo_gl_context_t *ctx);
  380.  
  381. cairo_private void
  382. _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
  383.                                    cairo_gl_tex_t tex_unit);
  384.  
  385. cairo_private cairo_bool_t
  386. _cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
  387.                                      GLenum *internal_format, GLenum *format,
  388.                                      GLenum *type, cairo_bool_t *has_alpha);
  389.  
  390. cairo_private void
  391. _cairo_gl_surface_scaled_font_fini ( cairo_scaled_font_t  *scaled_font);
  392.  
  393. cairo_private void
  394. _cairo_gl_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
  395.                                      cairo_scaled_font_t  *scaled_font);
  396.  
  397. cairo_private void
  398. _cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache);
  399.  
  400. cairo_private void
  401. _cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
  402.                             cairo_gl_glyph_cache_t *cache);
  403.  
  404. cairo_private cairo_int_status_t
  405. _cairo_gl_surface_show_glyphs (void                     *abstract_dst,
  406.                                cairo_operator_t          op,
  407.                                const cairo_pattern_t    *source,
  408.                                cairo_glyph_t            *glyphs,
  409.                                int                       num_glyphs,
  410.                                cairo_scaled_font_t      *scaled_font,
  411.                                cairo_clip_t             *clip,
  412.                                int                      *remaining_glyphs);
  413.  
  414. static inline int
  415. _cairo_gl_y_flip (cairo_gl_surface_t *surface, int y)
  416. {
  417.     if (surface->fb)
  418.         return y;
  419.     else
  420.         return (surface->height - 1) - y;
  421. }
  422.  
  423. cairo_private cairo_status_t
  424. _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx);
  425.  
  426. cairo_private void
  427. _cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx);
  428.  
  429. static cairo_always_inline cairo_bool_t
  430. _cairo_gl_context_is_flushed (cairo_gl_context_t *ctx)
  431. {
  432.     return ctx->vb == NULL;
  433. }
  434.  
  435. cairo_private cairo_status_t
  436. _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
  437.                               cairo_gl_operand_type_t source,
  438.                               cairo_gl_operand_type_t mask,
  439.                               cairo_gl_shader_in_t in,
  440.                               cairo_gl_shader_t **shader);
  441.  
  442. cairo_private void
  443. _cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
  444.                              const char *name,
  445.                              float value);
  446.  
  447. cairo_private void
  448. _cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
  449.                             const char *name,
  450.                             float value0, float value1);
  451.  
  452. cairo_private void
  453. _cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
  454.                             const char *name,
  455.                             float value0,
  456.                             float value1,
  457.                             float value2);
  458.  
  459. cairo_private void
  460. _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
  461.                             const char *name,
  462.                             float value0, float value1,
  463.                             float value2, float value3);
  464.  
  465. cairo_private void
  466. _cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
  467.                               const char *name,
  468.                               cairo_matrix_t* m);
  469.  
  470. cairo_private void
  471. _cairo_gl_shader_bind_texture (cairo_gl_context_t *ctx,
  472.                                const char *name,
  473.                                GLuint tex_unit);
  474.  
  475. cairo_private void
  476. _cairo_gl_set_shader (cairo_gl_context_t *ctx,
  477.                       cairo_gl_shader_t *shader);
  478.  
  479. cairo_private void
  480. _cairo_gl_shader_fini (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader);
  481.  
  482. slim_hidden_proto (cairo_gl_surface_create);
  483. slim_hidden_proto (cairo_gl_surface_create_for_texture);
  484.  
  485. #endif /* CAIRO_GL_PRIVATE_H */
  486.