void vegaMask(VGHandle mask, VGMaskOperation operation, VGint x, VGint y, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); if (width <=0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (operation < VG_CLEAR_MASK || operation > VG_SUBTRACT_MASK) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); if (operation == VG_CLEAR_MASK) { mask_fill(x, y, width, height, 0.f); } else if (operation == VG_FILL_MASK) { mask_fill(x, y, width, height, 1.f); } else if (vg_object_is_valid(mask, VG_OBJECT_IMAGE)) { struct vg_image *image = handle_to_image(mask); mask_using_image(image, operation, x, y, width, height); } else if (vg_object_is_valid(mask, VG_OBJECT_MASK)) { struct vg_mask_layer *layer = handle_to_masklayer(mask); mask_using_layer(layer, operation, x, y, width, height); } else { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); } }
static void vg_context_update_surface_mask_view(struct vg_context *ctx, uint width, uint height) { struct st_framebuffer *stfb = ctx->draw_buffer; struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view; struct pipe_context *pipe = ctx->pipe; if (old_sampler_view && old_sampler_view->texture->width0 == width && old_sampler_view->texture->height0 == height) return; /* we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to this texture and use it as a sampler, so while this wastes some space it makes both of those a lot simpler */ stfb->surface_mask_view = create_tex_and_view(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height); if (!stfb->surface_mask_view) { if (old_sampler_view) pipe_sampler_view_reference(&old_sampler_view, NULL); return; } /* XXX could this call be avoided? */ vg_validate_state(ctx); /* alpha mask starts with 1.f alpha */ mask_fill(0, 0, width, height, 1.f); /* if we had an old surface copy it over */ if (old_sampler_view) { struct pipe_box src_box; u_box_origin_2d(MIN2(old_sampler_view->texture->width0, stfb->surface_mask_view->texture->width0), MIN2(old_sampler_view->texture->height0, stfb->surface_mask_view->texture->height0), &src_box); pipe->resource_copy_region(pipe, stfb->surface_mask_view->texture, 0, 0, 0, 0, old_sampler_view->texture, 0, &src_box); } /* Free the old texture */ if (old_sampler_view) pipe_sampler_view_reference(&old_sampler_view, NULL); }
static void setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb) { struct pipe_context *pipe = ctx->pipe; struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view; /* we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to this texture and use it as a sampler, so while this wastes some space it makes both of those a lot simpler */ stfb->alpha_mask_view = create_tex_and_view(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height); if (!stfb->alpha_mask_view) { if (old_sampler_view) pipe_sampler_view_reference(&old_sampler_view, NULL); return; } /* XXX could this call be avoided? */ vg_validate_state(ctx); /* alpha mask starts with 1.f alpha */ mask_fill(0, 0, stfb->width, stfb->height, 1.f); /* if we had an old surface copy it over */ if (old_sampler_view) { struct pipe_subresource subsurf, subold_surf; subsurf.face = 0; subsurf.level = 0; subold_surf.face = 0; subold_surf.level = 0; pipe->resource_copy_region(pipe, stfb->alpha_mask_view->texture, subsurf, 0, 0, 0, old_sampler_view->texture, subold_surf, 0, 0, 0, MIN2(old_sampler_view->texture->width0, stfb->alpha_mask_view->texture->width0), MIN2(old_sampler_view->texture->height0, stfb->alpha_mask_view->texture->height0)); } /* Free the old texture */ if (old_sampler_view) pipe_sampler_view_reference(&old_sampler_view, NULL); }
static void setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb, uint width, uint height) { struct pipe_context *pipe = ctx->pipe; struct pipe_texture *old_texture = stfb->alpha_mask; /* we use PIPE_FORMAT_A8R8G8B8_UNORM because we want to render to this texture and use it as a sampler, so while this wastes some space it makes both of those a lot simpler */ stfb->alpha_mask = create_texture(pipe, PIPE_FORMAT_A8R8G8B8_UNORM, width, height); if (!stfb->alpha_mask) { if (old_texture) pipe_texture_reference(&old_texture, NULL); return; } vg_validate_state(ctx); /* alpha mask starts with 1.f alpha */ mask_fill(0, 0, width, height, 1.f); /* if we had an old surface copy it over */ if (old_texture) { struct pipe_surface *surface = pipe->screen->get_tex_surface( pipe->screen, stfb->alpha_mask, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); struct pipe_surface *old_surface = pipe->screen->get_tex_surface( pipe->screen, old_texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); if (pipe->surface_copy) { pipe->surface_copy(pipe, surface, 0, 0, old_surface, 0, 0, MIN2(old_surface->width, width), MIN2(old_surface->height, height)); } else { util_surface_copy(pipe, FALSE, surface, 0, 0, old_surface, 0, 0, MIN2(old_surface->width, width), MIN2(old_surface->height, height)); } if (surface) pipe_surface_reference(&surface, NULL); if (old_surface) pipe_surface_reference(&old_surface, NULL); } /* Free the old texture */ if (old_texture) pipe_texture_reference(&old_texture, NULL); }