1 /************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27 #ifndef VG_CONTEXT_H 28 #define VG_CONTEXT_H 29 30 #include "vg_state.h" 31 32 #include "pipe/p_format.h" 33 #include "pipe/p_state.h" 34 #include "util/u_pointer.h" 35 #include "util/u_math.h" 36 #include "state_tracker/st_api.h" 37 38 #include "cso_cache/cso_hash.h" 39 #include "cso_cache/cso_context.h" 40 41 struct renderer; 42 struct shaders_cache; 43 struct shader; 44 struct vg_shader; 45 struct mapi_table; 46 47 struct st_renderbuffer { 48 enum pipe_format format; 49 struct pipe_surface *surface; 50 struct pipe_resource *texture; 51 VGint width, height; 52 }; 53 54 struct st_framebuffer { 55 VGint width, height; 56 struct st_renderbuffer *strb; 57 struct st_renderbuffer *dsrb; 58 59 struct pipe_sampler_view *surface_mask_view; 60 61 struct pipe_sampler_view *blend_texture_view; 62 63 64 struct st_framebuffer_iface *iface; 65 enum st_attachment_type strb_att; 66 67 void *privateData; 68 int32_t stamp; 69 int32_t iface_stamp; 70 }; 71 72 enum vg_object_type { 73 VG_OBJECT_UNKNOWN = 0, 74 VG_OBJECT_PAINT, 75 VG_OBJECT_IMAGE, 76 VG_OBJECT_MASK, 77 VG_OBJECT_FONT, 78 VG_OBJECT_PATH, 79 80 VG_OBJECT_LAST 81 }; 82 enum dirty_state { 83 BLEND_DIRTY = 1 << 0, 84 FRAMEBUFFER_DIRTY = 1 << 1, 85 DEPTH_STENCIL_DIRTY = 1 << 2, 86 PAINT_DIRTY = 1 << 3, 87 88 ALL_DIRTY = BLEND_DIRTY | 89 FRAMEBUFFER_DIRTY | 90 DEPTH_STENCIL_DIRTY | 91 PAINT_DIRTY 92 }; 93 94 struct vg_context 95 { 96 struct st_context_iface iface; 97 struct mapi_table *dispatch; 98 99 struct pipe_context *pipe; 100 enum pipe_format ds_format; 101 102 struct { 103 struct vg_state vg; 104 VGbitfield dirty; 105 } state; 106 107 VGErrorCode _error; 108 109 struct st_framebuffer *draw_buffer; 110 111 struct cso_hash *owned_objects[VG_OBJECT_LAST]; 112 113 struct { 114 struct pipe_resource *cbuf; 115 struct pipe_sampler_state sampler; 116 117 struct vg_shader *union_fs; 118 struct vg_shader *intersect_fs; 119 struct vg_shader *subtract_fs; 120 struct vg_shader *set_fs; 121 } mask; 122 123 struct cso_context *cso_context; 124 125 struct renderer *renderer; 126 struct shaders_cache *sc; 127 struct shader *shader; 128 129 struct pipe_sampler_state blend_sampler; 130 struct vg_paint *default_paint; 131 132 struct blit_state *blit; 133 134 int32_t draw_stamp; 135 }; 136 137 138 /** 139 * Base class for VG objects like paths, images, fonts. 140 */ 141 struct vg_object { 142 enum vg_object_type type; 143 VGHandle handle; 144 struct vg_context *ctx; 145 }; 146 147 148 void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_object_type type); 149 void vg_free_object(struct vg_object *obj); 150 151 VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type); 152 153 struct vg_context *vg_create_context(struct pipe_context *pipe, 154 const void *visual, 155 struct vg_context *share); 156 void vg_destroy_context(struct vg_context *ctx); 157 struct vg_context *vg_current_context(void); 158 void vg_set_current_context(struct vg_context *ctx); 159 160 VGboolean vg_context_is_object_valid(struct vg_context *ctx, 161 enum vg_object_type type, 162 VGHandle object); 163 void vg_context_add_object(struct vg_context *ctx, 164 struct vg_object *obj); 165 void vg_context_remove_object(struct vg_context *ctx, 166 struct vg_object *obj); 167 168 void vg_validate_state(struct vg_context *ctx); 169 170 void vg_set_error(struct vg_context *ctx, 171 VGErrorCode code); 172 173 struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx); 174 struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx); 175 176 struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx); 177 178 VGboolean vg_get_paint_matrix(struct vg_context *ctx, 179 const struct matrix *paint_to_user, 180 const struct matrix *user_to_surface, 181 struct matrix *mat); 182 183 static INLINE VGboolean is_aligned_to(const void *ptr, VGbyte alignment) 184 { 185 void *aligned = align_pointer(ptr, alignment); 186 return (ptr == aligned) ? VG_TRUE : VG_FALSE; 187 } 188 189 static INLINE VGboolean is_aligned(const void *ptr) 190 { 191 return is_aligned_to(ptr, 4); 192 } 193 194 static INLINE void vg_shift_rectx(VGfloat coords[4], 195 const VGfloat *bounds, 196 const VGfloat shift) 197 { 198 coords[0] += shift; 199 coords[2] -= shift; 200 if (bounds) { 201 coords[2] = MIN2(coords[2], bounds[2]); 202 /* bound x/y + width/height */ 203 if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) { 204 coords[2] = (bounds[0] + bounds[2]) - coords[0]; 205 } 206 } 207 } 208 209 static INLINE void vg_shift_recty(VGfloat coords[4], 210 const VGfloat *bounds, 211 const VGfloat shift) 212 { 213 coords[1] += shift; 214 coords[3] -= shift; 215 if (bounds) { 216 coords[3] = MIN2(coords[3], bounds[3]); 217 if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) { 218 coords[3] = (bounds[1] + bounds[3]) - coords[1]; 219 } 220 } 221 } 222 223 static INLINE void vg_bound_rect(VGfloat coords[4], 224 const VGfloat bounds[4], 225 VGfloat shift[4]) 226 { 227 /* if outside the bounds */ 228 if (coords[0] > (bounds[0] + bounds[2]) || 229 coords[1] > (bounds[1] + bounds[3]) || 230 (coords[0] + coords[2]) < bounds[0] || 231 (coords[1] + coords[3]) < bounds[1]) { 232 coords[0] = 0.f; 233 coords[1] = 0.f; 234 coords[2] = 0.f; 235 coords[3] = 0.f; 236 shift[0] = 0.f; 237 shift[1] = 0.f; 238 return; 239 } 240 241 /* bound x */ 242 if (coords[0] < bounds[0]) { 243 shift[0] = bounds[0] - coords[0]; 244 coords[2] -= shift[0]; 245 coords[0] = bounds[0]; 246 } else 247 shift[0] = 0.f; 248 249 /* bound y */ 250 if (coords[1] < bounds[1]) { 251 shift[1] = bounds[1] - coords[1]; 252 coords[3] -= shift[1]; 253 coords[1] = bounds[1]; 254 } else 255 shift[1] = 0.f; 256 257 shift[2] = bounds[2] - coords[2]; 258 shift[3] = bounds[3] - coords[3]; 259 /* bound width/height */ 260 coords[2] = MIN2(coords[2], bounds[2]); 261 coords[3] = MIN2(coords[3], bounds[3]); 262 263 /* bound x/y + width/height */ 264 if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) { 265 coords[2] = (bounds[0] + bounds[2]) - coords[0]; 266 } 267 if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) { 268 coords[3] = (bounds[1] + bounds[3]) - coords[1]; 269 } 270 271 /* if outside the bounds */ 272 if ((coords[0] + coords[2]) < bounds[0] || 273 (coords[1] + coords[3]) < bounds[1]) { 274 coords[0] = 0.f; 275 coords[1] = 0.f; 276 coords[2] = 0.f; 277 coords[3] = 0.f; 278 return; 279 } 280 } 281 282 #endif 283