tizen 2.3.1 release
[framework/graphics/cairo.git] / src / cairo-gl-surface.c
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  */
40
41 #include "cairoint.h"
42
43 #include "cairo-gl-private.h"
44
45 #include "cairo-composite-rectangles-private.h"
46 #include "cairo-compositor-private.h"
47 #include "cairo-default-context-private.h"
48 #include "cairo-error-private.h"
49 #include "cairo-image-surface-inline.h"
50 #include "cairo-surface-backend-private.h"
51 #include "cairo-surface-shadow-private.h"
52 #include "cairo-surface-scale-translate-private.h"
53
54 static const cairo_surface_backend_t _cairo_gl_surface_backend;
55
56 static cairo_status_t
57 _cairo_gl_surface_flush (void *abstract_surface, unsigned flags);
58
59 static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
60 {
61     return surface->backend == &_cairo_gl_surface_backend;
62 }
63
64 static cairo_surface_t *
65 _cairo_gl_surface_shadow_surface (void *surface,
66                                   const cairo_bool_t has_blur,
67                                   int width, int height,
68                                   int *width_out, int *height_out)
69 {
70     int shadow_width, shadow_height;
71     cairo_gl_surface_t *shadow_surface = NULL;
72
73     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
74     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
75     if (ctx == NULL)
76         return NULL;
77
78     shadow_surface = ctx->shadow_scratch_surfaces[0];
79
80     if (shadow_surface) {
81         shadow_width = shadow_surface->width;
82         shadow_height = shadow_surface->height;
83
84         if (! has_blur) {
85             if(shadow_width >= width &&
86                shadow_height >= height) {
87                 *width_out = width;
88                 *height_out = height;
89                 return cairo_surface_reference (&shadow_surface->base);
90             }
91             else {
92                 cairo_surface_destroy (&shadow_surface->base);
93                 shadow_surface = NULL;
94             }
95         }
96         else {
97             if (shadow_width * 2 < width &&
98                 shadow_height * 2 < height) {
99                 if (shadow_width < MAX_SCRATCH_SIZE ||
100                     shadow_height < MAX_SCRATCH_SIZE) {
101                     cairo_surface_destroy (&shadow_surface->base);
102                     shadow_surface = NULL;
103                 }
104             }
105             else if (shadow_width > 4 * width &&
106                      shadow_height > 4 * height) {
107                 cairo_surface_destroy (&shadow_surface->base);
108                 shadow_surface = NULL;
109             }
110         }
111     }
112
113     if (! shadow_surface) {
114         shadow_width = shadow_height = MIN_SCRATCH_SIZE;
115         if (has_blur) {
116             while (shadow_width * 2 < width) {
117                 shadow_width *= 2;
118                 if (shadow_width == MAX_SCRATCH_SIZE)
119                     break;
120                 else if (shadow_width > MAX_SCRATCH_SIZE) {
121                     shadow_width *= 0.5;
122                     break;
123                 }
124             }
125             while (shadow_height * 2 < height) {
126                 shadow_height *= 2;
127                 if (shadow_height == MAX_SCRATCH_SIZE)
128                     break;
129                 else if (shadow_height > MAX_SCRATCH_SIZE) {
130                     shadow_height *= 0.5;
131                     break;
132                 }
133             }
134         }
135         else {
136             while (shadow_width < width) {
137                 shadow_width *= 2;
138                 if (shadow_width == MAX_SCRATCH_SIZE)
139                     break;
140                 else if (shadow_width > MAX_SCRATCH_SIZE) {
141                     shadow_width *= 0.5;
142                     break;
143                 }
144             }
145             while (shadow_height < height) {
146                 shadow_height *= 2;
147                 if (shadow_height == MAX_SCRATCH_SIZE)
148                     break;
149                 else if (shadow_height > MAX_SCRATCH_SIZE) {
150                     shadow_height *= 0.5;
151                     break;
152                 }
153             }
154         }
155
156
157         shadow_surface = (cairo_gl_surface_t *)
158                 _cairo_gl_surface_create_scratch (ctx,
159                                                   CAIRO_CONTENT_COLOR_ALPHA,
160                                                   shadow_width,
161                                                   shadow_height);
162         if (unlikely (shadow_surface->base.status)) {
163             cairo_surface_destroy (&shadow_surface->base);
164             return NULL;
165         }
166
167         _cairo_surface_release_device_reference (&shadow_surface->base);
168     }
169
170     ctx->shadow_scratch_surfaces[0] = shadow_surface;
171
172     shadow_surface->needs_to_cache = FALSE;
173     shadow_surface->force_no_cache = TRUE;
174
175     *width_out = width;
176     *height_out = height;
177
178     if (has_blur) {
179         while (*width_out > shadow_width) {
180             *width_out *= 0.5;
181         }
182
183         while (*height_out > shadow_height) {
184             *height_out *= 0.5;
185         }
186     }
187     else {
188         if (*width_out > MAX_SCRATCH_SIZE)
189             *width_out *= 0.5;
190         if (*height_out > MAX_SCRATCH_SIZE)
191             *height_out *= 0.5;
192     }
193
194     return cairo_surface_reference (&shadow_surface->base);
195 }
196
197 static cairo_surface_t *
198 _cairo_gl_surface_shadow_mask_surface (void *surface,
199                                        int width, int height,
200                                        unsigned int index)
201 {
202     cairo_gl_surface_t *mask_surface = NULL;
203
204     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
205     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
206     if (ctx == NULL)
207         return NULL;
208
209     if (index > 1)
210         return NULL;
211
212     mask_surface = ctx->shadow_masks[index];
213
214     if (mask_surface) {
215         if (mask_surface->width != width ||
216             mask_surface->height != height) {
217             cairo_surface_destroy (&mask_surface->base);
218             mask_surface = NULL;
219             ctx->shadow_masks[index] = NULL;
220         }
221     }
222
223     if (! mask_surface) {
224         mask_surface = (cairo_gl_surface_t *)
225                 _cairo_gl_surface_create_scratch (ctx,
226                                                   CAIRO_CONTENT_COLOR_ALPHA,
227                                                   width,
228                                                   height);
229         if (unlikely (mask_surface->base.status)) {
230             cairo_surface_destroy (&mask_surface->base);
231             return NULL;
232         }
233         _cairo_surface_release_device_reference (&mask_surface->base);
234     }
235
236     ctx->shadow_masks[index] = mask_surface;
237
238     mask_surface->needs_to_cache = FALSE;
239     mask_surface->force_no_cache = TRUE;
240
241     return cairo_surface_reference (&mask_surface->base);
242 }
243
244 static cairo_surface_t *
245 _cairo_gl_surface_glyph_shadow_surface (void *surface,
246                                         int width, int height,
247                                         cairo_bool_t for_source)
248 {
249     int shadow_width, shadow_height;
250     cairo_gl_surface_t *shadow_surface = NULL;
251
252     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
253     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
254     if (ctx == NULL)
255         return NULL;
256
257     if (! for_source)
258         shadow_surface = ctx->shadow_scratch_surfaces[1];
259     else
260         shadow_surface = ctx->shadow_scratch_surfaces[2];
261
262     if (shadow_surface) {
263         shadow_width = shadow_surface->width;
264         shadow_height = shadow_surface->height;
265
266         if (shadow_width < width ||
267             shadow_height < height) {
268            cairo_surface_destroy (&shadow_surface->base);
269            shadow_surface = NULL;
270         }
271     }
272
273     if (! shadow_surface) {
274         shadow_surface = (cairo_gl_surface_t *)
275                 _cairo_gl_surface_create_scratch (ctx,
276                                                   CAIRO_CONTENT_COLOR_ALPHA,
277                                                   width, height);
278         if (unlikely (shadow_surface->base.status)) {
279             cairo_surface_destroy (&shadow_surface->base);
280             return NULL;
281         }
282         _cairo_surface_release_device_reference (&shadow_surface->base);
283     }
284
285     if (! for_source)
286         ctx->shadow_scratch_surfaces[1] = shadow_surface;
287     else
288         ctx->shadow_scratch_surfaces[2] = shadow_surface;
289
290     shadow_surface->needs_to_cache = FALSE;
291     shadow_surface->force_no_cache = TRUE;
292
293     return cairo_surface_reference (&shadow_surface->base);
294 }
295
296 static cairo_surface_t *
297 _cairo_gl_surface_glyph_shadow_mask_surface (void *surface,
298                                              int width, int height,
299                                              unsigned index)
300 {
301     cairo_gl_surface_t *mask_surface = NULL;
302
303     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
304     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
305     if (ctx == NULL)
306         return NULL;
307
308     if (index > 1)
309         return NULL;
310
311     mask_surface = ctx->shadow_masks[index + 2];
312
313     if (mask_surface) {
314         if (mask_surface->width != width ||
315             mask_surface->height != height) {
316             cairo_surface_destroy (&mask_surface->base);
317             mask_surface = NULL;
318             ctx->shadow_masks[index + 2] = NULL;
319         }
320     }
321
322     if (! mask_surface) {
323         mask_surface = (cairo_gl_surface_t *)
324                 _cairo_gl_surface_create_scratch (ctx,
325                                                   CAIRO_CONTENT_ALPHA,
326                                                   width,
327                                                   height);
328         if (unlikely (mask_surface->base.status)) {
329             cairo_surface_destroy (&mask_surface->base);
330             return NULL;
331         }
332         _cairo_surface_release_device_reference (&mask_surface->base);
333     }
334
335     ctx->shadow_masks[index + 2] = mask_surface;
336
337     mask_surface->needs_to_cache = FALSE;
338     mask_surface->force_no_cache = TRUE;
339
340     return cairo_surface_reference (&mask_surface->base);
341 }
342
343 static cairo_bool_t
344 _cairo_gl_get_image_format_and_type_gles2 (pixman_format_code_t pixman_format,
345                                            GLenum *internal_format, GLenum *format,
346                                            GLenum *type, cairo_bool_t *has_alpha,
347                                            cairo_bool_t *needs_swap)
348 {
349     cairo_bool_t is_little_endian = _cairo_is_little_endian ();
350
351     *has_alpha = TRUE;
352
353     switch ((int) pixman_format) {
354     case PIXMAN_a8r8g8b8:
355         *internal_format = GL_BGRA;
356         *format = GL_BGRA;
357         *type = GL_UNSIGNED_BYTE;
358         *needs_swap = !is_little_endian;
359         return TRUE;
360
361     case PIXMAN_x8r8g8b8:
362         *internal_format = GL_BGRA;
363         *format = GL_BGRA;
364         *type = GL_UNSIGNED_BYTE;
365         *has_alpha = FALSE;
366         *needs_swap = !is_little_endian;
367         return TRUE;
368
369     case PIXMAN_a8b8g8r8:
370         *internal_format = GL_RGBA;
371         *format = GL_RGBA;
372         *type = GL_UNSIGNED_BYTE;
373         *needs_swap = !is_little_endian;
374         return TRUE;
375
376     case PIXMAN_x8b8g8r8:
377         *internal_format = GL_RGBA;
378         *format = GL_RGBA;
379         *type = GL_UNSIGNED_BYTE;
380         *has_alpha = FALSE;
381         *needs_swap = !is_little_endian;
382         return TRUE;
383
384     case PIXMAN_b8g8r8a8:
385         *internal_format = GL_BGRA;
386         *format = GL_BGRA;
387         *type = GL_UNSIGNED_BYTE;
388         *needs_swap = is_little_endian;
389         return TRUE;
390
391     case PIXMAN_b8g8r8x8:
392         *internal_format = GL_BGRA;
393         *format = GL_BGRA;
394         *type = GL_UNSIGNED_BYTE;
395         *has_alpha = FALSE;
396         *needs_swap = is_little_endian;
397         return TRUE;
398
399     case PIXMAN_r8g8b8:
400         *internal_format = GL_RGB;
401         *format = GL_RGB;
402         *type = GL_UNSIGNED_BYTE;
403         *needs_swap = is_little_endian;
404         return TRUE;
405
406     case PIXMAN_b8g8r8:
407         *internal_format = GL_RGB;
408         *format = GL_RGB;
409         *type = GL_UNSIGNED_BYTE;
410         *needs_swap = !is_little_endian;
411         return TRUE;
412
413     case PIXMAN_r5g6b5:
414         *internal_format = GL_RGB;
415         *format = GL_RGB;
416         *type = GL_UNSIGNED_SHORT_5_6_5;
417         *needs_swap = FALSE;
418         return TRUE;
419
420     case PIXMAN_b5g6r5:
421         *internal_format = GL_RGB;
422         *format = GL_RGB;
423         *type = GL_UNSIGNED_SHORT_5_6_5;
424         *needs_swap = TRUE;
425         return TRUE;
426
427     case PIXMAN_a1b5g5r5:
428         *internal_format = GL_RGBA;
429         *format = GL_RGBA;
430         *type = GL_UNSIGNED_SHORT_5_5_5_1;
431         *needs_swap = TRUE;
432         return TRUE;
433
434     case PIXMAN_x1b5g5r5:
435         *internal_format = GL_RGBA;
436         *format = GL_RGBA;
437         *type = GL_UNSIGNED_SHORT_5_5_5_1;
438         *has_alpha = FALSE;
439         *needs_swap = TRUE;
440         return TRUE;
441
442     case PIXMAN_a8:
443         *internal_format = GL_ALPHA;
444         *format = GL_ALPHA;
445         *type = GL_UNSIGNED_BYTE;
446         *needs_swap = FALSE;
447         return TRUE;
448
449     default:
450         return FALSE;
451     }
452 }
453
454 static cairo_bool_t
455 _cairo_gl_get_image_format_and_type_gl (pixman_format_code_t pixman_format,
456                                         GLenum *internal_format, GLenum *format,
457                                         GLenum *type, cairo_bool_t *has_alpha,
458                                         cairo_bool_t *needs_swap)
459 {
460     *has_alpha = TRUE;
461     *needs_swap = FALSE;
462
463     switch (pixman_format) {
464     case PIXMAN_a8r8g8b8:
465         *internal_format = GL_RGBA;
466         *format = GL_BGRA;
467         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
468         return TRUE;
469     case PIXMAN_x8r8g8b8:
470         *internal_format = GL_RGB;
471         *format = GL_BGRA;
472         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
473         *has_alpha = FALSE;
474         return TRUE;
475     case PIXMAN_a8b8g8r8:
476         *internal_format = GL_RGBA;
477         *format = GL_RGBA;
478         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
479         return TRUE;
480     case PIXMAN_x8b8g8r8:
481         *internal_format = GL_RGB;
482         *format = GL_RGBA;
483         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
484         *has_alpha = FALSE;
485         return TRUE;
486     case PIXMAN_b8g8r8a8:
487         *internal_format = GL_RGBA;
488         *format = GL_BGRA;
489         *type = GL_UNSIGNED_INT_8_8_8_8;
490         return TRUE;
491     case PIXMAN_b8g8r8x8:
492         *internal_format = GL_RGB;
493         *format = GL_BGRA;
494         *type = GL_UNSIGNED_INT_8_8_8_8;
495         *has_alpha = FALSE;
496         return TRUE;
497     case PIXMAN_r8g8b8:
498         *internal_format = GL_RGB;
499         *format = GL_RGB;
500         *type = GL_UNSIGNED_BYTE;
501         return TRUE;
502     case PIXMAN_b8g8r8:
503         *internal_format = GL_RGB;
504         *format = GL_BGR;
505         *type = GL_UNSIGNED_BYTE;
506         return TRUE;
507     case PIXMAN_r5g6b5:
508         *internal_format = GL_RGB;
509         *format = GL_RGB;
510         *type = GL_UNSIGNED_SHORT_5_6_5;
511         return TRUE;
512     case PIXMAN_b5g6r5:
513         *internal_format = GL_RGB;
514         *format = GL_RGB;
515         *type = GL_UNSIGNED_SHORT_5_6_5_REV;
516         return TRUE;
517     case PIXMAN_a1r5g5b5:
518         *internal_format = GL_RGBA;
519         *format = GL_BGRA;
520         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
521         return TRUE;
522     case PIXMAN_x1r5g5b5:
523         *internal_format = GL_RGB;
524         *format = GL_BGRA;
525         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
526         *has_alpha = FALSE;
527         return TRUE;
528     case PIXMAN_a1b5g5r5:
529         *internal_format = GL_RGBA;
530         *format = GL_RGBA;
531         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
532         return TRUE;
533     case PIXMAN_x1b5g5r5:
534         *internal_format = GL_RGB;
535         *format = GL_RGBA;
536         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
537         *has_alpha = FALSE;
538         return TRUE;
539     case PIXMAN_a8:
540         *internal_format = GL_ALPHA;
541         *format = GL_ALPHA;
542         *type = GL_UNSIGNED_BYTE;
543         return TRUE;
544
545     case PIXMAN_a2b10g10r10:
546     case PIXMAN_x2b10g10r10:
547     case PIXMAN_a4r4g4b4:
548     case PIXMAN_x4r4g4b4:
549     case PIXMAN_a4b4g4r4:
550     case PIXMAN_x4b4g4r4:
551     case PIXMAN_r3g3b2:
552     case PIXMAN_b2g3r3:
553     case PIXMAN_a2r2g2b2:
554     case PIXMAN_a2b2g2r2:
555     case PIXMAN_c8:
556     case PIXMAN_x4a4:
557     /* case PIXMAN_x4c4: */
558     case PIXMAN_x4g4:
559     case PIXMAN_a4:
560     case PIXMAN_r1g2b1:
561     case PIXMAN_b1g2r1:
562     case PIXMAN_a1r1g1b1:
563     case PIXMAN_a1b1g1r1:
564     case PIXMAN_c4:
565     case PIXMAN_g4:
566     case PIXMAN_a1:
567     case PIXMAN_g1:
568     case PIXMAN_yuy2:
569     case PIXMAN_yv12:
570     case PIXMAN_x2r10g10b10:
571     case PIXMAN_a2r10g10b10:
572     case PIXMAN_r8g8b8x8:
573     case PIXMAN_r8g8b8a8:
574     case PIXMAN_x14r6g6b6:
575     default:
576         return FALSE;
577     }
578 }
579
580 /*
581  * Extracts pixel data from an image surface.
582  */
583 static cairo_status_t
584 _cairo_gl_surface_extract_image_data (cairo_image_surface_t *image,
585                                       int x, int y,
586                                       int width, int height,
587                                       void **output)
588 {
589     int cpp = PIXMAN_FORMAT_BPP (image->pixman_format) / 8;
590     char *data = _cairo_malloc_ab (width * height, cpp);
591     char *dst = data;
592     unsigned char *src = image->data + y * image->stride + x * cpp;
593     int i;
594
595     if (unlikely (data == NULL))
596         return CAIRO_STATUS_NO_MEMORY;
597
598     for (i = 0; i < height; i++) {
599         memcpy (dst, src, width * cpp);
600         src += image->stride;
601         dst += width * cpp;
602     }
603
604     *output = data;
605
606     return CAIRO_STATUS_SUCCESS;
607 }
608
609 cairo_bool_t
610 _cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor,
611                                      pixman_format_code_t pixman_format,
612                                      GLenum *internal_format, GLenum *format,
613                                      GLenum *type, cairo_bool_t *has_alpha,
614                                      cairo_bool_t *needs_swap)
615 {
616     if (flavor == CAIRO_GL_FLAVOR_DESKTOP)
617         return _cairo_gl_get_image_format_and_type_gl (pixman_format,
618                                                        internal_format, format,
619                                                        type, has_alpha,
620                                                        needs_swap);
621     else
622         return _cairo_gl_get_image_format_and_type_gles2 (pixman_format,
623                                                           internal_format, format,
624                                                           type, has_alpha,
625                                                           needs_swap);
626
627 }
628
629 cairo_bool_t
630 _cairo_gl_operator_is_supported (cairo_operator_t op)
631 {
632     return op < CAIRO_OPERATOR_SATURATE;
633 }
634
635 static void
636 _cairo_gl_surface_embedded_operand_init (cairo_gl_surface_t *surface)
637 {
638     cairo_gl_operand_t *operand = &surface->operand;
639     cairo_surface_attributes_t *attributes = &operand->texture.attributes;
640
641     memset (operand, 0, sizeof (cairo_gl_operand_t));
642
643     operand->type = CAIRO_GL_OPERAND_TEXTURE;
644     operand->texture.surface = surface;
645     operand->texture.tex = surface->tex;
646     operand->pass = 0;
647
648     if (_cairo_gl_device_requires_power_of_two_textures (surface->base.device)) {
649         cairo_matrix_init_identity (&attributes->matrix);
650     } else {
651         cairo_matrix_init_scale (&attributes->matrix,
652                                  1.0 / surface->width,
653                                  1.0 / surface->height);
654     }
655
656     attributes->extend = CAIRO_EXTEND_NONE;
657     attributes->filter = CAIRO_FILTER_NEAREST;
658 }
659
660 void
661 _cairo_gl_surface_init (cairo_device_t *device,
662                         cairo_gl_surface_t *surface,
663                         cairo_content_t content,
664                         int width, int height)
665 {
666     assert (width > 0 && height > 0);
667
668     _cairo_surface_init (&surface->base,
669                          &_cairo_gl_surface_backend,
670                          device,
671                          content);
672
673     surface->width = width;
674     surface->height = height;
675     surface->needs_update = FALSE;
676     surface->size_changed = FALSE;
677     surface->needs_to_cache = FALSE;
678     surface->image_node = NULL;
679     surface->force_no_cache = FALSE;
680
681     surface->image_content_scale_x = 1.0;
682     surface->image_content_scale_y = 1.0;
683     surface->blur_stage = CAIRO_GL_BLUR_STAGE_NONE;
684
685     surface->clip_on_stencil_buffer = NULL;
686
687     surface->content_synced = TRUE;
688     surface->content_cleared = FALSE;
689
690     _cairo_gl_surface_embedded_operand_init (surface);
691 }
692
693 static cairo_surface_t *
694 _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
695                                               cairo_content_t       content,
696                                               GLuint                tex,
697                                               int                   width,
698                                               int                   height,
699                                               cairo_bool_t set_tex_param)
700 {
701     cairo_gl_surface_t *surface;
702
703     assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
704     surface = calloc (1, sizeof (cairo_gl_surface_t));
705     if (unlikely (surface == NULL))
706         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
707
708     surface->tex = tex;
709     _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
710
711     surface->supports_msaa = ctx->supports_msaa;
712     surface->num_samples = ctx->num_samples;
713     surface->supports_stencil = TRUE;
714
715     /* Create the texture used to store the surface's data. */
716     if (!set_tex_param) {
717     _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
718     ctx->dispatch.BindTexture (ctx->tex_target, surface->tex);
719     ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
720     ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
721     }
722
723     return &surface->base;
724 }
725
726 static cairo_surface_t *
727 _create_scratch_internal (cairo_gl_context_t *ctx,
728                           cairo_content_t content,
729                           int width,
730                           int height,
731                           cairo_bool_t for_caching)
732 {
733     cairo_gl_surface_t *surface;
734     GLenum format;
735     GLuint tex;
736
737     ctx->dispatch.GenTextures (1, &tex);
738     surface = (cairo_gl_surface_t *)
739         _cairo_gl_surface_create_scratch_for_texture (ctx, content,
740                                                       tex, width, height, FALSE);
741     if (unlikely (surface->base.status))
742         return &surface->base;
743
744     surface->owns_tex = TRUE;
745
746     /* adjust the texture size after setting our real extents */
747     if (width < 1)
748         width = 1;
749     if (height < 1)
750         height = 1;
751
752     switch (content) {
753     default:
754         ASSERT_NOT_REACHED;
755     case CAIRO_CONTENT_COLOR_ALPHA:
756         if (ctx->can_read_bgra)
757             format = GL_BGRA;
758         else
759             format = GL_RGBA;
760         break;
761     case CAIRO_CONTENT_ALPHA:
762         /* When using GL_ALPHA, compositing doesn't work properly, but for
763          * caching surfaces, we are just uploading pixel data, so it isn't
764          * an issue. */
765         if (for_caching)
766             format = GL_ALPHA;
767         else
768             format = GL_RGBA;
769         break;
770     case CAIRO_CONTENT_COLOR:
771         /* GL_RGB is almost what we want here -- sampling 1 alpha when
772          * texturing, using 1 as destination alpha factor in blending,
773          * etc.  However, when filtering with GL_CLAMP_TO_BORDER, the
774          * alpha channel of the border color will also be clamped to
775          * 1, when we actually want the border color we explicitly
776          * specified.  So, we have to store RGBA, and fill the alpha
777          * channel with 1 when blending.
778          */
779         if (ctx->can_read_bgra)
780             format = GL_BGRA;
781         else
782             format = GL_RGBA;
783         break;
784     }
785
786     ctx->dispatch.TexImage2D (ctx->tex_target, 0, format,
787                               width, height, 0,
788                   format, GL_UNSIGNED_BYTE, NULL);
789
790     return &surface->base;
791 }
792
793 cairo_surface_t *
794 _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
795                                   cairo_content_t       content,
796                                   int                   width,
797                                   int                   height)
798 {
799     return _create_scratch_internal (ctx, content, width, height, FALSE);
800 }
801
802 cairo_surface_t *
803 _cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx,
804                                               cairo_content_t content,
805                                               int width,
806                                               int height)
807 {
808     return _create_scratch_internal (ctx, content, width, height, TRUE);
809 }
810
811 static cairo_status_t
812 _cairo_gl_surface_clear (cairo_gl_surface_t  *surface,
813                          const cairo_color_t *color)
814 {
815     cairo_gl_context_t *ctx;
816     cairo_status_t status;
817     double r, g, b, a;
818
819     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
820     if (unlikely (status))
821         return status;
822
823     if (ctx->current_target == surface)
824         _cairo_gl_composite_flush (ctx);
825
826     /* FIXME:  for glesv3 and glesv2 with ANGLE extension of multisample
827        supports, it is much more expensive to paint texture back to
828        multisample renderbuffer.  Therefore, instead of clear
829        texture, we clear the renderbuffer.
830        In case, the next draw render target is texture, it will
831        blit renderbuffer back to texture */
832     if (ctx->gl_flavor != CAIRO_GL_FLAVOR_DESKTOP)
833         _cairo_gl_context_set_destination (ctx, surface, TRUE);
834     else
835         _cairo_gl_context_set_destination (ctx, surface, surface->msaa_active);
836     if (surface->base.content & CAIRO_CONTENT_COLOR) {
837         r = color->red   * color->alpha;
838         g = color->green * color->alpha;
839         b = color->blue  * color->alpha;
840     } else {
841         r = g = b = 0;
842     }
843     if (surface->base.content & CAIRO_CONTENT_ALPHA) {
844         a = color->alpha;
845     } else {
846         a = 1.0;
847     }
848
849     _disable_scissor_buffer (ctx);
850     if (ctx->states_cache.clear_red != r ||
851         ctx->states_cache.clear_green != g ||
852         ctx->states_cache.clear_blue != b ||
853         ctx->states_cache.clear_alpha != a) {
854
855         ctx->states_cache.clear_red = r;
856         ctx->states_cache.clear_green = g;
857         ctx->states_cache.clear_blue = b;
858         ctx->states_cache.clear_alpha = a;
859
860         ctx->dispatch.ClearColor (r, g, b, a);
861     }
862
863     /* optimize for mobile gl driver with deferred rendering */
864     if (surface->clip_on_stencil_buffer ||
865         ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
866         ctx->dispatch.Clear (GL_COLOR_BUFFER_BIT);
867     else {
868                 if (surface->clip_on_stencil_buffer) {
869                         _cairo_clip_destroy(surface->clip_on_stencil_buffer);
870                         surface->clip_on_stencil_buffer = NULL;
871                 }
872                 ctx->dispatch.Clear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
873     }
874
875     if (a == 0)
876         surface->base.is_clear = TRUE;
877
878     surface->content_changed = TRUE;
879     surface->content_synced = FALSE;
880     surface->content_cleared = TRUE;
881     return _cairo_gl_context_release (ctx, status);
882 }
883
884 static cairo_surface_t *
885 _cairo_gl_surface_create_and_clear_scratch (cairo_gl_context_t *ctx,
886                                             cairo_content_t content,
887                                             int width,
888                                             int height)
889 {
890     cairo_gl_surface_t *surface;
891     cairo_int_status_t status;
892
893     surface = (cairo_gl_surface_t *)
894         _cairo_gl_surface_create_scratch (ctx, content, width, height);
895     if (unlikely (surface->base.status))
896         return &surface->base;
897
898     /* Cairo surfaces start out initialized to transparent (black) */
899     status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
900     if (unlikely (status)) {
901         cairo_surface_destroy (&surface->base);
902         return _cairo_surface_create_in_error (status);
903     }
904
905     return &surface->base;
906 }
907
908 cairo_surface_t *
909 cairo_gl_surface_create (cairo_device_t         *abstract_device,
910                          cairo_content_t         content,
911                          int                     width,
912                          int                     height)
913 {
914     cairo_gl_context_t *ctx;
915     cairo_gl_surface_t *surface;
916     cairo_status_t status;
917
918     if (! CAIRO_CONTENT_VALID (content))
919         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
920
921     if (abstract_device == NULL)
922         return _cairo_image_surface_create_with_content (content, width, height);
923
924     if (abstract_device->status)
925         return _cairo_surface_create_in_error (abstract_device->status);
926
927     if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
928         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
929
930     status = _cairo_gl_context_acquire (abstract_device, &ctx);
931     if (unlikely (status))
932         return _cairo_surface_create_in_error (status);
933
934     surface = (cairo_gl_surface_t *)
935         _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
936     if (unlikely (surface->base.status)) {
937         status = _cairo_gl_context_release (ctx, surface->base.status);
938         cairo_surface_destroy (&surface->base);
939         return _cairo_surface_create_in_error (status);
940     }
941
942     status = _cairo_gl_context_release (ctx, status);
943     if (unlikely (status)) {
944         cairo_surface_destroy (&surface->base);
945         return _cairo_surface_create_in_error (status);
946     }
947
948     return &surface->base;
949 }
950 slim_hidden_def (cairo_gl_surface_create);
951
952 /**
953  * cairo_gl_surface_create_for_texture:
954  * @content: type of content in the surface
955  * @tex: name of texture to use for storage of surface pixels
956  * @width: width of the surface, in pixels
957  * @height: height of the surface, in pixels
958  *
959  * Creates a GL surface for the specified texture with the specified
960  * content and dimensions.  The texture must be kept around until the
961  * #cairo_surface_t is destroyed or cairo_surface_finish() is called
962  * on the surface.  The initial contents of @tex will be used as the
963  * initial image contents; you must explicitly clear the buffer,
964  * using, for example, cairo_rectangle() and cairo_fill() if you want
965  * it cleared.  The format of @tex should be compatible with @content,
966  * in the sense that it must have the color components required by
967  * @content.
968  *
969  * Return value: a pointer to the newly created surface. The caller
970  * owns the surface and should call cairo_surface_destroy() when done
971  * with it.
972  *
973  * This function always returns a valid pointer, but it will return a
974  * pointer to a "nil" surface if an error such as out of memory
975  * occurs. You can use cairo_surface_status() to check for this.
976  *
977  * Since: TBD
978  **/
979 cairo_surface_t *
980 cairo_gl_surface_create_for_texture (cairo_device_t     *abstract_device,
981                                      cairo_content_t     content,
982                                      unsigned int        tex,
983                                      int                 width,
984                                      int                 height)
985 {
986     cairo_gl_context_t *ctx;
987     cairo_gl_surface_t *surface;
988     cairo_status_t status;
989
990     if (! CAIRO_CONTENT_VALID (content))
991         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
992
993     if (abstract_device == NULL)
994         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
995
996     if (abstract_device->status)
997         return _cairo_surface_create_in_error (abstract_device->status);
998
999     if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
1000         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH));
1001
1002     status = _cairo_gl_context_acquire (abstract_device, &ctx);
1003     if (unlikely (status))
1004         return _cairo_surface_create_in_error (status);
1005
1006     surface = (cairo_gl_surface_t *)
1007         _cairo_gl_surface_create_scratch_for_texture (ctx, content,
1008                                                       tex, width, height, TRUE);
1009     status = _cairo_gl_context_release (ctx, status);
1010
1011     return &surface->base;
1012 }
1013 slim_hidden_def (cairo_gl_surface_create_for_texture);
1014
1015
1016 void
1017 cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
1018                            int              width,
1019                            int              height)
1020 {
1021     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
1022
1023     if (unlikely (abstract_surface->status))
1024         return;
1025     if (unlikely (abstract_surface->finished)) {
1026         _cairo_surface_set_error (abstract_surface,
1027                                   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1028         return;
1029     }
1030
1031     if (! _cairo_surface_is_gl (abstract_surface) ||
1032         _cairo_gl_surface_is_texture (surface)) {
1033         _cairo_surface_set_error (abstract_surface,
1034                                   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
1035         return;
1036     }
1037
1038     if (surface->width != width || surface->height != height) {
1039         surface->size_changed = TRUE;
1040         surface->width = width;
1041         surface->height = height;
1042     }
1043 }
1044
1045 int
1046 cairo_gl_surface_get_width (cairo_surface_t *abstract_surface)
1047 {
1048     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
1049
1050     if (! _cairo_surface_is_gl (abstract_surface))
1051         return 0;
1052
1053     return surface->width;
1054 }
1055
1056 int
1057 cairo_gl_surface_get_height (cairo_surface_t *abstract_surface)
1058 {
1059     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
1060
1061     if (! _cairo_surface_is_gl (abstract_surface))
1062         return 0;
1063
1064     return surface->height;
1065 }
1066
1067 void
1068 cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
1069 {
1070     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
1071
1072     if (unlikely (abstract_surface->status))
1073         return;
1074     if (unlikely (abstract_surface->finished)) {
1075         _cairo_surface_set_error (abstract_surface,
1076                                   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1077         return;
1078     }
1079
1080     if (! _cairo_surface_is_gl (abstract_surface)) {
1081         _cairo_surface_set_error (abstract_surface,
1082                                   CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
1083         return;
1084     }
1085
1086     if (! _cairo_gl_surface_is_texture (surface)) {
1087         cairo_gl_context_t *ctx;
1088         cairo_status_t status;
1089
1090         status = _cairo_gl_context_acquire (surface->base.device, &ctx);
1091         if (unlikely (status))
1092             return;
1093
1094         /* And in any case we should flush any pending operations. */
1095         _cairo_gl_composite_flush (ctx);
1096
1097         /* For swapping on EGL, at least, we need a valid context/target. */
1098         _cairo_gl_context_set_destination (ctx, surface, FALSE);
1099
1100         ctx->swap_buffers (ctx, surface);
1101
1102         /* according to khronos specs on egl 1.4, stencil buffer is
1103          * not preserved after eglSwapBuffers */
1104         if (surface->clip_on_stencil_buffer) {
1105             _cairo_clip_destroy (surface->clip_on_stencil_buffer);
1106             surface->clip_on_stencil_buffer = NULL;
1107         }
1108
1109         status = _cairo_gl_context_release (ctx, status);
1110         if (status)
1111             status = _cairo_surface_set_error (abstract_surface, status);
1112     }
1113 }
1114
1115 static cairo_bool_t
1116 _cairo_gl_surface_size_valid (cairo_gl_surface_t *surface,
1117                               int width, int height)
1118 {
1119     cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
1120     return width > 0 && height > 0 &&
1121         width <= ctx->max_framebuffer_size &&
1122         height <= ctx->max_framebuffer_size;
1123 }
1124
1125 static cairo_surface_t *
1126 _cairo_gl_surface_create_similar (void           *abstract_surface,
1127                                   cairo_content_t  content,
1128                                   int             width,
1129                                   int             height)
1130 {
1131     cairo_surface_t *surface = abstract_surface;
1132     cairo_gl_context_t *ctx;
1133     cairo_status_t status;
1134
1135     if (! _cairo_gl_surface_size_valid (abstract_surface, width, height))
1136         return _cairo_image_surface_create_with_content (content, width, height);
1137
1138     status = _cairo_gl_context_acquire (surface->device, &ctx);
1139     if (unlikely (status))
1140         return _cairo_surface_create_in_error (status);
1141
1142     surface = _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
1143
1144     status = _cairo_gl_context_release (ctx, status);
1145     if (unlikely (status)) {
1146         cairo_surface_destroy (surface);
1147         return _cairo_surface_create_in_error (status);
1148     }
1149
1150     return surface;
1151 }
1152
1153 static cairo_int_status_t
1154 _cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst,
1155                                       cairo_gl_context_t *ctx,
1156                                       int x, int y,
1157                                       int width, int height)
1158 {
1159     cairo_gl_composite_t setup;
1160     cairo_status_t status;
1161
1162     _cairo_gl_composite_flush (ctx);
1163     ctx->dispatch.ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
1164
1165     status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE,
1166                                        dst, FALSE);
1167     if (unlikely (status))
1168         goto CLEANUP;
1169
1170     _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_BLACK);
1171
1172     status = _cairo_gl_composite_begin (&setup, &ctx);
1173     if (unlikely (status))
1174         goto CLEANUP;
1175
1176     _cairo_gl_context_emit_rect (ctx, x, y, x + width, y + height);
1177
1178     status = _cairo_gl_context_release (ctx, status);
1179
1180   CLEANUP:
1181     _cairo_gl_composite_fini (&setup);
1182
1183     _cairo_gl_composite_flush (ctx);
1184     ctx->dispatch.ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1185
1186     return status;
1187 }
1188
1189 cairo_status_t
1190 _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
1191                               cairo_image_surface_t *src,
1192                               int src_x, int src_y,
1193                               int width, int height,
1194                               int dst_x, int dst_y,
1195                               cairo_bool_t force_flush)
1196 {
1197     GLenum internal_format, format, type;
1198     cairo_bool_t has_alpha, needs_swap;
1199     cairo_image_surface_t *clone = NULL;
1200     cairo_gl_context_t *ctx;
1201     int cpp;
1202     cairo_image_surface_t *rgba_clone = NULL;
1203     cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
1204
1205     status = _cairo_gl_context_acquire (dst->base.device, &ctx);
1206     if (unlikely (status))
1207         return status;
1208
1209     if (_cairo_gl_get_flavor (&ctx->dispatch) == CAIRO_GL_FLAVOR_ES2 ||
1210         _cairo_gl_get_flavor (&ctx->dispatch) == CAIRO_GL_FLAVOR_ES3) {
1211         pixman_format_code_t pixman_format;
1212         cairo_surface_pattern_t pattern;
1213         cairo_bool_t require_conversion = FALSE;
1214         pixman_format = _cairo_is_little_endian () ? PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
1215
1216         if (src->base.content != CAIRO_CONTENT_ALPHA) {
1217             if (src->pixman_format != pixman_format)
1218                 require_conversion = TRUE;
1219         }
1220         else if (dst->base.content != CAIRO_CONTENT_ALPHA)
1221             require_conversion = TRUE;
1222         else {
1223             if (src->pixman_format == PIXMAN_a1) {
1224                 pixman_format = PIXMAN_a8;
1225                 require_conversion = TRUE;
1226             }
1227         }
1228
1229         if (require_conversion) {
1230             rgba_clone = (cairo_image_surface_t *)
1231                 _cairo_image_surface_create_with_pixman_format (NULL,
1232                                                                 pixman_format,
1233                                                                 src->width,
1234                                                                 src->height,
1235                                                                 0);
1236             if (unlikely (rgba_clone->base.status))
1237                 goto FAIL;
1238
1239             _cairo_pattern_init_for_surface (&pattern, &src->base);
1240             status = _cairo_surface_paint (&rgba_clone->base,
1241                                            CAIRO_OPERATOR_SOURCE,
1242                                            &pattern.base, NULL);
1243             _cairo_pattern_fini (&pattern.base);
1244             if (unlikely (status))
1245                 goto FAIL;
1246
1247             src = rgba_clone;
1248         }
1249     }
1250
1251     if (! _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
1252                                                src->pixman_format,
1253                                                &internal_format,
1254                                                &format,
1255                                                &type,
1256                                                &has_alpha,
1257                                                &needs_swap))
1258     {
1259         cairo_bool_t is_supported;
1260
1261         clone = _cairo_image_surface_coerce (src);
1262         if (unlikely (status = clone->base.status))
1263             goto FAIL;
1264
1265         is_supported =
1266             _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
1267                                                  clone->pixman_format,
1268                                                  &internal_format,
1269                                                  &format,
1270                                                  &type,
1271                                                  &has_alpha,
1272                                                  &needs_swap);
1273         assert (is_supported);
1274         assert (!needs_swap);
1275         src = clone;
1276     }
1277
1278     cpp = PIXMAN_FORMAT_BPP (src->pixman_format) / 8;
1279
1280     if (force_flush) {
1281         status = _cairo_gl_surface_flush (&dst->base, 0);
1282         if (unlikely (status))
1283             goto FAIL;
1284     }
1285
1286     if (_cairo_gl_surface_is_texture (dst)) {
1287         void *data_start = src->data + src_y * src->stride + src_x * cpp;
1288         void *data_start_gles2 = NULL;
1289
1290         /*
1291          * Due to GL_UNPACK_ROW_LENGTH missing in GLES2 we have to extract the
1292          * image data ourselves in some cases. In particular, we must extract
1293          * the pixels if:
1294          * a. we don't want full-length lines or
1295          * b. the row stride cannot be handled by GL itself using a 4 byte
1296          *     alignment constraint
1297          */
1298         if (src->stride < 0 ||
1299             (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
1300              (src->width * cpp < src->stride - 3 ||
1301               width != src->width)))
1302         {
1303             ctx->dispatch.PixelStorei (GL_UNPACK_ALIGNMENT, 1);
1304             status = _cairo_gl_surface_extract_image_data (src, src_x, src_y,
1305                                                            width, height,
1306                                                            &data_start_gles2);
1307             if (unlikely (status))
1308                 goto FAIL;
1309
1310             data_start = data_start_gles2;
1311         }
1312         else
1313         {
1314             ctx->dispatch.PixelStorei (GL_UNPACK_ALIGNMENT, 4);
1315             if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
1316                 ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
1317                 ctx->dispatch.PixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp);
1318         }
1319
1320         /* we must resolve the renderbuffer to texture before we
1321            upload image */
1322         status = _cairo_gl_surface_resolve_multisampling (dst);
1323     if (unlikely (status)) {
1324         free (data_start_gles2);
1325         goto FAIL;
1326     }
1327
1328         _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
1329         ctx->dispatch.BindTexture (ctx->tex_target, dst->tex);
1330         ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1331         ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1332         ctx->dispatch.TexSubImage2D (ctx->tex_target, 0,
1333                          dst_x, dst_y, width, height,
1334                          format, type, data_start);
1335
1336         free (data_start_gles2);
1337
1338         /* If we just treated some rgb-only data as rgba, then we have to
1339          * go back and fix up the alpha channel where we filled in this
1340          * texture data.
1341          */
1342         if (!has_alpha) {
1343             _cairo_gl_surface_fill_alpha_channel (dst, ctx,
1344                                                   dst_x, dst_y,
1345                                                   width, height);
1346
1347         }
1348         dst->content_synced = FALSE;
1349     } else {
1350         cairo_surface_t *tmp;
1351
1352         tmp = _cairo_gl_surface_create_scratch (ctx,
1353                                                 dst->base.content,
1354                                                 width, height);
1355         if (unlikely (tmp->status))
1356             goto FAIL;
1357
1358         status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp,
1359                                                src,
1360                                                src_x, src_y,
1361                                                width, height,
1362                                                0, 0, force_flush);
1363         if (status == CAIRO_INT_STATUS_SUCCESS) {
1364             cairo_surface_pattern_t tmp_pattern;
1365             cairo_rectangle_int_t r;
1366             cairo_clip_t *clip;
1367
1368             _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
1369             cairo_matrix_init_translate (&tmp_pattern.base.matrix,
1370                                          -dst_x, -dst_y);
1371             tmp_pattern.base.filter = CAIRO_FILTER_NEAREST;
1372             tmp_pattern.base.extend = CAIRO_EXTEND_NONE;
1373
1374             r.x = dst_x;
1375             r.y = dst_y;
1376             r.width = width;
1377             r.height = height;
1378             clip = _cairo_clip_intersect_rectangle (NULL, &r);
1379             status = _cairo_surface_paint (&dst->base,
1380                                            CAIRO_OPERATOR_SOURCE,
1381                                            &tmp_pattern.base,
1382                                            clip);
1383             _cairo_clip_destroy (clip);
1384             _cairo_pattern_fini (&tmp_pattern.base);
1385         }
1386
1387         cairo_surface_destroy (tmp);
1388     }
1389
1390 FAIL:
1391     status = _cairo_gl_context_release (ctx, status);
1392
1393     if (clone)
1394         cairo_surface_destroy (&clone->base);
1395
1396     if (rgba_clone)
1397         cairo_surface_destroy (&rgba_clone->base);
1398
1399     if (status == CAIRO_INT_STATUS_SUCCESS) {
1400         dst->content_changed = TRUE;
1401         dst->content_synced = FALSE;
1402     }
1403
1404     return status;
1405 }
1406
1407 static int _cairo_gl_surface_flavor (cairo_gl_surface_t *surface)
1408 {
1409     cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
1410     return ctx->gl_flavor;
1411 }
1412
1413 static cairo_status_t
1414 _cairo_gl_surface_finish (void *abstract_surface)
1415 {
1416     cairo_gl_surface_t *surface = abstract_surface;
1417     cairo_status_t status;
1418     cairo_gl_context_t *ctx;
1419
1420     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
1421     if (unlikely (status))
1422         return status;
1423
1424     if ((ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE ||
1425          ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_GAUSSIAN) &&
1426         ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface)
1427         _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
1428     if ((ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE ||
1429          ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_GAUSSIAN) &&
1430         ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface)
1431         _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
1432     if (ctx->current_target == surface)
1433         ctx->current_target = NULL;
1434
1435     if (surface->fb)
1436         ctx->dispatch.DeleteFramebuffers (1, &surface->fb);
1437     if (surface->depth_stencil)
1438         ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil);
1439     if (surface->owns_tex)
1440         ctx->dispatch.DeleteTextures (1, &surface->tex);
1441
1442     if (surface->msaa_depth_stencil)
1443         ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_depth_stencil);
1444     if (surface->msaa_fb)
1445         ctx->dispatch.DeleteFramebuffers (1, &surface->msaa_fb);
1446     if (surface->msaa_rb)
1447         ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_rb);
1448
1449     if (surface->image_node) {
1450         surface->image_node->node.pinned = FALSE;
1451         _cairo_rtree_node_remove (&ctx->image_cache->rtree,
1452                                   &surface->image_node->node);
1453     }
1454
1455     if (surface->clip_on_stencil_buffer)
1456         _cairo_clip_destroy (surface->clip_on_stencil_buffer);
1457
1458     return _cairo_gl_context_release (ctx, status);
1459 }
1460
1461 static cairo_image_surface_t *
1462 _cairo_gl_surface_map_to_image (void      *abstract_surface,
1463                                 const cairo_rectangle_int_t   *extents)
1464 {
1465     cairo_gl_surface_t *surface = abstract_surface;
1466     cairo_image_surface_t *image;
1467     cairo_gl_context_t *ctx;
1468     GLenum format, type;
1469     pixman_format_code_t pixman_format;
1470     unsigned int cpp;
1471     cairo_bool_t flipped, mesa_invert;
1472     cairo_status_t status;
1473     int y;
1474
1475     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
1476     if (unlikely (status)) {
1477         return _cairo_image_surface_create_in_error (status);
1478     }
1479
1480     /* Want to use a switch statement here but the compiler gets whiny. */
1481     if (surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) {
1482         format = GL_BGRA;
1483         pixman_format = PIXMAN_a8r8g8b8;
1484         type = GL_UNSIGNED_INT_8_8_8_8_REV;
1485         cpp = 4;
1486     } else if (surface->base.content == CAIRO_CONTENT_COLOR) {
1487         format = GL_BGRA;
1488         pixman_format = PIXMAN_x8r8g8b8;
1489         type = GL_UNSIGNED_INT_8_8_8_8_REV;
1490         cpp = 4;
1491     } else if (surface->base.content == CAIRO_CONTENT_ALPHA) {
1492         format = GL_ALPHA;
1493         pixman_format = PIXMAN_a8;
1494         type = GL_UNSIGNED_BYTE;
1495         cpp = 1;
1496     } else {
1497         ASSERT_NOT_REACHED;
1498         return NULL;
1499     }
1500
1501     if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2 ||
1502         _cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES3) {
1503         /* If only RGBA is supported, we must download data in a compatible
1504          * format. This means that pixman will convert the data on the CPU when
1505          * interacting with other image surfaces. For ALPHA, GLES2 does not
1506          * support GL_PACK_ROW_LENGTH anyway, and this makes sure that the
1507          * pixman image that is created has row_stride = row_width * bpp. */
1508         if (surface->base.content == CAIRO_CONTENT_ALPHA || !ctx->can_read_bgra) {
1509             cairo_bool_t little_endian = _cairo_is_little_endian ();
1510             format = GL_RGBA;
1511
1512             if (surface->base.content == CAIRO_CONTENT_COLOR) {
1513                 pixman_format = little_endian ?
1514                     PIXMAN_x8b8g8r8 : PIXMAN_r8g8b8x8;
1515             } else {
1516                 pixman_format = little_endian ?
1517                     PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
1518             }
1519         }
1520
1521         /* GLES2 only supports GL_UNSIGNED_BYTE. */
1522         type = GL_UNSIGNED_BYTE;
1523         cpp = 4;
1524     }
1525
1526     image = (cairo_image_surface_t*)
1527         _cairo_image_surface_create_with_pixman_format (NULL,
1528                                                         pixman_format,
1529                                                         extents->width,
1530                                                         extents->height,
1531                                                         -1);
1532     if (unlikely (image->base.status)) {
1533         status = _cairo_gl_context_release (ctx, status);
1534         return image;
1535     }
1536
1537     cairo_surface_set_device_offset (&image->base, -extents->x, -extents->y);
1538
1539     /* If the original surface has not been modified or
1540      * is clear, we can avoid downloading data. */
1541     if (surface->base.is_clear || surface->base.serial == 0) {
1542         status = _cairo_gl_context_release (ctx, status);
1543         return image;
1544     }
1545
1546     /* This is inefficient, as we'd rather just read the thing without making
1547      * it the destination.  But then, this is the fallback path, so let's not
1548      * fall back instead.
1549      */
1550     _cairo_gl_composite_flush (ctx);
1551
1552     _cairo_gl_context_set_destination (ctx, surface, FALSE);
1553
1554     flipped = ! _cairo_gl_surface_is_texture (surface);
1555     mesa_invert = flipped && ctx->has_mesa_pack_invert;
1556
1557     ctx->dispatch.PixelStorei (GL_PACK_ALIGNMENT, 4);
1558     if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
1559         ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
1560         ctx->dispatch.PixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
1561     if (mesa_invert)
1562         ctx->dispatch.PixelStorei (GL_PACK_INVERT_MESA, 1);
1563
1564     y = extents->y;
1565     if (flipped)
1566         y = surface->height - extents->y - extents->height;
1567
1568     ctx->dispatch.ReadPixels (extents->x, y,
1569                   extents->width, extents->height,
1570                   format, type, image->data);
1571     if (mesa_invert)
1572         ctx->dispatch.PixelStorei (GL_PACK_INVERT_MESA, 0);
1573
1574     status = _cairo_gl_context_release (ctx, status);
1575     if (unlikely (status)) {
1576         cairo_surface_destroy (&image->base);
1577         return _cairo_image_surface_create_in_error (status);
1578     }
1579
1580     /* We must invert the image manualy if we lack GL_MESA_pack_invert */
1581     if (flipped && ! mesa_invert) {
1582         uint8_t stack[1024], *row = stack;
1583         uint8_t *top = image->data;
1584         uint8_t *bot = image->data + (image->height-1)*image->stride;
1585
1586         if (image->stride > (int)sizeof(stack)) {
1587             row = malloc (image->stride);
1588             if (unlikely (row == NULL)) {
1589                 cairo_surface_destroy (&image->base);
1590                 return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1591             }
1592         }
1593
1594         while (top < bot) {
1595             memcpy (row, top, image->stride);
1596             memcpy (top, bot, image->stride);
1597             memcpy (bot, row, image->stride);
1598             top += image->stride;
1599             bot -= image->stride;
1600         }
1601
1602         if (row != stack)
1603             free(row);
1604     }
1605
1606     image->base.is_clear = FALSE;
1607
1608     return image;
1609 }
1610
1611 static cairo_surface_t *
1612 _cairo_gl_surface_source (void                 *abstract_surface,
1613                           cairo_rectangle_int_t *extents)
1614 {
1615     cairo_gl_surface_t *surface = abstract_surface;
1616
1617     if (extents) {
1618         extents->x = extents->y = 0;
1619         extents->width  = surface->width;
1620         extents->height = surface->height;
1621     }
1622
1623     return &surface->base;
1624 }
1625
1626 static cairo_status_t
1627 _cairo_gl_surface_acquire_source_image (void                   *abstract_surface,
1628                                         cairo_image_surface_t **image_out,
1629                                         void                  **image_extra)
1630 {
1631     cairo_gl_surface_t *surface = abstract_surface;
1632     cairo_rectangle_int_t extents;
1633
1634     *image_extra = NULL;
1635
1636     extents.x = extents.y = 0;
1637     extents.width = surface->width;
1638     extents.height = surface->height;
1639
1640     *image_out = (cairo_image_surface_t *)
1641         _cairo_gl_surface_map_to_image (surface, &extents);
1642     return (*image_out)->base.status;
1643 }
1644
1645 static void
1646 _cairo_gl_surface_release_source_image (void                  *abstract_surface,
1647                                         cairo_image_surface_t *image,
1648                                         void                  *image_extra)
1649 {
1650     cairo_surface_destroy (&image->base);
1651 }
1652
1653 static cairo_int_status_t
1654 _cairo_gl_surface_unmap_image (void                   *abstract_surface,
1655                                cairo_image_surface_t *image)
1656 {
1657     cairo_int_status_t status;
1658
1659     status = _cairo_gl_surface_draw_image (abstract_surface, image,
1660                                            0, 0,
1661                                            image->width, image->height,
1662                                            image->base.device_transform_inverse.x0,
1663                                            image->base.device_transform_inverse.y0,
1664                                            TRUE);
1665
1666     cairo_surface_finish (&image->base);
1667     cairo_surface_destroy (&image->base);
1668
1669     return status;
1670 }
1671
1672 static cairo_bool_t
1673 _cairo_gl_surface_get_extents (void                  *abstract_surface,
1674                                cairo_rectangle_int_t *rectangle)
1675 {
1676     cairo_gl_surface_t *surface = abstract_surface;
1677
1678     rectangle->x = 0;
1679     rectangle->y = 0;
1680     rectangle->width  = surface->width;
1681     rectangle->height = surface->height;
1682
1683     return TRUE;
1684 }
1685
1686 static cairo_status_t
1687 _cairo_gl_surface_flush (void *abstract_surface, unsigned flags)
1688 {
1689     cairo_gl_surface_t *surface = abstract_surface;
1690     cairo_status_t status;
1691     cairo_gl_context_t *ctx;
1692
1693     if (flags)
1694         return CAIRO_STATUS_SUCCESS;
1695
1696     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
1697     if (unlikely (status))
1698         return status;
1699
1700     if (((ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE ||
1701           ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_GAUSSIAN) &&
1702          ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) ||
1703         ((ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE ||
1704           ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_GAUSSIAN) &&
1705          ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) ||
1706         (ctx->current_target == surface))
1707       _cairo_gl_composite_flush (ctx);
1708
1709     status = _cairo_gl_surface_resolve_multisampling (surface);
1710
1711     if (ctx->msaa_type != CAIRO_GL_NONE_MULTISAMPLE_TO_TEXTURE)
1712         ctx->dispatch.Flush ();
1713
1714     return _cairo_gl_context_release (ctx, status);
1715 }
1716
1717 cairo_int_status_t
1718 _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface)
1719 {
1720     cairo_gl_context_t *ctx;
1721     cairo_int_status_t status;
1722
1723     if (surface->base.device == NULL)
1724         return CAIRO_INT_STATUS_SUCCESS;
1725
1726     if (! surface->content_cleared) {
1727         /* GLES surfaces do not need explicit resolution. */
1728         if (! surface->msaa_active)
1729             return CAIRO_INT_STATUS_SUCCESS;
1730         else if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
1731                  !((cairo_gl_context_t *) surface->base.device)->has_angle_multisampling)
1732             return CAIRO_INT_STATUS_SUCCESS;
1733         else if (! _cairo_gl_surface_is_texture (surface))
1734             return CAIRO_INT_STATUS_SUCCESS;
1735     }
1736
1737     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
1738     if (unlikely (status))
1739         return status;
1740
1741     _cairo_gl_context_set_destination (ctx, surface, FALSE);
1742
1743     status = _cairo_gl_context_release (ctx, status);
1744
1745     surface->content_cleared = FALSE;
1746
1747     return status;
1748 }
1749
1750 static const cairo_compositor_t *
1751 get_compositor (cairo_gl_surface_t *surface)
1752 {
1753     cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
1754     return ctx->compositor;
1755 }
1756
1757 static cairo_int_status_t
1758 _cairo_gl_surface_paint (void                   *surface,
1759                          cairo_operator_t        op,
1760                          const cairo_pattern_t  *source,
1761                          const cairo_clip_t     *clip)
1762 {
1763     cairo_int_status_t status;
1764     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
1765     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
1766
1767     status = cairo_device_acquire (dst->base.device);
1768     if (unlikely (status))
1769         return status;
1770
1771     status = _cairo_surface_shadow_paint (surface, op, source, clip,
1772                                           &source->shadow);
1773     ctx->source_scratch_in_use = FALSE;
1774     if (unlikely (status)) {
1775         cairo_device_release (dst->base.device);
1776         return status;
1777     }
1778
1779     if (source->shadow.draw_shadow_only) {
1780         if (status == CAIRO_INT_STATUS_SUCCESS) {
1781             dst->content_changed = TRUE;
1782             dst->content_synced = FALSE;
1783         }
1784
1785         ctx->source_scratch_in_use = FALSE;
1786         cairo_device_release (dst->base.device);
1787         return status;
1788     }
1789
1790 #if 0 // Currently glClear does not get flushed to GPU so do not use this fast path for the time being
1791     /* simplify the common case of clearing the surface */
1792     if (clip == NULL) {
1793         if (op == CAIRO_OPERATOR_CLEAR) {
1794             status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
1795             cairo_device_release (dst->base.device);
1796             return status;
1797         }
1798         else if (source->type == CAIRO_PATTERN_TYPE_SOLID &&
1799                 (op == CAIRO_OPERATOR_SOURCE ||
1800                  (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
1801             status = _cairo_gl_surface_clear (surface,
1802                                             &((cairo_solid_pattern_t *) source)->color);
1803             cairo_device_release (dst->base.device);
1804             return status;
1805         }
1806     }
1807 #endif
1808
1809     status = _cairo_compositor_paint (get_compositor (surface), surface,
1810                                       op, source, clip);
1811     if (status == CAIRO_INT_STATUS_SUCCESS) {
1812         dst->content_changed = TRUE;
1813         dst->content_synced = FALSE;
1814     }
1815
1816     ctx->source_scratch_in_use = FALSE;
1817     cairo_device_release (dst->base.device);
1818     return status;
1819 }
1820
1821 static cairo_int_status_t
1822 _cairo_gl_surface_mask (void                     *surface,
1823                         cairo_operator_t          op,
1824                         const cairo_pattern_t   *source,
1825                         const cairo_pattern_t   *mask,
1826                         const cairo_clip_t      *clip)
1827 {
1828     cairo_int_status_t status;
1829     cairo_gl_surface_t *dst = (cairo_gl_surface_t *) surface;
1830     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
1831
1832     status = cairo_device_acquire (dst->base.device);
1833     if (unlikely (status))
1834         return status;
1835
1836     status = _cairo_surface_shadow_mask (surface, op, source, mask, clip,
1837                                           &source->shadow);
1838     ctx->source_scratch_in_use = FALSE;
1839     if (unlikely (status)) {
1840         cairo_device_release (dst->base.device);
1841         return status;
1842     }
1843
1844     if (source->shadow.draw_shadow_only) {
1845         if (status == CAIRO_INT_STATUS_SUCCESS) {
1846             dst->content_changed = TRUE;
1847             dst->content_synced = FALSE;
1848         }
1849
1850         ctx->source_scratch_in_use = FALSE;
1851         cairo_device_release (dst->base.device);
1852         return status;
1853     }
1854
1855     status = _cairo_compositor_mask (get_compositor (surface), surface,
1856                                      op, source, mask, clip);
1857     if (status == CAIRO_INT_STATUS_SUCCESS) {
1858         dst->content_changed = TRUE;
1859         dst->content_synced = FALSE;
1860
1861         ctx->source_scratch_in_use = FALSE;
1862         cairo_device_release (dst->base.device);
1863         return status;
1864     }
1865
1866     status = _cairo_compositor_mask (get_compositor (surface), surface,
1867                                      op, source, mask, clip);
1868     if (status == CAIRO_INT_STATUS_SUCCESS) {
1869         dst->content_changed = TRUE;
1870         dst->content_synced = FALSE;
1871     }
1872
1873     ctx->source_scratch_in_use = FALSE;
1874     cairo_device_release (dst->base.device);
1875     return status;
1876 }
1877
1878 static cairo_int_status_t
1879 _cairo_gl_surface_stroke (void                          *surface,
1880                           cairo_operator_t               op,
1881                           const cairo_pattern_t         *source,
1882                           const cairo_path_fixed_t      *path,
1883                           const cairo_stroke_style_t    *style,
1884                           const cairo_matrix_t          *ctm,
1885                           const cairo_matrix_t          *ctm_inverse,
1886                           double                         tolerance,
1887                           cairo_antialias_t              antialias,
1888                           const cairo_clip_t            *clip)
1889 {
1890     cairo_int_status_t status;
1891     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
1892     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
1893     cairo_shadow_type_t shadow_type = source->shadow.type;
1894
1895     status = cairo_device_acquire (dst->base.device);
1896     if (unlikely (status))
1897         return status;
1898
1899     if (shadow_type != CAIRO_SHADOW_INSET)
1900         status = _cairo_surface_shadow_stroke (surface, op, source, path,
1901                                                style, ctm, ctm_inverse,
1902                                                tolerance, antialias,
1903                                                clip, &source->shadow);
1904
1905     ctx->source_scratch_in_use = FALSE;
1906     if (unlikely (status)) {
1907         cairo_device_release (dst->base.device);
1908         return status;
1909     }
1910
1911     dst->content_changed = TRUE;
1912     dst->content_synced = FALSE;
1913
1914     if (shadow_type == CAIRO_SHADOW_DROP &&
1915         source->shadow.draw_shadow_only) {
1916         ctx->source_scratch_in_use = FALSE;
1917         cairo_device_release (dst->base.device);
1918         return status;
1919     }
1920
1921     ctx->source_scratch_in_use = FALSE;
1922
1923     if (! source->shadow.draw_shadow_only)
1924         status = _cairo_compositor_stroke (get_compositor (surface), surface,
1925                                            op, source, path, style,
1926                                            ctm, ctm_inverse, tolerance,
1927                                            antialias, clip);
1928     if (unlikely (status)) {
1929         ctx->source_scratch_in_use = FALSE;
1930         cairo_device_release (dst->base.device);
1931         return status;
1932     }
1933
1934     ctx->source_scratch_in_use = FALSE;
1935
1936     if (shadow_type == CAIRO_SHADOW_INSET)
1937         status = _cairo_surface_shadow_stroke (surface, op, source, path,
1938                                                style, ctm, ctm_inverse,
1939                                                tolerance, antialias,
1940                                                clip, &source->shadow);
1941
1942     ctx->source_scratch_in_use = FALSE;
1943     cairo_device_release (dst->base.device);
1944     return status;
1945 }
1946
1947 static cairo_int_status_t
1948 _cairo_gl_surface_fill (void                    *surface,
1949                         cairo_operator_t         op,
1950                         const cairo_pattern_t   *source,
1951                         const cairo_path_fixed_t*path,
1952                         cairo_fill_rule_t        fill_rule,
1953                         double                   tolerance,
1954                         cairo_antialias_t        antialias,
1955                         const cairo_clip_t      *clip)
1956 {
1957     cairo_status_t status;
1958     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
1959     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
1960     cairo_shadow_type_t shadow_type = source->shadow.type;
1961
1962     status = cairo_device_acquire (dst->base.device);
1963     if (unlikely (status))
1964         return status;
1965
1966     if (shadow_type != CAIRO_SHADOW_INSET)
1967         status = _cairo_surface_shadow_fill (surface, op, source, path,
1968                                              fill_rule, tolerance, antialias,
1969                                              clip, &source->shadow);
1970
1971     ctx->source_scratch_in_use = FALSE;
1972     if (unlikely (status)) {
1973         cairo_device_release (dst->base.device);
1974         return status;
1975     }
1976
1977     dst->content_changed = TRUE;
1978     dst->content_synced = FALSE;
1979
1980     if (shadow_type == CAIRO_SHADOW_DROP &&
1981         source->shadow.draw_shadow_only) {
1982         ctx->source_scratch_in_use = FALSE;
1983         cairo_device_release (dst->base.device);
1984         return status;
1985     }
1986
1987     ctx->source_scratch_in_use = FALSE;
1988
1989     if (! source->shadow.draw_shadow_only) {
1990         if (! source->shadow.path_is_fill_with_spread ||
1991             source->shadow.type != CAIRO_SHADOW_INSET)
1992             status = _cairo_compositor_fill (get_compositor (surface),
1993                                              surface,
1994                                              op, source, path,
1995                                              fill_rule, tolerance,
1996                                              antialias,
1997                                              clip);
1998         else
1999             status = _cairo_compositor_paint (get_compositor (surface),
2000                                               surface, op, source,
2001                                               clip);
2002     }
2003
2004     if (unlikely (status)) {
2005         ctx->source_scratch_in_use = FALSE;
2006         cairo_device_release (dst->base.device);
2007         return status;
2008     }
2009
2010     ctx->source_scratch_in_use = FALSE;
2011
2012     if (shadow_type == CAIRO_SHADOW_INSET)
2013         status = _cairo_surface_shadow_fill (surface, op, source, path,
2014                                              fill_rule, tolerance, antialias,
2015                                              clip, &source->shadow);
2016
2017     ctx->source_scratch_in_use = FALSE;
2018     cairo_device_release (dst->base.device);
2019
2020     return status;
2021 }
2022
2023 static cairo_int_status_t
2024 _cairo_gl_surface_glyphs (void                  *surface,
2025                           cairo_operator_t       op,
2026                           const cairo_pattern_t *source,
2027                           cairo_glyph_t         *glyphs,
2028                           int                    num_glyphs,
2029                           cairo_scaled_font_t   *font,
2030                           const cairo_clip_t    *clip)
2031 {
2032     cairo_int_status_t status;
2033     cairo_gl_surface_t *dst = (cairo_gl_surface_t *)surface;
2034     cairo_gl_context_t *ctx = (cairo_gl_context_t *)dst->base.device;
2035     cairo_shadow_type_t shadow_type = source->shadow.type;
2036
2037     status = cairo_device_acquire (dst->base.device);
2038     if (unlikely (status))
2039         return status;
2040
2041     if (shadow_type != CAIRO_SHADOW_INSET)
2042         status = _cairo_surface_shadow_glyphs (surface, op, source,
2043                                                font,
2044                                                glyphs, num_glyphs,
2045                                                clip, &source->shadow);
2046
2047     ctx->source_scratch_in_use = FALSE;
2048     if (unlikely (status)) {
2049         cairo_device_release (dst->base.device);
2050         return status;
2051     }
2052
2053     dst->content_changed = TRUE;
2054     dst->content_synced = FALSE;
2055
2056     if (shadow_type == CAIRO_SHADOW_DROP &&
2057         source->shadow.draw_shadow_only) {
2058         ctx->source_scratch_in_use = FALSE;
2059         cairo_device_release (dst->base.device);
2060         return status;
2061     }
2062
2063     ctx->source_scratch_in_use = FALSE;
2064
2065     if (! source->shadow.draw_shadow_only)
2066         status = _cairo_compositor_glyphs (get_compositor (surface), surface,
2067                                            op, source, glyphs, num_glyphs,
2068                                            font, clip);
2069
2070     if (unlikely (status)) {
2071         ctx->source_scratch_in_use = FALSE;
2072         cairo_device_release (dst->base.device);
2073         return status;
2074     }
2075
2076     ctx->source_scratch_in_use = FALSE;
2077
2078     if (shadow_type == CAIRO_SHADOW_INSET)
2079         status = _cairo_surface_shadow_glyphs (surface, op, source,
2080                                                font,
2081                                                glyphs, num_glyphs,
2082                                                clip, &source->shadow);
2083
2084     ctx->source_scratch_in_use = FALSE;
2085     cairo_device_release (dst->base.device);
2086     return status;
2087 }
2088
2089 static const cairo_surface_backend_t _cairo_gl_surface_backend = {
2090     CAIRO_SURFACE_TYPE_GL,
2091     _cairo_gl_surface_finish,
2092     _cairo_default_context_create,
2093
2094     _cairo_gl_surface_create_similar,
2095     NULL, /* similar image */
2096     _cairo_gl_surface_map_to_image,
2097     _cairo_gl_surface_unmap_image,
2098
2099     _cairo_gl_surface_source,
2100     _cairo_gl_surface_acquire_source_image,
2101     _cairo_gl_surface_release_source_image,
2102     NULL, /* snapshot */
2103
2104     NULL, /* copy_page */
2105     NULL, /* show_page */
2106
2107     _cairo_gl_surface_get_extents,
2108     _cairo_image_surface_get_font_options,
2109
2110     _cairo_gl_surface_flush,
2111     NULL, /* mark_dirty_rectangle */
2112
2113     _cairo_gl_surface_paint,
2114     _cairo_gl_surface_mask,
2115     _cairo_gl_surface_stroke,
2116     _cairo_gl_surface_fill,
2117     NULL, /* fill/stroke */
2118     _cairo_gl_surface_glyphs,
2119     NULL, /* has_text_glyphs */
2120     NULL, /* show_text_glyphs */
2121     NULL, /* get_supported_mime_types */
2122     _cairo_gl_surface_shadow_surface,
2123     _cairo_gl_surface_glyph_shadow_surface,
2124     _cairo_gl_surface_shadow_mask_surface,
2125     _cairo_gl_surface_glyph_shadow_mask_surface,
2126 };
2127
2128 cairo_status_t
2129 cairo_gl_surface_set_binding_texture (cairo_surface_t *abstract_surface,
2130                                unsigned int    texture)
2131 {
2132     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
2133
2134     if ((cairo_surface_get_type (&surface->base) != CAIRO_SURFACE_TYPE_GL) ||
2135         surface->tex)
2136         return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
2137
2138     surface->bounded_tex = texture;
2139     surface->operand.texture.tex = texture;
2140
2141     return CAIRO_STATUS_SUCCESS;
2142 }