1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.9
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.  All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2010 LunarG Inc.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Chia-I Wu <olv@lunarg.com>
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "state_tracker/st_api.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_box.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_surface.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_api.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_manager.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_context.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "api.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "handle.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_renderbuffer *strb = ctx->draw_buffer->strb;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe = ctx->pipe;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_surface surf_tmpl;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strb->texture == pt) {
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&pt, NULL);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* unreference existing ones */
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_surface_reference(&strb->surface, NULL);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&strb->texture, NULL);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb->width = strb->height = 0;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb->texture = pt;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   u_surface_default_template(&surf_tmpl, strb->texture,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              PIPE_BIND_RENDER_TARGET);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!strb->surface) {
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&strb->texture, NULL);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb->width = pt->width0;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb->height = pt->height0;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Flush the front buffer if the current context renders to the front buffer.
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_manager_flush_frontbuffer(struct vg_context *ctx)
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_framebuffer *stfb = ctx->draw_buffer;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!stfb)
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (stfb->strb_att) {
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_FRONT_LEFT:
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_FRONT_RIGHT:
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->iface->flush_front(stfb->iface, stfb->strb_att);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Re-validate the framebuffer.
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_manager_validate_framebuffer(struct vg_context *ctx)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_framebuffer *stfb = ctx->draw_buffer;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *pt;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int32_t new_stamp;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* no binding surface */
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!stfb)
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   new_stamp = p_atomic_read(&stfb->iface->stamp);
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (stfb->iface_stamp != new_stamp) {
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      do {
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* validate the fb */
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!stfb->iface->validate(stfb->iface, &stfb->strb_att,
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    1, &pt) || !pt)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stfb->iface_stamp = new_stamp;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new_stamp = p_atomic_read(&stfb->iface->stamp);
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } while (stfb->iface_stamp != new_stamp);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (vg_context_update_color_rb(ctx, pt) ||
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          stfb->width != pt->width0 ||
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          stfb->height != pt->height0)
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ++stfb->stamp;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->width = pt->width0;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->height = pt->height0;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->draw_stamp != stfb->stamp) {
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->draw_stamp = stfb->stamp;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_context_flush(struct st_context_iface *stctxi, unsigned flags,
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct pipe_fence_handle **fence)
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = (struct vg_context *) stctxi;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->pipe->flush(ctx->pipe, fence);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (flags & ST_FLUSH_FRONT)
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vg_manager_flush_frontbuffer(ctx);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_context_destroy(struct st_context_iface *stctxi)
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = (struct vg_context *) stctxi;
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe = ctx->pipe;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_destroy_context(ctx);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->destroy(pipe);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct st_context_iface *
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct st_context_attribs *attribs,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      enum st_context_error *error,
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct st_context_iface *shared_stctxi)
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(stapi->profile_mask & (1 << attribs->profile))) {
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error = ST_CONTEXT_ERROR_BAD_API;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* only 1.0 is supported */
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (attribs->major > 1 || (attribs->major == 1 && attribs->minor > 0)) {
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error = ST_CONTEXT_ERROR_BAD_VERSION;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* for VGHandle / pointer lookups */
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   init_handles();
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = smapi->screen->context_create(smapi->screen, NULL);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pipe) {
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error = ST_CONTEXT_ERROR_NO_MEMORY;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx = vg_create_context(pipe, NULL, shared_ctx);
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx) {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->destroy(pipe);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error = ST_CONTEXT_ERROR_NO_MEMORY;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->iface.destroy = vg_context_destroy;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->iface.flush = vg_context_flush;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->iface.teximage = NULL;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->iface.copy = NULL;
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->iface.st_context_private = (void *) smapi;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &ctx->iface;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct st_renderbuffer *
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_renderbuffer(enum pipe_format format)
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_renderbuffer *strb;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb = CALLOC_STRUCT(st_renderbuffer);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strb)
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      strb->format = format;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return strb;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdestroy_renderbuffer(struct st_renderbuffer *strb)
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_surface_reference(&strb->surface, NULL);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&strb->texture, NULL);
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(strb);
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Decide the buffer to render to.
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum st_attachment_type
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchoose_attachment(struct st_framebuffer_iface *stfbi)
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum st_attachment_type statt;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   statt = stfbi->visual->render_buffer;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (statt != ST_ATTACHMENT_INVALID) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* use the buffer given by the visual, unless it is unavailable */
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) {
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (statt) {
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case ST_ATTACHMENT_BACK_LEFT:
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            statt = ST_ATTACHMENT_FRONT_LEFT;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case ST_ATTACHMENT_BACK_RIGHT:
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            statt = ST_ATTACHMENT_FRONT_RIGHT;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!st_visual_have_buffers(stfbi->visual, 1 << statt))
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            statt = ST_ATTACHMENT_INVALID;
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return statt;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Bind the context to the given framebuffers.
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_context_bind_framebuffers(struct st_context_iface *stctxi,
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             struct st_framebuffer_iface *stdrawi,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             struct st_framebuffer_iface *streadi)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = (struct vg_context *) stctxi;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_framebuffer *stfb;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum st_attachment_type strb_att;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* the draw and read framebuffers must be the same */
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (stdrawi != streadi)
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->draw_buffer) {
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb = ctx->draw_buffer;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* free the existing fb */
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!stdrawi ||
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          stfb->strb_att != strb_att ||
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          stfb->strb->format != stdrawi->visual->color_format) {
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         destroy_renderbuffer(stfb->strb);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         destroy_renderbuffer(stfb->dsrb);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FREE(stfb);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ctx->draw_buffer = NULL;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!stdrawi)
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strb_att == ST_ATTACHMENT_INVALID)
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* create a new fb */
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx->draw_buffer) {
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb = CALLOC_STRUCT(st_framebuffer);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!stfb)
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!stfb->strb) {
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FREE(stfb);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->dsrb = create_renderbuffer(ctx->ds_format);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!stfb->dsrb) {
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FREE(stfb->strb);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FREE(stfb);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->width = 0;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->height = 0;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->strb_att = strb_att;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->stamp = 1;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfb->iface_stamp = p_atomic_read(&stdrawi->stamp) - 1;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->draw_buffer = stfb;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->draw_buffer->iface = stdrawi;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->draw_stamp = ctx->draw_buffer->stamp - 1;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    struct st_framebuffer_iface *stdrawi,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    struct st_framebuffer_iface *streadi)
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = (struct vg_context *) stctxi;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (stctxi)
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vg_context_bind_framebuffers(stctxi, stdrawi, streadi);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_set_current_context(ctx);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct st_context_iface *
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_api_get_current(struct st_api *stapi)
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = vg_current_context();
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (ctx) ? &ctx->iface : NULL;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_proc_t
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_api_get_proc_address(struct st_api *stapi, const char *procname)
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return api_get_proc_address(procname);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_api_destroy(struct st_api *stapi)
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct st_api vg_api = {
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "Vega " VEGA_VERSION_STRING,
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ST_API_OPENVG,
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ST_PROFILE_DEFAULT_MASK,
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0,
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_api_destroy,
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_api_get_proc_address,
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_api_create_context,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_api_make_current,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vg_api_get_current,
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct st_api *
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvg_api_get(void)
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &vg_api;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
385