OSDN Git Service

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