main: Fixed _mesa_GetCompressedTexImage_sw to copy slices correctly.
[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 = _mesa_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 }