diff options
author | Chia-I Wu <olv@lunarg.com> | 2010-11-28 01:58:05 +0800 |
---|---|---|
committer | Chia-I Wu <olv@lunarg.com> | 2010-12-01 11:23:50 +0800 |
commit | b730f0fc52a208b5f2a308199724ab02aa391fec (patch) | |
tree | a9b1bf0391003432042db1a6baae43c69892d655 | |
parent | 96c6637a1360f146bbf49ffb207ae943ecbbdf49 (diff) |
st/vega: Move g3d states to renderer.
Let vg_context focus on OpenVG states and renderer focus on gallium
states.
-rw-r--r-- | src/gallium/state_trackers/vega/renderer.c | 224 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/renderer.h | 7 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/vg_context.c | 187 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/vg_context.h | 12 |
4 files changed, 230 insertions, 200 deletions
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 7543fa1d41..d3fdf906e4 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -40,6 +40,7 @@ #include "util/u_simple_shaders.h" #include "util/u_memory.h" #include "util/u_sampler.h" +#include "util/u_math.h" #include "cso_cache/cso_context.h" #include "tgsi/tgsi_ureg.h" @@ -78,6 +79,16 @@ struct renderer { void *fs; + struct { + struct pipe_blend_state blend; + struct pipe_rasterizer_state rasterizer; + struct pipe_shader_state vs_state; + struct pipe_depth_stencil_alpha_state dsa; + struct pipe_framebuffer_state fb; + } g3d; + + struct pipe_resource *vs_const_buffer; + VGfloat vertices[4][2][4]; void *cached_vs[NUM_RENDERER_VS]; @@ -248,6 +259,30 @@ static void renderer_set_fs(struct renderer *r, RendererFs id) cso_set_fragment_shader_handle(r->cso, r->cached_fs[id]); } +typedef enum { + VEGA_Y0_TOP, + VEGA_Y0_BOTTOM +} VegaOrientation; + +static void vg_set_viewport(struct vg_context *ctx, + VegaOrientation orientation) +{ + struct st_framebuffer *stfb = ctx->draw_buffer; + struct pipe_viewport_state viewport; + VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f; + + viewport.scale[0] = stfb->width / 2.f; + viewport.scale[1] = stfb->height / y_scale; + viewport.scale[2] = 1.0; + viewport.scale[3] = 1.0; + viewport.translate[0] = stfb->width / 2.f; + viewport.translate[1] = stfb->height / 2.f; + viewport.translate[2] = 0.0; + viewport.translate[3] = 0.0; + + cso_set_viewport(ctx->cso_context, &viewport); +} + /** * Set renderer target. * @@ -930,8 +965,7 @@ void renderer_polygon_stencil(struct renderer *renderer, struct pipe_rasterizer_state raster; struct pipe_depth_stencil_alpha_state dsa; - /* TODO do not access owner state */ - raster = renderer->owner->state.g3d.rasterizer; + raster = renderer->g3d.rasterizer; dsa = renderer->u.polygon_stencil.dsa; /* front */ @@ -998,8 +1032,7 @@ VGboolean renderer_polygon_fill_begin(struct renderer *renderer, dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; dsa.stencil[0].valuemask = ~0; dsa.stencil[0].writemask = ~0; - /* TODO do not access owner state */ - dsa.depth = renderer->owner->state.g3d.dsa.depth; + dsa.depth = renderer->g3d.dsa.depth; cso_set_depth_stencil_alpha(renderer->cso, &dsa); renderer->state = RENDERER_STATE_POLYGON_FILL; @@ -1076,6 +1109,8 @@ void renderer_destroy(struct renderer *ctx) cso_delete_fragment_shader(ctx->cso, ctx->cached_fs[i]); } + pipe_resource_reference(&ctx->vs_const_buffer, NULL); + #if 0 if (ctx->fs) { cso_delete_fragment_shader(ctx->cso, ctx->fs); @@ -1085,6 +1120,187 @@ void renderer_destroy(struct renderer *ctx) FREE(ctx); } +static void update_clip_state(struct renderer *renderer, + const struct vg_state *state) +{ + struct pipe_depth_stencil_alpha_state *dsa = &renderer->g3d.dsa; + + memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); + + if (state->scissoring) { + struct pipe_framebuffer_state *fb = &renderer->g3d.fb; + int i; + + renderer_scissor_begin(renderer, VG_FALSE); + + for (i = 0; i < state->scissor_rects_num; ++i) { + const float x = state->scissor_rects[i * 4 + 0].f; + const float y = state->scissor_rects[i * 4 + 1].f; + const float width = state->scissor_rects[i * 4 + 2].f; + const float height = state->scissor_rects[i * 4 + 3].f; + VGint x0, y0, x1, y1, iw, ih; + + x0 = (VGint) x; + y0 = (VGint) y; + if (x0 < 0) + x0 = 0; + if (y0 < 0) + y0 = 0; + + /* note that x1 and y1 are exclusive */ + x1 = (VGint) ceilf(x + width); + y1 = (VGint) ceilf(y + height); + if (x1 > fb->width) + x1 = fb->width; + if (y1 > fb->height) + y1 = fb->height; + + iw = x1 - x0; + ih = y1 - y0; + if (iw > 0 && ih> 0 ) + renderer_scissor(renderer, x0, y0, iw, ih); + } + + renderer_scissor_end(renderer); + + dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */ + dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/ + dsa->depth.func = PIPE_FUNC_GEQUAL; + } +} + +/** + * Propogate OpenVG state changes to the renderer. Only framebuffer, blending + * and scissoring states are relevant here. + */ +void renderer_validate(struct renderer *renderer, + VGbitfield dirty, + const struct st_framebuffer *stfb, + const struct vg_state *state) +{ + assert(renderer->state == RENDERER_STATE_INIT); + + if (dirty & BLEND_DIRTY) { + struct pipe_blend_state *blend = &renderer->g3d.blend; + memset(blend, 0, sizeof(struct pipe_blend_state)); + blend->rt[0].blend_enable = 1; + blend->rt[0].colormask = PIPE_MASK_RGBA; + + switch (state->blend_mode) { + case VG_BLEND_SRC: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].blend_enable = 0; + break; + case VG_BLEND_SRC_OVER: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + break; + case VG_BLEND_DST_OVER: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; + break; + case VG_BLEND_SRC_IN: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + break; + case VG_BLEND_DST_IN: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + break; + case VG_BLEND_MULTIPLY: + case VG_BLEND_SCREEN: + case VG_BLEND_DARKEN: + case VG_BLEND_LIGHTEN: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].blend_enable = 0; + break; + case VG_BLEND_ADDITIVE: + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + break; + default: + assert(!"not implemented blend mode"); + } + cso_set_blend(renderer->cso, blend); + } + + if (dirty & RASTERIZER_DIRTY) { + struct pipe_rasterizer_state *raster = &renderer->g3d.rasterizer; + memset(raster, 0, sizeof(struct pipe_rasterizer_state)); + raster->gl_rasterization_rules = 1; + cso_set_rasterizer(renderer->cso, raster); + } + + if (dirty & FRAMEBUFFER_DIRTY) { + struct pipe_framebuffer_state *fb = &renderer->g3d.fb; + struct pipe_resource **cbuf = &renderer->vs_const_buffer; + VGfloat vs_consts[8]; + + memset(fb, 0, sizeof(struct pipe_framebuffer_state)); + fb->width = stfb->width; + fb->height = stfb->height; + fb->nr_cbufs = 1; + fb->cbufs[0] = stfb->strb->surface; + fb->zsbuf = stfb->dsrb->surface; + + cso_set_framebuffer(renderer->cso, fb); + vg_set_viewport(renderer->owner, VEGA_Y0_BOTTOM); + + /* surface coordinates to clipped coordinates */ + vs_consts[0] = 2.0f / fb->width; + vs_consts[1] = 2.0f / fb->height; + vs_consts[2] = 1.0f; + vs_consts[3] = 1.0f; + vs_consts[4] = -1.0f; + vs_consts[5] = -1.0f; + vs_consts[6] = 0.0f; + vs_consts[7] = 0.0f; + + pipe_resource_reference(cbuf, NULL); + *cbuf = pipe_buffer_create(renderer->pipe->screen, + PIPE_BIND_CONSTANT_BUFFER, + sizeof(vs_consts)); + + if (*cbuf) { + pipe_buffer_write(renderer->pipe, + *cbuf, 0, sizeof(vs_consts), vs_consts); + } + renderer->pipe->set_constant_buffer(renderer->pipe, + PIPE_SHADER_VERTEX, 0, *cbuf); + + /* we also got a new depth buffer */ + if (dirty & DEPTH_STENCIL_DIRTY) { + renderer->pipe->clear(renderer->pipe, + PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0); + } + } + + if (dirty & VS_DIRTY) + renderer_set_vs(renderer, RENDERER_VS_PLAIN); + + /* must be last because it renders to the depth buffer*/ + if (dirty & DEPTH_STENCIL_DIRTY) { + update_clip_state(renderer, state); + cso_set_depth_stencil_alpha(renderer->cso, &renderer->g3d.dsa); + } +} + void renderer_draw_quad(struct renderer *r, VGfloat x1, VGfloat y1, VGfloat x2, VGfloat y2, diff --git a/src/gallium/state_trackers/vega/renderer.h b/src/gallium/state_trackers/vega/renderer.h index 8d13c02f3b..763e57def5 100644 --- a/src/gallium/state_trackers/vega/renderer.h +++ b/src/gallium/state_trackers/vega/renderer.h @@ -33,6 +33,8 @@ struct renderer; struct vg_context; +struct vg_state; +struct st_framebuffer; struct pipe_resource; struct pipe_sampler_state; struct pipe_sampler_view; @@ -43,6 +45,11 @@ struct pipe_vertex_buffer; struct renderer *renderer_create(struct vg_context *owner); void renderer_destroy(struct renderer *); +void renderer_validate(struct renderer *renderer, + VGbitfield dirty, + const struct st_framebuffer *stfb, + const struct vg_state *state); + VGboolean renderer_copy_begin(struct renderer *renderer, struct pipe_surface *dst, VGboolean y0_top, diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index afb9579c1d..b9dbc4f00b 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -44,7 +44,6 @@ #include "util/u_memory.h" #include "util/u_blit.h" #include "util/u_sampler.h" -#include "util/u_math.h" struct vg_context *_vg_context = 0; @@ -269,179 +268,17 @@ void vg_context_remove_object(struct vg_context *ctx, } } -static void update_clip_state(struct vg_context *ctx) -{ - struct pipe_depth_stencil_alpha_state *dsa = &ctx->state.g3d.dsa; - struct vg_state *state = &ctx->state.vg; - - memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); - - if (state->scissoring) { - struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; - int i; - - renderer_scissor_begin(ctx->renderer, VG_FALSE); - - for (i = 0; i < state->scissor_rects_num; ++i) { - const float x = state->scissor_rects[i * 4 + 0].f; - const float y = state->scissor_rects[i * 4 + 1].f; - const float width = state->scissor_rects[i * 4 + 2].f; - const float height = state->scissor_rects[i * 4 + 3].f; - VGint x0, y0, x1, y1, iw, ih; - - x0 = (VGint) x; - y0 = (VGint) y; - if (x0 < 0) - x0 = 0; - if (y0 < 0) - y0 = 0; - - /* note that x1 and y1 are exclusive */ - x1 = (VGint) ceilf(x + width); - y1 = (VGint) ceilf(y + height); - if (x1 > fb->width) - x1 = fb->width; - if (y1 > fb->height) - y1 = fb->height; - - iw = x1 - x0; - ih = y1 - y0; - if (iw > 0 && ih> 0 ) - renderer_scissor(ctx->renderer, x0, y0, iw, ih); - } - - renderer_scissor_end(ctx->renderer); - - dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */ - dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/ - dsa->depth.func = PIPE_FUNC_GEQUAL; - } -} - void vg_validate_state(struct vg_context *ctx) { vg_manager_validate_framebuffer(ctx); - if ((ctx->state.dirty & BLEND_DIRTY)) { - struct pipe_blend_state *blend = &ctx->state.g3d.blend; - memset(blend, 0, sizeof(struct pipe_blend_state)); - blend->rt[0].blend_enable = 1; - blend->rt[0].colormask = PIPE_MASK_RGBA; - - switch (ctx->state.vg.blend_mode) { - case VG_BLEND_SRC: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].blend_enable = 0; - break; - case VG_BLEND_SRC_OVER: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - break; - case VG_BLEND_DST_OVER: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; - break; - case VG_BLEND_SRC_IN: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - break; - case VG_BLEND_DST_IN: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - break; - case VG_BLEND_MULTIPLY: - case VG_BLEND_SCREEN: - case VG_BLEND_DARKEN: - case VG_BLEND_LIGHTEN: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->rt[0].blend_enable = 0; - break; - case VG_BLEND_ADDITIVE: - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - break; - default: - assert(!"not implemented blend mode"); - } - cso_set_blend(ctx->cso_context, &ctx->state.g3d.blend); - } - if ((ctx->state.dirty & RASTERIZER_DIRTY)) { - struct pipe_rasterizer_state *raster = &ctx->state.g3d.rasterizer; - memset(raster, 0, sizeof(struct pipe_rasterizer_state)); - raster->gl_rasterization_rules = 1; - cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer); - } - if ((ctx->state.dirty & FRAMEBUFFER_DIRTY)) { - struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; - struct pipe_resource **cbuf = &ctx->vs_const_buffer; - VGfloat vs_consts[8]; - - memset(fb, 0, sizeof(struct pipe_framebuffer_state)); - fb->width = ctx->draw_buffer->width; - fb->height = ctx->draw_buffer->height; - fb->nr_cbufs = 1; - fb->cbufs[0] = ctx->draw_buffer->strb->surface; - fb->zsbuf = ctx->draw_buffer->dsrb->surface; - - cso_set_framebuffer(ctx->cso_context, fb); - vg_set_viewport(ctx, VEGA_Y0_BOTTOM); - - /* surface coordinates to clipped coordinates */ - vs_consts[0] = 2.0f / fb->width; - vs_consts[1] = 2.0f / fb->height; - vs_consts[2] = 1.0f; - vs_consts[3] = 1.0f; - vs_consts[4] = -1.0f; - vs_consts[5] = -1.0f; - vs_consts[6] = 0.0f; - vs_consts[7] = 0.0f; + renderer_validate(ctx->renderer, ctx->state.dirty, + ctx->draw_buffer, &ctx->state.vg); - pipe_resource_reference(cbuf, NULL); - *cbuf = pipe_buffer_create(ctx->pipe->screen, - PIPE_BIND_CONSTANT_BUFFER, - sizeof(vs_consts)); - - if (*cbuf) { - st_no_flush_pipe_buffer_write(ctx, *cbuf, - 0, sizeof(vs_consts), vs_consts); - } - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf); - - /* we also got a new depth buffer */ - if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) - ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0); - } - if ((ctx->state.dirty & VS_DIRTY)) { - cso_set_vertex_shader_handle(ctx->cso_context, - vg_plain_vs(ctx)); - } - - /* must be last because it renders to the depth buffer*/ - if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) { - update_clip_state(ctx); - cso_set_depth_stencil_alpha(ctx->cso_context, &ctx->state.g3d.dsa); - } + ctx->state.dirty = NONE_DIRTY; shader_set_masking(ctx->shader, ctx->state.vg.masking); shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode); - - ctx->state.dirty = NONE_DIRTY; } VGboolean vg_object_is_valid(void *ptr, enum vg_object_type type) @@ -572,21 +409,3 @@ void * vg_texture_vs(struct vg_context *ctx) return ctx->texture_vs->driver; } - -void vg_set_viewport(struct vg_context *ctx, VegaOrientation orientation) -{ - struct st_framebuffer *stfb = ctx->draw_buffer; - struct pipe_viewport_state viewport; - VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f; - - viewport.scale[0] = stfb->width / 2.f; - viewport.scale[1] = stfb->height / y_scale; - viewport.scale[2] = 1.0; - viewport.scale[3] = 1.0; - viewport.translate[0] = stfb->width / 2.f; - viewport.translate[1] = stfb->height / 2.f; - viewport.translate[2] = 0.0; - viewport.translate[3] = 0.0; - - cso_set_viewport(ctx->cso_context, &viewport); -} diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index 547674bd2a..b3263cdef5 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -98,13 +98,6 @@ struct vg_context struct { struct vg_state vg; - struct { - struct pipe_blend_state blend; - struct pipe_rasterizer_state rasterizer; - struct pipe_shader_state vs_state; - struct pipe_depth_stencil_alpha_state dsa; - struct pipe_framebuffer_state fb; - } g3d; VGbitfield dirty; } state; @@ -295,10 +288,5 @@ static INLINE void vg_bound_rect(VGfloat coords[4], void *vg_plain_vs(struct vg_context *ctx); void *vg_clear_vs(struct vg_context *ctx); void *vg_texture_vs(struct vg_context *ctx); -typedef enum { - VEGA_Y0_TOP, - VEGA_Y0_BOTTOM -} VegaOrientation; -void vg_set_viewport(struct vg_context *ctx, VegaOrientation orientation); #endif |