1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2009 Eric Anholt
4 * Copyright © 2009 Chris Wilson
5 * Copyright © 2005,2010 Red Hat, Inc
6 * Copyright © 2011 Linaro Limited
8 * This library is free software; you can redistribute it and/or
9 * modify it either under the terms of the GNU Lesser General Public
10 * License version 2.1 as published by the Free Software Foundation
11 * (the "LGPL") or, at your option, under the terms of the Mozilla
12 * Public License Version 1.1 (the "MPL"). If you do not alter this
13 * notice, a recipient may use your version of this file under either
14 * the MPL or the LGPL.
16 * You should have received a copy of the LGPL along with this library
17 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
19 * You should have received a copy of the MPL along with this library
20 * in the file COPYING-MPL-1.1
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License at
25 * http://www.mozilla.org/MPL/
27 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
28 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
29 * the specific language governing rights and limitations.
31 * The Original Code is the cairo graphics library.
33 * The Initial Developer of the Original Code is Red Hat, Inc.
36 * Benjamin Otte <otte@gnome.org>
37 * Carl Worth <cworth@cworth.org>
38 * Chris Wilson <chris@chris-wilson.co.uk>
39 * Eric Anholt <eric@anholt.net>
40 * T. Zachary Laine <whatwasthataddress@gmail.com>
41 * Alexandros Frantzis <alexandros.frantzis@linaro.org>
44 #ifndef CAIRO_GL_PRIVATE_H
45 #define CAIRO_GL_PRIVATE_H
47 #define GL_GLEXT_PROTOTYPES
52 #include "cairo-gl-gradient-private.h"
54 #include "cairo-device-private.h"
55 #include "cairo-error-private.h"
56 #include "cairo-rtree-private.h"
57 #include "cairo-scaled-font-private.h"
58 #include "cairo-spans-compositor-private.h"
59 #include "cairo-array-private.h"
60 #include "cairo-stroke-dash-private.h"
64 #if CAIRO_HAS_EVASGL_SURFACE
67 #if CAIRO_HAS_GL_SURFACE
70 #elif CAIRO_HAS_GLESV2_SURFACE
71 #include <GLES2/gl2.h>
72 #include <GLES2/gl2ext.h>
73 #elif CAIRO_HAS_GLESV3_SURFACE
74 #include <GLES3/gl3.h>
75 #include <GLES3/gl3ext.h>
80 #include "cairo-gl-ext-def-private.h"
84 #define CAIRO_GL_ENUM_UNINITIALIZED 0xFFFF
86 #if DEBUG_GL && __GNUC__
87 #define UNSUPPORTED(reason) ({ \
89 "cairo-gl: hit unsupported operation in %s(), line %d: %s\n", \
90 __FUNCTION__, __LINE__, reason); \
91 CAIRO_INT_STATUS_UNSUPPORTED; \
94 #define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
97 #define CAIRO_GL_VERSION_ENCODE(major, minor) ( \
101 /* maximal number of shaders we keep in the cache.
102 * Random number that is hopefully big enough to not cause many cache evictions. */
103 #define CAIRO_GL_MAX_SHADERS_PER_CONTEXT 64
105 /* VBO size that we allocate, smaller size means we gotta flush more often,
106 * but larger means hogging more memory and can cause trouble for drivers
107 * (especially on embedded devices). */
108 #define CAIRO_GL_VBO_SIZE (16*1024)
110 #define MIN_IMAGE_CACHE_WIDTH 512
111 #define MIN_IMAGE_CACHE_HEIGHT 512
112 #define MAX_IMAGE_CACHE_WIDTH 2048
113 #define MAX_IMAGE_CACHE_HEIGHT 2048
114 #define IMAGE_CACHE_MIN_SIZE 1
115 #define IMAGE_CACHE_MAX_SIZE 256
116 #define MIN_SCRATCH_SIZE 32
117 #define MAX_SCRATCH_SIZE 1024
119 typedef struct _cairo_gl_surface cairo_gl_surface_t;
120 typedef struct _cairo_gl_image cairo_gl_image_t;
122 /* Mali or SGX driver */
123 typedef enum _cairo_gl_multisample_ext_type {
124 CAIRO_GL_EXT_MULTISAMPLE_TO_TEXTURE,
125 CAIRO_GL_IMG_MULTISAMPLE_TO_TEXTURE,
126 CAIRO_GL_NONE_MULTISAMPLE_TO_TEXTURE
127 } cairo_gl_multisample_ext_type;
130 typedef enum _cairo_blur_stage {
131 CAIRO_GL_BLUR_STAGE_NONE,
132 CAIRO_GL_BLUR_STAGE_0, /* shrink stage */
133 CAIRO_GL_BLUR_STAGE_1, /* x/y pass */
134 CAIRO_GL_BLUR_STAGE_2 /* enlarge stage */
135 } cairo_blur_stage_t;
138 typedef enum cairo_gl_flavor {
139 CAIRO_GL_FLAVOR_NONE = 0,
140 CAIRO_GL_FLAVOR_DESKTOP = 1,
141 CAIRO_GL_FLAVOR_ES2 = 2,
142 CAIRO_GL_FLAVOR_ES3 = 3
145 /* The order here is sensitive because of the logic of
146 *_cairo_gl_shader_uniform_for_texunit. */
147 typedef enum cairo_gl_uniform_t {
148 CAIRO_GL_UNIFORM_TEXDIMS, /* "source_texdims" */
149 CAIRO_GL_UNIFORM_TEXGEN, /* "source_texgen" */
150 CAIRO_GL_UNIFORM_CONSTANT, /* "source_constant" */
151 CAIRO_GL_UNIFORM_SAMPLER, /* "source_sampler" */
152 CAIRO_GL_UNIFORM_A, /* "source_a" */
153 CAIRO_GL_UNIFORM_CIRCLE_D, /* "source_circle_d" */
154 CAIRO_GL_UNIFORM_RADIUS_0, /* "source_radius_0" */
155 CAIRO_GL_UNIFORM_BLUR_RADIUS,/* "source_blur_radius" */
156 CAIRO_GL_UNIFORM_BLURS, /* "source_blurs" */
157 CAIRO_GL_UNIFORM_BLUR_STEP, /* "source_blurstep" */
158 CAIRO_GL_UNIFORM_BLUR_X_AXIS, /* "source_blur_x_axis" */
159 CAIRO_GL_UNIFORM_BLUR_Y_AXIS, /* "source_blur_y_axis" */
160 CAIRO_GL_UNIFORM_ALPHA, /* "source_alpha */
162 CAIRO_GL_UNIFORM_MASK_TEXDIMS, /* "mask_texdims" */
163 CAIRO_GL_UNIFORM_MASK_TEXGEN, /* "mask_texgen" */
164 CAIRO_GL_UNIFORM_MASK_CONSTANT, /* "mask_constant" */
165 CAIRO_GL_UNIFORM_MASK_SAMPLER, /* "mask_sampler" */
166 CAIRO_GL_UNIFORM_MASK_A, /* "mask_a" */
167 CAIRO_GL_UNIFORM_MASK_CIRCLE_D, /* "mask_circle_d" */
168 CAIRO_GL_UNIFORM_MASK_RADIUS_0, /* "mask_radius_0" */
169 CAIRO_GL_UNIFORM_MASK_BLUR_RADIUS, /* "mask_blur_radius */
170 CAIRO_GL_UNIFORM_MASK_BLURS, /* "mask_blurs */
171 CAIRO_GL_UNIFORM_MASK_BLUR_STEP, /* "mask_blur_step" */
172 CAIRO_GL_UNIFORM_MASK_BLUR_X_AXIS, /* "mask_blur_x_axis" */
173 CAIRO_GL_UNIFORM_MASK_BLUR_Y_AXIS, /* "mask_blur_y_axis" */
174 CAIRO_GL_UNIFORM_MASK_ALPHA, /* "mask_alpha" */
176 CAIRO_GL_UNIFORM_PROJECTION_MATRIX, /* "ModelViewProjectionMatrix" */
180 } cairo_gl_uniform_t;
182 /* Indices for vertex attributes used by BindAttribLocation etc */
184 CAIRO_GL_VERTEX_ATTRIB_INDEX = 0,
185 CAIRO_GL_COLOR_ATTRIB_INDEX = 1,
186 CAIRO_GL_COVERAGE_ATTRIB_INDEX = 2,
187 CAIRO_GL_TEXCOORD0_ATTRIB_INDEX = 3,
188 CAIRO_GL_TEXCOORD1_ATTRIB_INDEX = 4,
189 CAIRO_GL_START_COORD0_ATTRIB_INDEX = 5,
190 CAIRO_GL_START_COORD1_ATTRIB_INDEX = 6,
191 CAIRO_GL_STOP_COORD0_ATTRIB_INDEX = 7,
192 CAIRO_GL_STOP_COORD1_ATTRIB_INDEX = 8
195 typedef enum cairo_gl_operand_type {
196 CAIRO_GL_OPERAND_NONE,
197 CAIRO_GL_OPERAND_CONSTANT,
198 CAIRO_GL_OPERAND_TEXTURE,
199 CAIRO_GL_OPERAND_LINEAR_GRADIENT,
200 CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0,
201 CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE,
202 CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT,
203 CAIRO_GL_OPERAND_GAUSSIAN,
205 CAIRO_GL_OPERAND_COUNT
206 } cairo_gl_operand_type_t;
208 typedef enum cairo_gl_draw_mode {
212 } cairo_gl_draw_mode_t;
214 /* This union structure describes a potential source or mask operand to the
215 * compositing equation.
217 typedef struct cairo_gl_operand {
218 cairo_gl_operand_type_t type;
219 int pass; /* 0 none, 1, x-axis, 2, y-axis */
223 cairo_gl_surface_t *surface;
224 cairo_gl_surface_t *owns_surface;
225 cairo_surface_attributes_t attributes;
227 cairo_bool_t use_atlas;
228 cairo_extend_t extend;
229 struct { float x, y; } p1, p2;
230 float coef[17]; /* max 1x/x1 kernel size */
236 cairo_bool_t encode_as_attribute;
239 cairo_gl_gradient_t *gradient;
241 cairo_circle_double_t circle_d;
243 cairo_extend_t extend;
247 unsigned int vertex_offset;
248 } cairo_gl_operand_t;
250 typedef struct cairo_gl_source {
251 cairo_surface_t base;
252 cairo_gl_operand_t operand;
255 struct _cairo_gl_surface {
256 cairo_surface_t base;
257 cairo_gl_operand_t operand;
261 GLuint tex; /* GL texture object containing our data. */
262 GLuint fb; /* GL framebuffer object wrapping our data. */
263 GLuint depth_stencil; /* GL renderbuffer object for holding stencil buffer clip. */
265 GLuint msaa_rb; /* The ARB MSAA path uses a renderbuffer. */
267 GLuint msaa_depth_stencil;
269 cairo_bool_t stencil_and_msaa_caps_initialized;
270 cairo_bool_t supports_stencil; /* Stencil support for for non-texture surfaces. */
271 cairo_bool_t supports_msaa;
272 cairo_bool_t num_samples;
273 cairo_bool_t force_no_msaa;
274 cairo_bool_t msaa_active; /* Whether the multisampling
275 framebuffer is active or not. */
276 cairo_bool_t content_synced; /* texture and renderbuffer content
278 cairo_bool_t content_cleared; /* last draw is glClear */
279 cairo_clip_t *clip_on_stencil_buffer;
282 cairo_bool_t needs_update;
283 cairo_bool_t size_changed;
285 cairo_region_t *clip_region;
286 GLuint bounded_tex; /* bounded tex for non-texture surface */
288 /* Indicate whether we need to cache it in image_cache. */
289 cairo_bool_t needs_to_cache;
290 cairo_bool_t force_no_cache;
291 double image_content_scale_x;
292 double image_content_scale_y;
293 cairo_blur_stage_t blur_stage;
294 /* Damage is too expensive to check, we use this flag. */
295 cairo_bool_t content_changed;
296 cairo_gl_image_t *image_node;
299 typedef struct cairo_gl_glyph_cache {
301 cairo_gl_surface_t *surface;
302 } cairo_gl_glyph_cache_t;
304 typedef enum cairo_gl_tex {
305 CAIRO_GL_TEX_SOURCE = 0,
306 CAIRO_GL_TEX_MASK = 1,
307 CAIRO_GL_TEX_TEMP = 2
310 typedef struct cairo_gl_shader {
311 GLuint fragment_shader;
313 GLint uniforms[CAIRO_GL_UNIFORM_MAX];
316 typedef struct _cairo_gl_image_cache {
318 cairo_gl_surface_t *surface;
319 cairo_bool_t copy_success;
320 } cairo_gl_image_cache_t;
322 struct _cairo_gl_image {
323 cairo_rtree_node_t node;
324 cairo_surface_t *original_surface;
325 struct { float x, y; } p1, p2;
326 cairo_gl_context_t *ctx;
329 typedef enum cairo_gl_shader_in {
330 CAIRO_GL_SHADER_IN_NORMAL,
331 CAIRO_GL_SHADER_IN_CA_SOURCE,
332 CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
334 CAIRO_GL_SHADER_IN_COUNT
335 } cairo_gl_shader_in_t;
338 typedef struct _cairo_gl_hairline_closure
340 cairo_gl_context_t *ctx;
342 cairo_stroker_dash_t dash;
344 cairo_matrix_t *ctm_inverse;
345 cairo_point_t current_point;
347 cairo_point_t stroke_first_point; /* First stroke point at move_to. */
348 double stroke_first_dx;
349 double stroke_first_dy;
350 cairo_bool_t stroke_first_capped;
351 cairo_bool_t moved_to_stroke_first_point;
353 cairo_line_cap_t cap_style;
355 cairo_bool_t line_last_capped;
357 cairo_point_t line_last_point;
361 cairo_bool_t initialized;
362 } cairo_gl_hairline_closure_t;
364 typedef enum cairo_gl_var_type {
366 CAIRO_GL_VAR_TEXCOORDS,
369 } cairo_gl_var_type_t;
371 typedef enum cairo_gl_primitive_type {
372 CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES,
373 CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS
374 } cairo_gl_primitive_type_t;
376 typedef void (*cairo_gl_emit_rect_t) (cairo_gl_context_t *ctx,
377 GLfloat x1, GLfloat y1,
378 GLfloat x2, GLfloat y2);
380 typedef void (*cairo_gl_emit_span_t) (cairo_gl_context_t *ctx,
381 GLfloat x1, GLfloat y1,
382 GLfloat x2, GLfloat y2,
385 typedef void (*cairo_gl_emit_glyph_t) (cairo_gl_context_t *ctx,
386 GLfloat x1, GLfloat y1,
387 GLfloat x2, GLfloat y2,
388 GLfloat glyph_x1, GLfloat glyph_y1,
389 GLfloat glyph_x2, GLfloat glyph_y2);
391 #define cairo_gl_var_type_hash(src,mask,src_atlas_extend,mask_atlas_extend,src_use_atlas,mask_use_atlas,spans,dest) ((spans) << 13) | ((mask) << 10 | (src << 7) | (mask_atlas_extend << 5) | (src_atlas_extend << 3) | (mask_use_atlas << 2) | (src_use_atlas << 1) | (dest))
392 #define CAIRO_GL_VAR_TYPE_MAX (1 << 14)
394 typedef void (*cairo_gl_generic_func_t)(void);
395 typedef cairo_gl_generic_func_t (*cairo_gl_get_proc_addr_func_t)(void *data, const char *procname);
397 typedef struct _cairo_gl_dispatch {
399 void (*ActiveTexture) (GLenum texture);
400 void (*BindTexture) (GLenum target, GLuint texture);
401 void (*BlendFunc) (GLenum sfactor, GLenum dfactor);
402 void (*BlendFuncSeparate) (GLenum srcRGB, GLenum dstRGB,
403 GLenum srcAlpha, GLenum dstAlpha);
404 void (*Clear) (GLbitfield mask);
405 void (*ClearColor) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
406 void (*ClearStencil) (GLint s);
407 void (*ColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
408 void (*DeleteTextures) (GLsizei n, const GLuint *textures);
409 void (*DepthMask)(GLboolean flag);
410 void (*Disable) (GLenum cap);
411 void (*DrawArrays) (GLenum mode, GLint first, GLsizei count);
412 void (*DrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
413 void (*Enable) (GLenum cap);
414 void (*Flush) (void);
415 void (*GenTextures) (GLsizei n, GLuint *textures);
416 void (*GetBooleanv) (GLenum pname, GLboolean *data);
417 GLenum (*GetError) (void);
418 void (*GetFloatv) (GLenum pname, GLfloat *data);
419 void (*GetIntegerv) (GLenum pname, GLint *data);
420 const GLubyte *(*GetString) (GLenum pname);
421 void (*PixelStorei) (GLenum pname, GLint param);
422 void (*ReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height,
423 GLenum format, GLenum type, GLvoid *data);
424 void (*Scissor) (GLint x, GLint y, GLsizei width, GLsizei height);
425 void (*StencilFunc) (GLenum func, GLint ref, GLuint mask);
426 void (*StencilMask) (GLuint mask);
427 void (*StencilOp) (GLenum sfail, GLenum dpfail, GLenum dppass);
428 void (*TexSubImage2D) (GLenum target, GLint level,
429 GLint xoffset, GLint yoffset,
430 GLsizei width, GLsizei height,
431 GLenum format, GLenum type, const GLvoid *data);
432 void (*TexImage2D) (GLenum target, GLint level, GLenum internalformat,
433 GLsizei width, GLsizei height,
434 GLint border, GLenum format,
435 GLenum type, const GLvoid *data);
436 void (*TexParameteri) (GLenum target, GLenum pname, GLint param);
437 #if defined(CAIRO_HAS_GL_SURFACE) || defined(CAIRO_HAS_EVASGL_SURFACE)
438 void (*DrawBuffer) (GLenum buf);
439 void (*ReadBuffer) (GLenum buf);
441 void (*Viewport) (GLint x, GLint y, GLsizei width, GLsizei height);
444 void (*GenBuffers) (GLsizei n, GLuint *buffers);
445 void (*BindBuffer) (GLenum target, GLuint buffer);
446 void (*BufferData) (GLenum target, GLsizeiptr size,
447 const GLvoid* data, GLenum usage);
448 GLvoid *(*MapBuffer) (GLenum target, GLenum access);
449 GLboolean (*UnmapBuffer) (GLenum target);
452 GLuint (*CreateShader) (GLenum type);
453 void (*ShaderSource) (GLuint shader, GLsizei count,
454 const GLchar** string, const GLint* length);
455 void (*CompileShader) (GLuint shader);
456 void (*GetShaderiv) (GLuint shader, GLenum pname, GLint *params);
457 void (*GetShaderInfoLog) (GLuint shader, GLsizei bufSize,
458 GLsizei *length, GLchar *infoLog);
459 void (*DeleteShader) (GLuint shader);
462 GLuint (*CreateProgram) (void);
463 void (*AttachShader) (GLuint program, GLuint shader);
464 void (*DeleteProgram) (GLuint program);
465 void (*LinkProgram) (GLuint program);
466 void (*UseProgram) (GLuint program);
467 void (*GetProgramiv) (GLuint program, GLenum pname, GLint *params);
468 void (*GetProgramInfoLog) (GLuint program, GLsizei bufSize,
469 GLsizei *length, GLchar *infoLog);
472 GLint (*GetUniformLocation) (GLuint program, const GLchar* name);
473 void (*Uniform1f) (GLint location, GLfloat x);
474 void (*Uniform2f) (GLint location, GLfloat x, GLfloat y);
475 void (*Uniform3f) (GLint location, GLfloat x, GLfloat y, GLfloat z);
476 void (*Uniform4f) (GLint location, GLfloat x, GLfloat y, GLfloat z,
478 void (*Uniform1fv) (GLint location, GLsizei count, const GLfloat *v);
480 void (*UniformMatrix3fv) (GLint location, GLsizei count,
481 GLboolean transpose, const GLfloat *value);
482 void (*UniformMatrix4fv) (GLint location, GLsizei count,
483 GLboolean transpose, const GLfloat *value);
484 void (*Uniform1i) (GLint location, GLint x);
487 void (*BindAttribLocation) (GLuint program, GLuint index,
489 void (*VertexAttribPointer) (GLuint index, GLint size, GLenum type,
490 GLboolean normalized, GLsizei stride,
491 const GLvoid *pointer);
492 void (*EnableVertexAttribArray) (GLuint index);
493 void (*DisableVertexAttribArray) (GLuint index);
495 /* Framebuffer objects */
496 void (*GenFramebuffers) (GLsizei n, GLuint* framebuffers);
497 void (*BindFramebuffer) (GLenum target, GLuint framebuffer);
498 void (*FramebufferTexture2D) (GLenum target, GLenum attachment,
499 GLenum textarget, GLuint texture,
501 GLenum (*CheckFramebufferStatus) (GLenum target);
502 void (*DeleteFramebuffers) (GLsizei n, const GLuint* framebuffers);
503 void (*GenRenderbuffers) (GLsizei n, GLuint *renderbuffers);
504 void (*BindRenderbuffer) (GLenum target, GLuint renderbuffer);
505 void (*RenderbufferStorage) (GLenum target, GLenum internal_format,
506 GLsizei width, GLsizei height);
507 void (*FramebufferRenderbuffer) (GLenum target, GLenum attachment,
508 GLenum renderbuffer_ttarget, GLuint renderbuffer);
509 void (*DeleteRenderbuffers) (GLsizei n, GLuint *renderbuffers);
510 void (*BlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
511 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
512 GLbitfield mask, GLenum filter);
513 void (*RenderbufferStorageMultisample) (GLenum target, GLsizei samples,
514 GLenum internalformat,
515 GLsizei width, GLsizei height);
516 void (*FramebufferTexture2DMultisample) (GLenum target, GLenum attachment,
517 GLenum textarget, GLuint texture,
518 GLint level, GLsizei samples);
519 } cairo_gl_dispatch_t;
521 typedef struct _cairo_gl_states {
522 cairo_rectangle_int_t viewport_box;
525 GLclampf clear_green;
527 GLclampf clear_alpha;
529 cairo_bool_t blend_enabled;
531 GLenum src_color_factor;
532 GLenum dst_color_factor;
533 GLenum src_alpha_factor;
534 GLenum dst_alpha_factor;
536 GLenum active_texture;
538 cairo_bool_t depth_mask;
540 cairo_bool_t scissor_test_enabled;
541 cairo_bool_t stencil_test_enabled;
545 struct _cairo_gl_context {
548 const cairo_compositor_t *compositor;
550 GLuint texture_load_pbo;
551 GLint max_framebuffer_size;
552 GLint max_texture_size;
557 cairo_bool_t supports_msaa;
560 cairo_bool_t has_shader_support;
562 GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX];
563 cairo_gl_shader_t fill_rectangles_shader;
564 cairo_cache_t shaders;
566 cairo_cache_t gradients;
568 /* cache[0] for gray font, cache[1] for rgba component alpha
569 * cache[2] for color glyph */
570 cairo_gl_glyph_cache_t glyph_cache[3];
573 cairo_gl_surface_t *current_target;
574 cairo_operator_t current_operator;
575 cairo_gl_shader_t *pre_shader; /* for component alpha */
576 cairo_gl_shader_t *current_shader;
578 cairo_gl_operand_t operands[2];
581 unsigned int vb_offset;
582 unsigned int vertex_size;
583 cairo_region_t *clip_region;
585 cairo_gl_primitive_type_t primitive_type;
586 cairo_array_t tristrip_indices;
588 cairo_bool_t has_mesa_pack_invert;
589 cairo_gl_dispatch_t dispatch;
590 GLfloat modelviewprojection_matrix[16];
591 cairo_gl_flavor_t gl_flavor;
592 cairo_bool_t has_map_buffer;
593 cairo_bool_t has_packed_depth_stencil;
594 cairo_bool_t has_npot_repeat;
595 cairo_bool_t can_read_bgra;
597 cairo_bool_t thread_aware;
599 cairo_gl_image_cache_t *image_cache;
600 cairo_gl_draw_mode_t draw_mode;
601 cairo_gl_states_t states_cache;
603 /* Intermediate mask surface for glyph rendering. Created on first access, enlarged on demand. */
604 cairo_gl_surface_t *glyph_mask;
605 /* Intermediate blur surface for gaussian blur. Created on first access, enlarged on demand. */
606 cairo_gl_surface_t *source_scratch_surfaces[2];
607 cairo_gl_surface_t *mask_scratch_surfaces[2];
608 cairo_gl_surface_t *shadow_scratch_surfaces[3];
609 cairo_gl_surface_t *shadow_masks[4];
610 cairo_bool_t source_scratch_in_use;
611 cairo_bool_t has_angle_multisampling;
612 cairo_gl_multisample_ext_type msaa_type;
614 void (*acquire) (void *ctx);
615 void (*release) (void *ctx);
617 void (*make_current) (void *ctx, cairo_gl_surface_t *surface);
618 void (*swap_buffers)(void *ctx, cairo_gl_surface_t *surface);
619 void (*destroy) (void *ctx);
622 typedef struct _cairo_gl_composite {
623 cairo_gl_surface_t *dst;
625 cairo_region_t *clip_region;
627 cairo_gl_operand_t src;
628 cairo_gl_operand_t mask;
632 cairo_bool_t multisample;
633 } cairo_gl_composite_t;
635 typedef struct _cairo_gl_font {
636 cairo_scaled_font_private_t base;
637 cairo_device_t *device;
641 static cairo_always_inline GLenum
642 _cairo_gl_get_error (cairo_gl_context_t *ctx)
644 GLenum err = ctx->dispatch.GetError();
647 while (ctx->dispatch.GetError ());
652 static inline cairo_device_t *
653 _cairo_gl_context_create_in_error (cairo_status_t status)
655 return (cairo_device_t *) _cairo_device_create_in_error (status);
658 cairo_private cairo_status_t
659 _cairo_gl_context_init (cairo_gl_context_t *ctx);
662 _cairo_gl_context_reset (cairo_gl_context_t *ctx);
665 _cairo_gl_surface_init (cairo_device_t *device,
666 cairo_gl_surface_t *surface,
667 cairo_content_t content,
668 int width, int height);
670 static cairo_always_inline cairo_bool_t cairo_warn
671 _cairo_gl_surface_is_texture (cairo_gl_surface_t *surface)
673 return surface->tex != 0;
676 cairo_private cairo_status_t
677 _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
678 cairo_image_surface_t *src,
679 int src_x, int src_y,
680 int width, int height,
681 int dst_x, int dst_y,
682 cairo_bool_t force_flush);
684 cairo_private cairo_int_status_t
685 _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface);
687 static cairo_always_inline cairo_bool_t
688 _cairo_gl_device_has_glsl (cairo_device_t *device)
690 return ((cairo_gl_context_t *) device)->has_shader_support;
693 static cairo_always_inline cairo_bool_t
694 _cairo_gl_device_requires_power_of_two_textures (cairo_device_t *device)
696 return ((cairo_gl_context_t *) device)->tex_target == GL_TEXTURE_RECTANGLE;
699 static cairo_always_inline cairo_status_t cairo_warn
700 _cairo_gl_context_acquire (cairo_device_t *device,
701 cairo_gl_context_t **ctx)
703 cairo_status_t status;
705 status = cairo_device_acquire (device);
706 if (unlikely (status))
709 /* clear potential previous GL errors */
710 _cairo_gl_get_error ((cairo_gl_context_t *) device);
712 *ctx = (cairo_gl_context_t *) device;
713 return CAIRO_STATUS_SUCCESS;
716 static cairo_always_inline cairo_warn cairo_status_t
717 _cairo_gl_context_release (cairo_gl_context_t *ctx, cairo_status_t status)
721 err = _cairo_gl_get_error (ctx);
723 if (unlikely (err)) {
724 cairo_status_t new_status;
725 new_status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
726 if (status == CAIRO_STATUS_SUCCESS)
730 cairo_device_release (&(ctx)->base);
736 _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
737 cairo_gl_surface_t *surface,
738 cairo_bool_t multisampling);
741 _cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
742 cairo_gl_surface_t *surface,
743 cairo_bool_t multisampling);
745 cairo_private cairo_gl_emit_rect_t
746 _cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx);
749 _cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
750 GLfloat x1, GLfloat y1,
751 GLfloat x2, GLfloat y2);
753 cairo_private cairo_gl_emit_span_t
754 _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx);
756 cairo_private cairo_gl_emit_glyph_t
757 _cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx,
758 const cairo_bool_t is_color_glyph);
761 _cairo_gl_context_activate (cairo_gl_context_t *ctx,
762 cairo_gl_tex_t tex_unit);
764 cairo_private cairo_bool_t
765 _cairo_gl_operator_is_supported (cairo_operator_t op);
767 cairo_private cairo_bool_t
768 _cairo_gl_ensure_stencil (cairo_gl_context_t *ctx,
769 cairo_gl_surface_t *surface);
771 static cairo_always_inline void
772 _disable_stencil_buffer (cairo_gl_context_t *ctx)
774 if (ctx->states_cache.stencil_test_enabled == TRUE) {
775 ctx->dispatch.Disable (GL_STENCIL_TEST);
776 ctx->states_cache.stencil_test_enabled = FALSE;
780 static cairo_always_inline void
781 _disable_scissor_buffer (cairo_gl_context_t *ctx)
783 if (ctx->states_cache.scissor_test_enabled == TRUE) {
784 ctx->dispatch.Disable (GL_SCISSOR_TEST);
785 ctx->states_cache.scissor_test_enabled = FALSE;
789 static cairo_always_inline void
790 _enable_stencil_buffer (cairo_gl_context_t *ctx)
792 if (ctx->states_cache.stencil_test_enabled == FALSE) {
793 ctx->dispatch.Enable (GL_STENCIL_TEST);
794 ctx->states_cache.stencil_test_enabled = TRUE;
798 static cairo_always_inline void
799 _enable_scissor_buffer (cairo_gl_context_t *ctx)
801 if (ctx->states_cache.scissor_test_enabled == FALSE) {
802 ctx->dispatch.Enable (GL_SCISSOR_TEST);
803 ctx->states_cache.scissor_test_enabled = TRUE;
807 cairo_private cairo_status_t
808 _cairo_gl_composite_init (cairo_gl_composite_t *setup,
810 cairo_gl_surface_t *dst,
811 cairo_bool_t has_component_alpha);
814 _cairo_gl_composite_fini (cairo_gl_composite_t *setup);
816 cairo_private cairo_status_t
817 _cairo_gl_composite_set_operator (cairo_gl_composite_t *setup,
819 cairo_bool_t assume_component_alpha);
822 _cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup,
823 cairo_region_t *clip_region);
826 _cairo_gl_composite_set_clip(cairo_gl_composite_t *setup,
829 cairo_private cairo_int_status_t
830 _cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
831 const cairo_pattern_t *pattern,
832 const cairo_rectangle_int_t *sample,
833 const cairo_rectangle_int_t *extents,
834 cairo_bool_t use_texgen,
835 cairo_bool_t encode_color_as_attribute);
838 _cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup,
839 const cairo_color_t *color);
842 _cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
843 const cairo_gl_operand_t *source);
845 cairo_private cairo_int_status_t
846 _cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
847 const cairo_pattern_t *pattern,
848 const cairo_rectangle_int_t *sample,
849 const cairo_rectangle_int_t *extents,
850 cairo_bool_t use_texgen);
853 _cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
854 const cairo_gl_operand_t *mask);
857 _cairo_gl_composite_set_spans (cairo_gl_composite_t *setup);
860 _cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup);
862 cairo_private cairo_status_t
863 _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
864 cairo_gl_context_t **ctx);
866 cairo_private cairo_status_t
867 _cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
868 cairo_gl_context_t *ctx);
871 _cairo_gl_composite_flush (cairo_gl_context_t *ctx);
873 cairo_private cairo_int_status_t
874 _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx,
875 cairo_gl_composite_t *setup,
876 const cairo_point_t quad[4]);
878 cairo_private cairo_int_status_t
879 _cairo_gl_composite_emit_int_quad_as_tristrip (cairo_gl_context_t *ctx,
880 cairo_gl_composite_t *setup,
883 cairo_private cairo_int_status_t
884 _cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx,
885 cairo_gl_composite_t *setup,
886 const cairo_point_t triangle[3]);
888 cairo_private cairo_int_status_t
889 _cairo_gl_composite_emit_point_as_tristrip_line (cairo_gl_context_t *ctx,
890 const cairo_point_t point[2],
891 cairo_bool_t start_point);
893 cairo_private cairo_int_status_t
894 _cairo_gl_composite_emit_point_as_single_line (cairo_gl_context_t *ctx,
895 const cairo_point_t point[2]);
898 _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
899 cairo_gl_tex_t tex_unit);
901 cairo_private cairo_bool_t
902 _cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor,
903 pixman_format_code_t pixman_format,
904 GLenum *internal_format, GLenum *format,
905 GLenum *type, cairo_bool_t *has_alpha,
906 cairo_bool_t *needs_swap);
909 _cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache);
912 _cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
913 cairo_gl_glyph_cache_t *cache);
915 cairo_private cairo_int_status_t
916 _cairo_gl_surface_show_glyphs (void *abstract_dst,
918 const cairo_pattern_t *source,
919 cairo_glyph_t *glyphs,
921 cairo_scaled_font_t *scaled_font,
922 const cairo_clip_t *clip,
923 int *remaining_glyphs);
925 cairo_private cairo_status_t
926 _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx);
929 _cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx);
931 static cairo_always_inline cairo_bool_t
932 _cairo_gl_context_is_flushed (cairo_gl_context_t *ctx)
934 return ctx->vb_offset == 0;
937 cairo_private cairo_status_t
938 _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
939 cairo_gl_operand_t *source,
940 cairo_gl_operand_t *mask,
941 cairo_bool_t use_coverage,
942 cairo_gl_shader_in_t in,
943 cairo_gl_shader_t **shader);
945 cairo_private cairo_gl_uniform_t
946 _cairo_gl_shader_uniform_for_texunit (cairo_gl_uniform_t uniform,
947 cairo_gl_tex_t tex_unit);
950 _cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
951 cairo_gl_uniform_t uniform,
955 _cairo_gl_shader_bind_float_array (cairo_gl_context_t *ctx,
956 cairo_gl_uniform_t uniform,
957 int num, float *values);
960 _cairo_gl_shader_bind_int (cairo_gl_context_t *ctx,
961 cairo_gl_uniform_t uniform,
965 _cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
966 cairo_gl_uniform_t uniform,
967 float value0, float value1);
970 _cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
971 cairo_gl_uniform_t uniform,
977 _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
978 cairo_gl_uniform_t uniform,
979 float value0, float value1,
980 float value2, float value3);
983 _cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
984 cairo_gl_uniform_t uniform,
985 const cairo_matrix_t* m);
988 _cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
989 cairo_gl_uniform_t uniform,
993 _cairo_gl_set_shader (cairo_gl_context_t *ctx,
994 cairo_gl_shader_t *shader);
997 _cairo_gl_shader_fini (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader);
1000 _cairo_gl_get_version (cairo_gl_dispatch_t *dispatch);
1002 cairo_private cairo_gl_flavor_t
1003 _cairo_gl_get_flavor (cairo_gl_dispatch_t *dispatch);
1005 cairo_private cairo_bool_t
1006 _cairo_gl_has_extension (cairo_gl_dispatch_t *dispatch, const char *ext);
1008 cairo_private cairo_status_t
1009 _cairo_gl_dispatch_init(cairo_gl_dispatch_t *dispatch,
1010 cairo_gl_get_proc_addr_func_t get_proc_addr,
1013 cairo_private cairo_int_status_t
1014 _cairo_gl_operand_init (cairo_gl_operand_t *operand,
1015 const cairo_pattern_t *pattern,
1016 cairo_gl_surface_t *dst,
1017 const cairo_rectangle_int_t *sample,
1018 const cairo_rectangle_int_t *extents,
1019 cairo_bool_t use_texgen,
1020 cairo_bool_t encode_color_as_attribute);
1023 _cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
1024 const cairo_color_t *color);
1026 cairo_private cairo_filter_t
1027 _cairo_gl_operand_get_filter (cairo_gl_operand_t *operand);
1030 _cairo_gl_operand_get_gl_filter (cairo_gl_operand_t *operand);
1032 cairo_private cairo_extend_t
1033 _cairo_gl_operand_get_extend (cairo_gl_operand_t *operand);
1035 cairo_private cairo_extend_t
1036 _cairo_gl_operand_get_atlas_extend (cairo_gl_operand_t *operand);
1038 cairo_private unsigned int
1039 _cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand);
1041 cairo_private cairo_bool_t
1042 _cairo_gl_operand_get_use_atlas (cairo_gl_operand_t *operand);
1044 cairo_private cairo_bool_t
1045 _cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
1046 cairo_gl_operand_t *source,
1047 unsigned int vertex_offset);
1050 _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
1051 cairo_gl_operand_t *operand,
1052 cairo_gl_tex_t tex_unit);
1055 _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
1061 _cairo_gl_operand_copy (cairo_gl_operand_t *dst,
1062 const cairo_gl_operand_t *src);
1065 _cairo_gl_operand_translate (cairo_gl_operand_t *operand,
1066 double tx, double ty);
1069 _cairo_gl_operand_destroy (cairo_gl_operand_t *operand);
1071 cairo_private const cairo_compositor_t *
1072 _cairo_gl_msaa_compositor_get (void);
1074 cairo_private const cairo_compositor_t *
1075 _cairo_gl_span_compositor_get (void);
1077 cairo_private const cairo_compositor_t *
1078 _cairo_gl_traps_compositor_get (void);
1080 cairo_private cairo_int_status_t
1081 _cairo_gl_check_composite_glyphs (const cairo_composite_rectangles_t *extents,
1082 cairo_scaled_font_t *scaled_font,
1083 cairo_glyph_t *glyphs,
1086 cairo_private cairo_int_status_t
1087 _cairo_gl_composite_glyphs (void *_dst,
1088 cairo_operator_t op,
1089 cairo_surface_t *_src,
1094 cairo_composite_glyphs_info_t *info);
1096 cairo_private cairo_int_status_t
1097 _cairo_gl_composite_glyphs_with_clip (void *_dst,
1098 cairo_operator_t op,
1099 cairo_surface_t *_src,
1104 cairo_composite_glyphs_info_t *info,
1105 cairo_clip_t *clip);
1108 _cairo_gl_image_node_destroy (cairo_rtree_node_t *node);
1111 _cairo_gl_image_node_fini (void *data);
1114 _cairo_gl_image_cache_unlock (cairo_gl_context_t *ctx);
1116 cairo_private cairo_int_status_t
1117 _cairo_gl_image_cache_init (cairo_gl_context_t *ctx, int width, int height,
1118 cairo_gl_image_cache_t **image_cache);
1120 _cairo_gl_image_cache_fini (cairo_gl_context_t *ctx);
1123 _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
1124 cairo_gl_surface_t *surface);
1126 cairo_private cairo_surface_t *
1127 _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
1128 cairo_content_t content,
1132 cairo_private cairo_surface_t *
1133 _cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx,
1134 cairo_content_t content,
1138 cairo_private cairo_surface_t *
1139 _cairo_gl_pattern_to_source (cairo_surface_t *dst,
1140 const cairo_pattern_t *pattern,
1141 cairo_bool_t is_mask,
1142 const cairo_rectangle_int_t *extents,
1143 const cairo_rectangle_int_t *sample,
1144 int *src_x, int *src_y);
1146 cairo_private cairo_int_status_t
1147 _cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx,
1148 cairo_gl_composite_t *setup,
1149 cairo_clip_t *clip);
1151 cairo_private cairo_surface_t *
1152 _cairo_gl_white_source (void);
1155 _cairo_gl_scissor_to_rectangle (cairo_gl_surface_t *surface,
1156 const cairo_rectangle_int_t *r);
1158 static inline cairo_gl_operand_t *
1159 source_to_operand (cairo_surface_t *surface)
1161 cairo_gl_source_t *source = (cairo_gl_source_t *)surface;
1162 return source ? &source->operand : NULL;
1166 _cairo_gl_glyph_cache_unlock (cairo_gl_glyph_cache_t *cache)
1168 _cairo_rtree_unpin (&cache->rtree);
1173 cairo_private cairo_bool_t
1174 _cairo_gl_hairline_style_is_hairline (const cairo_stroke_style_t *style,
1175 const cairo_matrix_t *ctm);
1177 cairo_private cairo_status_t
1178 _cairo_gl_hairline_move_to (void *closure,
1179 const cairo_point_t *point);
1181 cairo_private cairo_status_t
1182 _cairo_gl_hairline_line_to (void *closure,
1183 const cairo_point_t *point);
1185 cairo_private cairo_status_t
1186 _cairo_gl_hairline_line_to_dashed (void *closure,
1187 const cairo_point_t *point);
1189 cairo_private cairo_status_t
1190 _cairo_gl_hairline_curve_to (void *closure,
1191 const cairo_point_t *p0,
1192 const cairo_point_t *p1,
1193 const cairo_point_t *p2);
1195 cairo_private cairo_status_t
1196 _cairo_gl_hairline_close_path (void *closure);
1198 cairo_private cairo_status_t
1199 _cairo_gl_path_fixed_stroke_to_hairline (const cairo_path_fixed_t *path,
1200 cairo_gl_hairline_closure_t *closure,
1201 const cairo_stroke_style_t *style,
1202 const cairo_matrix_t *ctm,
1203 const cairo_matrix_t *ctm_inverse,
1204 cairo_path_fixed_move_to_func_t *move_to,
1205 cairo_path_fixed_line_to_func_t *line_to,
1206 cairo_path_fixed_curve_to_func_t *curve_to,
1207 cairo_path_fixed_close_path_func_t *close_path);
1209 cairo_private cairo_gl_surface_t *
1210 _cairo_gl_gaussian_filter (cairo_gl_surface_t *dst,
1211 const cairo_surface_pattern_t *pattern,
1212 cairo_gl_surface_t *src,
1213 cairo_rectangle_int_t *extents_out);
1215 static inline cairo_bool_t
1216 _cairo_gl_surface_is_scratch (cairo_gl_context_t *ctx,
1217 cairo_gl_surface_t *surface)
1221 for (i = 0; i < 2; i++) {
1222 if (surface == ctx->source_scratch_surfaces[i] ||
1223 surface == ctx->mask_scratch_surfaces[i] ||
1224 surface == ctx->shadow_scratch_surfaces[i])
1228 if (surface == ctx->shadow_scratch_surfaces[2])
1234 slim_hidden_proto (cairo_gl_surface_create);
1235 slim_hidden_proto (cairo_gl_surface_create_for_texture);
1237 #endif /* CAIRO_GL_PRIVATE_H */