1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 2013 Timothy Arceri All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg#include "arrayobj.h" 27848b8605Smrg#include "bufferobj.h" 28848b8605Smrg#include "context.h" 29848b8605Smrg#include "dlist.h" 30848b8605Smrg#include "enums.h" 31848b8605Smrg#include "fbobject.h" 32848b8605Smrg#include "objectlabel.h" 33b8e80941Smrg#include "pipelineobj.h" 34848b8605Smrg#include "queryobj.h" 35848b8605Smrg#include "samplerobj.h" 36848b8605Smrg#include "shaderobj.h" 37848b8605Smrg#include "syncobj.h" 38848b8605Smrg#include "texobj.h" 39848b8605Smrg#include "transformfeedback.h" 40848b8605Smrg 41848b8605Smrg 42848b8605Smrg/** 43848b8605Smrg * Helper for _mesa_ObjectLabel() and _mesa_ObjectPtrLabel(). 44848b8605Smrg */ 45848b8605Smrgstatic void 46848b8605Smrgset_label(struct gl_context *ctx, char **labelPtr, const char *label, 47848b8605Smrg int length, const char *caller) 48848b8605Smrg{ 49b8e80941Smrg free(*labelPtr); 50b8e80941Smrg *labelPtr = NULL; 51848b8605Smrg 52848b8605Smrg /* set new label string */ 53848b8605Smrg if (label) { 54848b8605Smrg if (length >= 0) { 55848b8605Smrg if (length >= MAX_LABEL_LENGTH) 56848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 57848b8605Smrg "%s(length=%d, which is not less than " 58848b8605Smrg "GL_MAX_LABEL_LENGTH=%d)", caller, length, 59848b8605Smrg MAX_LABEL_LENGTH); 60848b8605Smrg 61848b8605Smrg /* explicit length */ 62b8e80941Smrg *labelPtr = malloc(length+1); 63848b8605Smrg if (*labelPtr) { 64848b8605Smrg memcpy(*labelPtr, label, length); 65848b8605Smrg /* length is not required to include the null terminator so 66848b8605Smrg * add one just in case 67848b8605Smrg */ 68848b8605Smrg (*labelPtr)[length] = '\0'; 69848b8605Smrg } 70848b8605Smrg } 71848b8605Smrg else { 72848b8605Smrg int len = strlen(label); 73848b8605Smrg if (len >= MAX_LABEL_LENGTH) 74848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 75848b8605Smrg "%s(label length=%d, which is not less than " 76848b8605Smrg "GL_MAX_LABEL_LENGTH=%d)", caller, len, 77848b8605Smrg MAX_LABEL_LENGTH); 78848b8605Smrg 79848b8605Smrg /* null-terminated string */ 80b8e80941Smrg *labelPtr = strdup(label); 81848b8605Smrg } 82848b8605Smrg } 83848b8605Smrg} 84848b8605Smrg 85848b8605Smrg/** 86848b8605Smrg * Helper for _mesa_GetObjectLabel() and _mesa_GetObjectPtrLabel(). 87848b8605Smrg * \param src the src label (may be null) 88848b8605Smrg * \param dst pointer to dest buffer (may be null) 89848b8605Smrg * \param length returns length of label (may be null) 90848b8605Smrg * \param bufsize size of dst buffer 91848b8605Smrg */ 92848b8605Smrgstatic void 93848b8605Smrgcopy_label(const GLchar *src, GLchar *dst, GLsizei *length, GLsizei bufSize) 94848b8605Smrg{ 95848b8605Smrg int labelLen = 0; 96848b8605Smrg 97848b8605Smrg /* From http://www.opengl.org/registry/specs/KHR/debug.txt: 98848b8605Smrg * "If <length> is NULL, no length is returned. The maximum number of 99848b8605Smrg * characters that may be written into <label>, including the null 100848b8605Smrg * terminator, is specified by <bufSize>. If no debug label was specified 101848b8605Smrg * for the object then <label> will contain a null-terminated empty string, 102848b8605Smrg * and zero will be returned in <length>. If <label> is NULL and <length> 103848b8605Smrg * is non-NULL then no string will be returned and the length of the label 104848b8605Smrg * will be returned in <length>." 105848b8605Smrg */ 106848b8605Smrg 107848b8605Smrg if (src) 108848b8605Smrg labelLen = strlen(src); 109848b8605Smrg 110b8e80941Smrg if (bufSize == 0) { 111b8e80941Smrg if (length) 112b8e80941Smrg *length = labelLen; 113b8e80941Smrg return; 114b8e80941Smrg } 115b8e80941Smrg 116848b8605Smrg if (dst) { 117848b8605Smrg if (src) { 118848b8605Smrg if (bufSize <= labelLen) 119848b8605Smrg labelLen = bufSize - 1; 120848b8605Smrg 121848b8605Smrg memcpy(dst, src, labelLen); 122848b8605Smrg } 123848b8605Smrg 124848b8605Smrg dst[labelLen] = '\0'; 125848b8605Smrg } 126848b8605Smrg 127848b8605Smrg if (length) 128848b8605Smrg *length = labelLen; 129848b8605Smrg} 130848b8605Smrg 131848b8605Smrg/** 132848b8605Smrg * Helper for _mesa_ObjectLabel() and _mesa_GetObjectLabel(). 133848b8605Smrg */ 134848b8605Smrgstatic char ** 135848b8605Smrgget_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, 136848b8605Smrg const char *caller) 137848b8605Smrg{ 138848b8605Smrg char **labelPtr = NULL; 139848b8605Smrg 140848b8605Smrg switch (identifier) { 141848b8605Smrg case GL_BUFFER: 142848b8605Smrg { 143848b8605Smrg struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, name); 144848b8605Smrg if (bufObj) 145848b8605Smrg labelPtr = &bufObj->Label; 146848b8605Smrg } 147848b8605Smrg break; 148848b8605Smrg case GL_SHADER: 149848b8605Smrg { 150848b8605Smrg struct gl_shader *shader = _mesa_lookup_shader(ctx, name); 151848b8605Smrg if (shader) 152848b8605Smrg labelPtr = &shader->Label; 153848b8605Smrg } 154848b8605Smrg break; 155848b8605Smrg case GL_PROGRAM: 156848b8605Smrg { 157848b8605Smrg struct gl_shader_program *program = 158848b8605Smrg _mesa_lookup_shader_program(ctx, name); 159848b8605Smrg if (program) 160848b8605Smrg labelPtr = &program->Label; 161848b8605Smrg } 162848b8605Smrg break; 163848b8605Smrg case GL_VERTEX_ARRAY: 164848b8605Smrg { 165848b8605Smrg struct gl_vertex_array_object *obj = _mesa_lookup_vao(ctx, name); 166848b8605Smrg if (obj) 167848b8605Smrg labelPtr = &obj->Label; 168848b8605Smrg } 169848b8605Smrg break; 170848b8605Smrg case GL_QUERY: 171848b8605Smrg { 172848b8605Smrg struct gl_query_object *query = _mesa_lookup_query_object(ctx, name); 173848b8605Smrg if (query) 174848b8605Smrg labelPtr = &query->Label; 175848b8605Smrg } 176848b8605Smrg break; 177848b8605Smrg case GL_TRANSFORM_FEEDBACK: 178848b8605Smrg { 179b8e80941Smrg /* From the GL 4.5 specification, page 536: 180b8e80941Smrg * "An INVALID_VALUE error is generated if name is not the name of a 181b8e80941Smrg * valid object of the type specified by identifier." 182b8e80941Smrg */ 183848b8605Smrg struct gl_transform_feedback_object *tfo = 184848b8605Smrg _mesa_lookup_transform_feedback_object(ctx, name); 185b8e80941Smrg if (tfo && tfo->EverBound) 186848b8605Smrg labelPtr = &tfo->Label; 187848b8605Smrg } 188848b8605Smrg break; 189848b8605Smrg case GL_SAMPLER: 190848b8605Smrg { 191848b8605Smrg struct gl_sampler_object *so = _mesa_lookup_samplerobj(ctx, name); 192848b8605Smrg if (so) 193848b8605Smrg labelPtr = &so->Label; 194848b8605Smrg } 195848b8605Smrg break; 196848b8605Smrg case GL_TEXTURE: 197848b8605Smrg { 198848b8605Smrg struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name); 199b8e80941Smrg if (texObj && texObj->Target) 200848b8605Smrg labelPtr = &texObj->Label; 201848b8605Smrg } 202848b8605Smrg break; 203848b8605Smrg case GL_RENDERBUFFER: 204848b8605Smrg { 205848b8605Smrg struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name); 206848b8605Smrg if (rb) 207848b8605Smrg labelPtr = &rb->Label; 208848b8605Smrg } 209848b8605Smrg break; 210848b8605Smrg case GL_FRAMEBUFFER: 211848b8605Smrg { 212848b8605Smrg struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, name); 213848b8605Smrg if (rb) 214848b8605Smrg labelPtr = &rb->Label; 215848b8605Smrg } 216848b8605Smrg break; 217848b8605Smrg case GL_DISPLAY_LIST: 218848b8605Smrg if (ctx->API == API_OPENGL_COMPAT) { 219848b8605Smrg struct gl_display_list *list = _mesa_lookup_list(ctx, name); 220848b8605Smrg if (list) 221848b8605Smrg labelPtr = &list->Label; 222848b8605Smrg } 223848b8605Smrg else { 224848b8605Smrg goto invalid_enum; 225848b8605Smrg } 226848b8605Smrg break; 227848b8605Smrg case GL_PROGRAM_PIPELINE: 228b8e80941Smrg { 229b8e80941Smrg struct gl_pipeline_object *pipe = 230b8e80941Smrg _mesa_lookup_pipeline_object(ctx, name); 231b8e80941Smrg if (pipe) 232b8e80941Smrg labelPtr = &pipe->Label; 233b8e80941Smrg } 234b8e80941Smrg break; 235848b8605Smrg default: 236848b8605Smrg goto invalid_enum; 237848b8605Smrg } 238848b8605Smrg 239848b8605Smrg if (NULL == labelPtr) { 240848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(name = %u)", caller, name); 241848b8605Smrg } 242848b8605Smrg 243848b8605Smrg return labelPtr; 244848b8605Smrg 245848b8605Smrginvalid_enum: 246848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "%s(identifier = %s)", 247b8e80941Smrg caller, _mesa_enum_to_string(identifier)); 248848b8605Smrg return NULL; 249848b8605Smrg} 250848b8605Smrg 251848b8605Smrgvoid GLAPIENTRY 252848b8605Smrg_mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length, 253848b8605Smrg const GLchar *label) 254848b8605Smrg{ 255848b8605Smrg GET_CURRENT_CONTEXT(ctx); 256b8e80941Smrg const char *callerstr; 257848b8605Smrg char **labelPtr; 258848b8605Smrg 259b8e80941Smrg if (_mesa_is_desktop_gl(ctx)) 260b8e80941Smrg callerstr = "glObjectLabel"; 261b8e80941Smrg else 262b8e80941Smrg callerstr = "glObjectLabelKHR"; 263b8e80941Smrg 264b8e80941Smrg labelPtr = get_label_pointer(ctx, identifier, name, callerstr); 265848b8605Smrg if (!labelPtr) 266848b8605Smrg return; 267848b8605Smrg 268b8e80941Smrg set_label(ctx, labelPtr, label, length, callerstr); 269848b8605Smrg} 270848b8605Smrg 271848b8605Smrgvoid GLAPIENTRY 272848b8605Smrg_mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, 273848b8605Smrg GLsizei *length, GLchar *label) 274848b8605Smrg{ 275848b8605Smrg GET_CURRENT_CONTEXT(ctx); 276b8e80941Smrg const char *callerstr; 277848b8605Smrg char **labelPtr; 278848b8605Smrg 279b8e80941Smrg if (_mesa_is_desktop_gl(ctx)) 280b8e80941Smrg callerstr = "glGetObjectLabel"; 281b8e80941Smrg else 282b8e80941Smrg callerstr = "glGetObjectLabelKHR"; 283b8e80941Smrg 284848b8605Smrg if (bufSize < 0) { 285b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr, 286848b8605Smrg bufSize); 287848b8605Smrg return; 288848b8605Smrg } 289848b8605Smrg 290b8e80941Smrg labelPtr = get_label_pointer(ctx, identifier, name, callerstr); 291848b8605Smrg if (!labelPtr) 292848b8605Smrg return; 293848b8605Smrg 294848b8605Smrg copy_label(*labelPtr, label, length, bufSize); 295848b8605Smrg} 296848b8605Smrg 297848b8605Smrgvoid GLAPIENTRY 298848b8605Smrg_mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) 299848b8605Smrg{ 300848b8605Smrg GET_CURRENT_CONTEXT(ctx); 301b8e80941Smrg struct gl_sync_object *syncObj; 302b8e80941Smrg const char *callerstr; 303848b8605Smrg char **labelPtr; 304848b8605Smrg 305b8e80941Smrg syncObj = _mesa_get_and_ref_sync(ctx, (void*)ptr, true); 306b8e80941Smrg 307b8e80941Smrg if (_mesa_is_desktop_gl(ctx)) 308b8e80941Smrg callerstr = "glObjectPtrLabel"; 309b8e80941Smrg else 310b8e80941Smrg callerstr = "glObjectPtrLabelKHR"; 311b8e80941Smrg 312b8e80941Smrg if (!syncObj) { 313b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)", 314b8e80941Smrg callerstr); 315848b8605Smrg return; 316848b8605Smrg } 317848b8605Smrg 318848b8605Smrg labelPtr = &syncObj->Label; 319848b8605Smrg 320b8e80941Smrg set_label(ctx, labelPtr, label, length, callerstr); 321b8e80941Smrg _mesa_unref_sync_object(ctx, syncObj, 1); 322848b8605Smrg} 323848b8605Smrg 324848b8605Smrgvoid GLAPIENTRY 325848b8605Smrg_mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, 326848b8605Smrg GLchar *label) 327848b8605Smrg{ 328848b8605Smrg GET_CURRENT_CONTEXT(ctx); 329b8e80941Smrg struct gl_sync_object *syncObj; 330b8e80941Smrg const char *callerstr; 331848b8605Smrg char **labelPtr; 332b8e80941Smrg 333b8e80941Smrg if (_mesa_is_desktop_gl(ctx)) 334b8e80941Smrg callerstr = "glGetObjectPtrLabel"; 335b8e80941Smrg else 336b8e80941Smrg callerstr = "glGetObjectPtrLabelKHR"; 337848b8605Smrg 338848b8605Smrg if (bufSize < 0) { 339b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr, 340848b8605Smrg bufSize); 341848b8605Smrg return; 342848b8605Smrg } 343848b8605Smrg 344b8e80941Smrg syncObj = _mesa_get_and_ref_sync(ctx, (void*)ptr, true); 345b8e80941Smrg if (!syncObj) { 346b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)", 347b8e80941Smrg callerstr); 348848b8605Smrg return; 349848b8605Smrg } 350848b8605Smrg 351848b8605Smrg labelPtr = &syncObj->Label; 352848b8605Smrg 353848b8605Smrg copy_label(*labelPtr, label, length, bufSize); 354b8e80941Smrg _mesa_unref_sync_object(ctx, syncObj, 1); 355848b8605Smrg} 356