objectlabel.c revision af69d88d
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 */ 44static void 45set_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 */ 94static void 95copy_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 */ 130static char ** 131get_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 232invalid_enum: 233 _mesa_error(ctx, GL_INVALID_ENUM, "%s(identifier = %s)", 234 caller, _mesa_lookup_enum_by_nr(identifier)); 235 return NULL; 236} 237 238void 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 252void 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 272void 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 289void 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} 312