OSDN Git Service

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