OSDN Git Service

Remove useless checks for NULL before freeing
[android-x86/external-mesa.git] / src / gallium / state_trackers / hgl / hgl.c
1 /*
2  * Copyright 2012-2013, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *      Artur Wyszynski, harakash@gmail.com
7  *      Alexander von Gluck IV, kallisti5@unixzen.com
8  */
9
10
11 #include "GLView.h"
12
13 #include "main/context.h"
14 #include "main/framebuffer.h"
15 #include "main/renderbuffer.h"
16 #include "pipe/p_format.h"
17 #include "util/u_atomic.h"
18 #include "util/u_memory.h"
19
20 #include "hgl_context.h"
21
22
23 #ifdef DEBUG
24 #   define TRACE(x...) printf("hgl:state_tracker: " x)
25 #   define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
26 #else
27 #   define TRACE(x...)
28 #   define CALLED()
29 #endif
30 #define ERROR(x...) printf("hgl:state_tracker: " x)
31
32
33 static boolean
34 hgl_st_framebuffer_flush_front(struct st_context_iface *stctx,
35         struct st_framebuffer_iface* stfb, enum st_attachment_type statt)
36 {
37         CALLED();
38
39         struct hgl_context* context = (struct hgl_context*)stfb->st_manager_private;
40
41         if (!context) {
42                 ERROR("%s: Couldn't obtain valid hgl_context!\n", __func__);
43                 return FALSE;
44         }
45
46         #if 0
47         struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
48         pipe_mutex_lock(stwfb->fb->mutex);
49
50         struct pipe_resource* resource = textures[statt];
51         if (resource)
52                 stw_framebuffer_present_locked(...);
53         #endif
54
55         return TRUE;
56 }
57
58
59 /**
60  * Called by the st manager to validate the framebuffer (allocate
61  * its resources).
62  */
63 static boolean
64 hgl_st_framebuffer_validate(struct st_context_iface *stctx,
65         struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts,
66         unsigned count, struct pipe_resource **out)
67 {
68         CALLED();
69
70         if (!stfbi) {
71                 ERROR("%s: Invalid st framebuffer interface!\n", __func__);
72                 return FALSE;
73         }
74
75         struct hgl_context* context = (struct hgl_context*)stfbi->st_manager_private;
76
77         if (!context) {
78                 ERROR("%s: Couldn't obtain valid hgl_context!\n", __func__);
79                 return FALSE;
80         }
81
82         int32 width = 0;
83         int32 height = 0;
84         get_bitmap_size(context->bitmap, &width, &height);
85
86         struct pipe_resource templat;
87         memset(&templat, 0, sizeof(templat));
88         templat.target = PIPE_TEXTURE_RECT;
89         templat.width0 = width;
90         templat.height0 = height;
91         templat.depth0 = 1;
92         templat.array_size = 1;
93         templat.usage = PIPE_USAGE_DEFAULT;
94
95         if (context->stVisual && context->manager && context->manager->screen) {
96                 TRACE("%s: Updating resources\n", __func__);
97                 for (unsigned i = 0; i < count; i++) {
98                         enum pipe_format format = PIPE_FORMAT_NONE;
99                         unsigned bind = 0;
100
101                         switch(statts[i]) {
102                                 case ST_ATTACHMENT_FRONT_LEFT:
103                                 case ST_ATTACHMENT_BACK_LEFT:
104                                         format = context->stVisual->color_format;
105                                         bind = PIPE_BIND_DISPLAY_TARGET
106                                                 | PIPE_BIND_RENDER_TARGET;
107                                         break;
108                                 case ST_ATTACHMENT_DEPTH_STENCIL:
109                                         format = context->stVisual->depth_stencil_format;
110                                         bind = PIPE_BIND_DEPTH_STENCIL;
111                                         break;
112                                 case ST_ATTACHMENT_ACCUM:
113                                         format = context->stVisual->accum_format;
114                                         bind = PIPE_BIND_RENDER_TARGET;
115                                         break;
116                                 default:
117                                         format = PIPE_FORMAT_NONE;
118                                         break;
119                         }
120
121                         if (format != PIPE_FORMAT_NONE) {
122                                 templat.format = format;
123                                 templat.bind = bind;
124
125                                 struct pipe_screen* screen = context->manager->screen;
126                                 context->textures[i] = screen->resource_create(screen, &templat);
127                                 out[i] = context->textures[i];
128                         }
129                 }
130         }
131
132         return TRUE;
133 }
134
135
136 static int
137 hgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param)
138 {
139         CALLED();
140
141         switch (param) {
142                 case ST_MANAGER_BROKEN_INVALIDATE:
143                         TRACE("%s: TODO: How should we handle BROKEN_INVALIDATE calls?\n",
144                                 __func__);
145                         // For now we force validation of the framebuffer.
146                         return 1;
147         }
148
149         return 0;
150 }
151
152
153 /**
154  * Create new framebuffer
155  */
156 struct hgl_buffer *
157 hgl_create_st_framebuffer(struct hgl_context* context)
158 {
159         CALLED();
160
161         struct hgl_buffer *buffer = CALLOC_STRUCT(hgl_buffer);
162
163         assert(context);
164         assert(context->stVisual);
165
166         if (buffer) {
167                 // Copy context visual into framebuffer
168                 memcpy(&buffer->visual, context->stVisual, sizeof(struct st_visual));
169
170                 // calloc and configure our st_framebuffer interface
171                 buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface);
172                 if (!buffer->stfbi) {
173                         ERROR("%s: Couldn't calloc framebuffer!\n", __func__);
174                         return NULL;
175                 }
176
177                 struct st_framebuffer_iface* stfbi = buffer->stfbi;
178                 p_atomic_set(&stfbi->stamp, 1);
179                 stfbi->flush_front = hgl_st_framebuffer_flush_front;
180                 stfbi->validate = hgl_st_framebuffer_validate;
181                 stfbi->st_manager_private = (void*)context;
182                 stfbi->visual = &buffer->visual;
183
184                 // TODO: Do we need linked list?
185         }
186
187    return buffer;
188 }
189
190
191 struct st_manager *
192 hgl_create_st_manager(struct pipe_screen* screen)
193 {
194         CALLED();
195
196         assert(screen);
197         struct st_manager* manager = CALLOC_STRUCT(st_manager);
198
199         if (!manager) {
200                 ERROR("%s: Couldn't allocate state tracker manager!\n", __func__);
201                 return NULL;
202         }
203
204         //manager->display = dpy;
205         manager->screen = screen;
206         manager->get_param = hgl_st_manager_get_param;
207
208         return manager;
209 }
210
211
212 void
213 hgl_destroy_st_manager(struct st_manager *manager)
214 {
215         CALLED();
216
217         FREE(manager);
218 }
219
220
221 struct st_visual*
222 hgl_create_st_visual(ulong options)
223 {
224         struct st_visual* visual = CALLOC_STRUCT(st_visual);
225         if (!visual) {
226                 ERROR("%s: Couldn't allocate st_visual\n", __func__);
227                 return NULL;
228         }
229
230         // Calculate visual configuration
231         const GLboolean rgbFlag     = ((options & BGL_INDEX) == 0);
232         const GLboolean alphaFlag   = ((options & BGL_ALPHA) == BGL_ALPHA);
233         const GLboolean dblFlag     = ((options & BGL_DOUBLE) == BGL_DOUBLE);
234         const GLboolean stereoFlag  = false;
235         const GLint depth           = (options & BGL_DEPTH) ? 24 : 0;
236         const GLint stencil         = (options & BGL_STENCIL) ? 8 : 0;
237         const GLint accum           = (options & BGL_ACCUM) ? 16 : 0;
238         const GLint red             = rgbFlag ? 8 : 5;
239         const GLint green           = rgbFlag ? 8 : 5;
240         const GLint blue            = rgbFlag ? 8 : 5;
241         const GLint alpha           = alphaFlag ? 8 : 0;
242
243         TRACE("rgb      :\t%d\n", (bool)rgbFlag);
244         TRACE("alpha    :\t%d\n", (bool)alphaFlag);
245         TRACE("dbl      :\t%d\n", (bool)dblFlag);
246         TRACE("stereo   :\t%d\n", (bool)stereoFlag);
247         TRACE("depth    :\t%d\n", depth);
248         TRACE("stencil  :\t%d\n", stencil);
249         TRACE("accum    :\t%d\n", accum);
250         TRACE("red      :\t%d\n", red);
251         TRACE("green    :\t%d\n", green);
252         TRACE("blue     :\t%d\n", blue);
253         TRACE("alpha    :\t%d\n", alpha);
254
255         // Determine color format
256         if (red == 8) {
257                 if (alpha == 8)
258                         visual->color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
259                 else
260                         visual->color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
261         } else {
262                 // TODO: I think this should be RGB vs BGR
263                 visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
264     }
265
266         // Determine depth stencil format
267         switch (depth) {
268                 default:
269                 case 0:
270                         visual->depth_stencil_format = PIPE_FORMAT_NONE;
271                         break;
272                 case 16:
273                         visual->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
274                         break;
275                 case 24:
276                         if ((options & BGL_STENCIL) != 0)
277                                 visual->depth_stencil_format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
278                         else
279                                 visual->depth_stencil_format = PIPE_FORMAT_X8Z24_UNORM;
280                         break;
281                 case 32:
282                         visual->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
283                         break;
284         }
285
286         visual->accum_format = (options & BGL_ACCUM)
287                 ? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
288
289         visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
290         visual->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
291
292         if (dblFlag) {
293                 visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
294                 visual->render_buffer = ST_ATTACHMENT_BACK_LEFT;
295         }
296
297         if (stereoFlag) {
298                 visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
299                 if (dblFlag)
300                         visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
301     }
302
303         if ((options & BGL_DEPTH) || (options & BGL_STENCIL))
304                 visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
305
306         return visual;
307 }
308
309
310 void
311 hgl_destroy_st_visual(struct st_visual* visual)
312 {
313         CALLED();
314
315         FREE(visual);
316 }