Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2010 LunarG Inc.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Chia-I Wu 
26
 */
27
 
28
#include "util/u_memory.h"
29
#include "util/u_string.h"
30
#include "util/u_inlines.h"
31
#include "util/u_pointer.h"
32
#include "util/u_dl.h"
33
#include "egldriver.h"
34
#include "eglimage.h"
35
#include "eglmutex.h"
36
 
37
#include "egl_g3d.h"
38
#include "egl_g3d_st.h"
39
 
40
struct egl_g3d_st_manager {
41
   struct st_manager base;
42
   _EGLDisplay *display;
43
};
44
 
45
static INLINE struct egl_g3d_st_manager *
46
egl_g3d_st_manager(struct st_manager *smapi)
47
{
48
   return (struct egl_g3d_st_manager *) smapi;
49
}
50
 
51
static boolean
52
egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
53
                                 void *egl_image,
54
                                 struct st_egl_image *out)
55
{
56
   struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
57
   EGLImageKHR handle = (EGLImageKHR) egl_image;
58
   _EGLImage *img;
59
   struct egl_g3d_image *gimg;
60
 
61
   /* this is called from state trackers */
62
   _eglLockMutex(&gsmapi->display->Mutex);
63
 
64
   img = _eglLookupImage(handle, gsmapi->display);
65
   if (!img) {
66
      _eglUnlockMutex(&gsmapi->display->Mutex);
67
      return FALSE;
68
   }
69
 
70
   gimg = egl_g3d_image(img);
71
 
72
   out->texture = NULL;
73
   pipe_resource_reference(&out->texture, gimg->texture);
74
   out->level = gimg->level;
75
   out->layer = gimg->layer;
76
 
77
   _eglUnlockMutex(&gsmapi->display->Mutex);
78
 
79
   return TRUE;
80
}
81
 
82
static int
83
egl_g3d_st_manager_get_param(struct st_manager *smapi,
84
                             enum st_manager_param param)
85
{
86
   return 0;
87
}
88
 
89
struct st_manager *
90
egl_g3d_create_st_manager(_EGLDisplay *dpy)
91
{
92
   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
93
   struct egl_g3d_st_manager *gsmapi;
94
 
95
   gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
96
   if (gsmapi) {
97
      gsmapi->display = dpy;
98
 
99
      gsmapi->base.screen = gdpy->native->screen;
100
      gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image;
101
      gsmapi->base.get_param = egl_g3d_st_manager_get_param;
102
   }
103
 
104
   return &gsmapi->base;;
105
}
106
 
107
void
108
egl_g3d_destroy_st_manager(struct st_manager *smapi)
109
{
110
   struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
111
   FREE(gsmapi);
112
}
113
 
114
static boolean
115
egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_context_iface *stctx,
116
                                           struct st_framebuffer_iface *stfbi,
117
                                           enum st_attachment_type statt)
118
{
119
   return TRUE;
120
}
121
 
122
static void
123
pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
124
{
125
   /* TODO */
126
}
127
 
128
static void
129
pbuffer_allocate_pbuffer_texture(struct egl_g3d_surface *gsurf)
130
{
131
   struct egl_g3d_display *gdpy =
132
      egl_g3d_display(gsurf->base.Resource.Display);
133
   struct pipe_screen *screen = gdpy->native->screen;
134
   struct pipe_resource templ, *ptex;
135
 
136
   memset(&templ, 0, sizeof(templ));
137
   templ.target = PIPE_TEXTURE_2D;
138
   templ.last_level = 0;
139
   templ.width0 = gsurf->base.Width;
140
   templ.height0 = gsurf->base.Height;
141
   templ.depth0 = 1;
142
   templ.array_size = 1;
143
   templ.format = gsurf->stvis.color_format;
144
   /* for rendering and binding to texture */
145
   templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
146
 
147
   ptex = screen->resource_create(screen, &templ);
148
   gsurf->render_texture = ptex;
149
}
150
 
151
static boolean
152
egl_g3d_st_framebuffer_validate_pbuffer(struct st_context_iface *stctx,
153
                                        struct st_framebuffer_iface *stfbi,
154
                                        const enum st_attachment_type *statts,
155
                                        unsigned count,
156
                                        struct pipe_resource **out)
157
{
158
   _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
159
   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
160
   unsigned i;
161
 
162
   for (i = 0; i < count; i++) {
163
      out[i] = NULL;
164
 
165
      if (gsurf->stvis.render_buffer != statts[i])
166
         continue;
167
 
168
      if (!gsurf->render_texture) {
169
         switch (gsurf->client_buffer_type) {
170
         case EGL_NONE:
171
            pbuffer_allocate_pbuffer_texture(gsurf);
172
            break;
173
         case EGL_OPENVG_IMAGE:
174
            pbuffer_reference_openvg_image(gsurf);
175
            break;
176
         default:
177
            break;
178
         }
179
 
180
         if (!gsurf->render_texture)
181
            return FALSE;
182
      }
183
 
184
      pipe_resource_reference(&out[i], gsurf->render_texture);
185
   }
186
 
187
   return TRUE;
188
}
189
 
190
static boolean
191
egl_g3d_st_framebuffer_flush_front(struct st_context_iface *stctx,
192
                                   struct st_framebuffer_iface *stfbi,
193
                                   enum st_attachment_type statt)
194
{
195
   _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
196
   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
197
   struct native_present_control ctrl;
198
 
199
   memset(&ctrl, 0, sizeof(ctrl));
200
   ctrl.natt = NATIVE_ATTACHMENT_FRONT_LEFT;
201
 
202
   return gsurf->native->present(gsurf->native, &ctrl);
203
}
204
 
205
static boolean
206
egl_g3d_st_framebuffer_validate(struct st_context_iface *stctx,
207
                                struct st_framebuffer_iface *stfbi,
208
                                const enum st_attachment_type *statts,
209
                                unsigned count,
210
                                struct pipe_resource **out)
211
{
212
   _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
213
   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
214
   struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
215
   uint attachment_mask = 0;
216
   unsigned i;
217
 
218
   for (i = 0; i < count; i++) {
219
      int natt;
220
 
221
      switch (statts[i]) {
222
      case ST_ATTACHMENT_FRONT_LEFT:
223
         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
224
         break;
225
      case ST_ATTACHMENT_BACK_LEFT:
226
         natt = NATIVE_ATTACHMENT_BACK_LEFT;
227
         break;
228
      case ST_ATTACHMENT_FRONT_RIGHT:
229
         natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
230
         break;
231
      case ST_ATTACHMENT_BACK_RIGHT:
232
         natt = NATIVE_ATTACHMENT_BACK_RIGHT;
233
         break;
234
      default:
235
         natt = -1;
236
         break;
237
      }
238
 
239
      if (natt >= 0)
240
         attachment_mask |= 1 << natt;
241
   }
242
 
243
   if (!gsurf->native->validate(gsurf->native, attachment_mask,
244
         &gsurf->sequence_number, textures, &gsurf->base.Width,
245
         &gsurf->base.Height))
246
      return FALSE;
247
 
248
   for (i = 0; i < count; i++) {
249
      struct pipe_resource *tex;
250
      int natt;
251
 
252
      switch (statts[i]) {
253
      case ST_ATTACHMENT_FRONT_LEFT:
254
         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
255
         break;
256
      case ST_ATTACHMENT_BACK_LEFT:
257
         natt = NATIVE_ATTACHMENT_BACK_LEFT;
258
         break;
259
      case ST_ATTACHMENT_FRONT_RIGHT:
260
         natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
261
         break;
262
      case ST_ATTACHMENT_BACK_RIGHT:
263
         natt = NATIVE_ATTACHMENT_BACK_RIGHT;
264
         break;
265
      default:
266
         natt = -1;
267
         break;
268
      }
269
 
270
      if (natt >= 0) {
271
         tex = textures[natt];
272
 
273
         if (statts[i] == stfbi->visual->render_buffer)
274
            pipe_resource_reference(&gsurf->render_texture, tex);
275
 
276
         if (attachment_mask & (1 << natt)) {
277
            /* transfer the ownership to the caller */
278
            out[i] = tex;
279
            attachment_mask &= ~(1 << natt);
280
         }
281
         else {
282
            /* the attachment is listed more than once */
283
            pipe_resource_reference(&out[i], tex);
284
         }
285
      }
286
   }
287
 
288
   return TRUE;
289
}
290
 
291
struct st_framebuffer_iface *
292
egl_g3d_create_st_framebuffer(_EGLSurface *surf)
293
{
294
   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
295
   struct st_framebuffer_iface *stfbi;
296
 
297
   stfbi = CALLOC_STRUCT(st_framebuffer_iface);
298
   if (!stfbi)
299
      return NULL;
300
 
301
   stfbi->visual = &gsurf->stvis;
302
   p_atomic_set(&stfbi->stamp, 1);
303
 
304
   if (gsurf->base.Type != EGL_PBUFFER_BIT) {
305
      stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
306
      stfbi->validate = egl_g3d_st_framebuffer_validate;
307
   }
308
   else {
309
      stfbi->flush_front = egl_g3d_st_framebuffer_flush_front_pbuffer;
310
      stfbi->validate = egl_g3d_st_framebuffer_validate_pbuffer;
311
   }
312
   stfbi->st_manager_private = (void *) &gsurf->base;
313
 
314
   return stfbi;
315
}
316
 
317
void
318
egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
319
{
320
   FREE(stfbi);
321
}