Changes.
[cairo/gpu.git] / src / gpu / cairo-gpu-impl-surface.h
blob829f6b427d8c9a38df05203013eb53e2ef8d5065
1 static inline void
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;
11 else if(width)
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;
25 static inline void
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);
31 static inline void
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);
37 static inline void
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;
46 static inline void
47 _cairo_gpu_surface_cleared(cairo_gpu_surface_t* surface)
49 _cairo_gpu_surface_cleared_(surface, _cairo_gpu_surface_destination(surface));
52 static void
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);
59 static void
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)
73 if(!out->width)
75 else if(!in->width)
77 _cairo_gpu_emit_rect(vp, out->x, out->y, out->width, out->height);
79 else
81 int y = MAX(in->y, out->y);
82 int h = MIN(in->y + in->height, out->y + out->height) - y;
84 int t;
85 int yb;
87 // over(in) & out
88 yb = MIN(in->y, out->y + out->height);
89 t = yb - out->y;
90 if(t > 0)
91 _cairo_gpu_emit_rect(vp, out->x, out->y, out->width, t);
93 if(h > 0)
95 // directly_left(in) & out
96 t = in->x - out->x;
97 if(t > 0)
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);;
102 if(t > 0)
103 _cairo_gpu_emit_rect(vp, in->x + in->width, y, t, h);
106 // under(in) & out
107 yb = MAX(in->y + in->height, out->y);
108 t = (out->y + out->height) - yb;
109 if(t > 0)
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)
117 if(!out->width)
119 else if(!in->width)
121 _cairo_gpu_context_fill_rect(ctx, surface, out->x, out->y, out->width, out->height, r, g, b, a);
123 else
125 int y = MAX(in->y, out->y);
126 int h = MIN(in->y + in->height, out->y + out->height) - y;
128 int t;
129 int yb;
131 // over(in) & out
132 yb = MIN(in->y, out->y + out->height);
133 t = yb - out->y;
134 if(t > 0)
135 _cairo_gpu_context_fill_rect(ctx, surface, out->x, out->y, out->width, t, r, g, b, a);
137 if(h > 0)
139 // directly_left(in) & out
140 t = in->x - out->x;
141 if(t > 0)
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);;
146 if(t > 0)
147 _cairo_gpu_context_fill_rect(ctx, surface, in->x + in->width, y, t, h, r, g, b, a);
150 // under(in) & out
151 yb = MAX(in->y + in->height, out->y);
152 t = (out->y + out->height) - yb;
153 if(t > 0)
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 */
159 static inline void
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)
168 int x2, y2;
170 int c;
172 if(!bbox->width || !bbox->height)
173 return;
175 x = MAX(x, bbox->x);
176 y = MAX(y, bbox->y);
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);
181 if(c >= 3)
183 if(c == 4)
185 bbox->width = 0;
186 bbox->height = 0;
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;
195 bbox->y = y2;
197 else if((bbox->x + (int)bbox->width) != x2)
199 bbox->width -= x2 - bbox->x;
200 bbox->x = x2;
204 width = x2 - x;
205 height = y2 - y;
207 else
208 _cairo_gpu_surface_modified(surface, x, y, width, height);
210 if(!width || !height)
211 return;
213 _cairo_gpu_context_fill_rect(ctx, surface, x, y, width, height, r, g, b, a);
216 static void
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;
222 attrs.matrix.xy = 0;
223 attrs.matrix.x0 = src_x;
225 attrs.matrix.yx = 0;
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;
230 attrs.extra = 0;
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);
241 static void
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);
249 static void
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];
269 *owned = 0;
271 else
273 texture_pp = &texture;
274 *owned = 1;
277 if(!*texture_pp)
279 texture = *texture_pp = (cairo_gpu_texture_t*)malloc(sizeof(cairo_gpu_texture_t));
280 _cairo_gpu_texture_create(ctx, texture, width, 1);
282 else
283 texture = *texture_pp;
285 return texture;
288 static void
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)
291 if(!dst->has_clip)
293 _cairo_gpu_context_set_viewport(ctx, 0, 0, dst->width, dst->height);
294 _cairo_gpu_context_draw(ctx);
296 else
298 int i, nboxes;
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)
313 continue;
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)
346 nwidth <<= 1;
347 while(nheight < width)
348 nheight <<= 1;
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);
352 else
353 surf = space->cached_mask_surface;
355 if(aa && !surf->color_samples && !surf->coverage_samples)
357 int *aap;
359 for(aap = _cairo_gpu_aa_formats; *aap; aap += 2)
361 if(!_cairo_gpu_surface_set_samples(surf, aap[0], aap[1]))
362 break;
365 printf("set mask msaa to %i %i\n", aap[0], aap[1]);
367 if(!*aap)
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);
373 return 0;
375 else
377 assert(aap[0] == surf->coverage_samples);
378 space->msaa_samples = surf->coverage_samples;
381 space->cached_mask_surface = surf;
383 return surf;
386 static void
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;
398 _cairo_gpu_enter();
399 status = _cairo_gpu_surface_get_image(surface, NULL, image_out, NULL, image_extra);
400 _cairo_gpu_exit();
402 return status;
405 static void
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;
409 _cairo_gpu_enter();
410 _cairo_gpu_surface_put_image(surface, image, 0, 0, image->width, image->height, 0, 0, 1, image_extra);
411 _cairo_gpu_exit();
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;
421 _cairo_gpu_enter();
422 status = _cairo_gpu_surface_get_image(surface, interest_rect, image_out, image_rect_out, image_extra);
423 _cairo_gpu_exit();
425 return status;
428 static void
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;
434 _cairo_gpu_enter();
435 status = _cairo_gpu_surface_put_image(dst, image, 0, 0, image->width, image->height, image_rect->x, image_rect->y, 1, image_extra);
437 if(status)
438 status = _cairo_surface_set_error(abstract_surface, status);
439 _cairo_gpu_exit();
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;
453 _cairo_gpu_enter();
455 // this makes it valid, thus flushing
456 _cairo_gpu_surface_bind_drawable(surface, 0);
458 _cairo_gpu_exit();
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)
480 *clone_offset_x = 0;
481 *clone_offset_y = 0;
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;
490 _cairo_gpu_enter();
492 clone = (cairo_gpu_surface_t *) _cairo_gpu_surface_create_similar(&surface->base, content, width, height);
493 if(clone == NULL)
495 status = CAIRO_INT_STATUS_UNSUPPORTED;
496 goto out;
498 if(clone->base.status)
500 status = clone->base.status;
501 goto out;
504 status = _cairo_gpu_surface_draw_image(clone, image_src, src_x, src_y, width, height, 0, 0);
506 if(status)
508 cairo_surface_destroy(&clone->base);
509 goto out;
512 *clone_out = &clone->base;
513 *clone_offset_x = src_x;
514 *clone_offset_y = src_y;
516 out:
517 _cairo_gpu_exit();
518 return status;
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;
526 rectangle->x = 0;
527 rectangle->y = 0;
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);
540 if(!status)
541 surface->valid_mask = 0;
542 return status;
545 static void
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);
555 static void
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)
563 return;
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);
575 else
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;
619 else
621 if(surface->valid_mask & (1 << SURF_PSEUDO_PADDING))
622 return;
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);
642 else
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;