2 _cairo_gpu_surface_modified_(cairo_gpu_surface_t
* surface
, int i
, int x
, int y
, int width
, int height
)
4 if(!surface
->bbox
[i
].width
)
6 surface
->bbox
[i
].x
= x
;
7 surface
->bbox
[i
].y
= y
;
8 surface
->bbox
[i
].width
= width
;
9 surface
->bbox
[i
].height
= height
;
13 int x2
= MAX(surface
->bbox
[i
].x
+ surface
->bbox
[i
].width
, x
+ width
);
14 int y2
= MAX(surface
->bbox
[i
].y
+ surface
->bbox
[i
].height
, y
+ height
);
16 surface
->bbox
[i
].x
= MIN(x
, surface
->bbox
[i
].x
);
17 surface
->bbox
[i
].y
= MIN(y
, surface
->bbox
[i
].y
);
18 surface
->bbox
[i
].width
= x2
- surface
->bbox
[i
].x
;
19 surface
->bbox
[i
].height
= y2
- surface
->bbox
[i
].y
;
22 surface
->valid_mask
= 1 << i
;
26 _cairo_gpu_surface_modified(cairo_gpu_surface_t
* surface
, int x
, int y
, int width
, int height
)
28 _cairo_gpu_surface_modified_(surface
, _cairo_gpu_surface_destination(surface
), x
, y
, width
, height
);
32 _cairo_gpu_surface_modified_drawable(cairo_gpu_surface_t
* surface
, int x
, int y
, int width
, int height
)
34 _cairo_gpu_surface_modified_(surface
, _cairo_gpu_surface_destination_drawable(surface
), x
, y
, width
, height
);
38 _cairo_gpu_surface_cleared_(cairo_gpu_surface_t
* surface
, int idx
)
40 surface
->bbox
[idx
].width
= 0;
41 surface
->bbox
[idx
].height
= 0;
43 surface
->valid_mask
= 1 << idx
;
47 _cairo_gpu_surface_cleared(cairo_gpu_surface_t
* surface
)
49 _cairo_gpu_surface_cleared_(surface
, _cairo_gpu_surface_destination(surface
));
53 _cairo_gpu_context_set_discontinuous_width(cairo_gpu_context_t
* ctx
, int idx
, unsigned width
)
55 float so
[4] = {0.5 / (double)width
, 0.75 / (double)width
, 0.0, 0.0};
56 _cairo_gpu_context_set_frag_param(ctx
, FRAGENV_TEX_DISCONTINUOUS_SO(idx
), so
);
60 _cairo_gpu_context_set_radial_gradient(cairo_gpu_context_t
* ctx
, int idx
, float* mac
, float* so
)
62 //printf("a = %f\n", a);
63 //printf("-b/2: %f %f %f\n", mbd2[0], mbd2[1], mbd2[2]);
64 //printf("-ac: %f %f %f\n", mac[0], mac[1], mac[2]);
65 //printf("* %f + %f\n", so[0], so[2]);
66 _cairo_gpu_context_set_frag_param(ctx
, FRAGENV_TEX_RADIAL_MAC(idx
), mac
);
67 _cairo_gpu_context_set_frag_param(ctx
, FRAGENV_TEX_RADIAL_SO(idx
), so
);
70 static __attribute__((unused
)) void
71 _cairo_gpu_emit_rect_diff(float **vp
, cairo_rectangle_int_t
* out
, cairo_rectangle_int_t
* in
)
77 _cairo_gpu_emit_rect(vp
, out
->x
, out
->y
, out
->width
, out
->height
);
81 int y
= MAX(in
->y
, out
->y
);
82 int h
= MIN(in
->y
+ in
->height
, out
->y
+ out
->height
) - y
;
88 yb
= MIN(in
->y
, out
->y
+ out
->height
);
91 _cairo_gpu_emit_rect(vp
, out
->x
, out
->y
, out
->width
, t
);
95 // directly_left(in) & out
98 _cairo_gpu_emit_rect(vp
, out
->x
, y
, t
, h
);
100 // directly_right(in) & out
101 t
= (out
->x
+ out
->width
) - (in
->y
+ in
->width
);;
103 _cairo_gpu_emit_rect(vp
, in
->x
+ in
->width
, y
, t
, h
);
107 yb
= MAX(in
->y
+ in
->height
, out
->y
);
108 t
= (out
->y
+ out
->height
) - yb
;
110 _cairo_gpu_emit_rect(vp
, out
->x
, yb
, out
->width
, t
);
114 static __attribute__((unused
)) void
115 _cairo_gpu_fill_rect_diff(cairo_gpu_context_t
* ctx
, cairo_gpu_surface_t
* surface
, cairo_rectangle_int_t
* out
, cairo_rectangle_int_t
* in
, float r
, float g
, float b
, float a
)
121 _cairo_gpu_context_fill_rect(ctx
, surface
, out
->x
, out
->y
, out
->width
, out
->height
, r
, g
, b
, a
);
125 int y
= MAX(in
->y
, out
->y
);
126 int h
= MIN(in
->y
+ in
->height
, out
->y
+ out
->height
) - y
;
132 yb
= MIN(in
->y
, out
->y
+ out
->height
);
135 _cairo_gpu_context_fill_rect(ctx
, surface
, out
->x
, out
->y
, out
->width
, t
, r
, g
, b
, a
);
139 // directly_left(in) & out
142 _cairo_gpu_context_fill_rect(ctx
, surface
, out
->x
, y
, t
, h
, r
, g
, b
, a
);
144 // directly_right(in) & out
145 t
= (out
->x
+ out
->width
) - (in
->y
+ in
->width
);;
147 _cairo_gpu_context_fill_rect(ctx
, surface
, in
->x
+ in
->width
, y
, t
, h
, r
, g
, b
, a
);
151 yb
= MAX(in
->y
+ in
->height
, out
->y
);
152 t
= (out
->y
+ out
->height
) - yb
;
154 _cairo_gpu_context_fill_rect(ctx
, surface
, out
->x
, yb
, out
->width
, t
, r
, g
, b
, a
);
158 /* ignores clipping, use only when that is appropriate */
160 _cairo_gpu_solid_rect(cairo_gpu_context_t
* ctx
, cairo_gpu_surface_t
* surface
, int x
, int y
, int width
, int height
, float r
, float g
, float b
, float a
)
162 int i
= _cairo_gpu_surface_destination(surface
);
163 cairo_rectangle_int_t
*bbox
= &surface
->bbox
[i
];
165 /* if clearing, intersect with the bounding box and try to subtract the rect from the box */
166 if(!r
&& !g
&& !b
&& !a
)
172 if(!bbox
->width
|| !bbox
->height
)
177 x2
= MIN(x
+ width
, bbox
->x
+ (int)bbox
->width
);
178 y2
= MIN(y
+ height
, bbox
->y
+ (int)bbox
->height
);
180 c
= (bbox
->x
== x
) + (bbox
->y
== y
) + ((int)(bbox
->x
+ bbox
->width
) == x2
) + ((int)(bbox
->y
+ bbox
->height
) == y2
);
188 else if(bbox
->x
!= x
)
189 bbox
->width
= x
- bbox
->x
;
190 else if(bbox
->y
!= y
)
191 bbox
->height
= y
- bbox
->y
;
192 else if((bbox
->y
+ (int)bbox
->height
) != y2
)
194 bbox
->height
-= y2
- bbox
->y
;
197 else if((bbox
->x
+ (int)bbox
->width
) != x2
)
199 bbox
->width
-= x2
- bbox
->x
;
208 _cairo_gpu_surface_modified(surface
, x
, y
, width
, height
);
210 if(!width
|| !height
)
213 _cairo_gpu_context_fill_rect(ctx
, surface
, x
, y
, width
, height
, r
, g
, b
, a
);
217 _cairo_gpu_prepare_blit_image(cairo_gpu_context_t
* ctx
, cairo_gpu_texture_t
* texture
, int src_x
, int src_y
, int zoom_x
, int zoom_y
)
219 cairo_surface_attributes_t attrs
;
221 attrs
.matrix
.xx
= 1.0 / zoom_x
;
223 attrs
.matrix
.x0
= src_x
;
226 attrs
.matrix
.yy
= 1.0 / zoom_y
;
227 attrs
.matrix
.y0
= src_y
;
228 attrs
.filter
= CAIRO_FILTER_NEAREST
;
229 attrs
.extend
= CAIRO_EXTEND_NONE
;
232 _cairo_gpu_texture_adjust_matrix(texture
, &attrs
.matrix
);
234 _cairo_gpu_context_set_blend(ctx
, BLEND_SOURCE
);
235 _cairo_gpu_context_set_raster(ctx
, 0);
236 _cairo_gpu_context_set_vert_frag(ctx
, VERT_TEX_GEN
<< VERT_TEX_SHIFT
,
237 ((FRAG_TEX_COLOR_RGBA
| (texture
->target_idx
== TARGET_RECTANGLE
? FRAG_TEX_RECTANGLE
: 0)) << FRAG_TEX_SHIFT
));
238 _cairo_gpu_context_set_texture_and_attributes(ctx
, 0, texture
, &attrs
);
242 _cairo_gpu_finish_blit_image(cairo_gpu_context_t
* ctx
, cairo_gpu_surface_t
* dst
, int dst_x
, int dst_y
, int width
, int height
)
244 _cairo_gpu_context_set_viewport(ctx
, 0, 0, dst
->width
, dst
->height
);
245 _cairo_gpu_context_set_translation(ctx
, dst_x
, dst_y
);
246 _cairo_gpu_context_draw_rect(ctx
, 0, 0, width
, height
);
250 _cairo_gpu_blit_image(cairo_gpu_context_t
* ctx
, cairo_gpu_surface_t
* dst
, cairo_gpu_texture_t
* texture
, int dst_x
, int dst_y
, int src_x
, int src_y
, int width
, int height
, int zoom_x
, int zoom_y
)
252 _cairo_gpu_prepare_blit_image(ctx
, texture
, src_x
, src_y
, zoom_x
, zoom_y
);
253 _cairo_gpu_finish_blit_image(ctx
, dst
, dst_x
, dst_y
, width
, height
);
256 static cairo_gpu_texture_t
*
257 _cairo_gpu_temp_1d_image(cairo_gpu_context_t
* ctx
, unsigned idx
, unsigned* pwidth
, int* owned
)
259 unsigned width
= *pwidth
;
260 cairo_gpu_texture_t
** texture_pp
;
261 cairo_gpu_texture_t
* texture
= 0;
263 if(!ctx
->space
->tex_npot
&& !ctx
->space
->tex_rectangle
&& !is_pow2(width
))
264 *pwidth
= width
= higher_pow2(width
);
266 if(width
<= MAX_SMALL_WIDTH
)
268 texture_pp
= &ctx
->tls
->small_texture_pools
[idx
].texture
[width
- 1];
273 texture_pp
= &texture
;
279 texture
= *texture_pp
= (cairo_gpu_texture_t
*)malloc(sizeof(cairo_gpu_texture_t
));
280 _cairo_gpu_texture_create(ctx
, texture
, width
, 1);
283 texture
= *texture_pp
;
289 _cairo_gpu_draw_clipped(cairo_gpu_context_t
* ctx
, cairo_gpu_surface_t
* dst
, int dst_x
, int dst_y
, int width
, int height
)
293 _cairo_gpu_context_set_viewport(ctx
, 0, 0, dst
->width
, dst
->height
);
294 _cairo_gpu_context_draw(ctx
);
299 pixman_box32_t
*pboxes
;
301 pboxes
= pixman_region32_rectangles(&dst
->clip
.rgn
, &nboxes
);
302 for(i
= 0; i
< nboxes
; ++i
)
304 int x1
= MAX(dst_x
, pboxes
[i
].x1
);
306 int y1
= MAX(dst_y
, pboxes
[i
].y1
);
308 int x2
= MIN(dst_x
+ width
, pboxes
[i
].x2
);
310 int y2
= MIN(dst_y
+ height
, pboxes
[i
].y2
);
312 if(x1
>= x2
|| y1
>= y2
)
315 //printf("%i %i %i %i %i\n", i, x1, y1, x2, y2);
317 _cairo_gpu_context_set_viewport(ctx
, x1
, y1
, x2
- x1
, y2
- y1
);
318 _cairo_gpu_context_draw(ctx
);
324 static cairo_surface_t
*
325 _cairo_gpu_surface_create_similar(void *abstract_surface
, cairo_content_t content
, int width
, int height
)
327 cairo_gpu_surface_t
*surface
= abstract_surface
;
329 // TODO: specify mantissa/exponent correctly
330 return _cairo_gpu_surface_create(surface
->space
, 0, content
, 0, 0, 0, width
, height
, 0, 0, 0, 0);
333 static cairo_gpu_surface_t
*
334 _cairo_gpu_space_get_cached_mask_surface(cairo_gpu_space_t
* space
, unsigned width
, unsigned height
, int aa
)
336 cairo_gpu_surface_t
*surf
;
338 CAIRO_MUTEX_LOCK(space
->cached_mask_surface_mutex
);
339 if(!space
->cached_mask_surface
|| space
->cached_mask_surface
->width
< width
|| space
->cached_mask_surface
->height
< width
)
341 unsigned nwidth
= space
->cached_mask_surface
? space
->cached_mask_surface
->width
: 16;
343 unsigned nheight
= space
->cached_mask_surface
? space
->cached_mask_surface
->height
: 16;
345 while(nwidth
< width
)
347 while(nheight
< width
)
350 surf
= (cairo_gpu_surface_t
*) cairo_surface_create(&space
->base
, &space
->cached_mask_surface
->base
, CAIRO_CONTENT_ALPHA
, nwidth
, nheight
, 0, 8, 0, 0);
353 surf
= space
->cached_mask_surface
;
355 if(aa
&& !surf
->color_samples
&& !surf
->coverage_samples
)
359 for(aap
= _cairo_gpu_aa_formats
; *aap
; aap
+= 2)
361 if(!_cairo_gpu_surface_set_samples(surf
, aap
[0], aap
[1]))
365 printf("set mask msaa to %i %i\n", aap
[0], aap
[1]);
369 if(!space
->cached_mask_surface
)
370 cairo_surface_destroy(&surf
->base
);
371 space
->msaa_samples
= 1;
372 CAIRO_MUTEX_UNLOCK(space
->cached_mask_surface_mutex
);
377 assert(aap
[0] == surf
->coverage_samples
);
378 space
->msaa_samples
= surf
->coverage_samples
;
381 space
->cached_mask_surface
= surf
;
387 _cairo_gpu_space_put_cached_mask_surface(cairo_gpu_space_t
* space
, cairo_gpu_surface_t
* surf
)
389 CAIRO_MUTEX_UNLOCK(space
->cached_mask_surface_mutex
);
392 static cairo_status_t
393 _cairo_gpu_surface_acquire_source_image(void *abstract_surface
, cairo_image_surface_t
** image_out
, void **image_extra
)
395 cairo_status_t status
;
396 cairo_gpu_surface_t
*surface
= abstract_surface
;
399 status
= _cairo_gpu_surface_get_image(surface
, NULL
, image_out
, NULL
, image_extra
);
406 _cairo_gpu_surface_release_source_image(void *abstract_surface
, cairo_image_surface_t
* image
, void *image_extra
)
408 cairo_gpu_surface_t
*surface
= abstract_surface
;
410 _cairo_gpu_surface_put_image(surface
, image
, 0, 0, image
->width
, image
->height
, 0, 0, 1, image_extra
);
412 cairo_surface_destroy(&image
->base
);
415 static cairo_status_t
416 _cairo_gpu_surface_acquire_dest_image(void *abstract_surface
, cairo_rectangle_int_t
* interest_rect
, cairo_image_surface_t
** image_out
, cairo_rectangle_int_t
* image_rect_out
, void **image_extra
)
418 cairo_status_t status
;
419 cairo_gpu_surface_t
*surface
= abstract_surface
;
422 status
= _cairo_gpu_surface_get_image(surface
, interest_rect
, image_out
, image_rect_out
, image_extra
);
429 _cairo_gpu_surface_release_dest_image(void *abstract_surface
, cairo_rectangle_int_t
* interest_rect
, cairo_image_surface_t
* image
, cairo_rectangle_int_t
* image_rect
, void *image_extra
)
431 cairo_status_t status
;
432 cairo_gpu_surface_t
* dst
= abstract_surface
;
435 status
= _cairo_gpu_surface_put_image(dst
, image
, 0, 0, image
->width
, image
->height
, image_rect
->x
, image_rect
->y
, 1, image_extra
);
438 status
= _cairo_surface_set_error(abstract_surface
, status
);
441 cairo_surface_destroy(&image
->base
);
444 static inline cairo_status_t
445 _cairo_gpu_surface_flush(void *abstract_surface
)
447 cairo_gpu_surface_t
*surface
= abstract_surface
;
448 int i
= _cairo_gpu_surface_destination_drawable(surface
);
450 if(i
< 0 || !surface
->valid_mask
|| surface
->valid_mask
& (1 << i
) || !surface
->public_drawable
)
451 return CAIRO_STATUS_SUCCESS
;
455 // this makes it valid, thus flushing
456 _cairo_gpu_surface_bind_drawable(surface
, 0);
459 return CAIRO_STATUS_SUCCESS
;
462 static inline cairo_status_t
463 _cairo_gpu_surface_mark_dirty_rectangle(void *abstract_surface
, int x
, int y
, int width
, int height
)
465 cairo_gpu_surface_t
*surface
= abstract_surface
;
466 _cairo_gpu_surface_modified_drawable(surface
, x
, y
, width
, height
);
467 return CAIRO_STATUS_SUCCESS
;
470 static cairo_status_t
471 _cairo_gpu_surface_clone_similar(void *abstract_surface
, cairo_surface_t
* src
, cairo_content_t content
, int src_x
, int src_y
, int width
, int height
, int *clone_offset_x
, int *clone_offset_y
, cairo_surface_t
** clone_out
)
473 cairo_gpu_surface_t
*surface
= abstract_surface
;
474 cairo_gpu_surface_t
*clone
;
475 cairo_image_surface_t
*image_src
= (cairo_image_surface_t
*) src
;
476 cairo_status_t status
;
478 if(src
->backend
== surface
->base
.backend
)
482 *clone_out
= cairo_surface_reference(src
);
484 return CAIRO_STATUS_SUCCESS
;
487 if(!_cairo_surface_is_image(src
))
488 return CAIRO_INT_STATUS_UNSUPPORTED
;
492 clone
= (cairo_gpu_surface_t
*) _cairo_gpu_surface_create_similar(&surface
->base
, content
, width
, height
);
495 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
498 if(clone
->base
.status
)
500 status
= clone
->base
.status
;
504 status
= _cairo_gpu_surface_draw_image(clone
, image_src
, src_x
, src_y
, width
, height
, 0, 0);
508 cairo_surface_destroy(&clone
->base
);
512 *clone_out
= &clone
->base
;
513 *clone_offset_x
= src_x
;
514 *clone_offset_y
= src_y
;
521 static cairo_int_status_t
522 _cairo_gpu_surface_get_extents(void *abstract_surface
, cairo_rectangle_int_t
* rectangle
)
524 cairo_gpu_surface_t
*surface
= abstract_surface
;
528 rectangle
->width
= surface
->width
;
529 rectangle
->height
= surface
->height
;
531 return CAIRO_STATUS_SUCCESS
;
535 static cairo_int_status_t
536 _cairo_gpu_surface_show_page(void *abstract_surface
)
538 cairo_gpu_surface_t
*surface
= (cairo_gpu_surface_t
*) abstract_surface
;
539 cairo_int_status_t status
= _cairo_gpu_surface_copy_page(surface
);
541 surface
->valid_mask
= 0;
546 _cairo_gpu_surface_get_font_options (void *abstract_surface
,
547 cairo_font_options_t
*options
)
549 cairo_gpu_surface_t
*surface
= abstract_surface
;
551 *options
= *_cairo_gpu_get_font_options (surface
->space
);
556 _cairo_gpu_surface_fix_pad(cairo_gpu_surface_t
* surface
, cairo_extend_t extend
)
558 cairo_gpu_context_t
*ctx
;
560 if(extend
== CAIRO_EXTEND_NONE
)
562 if(surface
->transparent_padding
)
565 if(surface
->space
->use_fbo
)
567 ctx
= _cairo_gpu_surface_bind(surface
, FB_DRAW
);
569 if(surface
->width
< surface
->texture
.width
)
570 _cairo_gpu_context_fill_rect(ctx
, surface
, surface
->width
, 0, surface
->texture
.width
, surface
->height
, 0, 0, 0, 0);
572 if(surface
->height
< surface
->texture
.height
)
573 _cairo_gpu_context_fill_rect(ctx
, surface
, 0, surface
->height
, surface
->texture
.width
, surface
->texture
.height
- surface
->height
, 0, 0, 0, 0);
577 cairo_gpu_surface_t
* temp
;
578 unsigned w
= surface
->texture
.width
- surface
->width
;
579 unsigned h
= surface
->texture
.height
- surface
->height
;
581 if(surface
->width
< surface
->texture
.width
)
582 h
= MAX(h
, surface
->height
);
584 if(surface
->height
< surface
->texture
.height
)
585 w
= MAX(w
, surface
->width
);
587 temp
= _cairo_gpu_space_get_cached_mask_surface(surface
->space
, w
, h
, 0);
588 temp
->base
.content
= CAIRO_CONTENT_COLOR_ALPHA
;
589 //temp->clear_rgba = 1;
591 _cairo_gpu_surface_orient_drawable_like_texture(temp
, surface
);
593 ctx
= _cairo_gpu_surface_bind(temp
, FB_READ
| FB_DRAW
);
595 if(surface
->width
< surface
->texture
.width
)
597 _cairo_gpu_context_fill_rect(ctx
, surface
, 0, 0, surface
->texture
.width
- surface
->width
, surface
->height
, 0, 0, 0, 0);
598 _cairo_gpu_context_read_to_texture(ctx
, surface
, surface
->width
, 0, 0, 0, surface
->texture
.width
- surface
->width
, surface
->height
);
601 if(surface
->height
< surface
->texture
.height
)
603 _cairo_gpu_context_fill_rect(ctx
, surface
, 0, 0, surface
->width
, surface
->texture
.height
- surface
->height
, 0, 0, 0, 0);
604 _cairo_gpu_context_read_to_texture(ctx
, surface
, 0, surface
->height
, 0, 0, surface
->width
, surface
->texture
.height
- surface
->height
);
606 if(surface
->width
< surface
->texture
.width
)
607 _cairo_gpu_context_read_to_texture(ctx
, surface
, surface
->width
, surface
->height
, 0, 0, surface
->texture
.width
- surface
->width
, surface
->texture
.height
- surface
->height
);
610 _cairo_gpu_surface_modified(temp
, 0, 0, w
, h
);
612 temp
->base
.content
= CAIRO_CONTENT_ALPHA
;
613 _cairo_gpu_space_put_cached_mask_surface(surface
->space
, temp
);
616 surface
->valid_mask
&= ~(1 << SURF_PSEUDO_PADDING
);
617 surface
->transparent_padding
= 1;
621 if(surface
->valid_mask
& (1 << SURF_PSEUDO_PADDING
))
624 if(surface
->space
->use_fbo
)
626 // only with FBO we have destination as large as the texture
627 ctx
= _cairo_gpu_surface_bind(surface
, FB_READ
| FB_DRAW
);
629 if(surface
->width
< surface
->texture
.width
)
630 _cairo_gpu_context_blit_zoom(ctx
, surface
, surface
->width
, 0, surface
->width
- 1, 0, 1, surface
->height
, surface
->texture
.width
- surface
->width
, 1);
632 if(surface
->height
< surface
->texture
.height
)
634 _cairo_gpu_context_blit_zoom(ctx
, surface
, 0, surface
->height
, 0, surface
->height
- 1, surface
->width
, 1, 1, surface
->texture
.height
- surface
->height
);
636 if(surface
->width
< surface
->texture
.width
)
638 _cairo_gpu_context_blit_zoom(ctx
, surface
, surface
->width
, surface
->height
, surface
->width
- 1, surface
->height
- 1, 1, 1, surface
->texture
.width
- surface
->width
, surface
->texture
.height
- surface
->height
);
644 cairo_gpu_surface_t
* temp
;
645 unsigned w
= surface
->texture
.width
- surface
->width
;
646 unsigned h
= surface
->texture
.height
- surface
->height
;
648 if(surface
->width
< surface
->texture
.width
)
649 h
= MAX(h
, surface
->height
);
651 if(surface
->height
< surface
->texture
.height
)
652 w
= MAX(w
, surface
->width
);
654 // Clever hack here that allows us to reuse the cached mask surface!
655 // here we don't have FBOs, so the cached mask surface is not MSAA, hence we can safely use it!
656 // not having FBO means the card can only render to RGBA even if we only have an alpha surface.
657 // the texture may be alpha-only but we don't care
658 // But! We must clear all the channels, so we use the "clear RGBA" hack
659 // clear_rgba should be unnecessary since alpha-only use will ignore color channels and we clear the parts we use ourselves
660 temp
= _cairo_gpu_space_get_cached_mask_surface(surface
->space
, w
, h
, 0);
661 temp
->base
.content
= CAIRO_CONTENT_COLOR_ALPHA
;
662 //temp->clear_rgba = 1;
664 _cairo_gpu_surface_orient_drawable_like_texture(temp
, surface
);
666 ctx
= _cairo_gpu_surface_bind(temp
, FB_DRAW
);
668 if(surface
->width
< surface
->texture
.width
)
670 _cairo_gpu_blit_image(ctx
, temp
, &surface
->texture
, 0, 0,
671 surface
->width
- 1, 0, surface
->texture
.width
- surface
->width
, surface
->height
, surface
->texture
.width
- surface
->width
, 1);
672 _cairo_gpu_context_read_to_texture(ctx
, surface
, surface
->width
, 0, 0, 0, surface
->texture
.width
- surface
->width
, surface
->height
);
675 if(surface
->height
< surface
->texture
.height
)
677 _cairo_gpu_blit_image(ctx
, temp
, &surface
->texture
, 0, 0,
678 0, surface
->height
- 1, surface
->width
, surface
->texture
.height
- surface
->height
, 1, surface
->texture
.height
- surface
->height
);
679 _cairo_gpu_context_read_to_texture(ctx
, surface
, 0, surface
->height
, 0, 0, surface
->width
, surface
->texture
.height
- surface
->height
);
681 if(surface
->width
< surface
->texture
.width
)
683 _cairo_gpu_blit_image(ctx
, temp
, &surface
->texture
, 0, 0,
684 surface
->width
- 1, surface
->height
- 1, surface
->texture
.width
- surface
->width
, surface
->texture
.height
- surface
->height
, surface
->width
, surface
->height
);
685 _cairo_gpu_context_read_to_texture(ctx
, surface
, surface
->width
, surface
->height
, 0, 0, surface
->texture
.width
- surface
->width
, surface
->texture
.height
- surface
->height
);
689 _cairo_gpu_surface_modified(temp
, 0, 0, w
, h
);
691 temp
->base
.content
= CAIRO_CONTENT_ALPHA
;
692 _cairo_gpu_space_put_cached_mask_surface(surface
->space
, temp
);
695 surface
->valid_mask
|= (1 << SURF_PSEUDO_PADDING
);
696 surface
->transparent_padding
= 0;