mesa: Rename _mesa_lookup_arrayobj to _mesa_lookup_vao.
[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_vertex_array_object *obj = _mesa_lookup_vao(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 if (bufSize < 0) {
260 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectLabel(bufSize = %d)",
261 bufSize);
262 return;
263 }
264
265 labelPtr = get_label_pointer(ctx, identifier, name, "glGetObjectLabel");
266 if (!labelPtr)
267 return;
268
269 copy_label(*labelPtr, label, length, bufSize);
270 }
271
272 void GLAPIENTRY
273 _mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
274 {
275 GET_CURRENT_CONTEXT(ctx);
276 char **labelPtr;
277 struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr;
278
279 if (!_mesa_validate_sync(ctx, syncObj)) {
280 _mesa_error(ctx, GL_INVALID_VALUE, "glObjectPtrLabel (not a valid sync object)");
281 return;
282 }
283
284 labelPtr = &syncObj->Label;
285
286 set_label(ctx, labelPtr, label, length, "glObjectPtrLabel");
287 }
288
289 void GLAPIENTRY
290 _mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length,
291 GLchar *label)
292 {
293 GET_CURRENT_CONTEXT(ctx);
294 char **labelPtr;
295 struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr;
296
297 if (bufSize < 0) {
298 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectPtrLabel(bufSize = %d)",
299 bufSize);
300 return;
301 }
302
303 if (!_mesa_validate_sync(ctx, syncObj)) {
304 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectPtrLabel (not a valid sync object)");
305 return;
306 }
307
308 labelPtr = &syncObj->Label;
309
310 copy_label(*labelPtr, label, length, bufSize);
311 }