vg_context.c revision 99c67f27d35a4bbbbefada8117d5972c7583cf42
1cf3056db0fee1db7921214b1f25cea04e959e105Chris Lattner/************************************************************************** 22b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman * 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * Copyright 2009 VMware, Inc. All Rights Reserved. 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner * Permission is hereby granted, free of charge, to any person obtaining a 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner * copy of this software and associated documentation files (the 72b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman * "Software"), to deal in the Software without restriction, including 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * without limitation the rights to use, copy, modify, merge, publish, 9b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner * distribute, sub license, and/or sell copies of the Software, and to 10ba12c23ca7684c94dd538577827dce8b3c1cf451Chris Lattner * permit persons to whom the Software is furnished to do so, subject to 11ba12c23ca7684c94dd538577827dce8b3c1cf451Chris Lattner * the following conditions: 12ba12c23ca7684c94dd538577827dce8b3c1cf451Chris Lattner * 13b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner * The above copyright notice and this permission notice (including the 14b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner * next paragraph) shall be included in all copies or substantial portions 15b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner * of the Software. 16b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner * 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21c287137ce7455c63be0075e0d5aba0bab4f125eaChris Lattner * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 220555ed8bffc697f10b467e6f5c2c6188f8650e11Chris Lattner * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 241997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel * 25d8cc7be0262092882d848a1c7d8a4cb6752cce6fOwen Anderson **************************************************************************/ 26ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson 27b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "vg_context.h" 28b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner 29b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "paint.h" 30b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "renderer.h" 31db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner#include "shaders_cache.h" 322b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman#include "shader.h" 33a5dcc4f7b2a65afbeec9008733f47e6beee24bdeChris Lattner#include "vg_manager.h" 34eea6c95d5d9f202ccb4e90995dc8a4a4c439cec3Julien Lerouge#include "api.h" 352b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman#include "mask.h" 36b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "handle.h" 37b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner 38b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "pipe/p_context.h" 39b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "util/u_inlines.h" 40b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner 41b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner#include "cso_cache/cso_context.h" 42b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner 43c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner#include "util/u_memory.h" 44c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner#include "util/u_blit.h" 452b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman#include "util/u_sampler.h" 46c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner#include "util/u_surface.h" 47c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner#include "util/u_format.h" 48e840434755e2165ac20ec55e9d5ff3d2defac2d2Reid Spencer 49e840434755e2165ac20ec55e9d5ff3d2defac2d2Reid Spencerstruct vg_context *_vg_context = 0; 50dedf2bd5a34dac25e4245f58bb902ced6b64edd9Misha Brukman 51dedf2bd5a34dac25e4245f58bb902ced6b64edd9Misha Brukmanstruct vg_context * vg_current_context(void) 52c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner{ 53c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner return _vg_context; 54c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner} 55c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner 562fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner/** 57b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner * A depth/stencil rb will be needed regardless of what the visual says. 58b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner */ 5993193f806378e06092820c099e437886c7309b94Chris Lattnerstatic boolean 6093193f806378e06092820c099e437886c7309b94Chris Lattnerchoose_depth_stencil_format(struct vg_context *ctx) 61b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner{ 622c69184fd6c982349b1a7a7a06596418ea7702f2Chris Lattner struct pipe_screen *screen = ctx->pipe->screen; 632c69184fd6c982349b1a7a7a06596418ea7702f2Chris Lattner enum pipe_format formats[] = { 647e70829632f82de15db187845666aaca6e04b792Chris Lattner PIPE_FORMAT_Z24_UNORM_S8_USCALED, 65c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner PIPE_FORMAT_S8_USCALED_Z24_UNORM, 66c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner PIPE_FORMAT_NONE 67c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner }; 68b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner enum pipe_format *fmt; 697e70829632f82de15db187845666aaca6e04b792Chris Lattner 70a92dc193971daec428337dad437f08b8b2e5ceafChris Lattner for (fmt = formats; *fmt != PIPE_FORMAT_NONE; fmt++) { 717e70829632f82de15db187845666aaca6e04b792Chris Lattner if (screen->is_format_supported(screen, *fmt, 722b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) 732fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner break; 742fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner } 7593193f806378e06092820c099e437886c7309b94Chris Lattner 767e70829632f82de15db187845666aaca6e04b792Chris Lattner ctx->ds_format = *fmt; 7793193f806378e06092820c099e437886c7309b94Chris Lattner 786ffe551f657c948d6a473a198ecbd1188bf9ce45Chris Lattner return (ctx->ds_format != PIPE_FORMAT_NONE); 792b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman} 80a5dcc4f7b2a65afbeec9008733f47e6beee24bdeChris Lattner 816ffe551f657c948d6a473a198ecbd1188bf9ce45Chris Lattnervoid vg_set_current_context(struct vg_context *ctx) 8293193f806378e06092820c099e437886c7309b94Chris Lattner{ 83c2bcde4da07910253b24009132c1a5adc81c88fdChris Lattner _vg_context = ctx; 8493193f806378e06092820c099e437886c7309b94Chris Lattner api_make_dispatch_current((ctx) ? ctx->dispatch : NULL); 85b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner} 862b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman 87b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattnerstruct vg_context * vg_create_context(struct pipe_context *pipe, 88b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner const void *visual, 89b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner struct vg_context *share) 90b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner{ 91b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner struct vg_context *ctx; 92b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner 93b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner ctx = CALLOC_STRUCT(vg_context); 9445cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner 9545cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner ctx->pipe = pipe; 96db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner if (!choose_depth_stencil_format(ctx)) { 972c69184fd6c982349b1a7a7a06596418ea7702f2Chris Lattner FREE(ctx); 98368381e9ab590369213bbad690d2ff6f21b2144fChris Lattner return NULL; 992c69184fd6c982349b1a7a7a06596418ea7702f2Chris Lattner } 100b61107aa51db1bc66f6a2bb895926ca9b2f1f3f1Chris Lattner 101 ctx->dispatch = api_create_dispatch(); 102 103 vg_init_state(&ctx->state.vg); 104 ctx->state.dirty = ALL_DIRTY; 105 106 ctx->cso_context = cso_create_context(pipe); 107 108 ctx->default_paint = paint_create(ctx); 109 ctx->state.vg.stroke_paint = ctx->default_paint; 110 ctx->state.vg.fill_paint = ctx->default_paint; 111 112 113 ctx->mask.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 114 ctx->mask.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 115 ctx->mask.sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 116 ctx->mask.sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 117 ctx->mask.sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 118 ctx->mask.sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 119 ctx->mask.sampler.normalized_coords = 0; 120 121 ctx->blend_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 122 ctx->blend_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 123 ctx->blend_sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 124 ctx->blend_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 125 ctx->blend_sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 126 ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 127 ctx->blend_sampler.normalized_coords = 0; 128 129 vg_set_error(ctx, VG_NO_ERROR); 130 131 ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create(); 132 ctx->owned_objects[VG_OBJECT_IMAGE] = cso_hash_create(); 133 ctx->owned_objects[VG_OBJECT_MASK] = cso_hash_create(); 134 ctx->owned_objects[VG_OBJECT_FONT] = cso_hash_create(); 135 ctx->owned_objects[VG_OBJECT_PATH] = cso_hash_create(); 136 137 ctx->renderer = renderer_create(ctx); 138 ctx->sc = shaders_cache_create(ctx); 139 ctx->shader = shader_create(ctx); 140 141 ctx->blit = util_create_blit(ctx->pipe, ctx->cso_context); 142 143 return ctx; 144} 145 146void vg_destroy_context(struct vg_context *ctx) 147{ 148 struct pipe_resource **cbuf = &ctx->mask.cbuf; 149 150 util_destroy_blit(ctx->blit); 151 renderer_destroy(ctx->renderer); 152 shaders_cache_destroy(ctx->sc); 153 shader_destroy(ctx->shader); 154 paint_destroy(ctx->default_paint); 155 156 if (*cbuf) 157 pipe_resource_reference(cbuf, NULL); 158 159 if (ctx->mask.union_fs) 160 vg_shader_destroy(ctx, ctx->mask.union_fs); 161 if (ctx->mask.intersect_fs) 162 vg_shader_destroy(ctx, ctx->mask.intersect_fs); 163 if (ctx->mask.subtract_fs) 164 vg_shader_destroy(ctx, ctx->mask.subtract_fs); 165 if (ctx->mask.set_fs) 166 vg_shader_destroy(ctx, ctx->mask.set_fs); 167 168 cso_release_all(ctx->cso_context); 169 cso_destroy_context(ctx->cso_context); 170 171 cso_hash_delete(ctx->owned_objects[VG_OBJECT_PAINT]); 172 cso_hash_delete(ctx->owned_objects[VG_OBJECT_IMAGE]); 173 cso_hash_delete(ctx->owned_objects[VG_OBJECT_MASK]); 174 cso_hash_delete(ctx->owned_objects[VG_OBJECT_FONT]); 175 cso_hash_delete(ctx->owned_objects[VG_OBJECT_PATH]); 176 177 api_destroy_dispatch(ctx->dispatch); 178 179 FREE(ctx); 180} 181 182void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_object_type type) 183{ 184 obj->type = type; 185 obj->ctx = ctx; 186 obj->handle = create_handle(obj); 187} 188 189/** free object resources, but not the object itself */ 190void vg_free_object(struct vg_object *obj) 191{ 192 obj->type = 0; 193 obj->ctx = NULL; 194 destroy_handle(obj->handle); 195} 196 197VGboolean vg_context_is_object_valid(struct vg_context *ctx, 198 enum vg_object_type type, 199 VGHandle object) 200{ 201 if (ctx) { 202 struct cso_hash *hash = ctx->owned_objects[type]; 203 if (!hash) 204 return VG_FALSE; 205 return cso_hash_contains(hash, (unsigned)(long)object); 206 } 207 return VG_FALSE; 208} 209 210void vg_context_add_object(struct vg_context *ctx, 211 enum vg_object_type type, 212 void *ptr) 213{ 214 if (ctx) { 215 struct cso_hash *hash = ctx->owned_objects[type]; 216 if (!hash) 217 return; 218 cso_hash_insert(hash, (unsigned)(long)ptr, ptr); 219 } 220} 221 222void vg_context_remove_object(struct vg_context *ctx, 223 enum vg_object_type type, 224 void *ptr) 225{ 226 if (ctx) { 227 struct cso_hash *hash = ctx->owned_objects[type]; 228 if (!hash) 229 return; 230 cso_hash_take(hash, (unsigned)(long)ptr); 231 } 232} 233 234static struct pipe_resource * 235create_texture(struct pipe_context *pipe, enum pipe_format format, 236 VGint width, VGint height) 237{ 238 struct pipe_resource templ; 239 240 memset(&templ, 0, sizeof(templ)); 241 242 if (format != PIPE_FORMAT_NONE) { 243 templ.format = format; 244 } 245 else { 246 templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; 247 } 248 249 templ.target = PIPE_TEXTURE_2D; 250 templ.width0 = width; 251 templ.height0 = height; 252 templ.depth0 = 1; 253 templ.array_size = 1; 254 templ.last_level = 0; 255 256 if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) { 257 templ.bind = PIPE_BIND_DEPTH_STENCIL; 258 } else { 259 templ.bind = (PIPE_BIND_DISPLAY_TARGET | 260 PIPE_BIND_RENDER_TARGET | 261 PIPE_BIND_SAMPLER_VIEW); 262 } 263 264 return pipe->screen->resource_create(pipe->screen, &templ); 265} 266 267static struct pipe_sampler_view * 268create_tex_and_view(struct pipe_context *pipe, enum pipe_format format, 269 VGint width, VGint height) 270{ 271 struct pipe_resource *texture; 272 struct pipe_sampler_view view_templ; 273 struct pipe_sampler_view *view; 274 275 texture = create_texture(pipe, format, width, height); 276 277 if (!texture) 278 return NULL; 279 280 u_sampler_view_default_template(&view_templ, texture, texture->format); 281 view = pipe->create_sampler_view(pipe, texture, &view_templ); 282 /* want the texture to go away if the view is freed */ 283 pipe_resource_reference(&texture, NULL); 284 285 return view; 286} 287 288static void 289vg_context_update_surface_mask_view(struct vg_context *ctx, 290 uint width, uint height) 291{ 292 struct st_framebuffer *stfb = ctx->draw_buffer; 293 struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view; 294 struct pipe_context *pipe = ctx->pipe; 295 296 if (old_sampler_view && 297 old_sampler_view->texture->width0 == width && 298 old_sampler_view->texture->height0 == height) 299 return; 300 301 /* 302 we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to 303 this texture and use it as a sampler, so while this wastes some 304 space it makes both of those a lot simpler 305 */ 306 stfb->surface_mask_view = create_tex_and_view(pipe, 307 PIPE_FORMAT_B8G8R8A8_UNORM, width, height); 308 309 if (!stfb->surface_mask_view) { 310 if (old_sampler_view) 311 pipe_sampler_view_reference(&old_sampler_view, NULL); 312 return; 313 } 314 315 /* XXX could this call be avoided? */ 316 vg_validate_state(ctx); 317 318 /* alpha mask starts with 1.f alpha */ 319 mask_fill(0, 0, width, height, 1.f); 320 321 /* if we had an old surface copy it over */ 322 if (old_sampler_view) { 323 struct pipe_box src_box; 324 u_box_origin_2d(MIN2(old_sampler_view->texture->width0, 325 stfb->surface_mask_view->texture->width0), 326 MIN2(old_sampler_view->texture->height0, 327 stfb->surface_mask_view->texture->height0), 328 &src_box); 329 330 pipe->resource_copy_region(pipe, 331 stfb->surface_mask_view->texture, 332 0, 0, 0, 0, 333 old_sampler_view->texture, 334 0, &src_box); 335 } 336 337 /* Free the old texture 338 */ 339 if (old_sampler_view) 340 pipe_sampler_view_reference(&old_sampler_view, NULL); 341} 342 343static void 344vg_context_update_blend_texture_view(struct vg_context *ctx, 345 uint width, uint height) 346{ 347 struct pipe_context *pipe = ctx->pipe; 348 struct st_framebuffer *stfb = ctx->draw_buffer; 349 struct pipe_sampler_view *old = stfb->blend_texture_view; 350 351 if (old && 352 old->texture->width0 == width && 353 old->texture->height0 == height) 354 return; 355 356 stfb->blend_texture_view = create_tex_and_view(pipe, 357 PIPE_FORMAT_B8G8R8A8_UNORM, width, height); 358 359 pipe_sampler_view_reference(&old, NULL); 360} 361 362static boolean 363vg_context_update_depth_stencil_rb(struct vg_context * ctx, 364 uint width, uint height) 365{ 366 struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb; 367 struct pipe_context *pipe = ctx->pipe; 368 struct pipe_surface surf_tmpl; 369 370 if ((dsrb->width == width && dsrb->height == height) && dsrb->texture) 371 return FALSE; 372 373 /* unreference existing ones */ 374 pipe_surface_reference(&dsrb->surface, NULL); 375 pipe_resource_reference(&dsrb->texture, NULL); 376 dsrb->width = dsrb->height = 0; 377 378 dsrb->texture = create_texture(pipe, dsrb->format, width, height); 379 if (!dsrb->texture) 380 return TRUE; 381 382 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 383 u_surface_default_template(&surf_tmpl, dsrb->texture, 384 PIPE_BIND_DEPTH_STENCIL); 385 dsrb->surface = pipe->create_surface(pipe, 386 dsrb->texture, 387 &surf_tmpl); 388 if (!dsrb->surface) { 389 pipe_resource_reference(&dsrb->texture, NULL); 390 return TRUE; 391 } 392 393 dsrb->width = width; 394 dsrb->height = height; 395 396 assert(dsrb->surface->width == width); 397 assert(dsrb->surface->height == height); 398 399 return TRUE; 400} 401 402void vg_validate_state(struct vg_context *ctx) 403{ 404 struct st_framebuffer *stfb = ctx->draw_buffer; 405 406 vg_manager_validate_framebuffer(ctx); 407 408 if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height)) 409 ctx->state.dirty |= DEPTH_STENCIL_DIRTY; 410 411 /* blend state depends on fb format */ 412 if (ctx->state.dirty & FRAMEBUFFER_DIRTY) 413 ctx->state.dirty |= BLEND_DIRTY; 414 415 renderer_validate(ctx->renderer, ctx->state.dirty, 416 ctx->draw_buffer, &ctx->state.vg); 417 418 ctx->state.dirty = 0; 419 420 shader_set_masking(ctx->shader, ctx->state.vg.masking); 421 shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode); 422 shader_set_color_transform(ctx->shader, ctx->state.vg.color_transform); 423} 424 425VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type) 426{ 427 struct vg_object *obj = handle_to_object(object); 428 if (obj && is_aligned(obj) && obj->type == type) 429 return VG_TRUE; 430 else 431 return VG_FALSE; 432} 433 434void vg_set_error(struct vg_context *ctx, 435 VGErrorCode code) 436{ 437 /*vgGetError returns the oldest error code provided by 438 * an API call on the current context since the previous 439 * call to vgGetError on that context (or since the creation 440 of the context).*/ 441 if (ctx->_error == VG_NO_ERROR) 442 ctx->_error = code; 443} 444 445static void vg_prepare_blend_texture(struct vg_context *ctx, 446 struct pipe_sampler_view *src) 447{ 448 struct st_framebuffer *stfb = ctx->draw_buffer; 449 struct pipe_surface *surf; 450 struct pipe_surface surf_tmpl; 451 452 vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height); 453 454 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 455 u_surface_default_template(&surf_tmpl, stfb->blend_texture_view->texture, 456 PIPE_BIND_RENDER_TARGET); 457 surf = ctx->pipe->create_surface(ctx->pipe, 458 stfb->blend_texture_view->texture, 459 &surf_tmpl); 460 if (surf) { 461 util_blit_pixels_tex(ctx->blit, 462 src, 0, 0, stfb->width, stfb->height, 463 surf, 0, 0, stfb->width, stfb->height, 464 0.0, PIPE_TEX_MIPFILTER_NEAREST); 465 466 pipe_surface_reference(&surf, NULL); 467 } 468} 469 470struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx) 471{ 472 struct pipe_context *pipe = ctx->pipe; 473 struct pipe_sampler_view *view; 474 struct pipe_sampler_view view_templ; 475 struct st_framebuffer *stfb = ctx->draw_buffer; 476 struct st_renderbuffer *strb = stfb->strb; 477 478 vg_validate_state(ctx); 479 480 u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format); 481 view = pipe->create_sampler_view(pipe, strb->texture, &view_templ); 482 483 vg_prepare_blend_texture(ctx, view); 484 485 pipe_sampler_view_reference(&view, NULL); 486 487 return stfb->blend_texture_view; 488} 489 490 491struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx) 492{ 493 struct st_framebuffer *stfb = ctx->draw_buffer; 494 495 vg_validate_state(ctx); 496 497 vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height); 498 vg_prepare_blend_texture(ctx, stfb->surface_mask_view); 499 500 return stfb->blend_texture_view; 501} 502 503struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx) 504{ 505 struct st_framebuffer *stfb = ctx->draw_buffer; 506 507 vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height); 508 509 return stfb->surface_mask_view; 510} 511 512/** 513 * A transformation from window coordinates to paint coordinates. 514 */ 515VGboolean vg_get_paint_matrix(struct vg_context *ctx, 516 const struct matrix *paint_to_user, 517 const struct matrix *user_to_surface, 518 struct matrix *mat) 519{ 520 struct matrix tmp; 521 522 /* get user-to-paint matrix */ 523 memcpy(mat, paint_to_user, sizeof(*paint_to_user)); 524 if (!matrix_invert(mat)) 525 return VG_FALSE; 526 527 /* get surface-to-user matrix */ 528 memcpy(&tmp, user_to_surface, sizeof(*user_to_surface)); 529 if (!matrix_invert(&tmp)) 530 return VG_FALSE; 531 532 matrix_mult(mat, &tmp); 533 534 return VG_TRUE; 535} 536