OSDN Git Service

mesa: use strdup() instead of _mesa_strdup()
[android-x86/external-mesa.git] / src / mesa / main / objectlabel.c
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2013  Timothy Arceri   All Rights Reserved.
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
17  * OR 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
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25
26 #include "arrayobj.h"
27 #include "bufferobj.h"
28 #include "context.h"
29 #include "dlist.h"
30 #include "enums.h"
31 #include "fbobject.h"
32 #include "objectlabel.h"
33 #include "queryobj.h"
34 #include "samplerobj.h"
35 #include "shaderobj.h"
36 #include "syncobj.h"
37 #include "texobj.h"
38 #include "transformfeedback.h"
39
40
41 /**
42  * Helper for _mesa_ObjectLabel() and _mesa_ObjectPtrLabel().
43  */
44 static void
45 set_label(struct gl_context *ctx, char **labelPtr, const char *label,
46           int length, const char *caller)
47 {
48    free(*labelPtr);
49    *labelPtr = NULL;
50
51    /* set new label string */
52    if (label) {
53       if (length >= 0) {
54          if (length >= MAX_LABEL_LENGTH)
55             _mesa_error(ctx, GL_INVALID_VALUE,
56                         "%s(length=%d, which is not less than "
57                         "GL_MAX_LABEL_LENGTH=%d)", caller, length,
58                         MAX_LABEL_LENGTH);
59
60          /* explicit length */
61          *labelPtr = malloc(length+1);
62          if (*labelPtr) {
63             memcpy(*labelPtr, label, length);
64             /* length is not required to include the null terminator so
65              * add one just in case
66              */
67             (*labelPtr)[length] = '\0';
68          }
69       }
70       else {
71          int len = strlen(label);
72          if (len >= MAX_LABEL_LENGTH)
73             _mesa_error(ctx, GL_INVALID_VALUE,
74                 "%s(label length=%d, which is not less than "
75                 "GL_MAX_LABEL_LENGTH=%d)", caller, len,
76                 MAX_LABEL_LENGTH);
77
78          /* null-terminated string */
79          *labelPtr = strdup(label);
80       }
81    }
82 }
83
84 /**
85  * Helper for _mesa_GetObjectLabel() and _mesa_GetObjectPtrLabel().
86  * \param src  the src label (may be null)
87  * \param dst  pointer to dest buffer (may be null)
88  * \param length  returns length of label (may be null)
89  * \param bufsize  size of dst buffer
90  */
91 static void
92 copy_label(const GLchar *src, GLchar *dst, GLsizei *length, GLsizei bufSize)
93 {
94    int labelLen = 0;
95
96    /* From http://www.opengl.org/registry/specs/KHR/debug.txt:
97     * "If <length> is NULL, no length is returned. The maximum number of
98     * characters that may be written into <label>, including the null
99     * terminator, is specified by <bufSize>. If no debug label was specified
100     * for the object then <label> will contain a null-terminated empty string,
101     * and zero will be returned in <length>. If <label> is NULL and <length>
102     * is non-NULL then no string will be returned and the length of the label
103     * will be returned in <length>."
104     */
105
106    if (src)
107       labelLen = strlen(src);
108
109    if (dst) {
110       if (src) {
111          if (bufSize <= labelLen)
112             labelLen = bufSize - 1;
113
114          memcpy(dst, src, labelLen);
115       }
116
117       dst[labelLen] = '\0';
118    }
119
120    if (length)
121       *length = labelLen;
122 }
123
124 /**
125  * Helper for _mesa_ObjectLabel() and _mesa_GetObjectLabel().
126  */
127 static char **
128 get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name,
129                   const char *caller)
130 {
131    char **labelPtr = NULL;
132
133    switch (identifier) {
134    case GL_BUFFER:
135       {
136          struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, name);
137          if (bufObj)
138             labelPtr = &bufObj->Label;
139       }
140       break;
141    case GL_SHADER:
142       {
143          struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
144          if (shader)
145             labelPtr = &shader->Label;
146       }
147       break;
148    case GL_PROGRAM:
149       {
150          struct gl_shader_program *program =
151             _mesa_lookup_shader_program(ctx, name);
152          if (program)
153             labelPtr = &program->Label;
154       }
155       break;
156    case GL_VERTEX_ARRAY:
157       {
158          struct gl_vertex_array_object *obj = _mesa_lookup_vao(ctx, name);
159          if (obj)
160             labelPtr = &obj->Label;
161       }
162       break;
163    case GL_QUERY:
164       {
165          struct gl_query_object *query = _mesa_lookup_query_object(ctx, name);
166          if (query)
167             labelPtr = &query->Label;
168       }
169       break;
170    case GL_TRANSFORM_FEEDBACK:
171       {
172          struct gl_transform_feedback_object *tfo =
173             _mesa_lookup_transform_feedback_object(ctx, name);
174          if (tfo)
175             labelPtr = &tfo->Label;
176       }
177       break;
178    case GL_SAMPLER:
179       {
180          struct gl_sampler_object *so = _mesa_lookup_samplerobj(ctx, name);
181          if (so)
182             labelPtr = &so->Label;
183       }
184       break;
185    case GL_TEXTURE:
186       {
187          struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name);
188          if (texObj)
189             labelPtr = &texObj->Label;
190       }
191       break;
192    case GL_RENDERBUFFER:
193       {
194          struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
195          if (rb)
196             labelPtr = &rb->Label;
197       }
198       break;
199    case GL_FRAMEBUFFER:
200       {
201          struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, name);
202          if (rb)
203             labelPtr = &rb->Label;
204       }
205       break;
206    case GL_DISPLAY_LIST:
207       if (ctx->API == API_OPENGL_COMPAT) {
208          struct gl_display_list *list = _mesa_lookup_list(ctx, name);
209          if (list)
210             labelPtr = &list->Label;
211       }
212       else {
213          goto invalid_enum;
214       }
215       break;
216    case GL_PROGRAM_PIPELINE:
217       /* requires GL 4.2 */
218       goto invalid_enum;
219    default:
220       goto invalid_enum;
221    }
222
223    if (NULL == labelPtr) {
224       _mesa_error(ctx, GL_INVALID_VALUE, "%s(name = %u)", caller, name);
225    }
226
227    return labelPtr;
228
229 invalid_enum:
230    _mesa_error(ctx, GL_INVALID_ENUM, "%s(identifier = %s)",
231                caller, _mesa_lookup_enum_by_nr(identifier));
232    return NULL;
233 }
234
235 void GLAPIENTRY
236 _mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length,
237                   const GLchar *label)
238 {
239    GET_CURRENT_CONTEXT(ctx);
240    char **labelPtr;
241
242    labelPtr = get_label_pointer(ctx, identifier, name, "glObjectLabel");
243    if (!labelPtr)
244       return;
245
246    set_label(ctx, labelPtr, label, length, "glObjectLabel");
247 }
248
249 void GLAPIENTRY
250 _mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
251                      GLsizei *length, GLchar *label)
252 {
253    GET_CURRENT_CONTEXT(ctx);
254    char **labelPtr;
255
256    if (bufSize < 0) {
257       _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectLabel(bufSize = %d)",
258                   bufSize);
259       return;
260    }
261
262    labelPtr = get_label_pointer(ctx, identifier, name, "glGetObjectLabel");
263    if (!labelPtr)
264       return;
265
266    copy_label(*labelPtr, label, length, bufSize);
267 }
268
269 void GLAPIENTRY
270 _mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
271 {
272    GET_CURRENT_CONTEXT(ctx);
273    char **labelPtr;
274    struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr;
275
276    if (!_mesa_validate_sync(ctx, syncObj)) {
277       _mesa_error(ctx, GL_INVALID_VALUE, "glObjectPtrLabel (not a valid sync object)");
278       return;
279    }
280
281    labelPtr = &syncObj->Label;
282
283    set_label(ctx, labelPtr, label, length, "glObjectPtrLabel");
284 }
285
286 void GLAPIENTRY
287 _mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length,
288                         GLchar *label)
289 {
290    GET_CURRENT_CONTEXT(ctx);
291    char **labelPtr;
292    struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr;
293
294    if (bufSize < 0) {
295       _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectPtrLabel(bufSize = %d)",
296                   bufSize);
297       return;
298    }
299
300    if (!_mesa_validate_sync(ctx, syncObj)) {
301       _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectPtrLabel (not a valid sync object)");
302       return;
303    }
304
305    labelPtr = &syncObj->Label;
306
307    copy_label(*labelPtr, label, length, bufSize);
308 }