xref: /third_party/mesa3d/src/mesa/main/objectlabel.c (revision bf215546)
1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 2013  Timothy Arceri   All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
12bf215546Sopenharmony_ci *
13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "arrayobj.h"
27bf215546Sopenharmony_ci#include "bufferobj.h"
28bf215546Sopenharmony_ci#include "context.h"
29bf215546Sopenharmony_ci#include "dlist.h"
30bf215546Sopenharmony_ci#include "enums.h"
31bf215546Sopenharmony_ci#include "fbobject.h"
32bf215546Sopenharmony_ci#include "pipelineobj.h"
33bf215546Sopenharmony_ci#include "queryobj.h"
34bf215546Sopenharmony_ci#include "samplerobj.h"
35bf215546Sopenharmony_ci#include "shaderobj.h"
36bf215546Sopenharmony_ci#include "syncobj.h"
37bf215546Sopenharmony_ci#include "texobj.h"
38bf215546Sopenharmony_ci#include "transformfeedback.h"
39bf215546Sopenharmony_ci#include "api_exec_decl.h"
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci/**
43bf215546Sopenharmony_ci * Helper for _mesa_ObjectLabel() and _mesa_ObjectPtrLabel().
44bf215546Sopenharmony_ci */
45bf215546Sopenharmony_cistatic void
46bf215546Sopenharmony_ciset_label(struct gl_context *ctx, char **labelPtr, const char *label,
47bf215546Sopenharmony_ci          int length, const char *caller)
48bf215546Sopenharmony_ci{
49bf215546Sopenharmony_ci   free(*labelPtr);
50bf215546Sopenharmony_ci   *labelPtr = NULL;
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   /* set new label string */
53bf215546Sopenharmony_ci   if (label) {
54bf215546Sopenharmony_ci      if (length >= 0) {
55bf215546Sopenharmony_ci         if (length >= MAX_LABEL_LENGTH)
56bf215546Sopenharmony_ci            _mesa_error(ctx, GL_INVALID_VALUE,
57bf215546Sopenharmony_ci                        "%s(length=%d, which is not less than "
58bf215546Sopenharmony_ci                        "GL_MAX_LABEL_LENGTH=%d)", caller, length,
59bf215546Sopenharmony_ci                        MAX_LABEL_LENGTH);
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci         /* explicit length */
62bf215546Sopenharmony_ci         *labelPtr = malloc(length+1);
63bf215546Sopenharmony_ci         if (*labelPtr) {
64bf215546Sopenharmony_ci            memcpy(*labelPtr, label, length);
65bf215546Sopenharmony_ci            /* length is not required to include the null terminator so
66bf215546Sopenharmony_ci             * add one just in case
67bf215546Sopenharmony_ci             */
68bf215546Sopenharmony_ci            (*labelPtr)[length] = '\0';
69bf215546Sopenharmony_ci         }
70bf215546Sopenharmony_ci      }
71bf215546Sopenharmony_ci      else {
72bf215546Sopenharmony_ci         int len = strlen(label);
73bf215546Sopenharmony_ci         if (len >= MAX_LABEL_LENGTH)
74bf215546Sopenharmony_ci            _mesa_error(ctx, GL_INVALID_VALUE,
75bf215546Sopenharmony_ci                "%s(label length=%d, which is not less than "
76bf215546Sopenharmony_ci                "GL_MAX_LABEL_LENGTH=%d)", caller, len,
77bf215546Sopenharmony_ci                MAX_LABEL_LENGTH);
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci         /* null-terminated string */
80bf215546Sopenharmony_ci         *labelPtr = strdup(label);
81bf215546Sopenharmony_ci      }
82bf215546Sopenharmony_ci   }
83bf215546Sopenharmony_ci}
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci/**
86bf215546Sopenharmony_ci * Helper for _mesa_GetObjectLabel() and _mesa_GetObjectPtrLabel().
87bf215546Sopenharmony_ci * \param src  the src label (may be null)
88bf215546Sopenharmony_ci * \param dst  pointer to dest buffer (may be null)
89bf215546Sopenharmony_ci * \param length  returns length of label (may be null)
90bf215546Sopenharmony_ci * \param bufsize  size of dst buffer
91bf215546Sopenharmony_ci */
92bf215546Sopenharmony_cistatic void
93bf215546Sopenharmony_cicopy_label(const GLchar *src, GLchar *dst, GLsizei *length, GLsizei bufSize)
94bf215546Sopenharmony_ci{
95bf215546Sopenharmony_ci   int labelLen = 0;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   /* From http://www.opengl.org/registry/specs/KHR/debug.txt:
98bf215546Sopenharmony_ci    * "If <length> is NULL, no length is returned. The maximum number of
99bf215546Sopenharmony_ci    * characters that may be written into <label>, including the null
100bf215546Sopenharmony_ci    * terminator, is specified by <bufSize>. If no debug label was specified
101bf215546Sopenharmony_ci    * for the object then <label> will contain a null-terminated empty string,
102bf215546Sopenharmony_ci    * and zero will be returned in <length>. If <label> is NULL and <length>
103bf215546Sopenharmony_ci    * is non-NULL then no string will be returned and the length of the label
104bf215546Sopenharmony_ci    * will be returned in <length>."
105bf215546Sopenharmony_ci    */
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   if (src)
108bf215546Sopenharmony_ci      labelLen = strlen(src);
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   if (bufSize == 0) {
111bf215546Sopenharmony_ci      if (length)
112bf215546Sopenharmony_ci         *length = labelLen;
113bf215546Sopenharmony_ci      return;
114bf215546Sopenharmony_ci   }
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   if (dst) {
117bf215546Sopenharmony_ci      if (src) {
118bf215546Sopenharmony_ci         if (bufSize <= labelLen)
119bf215546Sopenharmony_ci            labelLen = bufSize - 1;
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci         memcpy(dst, src, labelLen);
122bf215546Sopenharmony_ci      }
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci      dst[labelLen] = '\0';
125bf215546Sopenharmony_ci   }
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci   if (length)
128bf215546Sopenharmony_ci      *length = labelLen;
129bf215546Sopenharmony_ci}
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci/**
132bf215546Sopenharmony_ci * Helper for _mesa_ObjectLabel() and _mesa_GetObjectLabel().
133bf215546Sopenharmony_ci */
134bf215546Sopenharmony_cistatic char **
135bf215546Sopenharmony_ciget_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name,
136bf215546Sopenharmony_ci                  const char *caller)
137bf215546Sopenharmony_ci{
138bf215546Sopenharmony_ci   char **labelPtr = NULL;
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci   switch (identifier) {
141bf215546Sopenharmony_ci   case GL_BUFFER:
142bf215546Sopenharmony_ci      {
143bf215546Sopenharmony_ci         struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, name);
144bf215546Sopenharmony_ci         if (bufObj)
145bf215546Sopenharmony_ci            labelPtr = &bufObj->Label;
146bf215546Sopenharmony_ci      }
147bf215546Sopenharmony_ci      break;
148bf215546Sopenharmony_ci   case GL_SHADER:
149bf215546Sopenharmony_ci      {
150bf215546Sopenharmony_ci         struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
151bf215546Sopenharmony_ci         if (shader)
152bf215546Sopenharmony_ci            labelPtr = &shader->Label;
153bf215546Sopenharmony_ci      }
154bf215546Sopenharmony_ci      break;
155bf215546Sopenharmony_ci   case GL_PROGRAM:
156bf215546Sopenharmony_ci      {
157bf215546Sopenharmony_ci         struct gl_shader_program *program =
158bf215546Sopenharmony_ci            _mesa_lookup_shader_program(ctx, name);
159bf215546Sopenharmony_ci         if (program)
160bf215546Sopenharmony_ci            labelPtr = &program->Label;
161bf215546Sopenharmony_ci      }
162bf215546Sopenharmony_ci      break;
163bf215546Sopenharmony_ci   case GL_VERTEX_ARRAY:
164bf215546Sopenharmony_ci      {
165bf215546Sopenharmony_ci         struct gl_vertex_array_object *obj = _mesa_lookup_vao(ctx, name);
166bf215546Sopenharmony_ci         if (obj)
167bf215546Sopenharmony_ci            labelPtr = &obj->Label;
168bf215546Sopenharmony_ci      }
169bf215546Sopenharmony_ci      break;
170bf215546Sopenharmony_ci   case GL_QUERY:
171bf215546Sopenharmony_ci      {
172bf215546Sopenharmony_ci         struct gl_query_object *query = _mesa_lookup_query_object(ctx, name);
173bf215546Sopenharmony_ci         if (query)
174bf215546Sopenharmony_ci            labelPtr = &query->Label;
175bf215546Sopenharmony_ci      }
176bf215546Sopenharmony_ci      break;
177bf215546Sopenharmony_ci   case GL_TRANSFORM_FEEDBACK:
178bf215546Sopenharmony_ci      {
179bf215546Sopenharmony_ci         /* From the GL 4.5 specification, page 536:
180bf215546Sopenharmony_ci          * "An INVALID_VALUE error is generated if name is not the name of a
181bf215546Sopenharmony_ci          *  valid object of the type specified by identifier."
182bf215546Sopenharmony_ci          */
183bf215546Sopenharmony_ci         struct gl_transform_feedback_object *tfo =
184bf215546Sopenharmony_ci            _mesa_lookup_transform_feedback_object(ctx, name);
185bf215546Sopenharmony_ci         if (tfo && tfo->EverBound)
186bf215546Sopenharmony_ci            labelPtr = &tfo->Label;
187bf215546Sopenharmony_ci      }
188bf215546Sopenharmony_ci      break;
189bf215546Sopenharmony_ci   case GL_SAMPLER:
190bf215546Sopenharmony_ci      {
191bf215546Sopenharmony_ci         struct gl_sampler_object *so = _mesa_lookup_samplerobj(ctx, name);
192bf215546Sopenharmony_ci         if (so)
193bf215546Sopenharmony_ci            labelPtr = &so->Label;
194bf215546Sopenharmony_ci      }
195bf215546Sopenharmony_ci      break;
196bf215546Sopenharmony_ci   case GL_TEXTURE:
197bf215546Sopenharmony_ci      {
198bf215546Sopenharmony_ci         struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name);
199bf215546Sopenharmony_ci         if (texObj && texObj->Target)
200bf215546Sopenharmony_ci            labelPtr = &texObj->Label;
201bf215546Sopenharmony_ci      }
202bf215546Sopenharmony_ci      break;
203bf215546Sopenharmony_ci   case GL_RENDERBUFFER:
204bf215546Sopenharmony_ci      {
205bf215546Sopenharmony_ci         struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
206bf215546Sopenharmony_ci         if (rb)
207bf215546Sopenharmony_ci            labelPtr = &rb->Label;
208bf215546Sopenharmony_ci      }
209bf215546Sopenharmony_ci      break;
210bf215546Sopenharmony_ci   case GL_FRAMEBUFFER:
211bf215546Sopenharmony_ci      {
212bf215546Sopenharmony_ci         struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, name);
213bf215546Sopenharmony_ci         if (rb)
214bf215546Sopenharmony_ci            labelPtr = &rb->Label;
215bf215546Sopenharmony_ci      }
216bf215546Sopenharmony_ci      break;
217bf215546Sopenharmony_ci   case GL_DISPLAY_LIST:
218bf215546Sopenharmony_ci      if (ctx->API == API_OPENGL_COMPAT) {
219bf215546Sopenharmony_ci         struct gl_display_list *list = _mesa_lookup_list(ctx, name, false);
220bf215546Sopenharmony_ci         if (list)
221bf215546Sopenharmony_ci            labelPtr = &list->Label;
222bf215546Sopenharmony_ci      }
223bf215546Sopenharmony_ci      else {
224bf215546Sopenharmony_ci         goto invalid_enum;
225bf215546Sopenharmony_ci      }
226bf215546Sopenharmony_ci      break;
227bf215546Sopenharmony_ci   case GL_PROGRAM_PIPELINE:
228bf215546Sopenharmony_ci      {
229bf215546Sopenharmony_ci         struct gl_pipeline_object *pipe =
230bf215546Sopenharmony_ci            _mesa_lookup_pipeline_object(ctx, name);
231bf215546Sopenharmony_ci         if (pipe)
232bf215546Sopenharmony_ci            labelPtr = &pipe->Label;
233bf215546Sopenharmony_ci      }
234bf215546Sopenharmony_ci      break;
235bf215546Sopenharmony_ci   default:
236bf215546Sopenharmony_ci      goto invalid_enum;
237bf215546Sopenharmony_ci   }
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   if (NULL == labelPtr) {
240bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "%s(name = %u)", caller, name);
241bf215546Sopenharmony_ci   }
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci   return labelPtr;
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ciinvalid_enum:
246bf215546Sopenharmony_ci   _mesa_error(ctx, GL_INVALID_ENUM, "%s(identifier = %s)",
247bf215546Sopenharmony_ci               caller, _mesa_enum_to_string(identifier));
248bf215546Sopenharmony_ci   return NULL;
249bf215546Sopenharmony_ci}
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_civoid GLAPIENTRY
252bf215546Sopenharmony_ci_mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length,
253bf215546Sopenharmony_ci                  const GLchar *label)
254bf215546Sopenharmony_ci{
255bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
256bf215546Sopenharmony_ci   const char *callerstr;
257bf215546Sopenharmony_ci   char **labelPtr;
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_ci   if (_mesa_is_desktop_gl(ctx))
260bf215546Sopenharmony_ci      callerstr = "glObjectLabel";
261bf215546Sopenharmony_ci   else
262bf215546Sopenharmony_ci      callerstr = "glObjectLabelKHR";
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci   labelPtr = get_label_pointer(ctx, identifier, name, callerstr);
265bf215546Sopenharmony_ci   if (!labelPtr)
266bf215546Sopenharmony_ci      return;
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   set_label(ctx, labelPtr, label, length, callerstr);
269bf215546Sopenharmony_ci}
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_civoid GLAPIENTRY
272bf215546Sopenharmony_ci_mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
273bf215546Sopenharmony_ci                     GLsizei *length, GLchar *label)
274bf215546Sopenharmony_ci{
275bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
276bf215546Sopenharmony_ci   const char *callerstr;
277bf215546Sopenharmony_ci   char **labelPtr;
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   if (_mesa_is_desktop_gl(ctx))
280bf215546Sopenharmony_ci      callerstr = "glGetObjectLabel";
281bf215546Sopenharmony_ci   else
282bf215546Sopenharmony_ci      callerstr = "glGetObjectLabelKHR";
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   if (bufSize < 0) {
285bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr,
286bf215546Sopenharmony_ci                  bufSize);
287bf215546Sopenharmony_ci      return;
288bf215546Sopenharmony_ci   }
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   labelPtr = get_label_pointer(ctx, identifier, name, callerstr);
291bf215546Sopenharmony_ci   if (!labelPtr)
292bf215546Sopenharmony_ci      return;
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci   copy_label(*labelPtr, label, length, bufSize);
295bf215546Sopenharmony_ci}
296bf215546Sopenharmony_ci
297bf215546Sopenharmony_civoid GLAPIENTRY
298bf215546Sopenharmony_ci_mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
299bf215546Sopenharmony_ci{
300bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
301bf215546Sopenharmony_ci   struct gl_sync_object *syncObj;
302bf215546Sopenharmony_ci   const char *callerstr;
303bf215546Sopenharmony_ci   char **labelPtr;
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci   syncObj = _mesa_get_and_ref_sync(ctx, (void*)ptr, true);
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci   if (_mesa_is_desktop_gl(ctx))
308bf215546Sopenharmony_ci      callerstr = "glObjectPtrLabel";
309bf215546Sopenharmony_ci   else
310bf215546Sopenharmony_ci      callerstr = "glObjectPtrLabelKHR";
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci   if (!syncObj) {
313bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)",
314bf215546Sopenharmony_ci                  callerstr);
315bf215546Sopenharmony_ci      return;
316bf215546Sopenharmony_ci   }
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci   labelPtr = &syncObj->Label;
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci   set_label(ctx, labelPtr, label, length, callerstr);
321bf215546Sopenharmony_ci   _mesa_unref_sync_object(ctx, syncObj, 1);
322bf215546Sopenharmony_ci}
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_civoid GLAPIENTRY
325bf215546Sopenharmony_ci_mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length,
326bf215546Sopenharmony_ci                        GLchar *label)
327bf215546Sopenharmony_ci{
328bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
329bf215546Sopenharmony_ci   struct gl_sync_object *syncObj;
330bf215546Sopenharmony_ci   const char *callerstr;
331bf215546Sopenharmony_ci   char **labelPtr;
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci   if (_mesa_is_desktop_gl(ctx))
334bf215546Sopenharmony_ci      callerstr = "glGetObjectPtrLabel";
335bf215546Sopenharmony_ci   else
336bf215546Sopenharmony_ci      callerstr = "glGetObjectPtrLabelKHR";
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci   if (bufSize < 0) {
339bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr,
340bf215546Sopenharmony_ci                  bufSize);
341bf215546Sopenharmony_ci      return;
342bf215546Sopenharmony_ci   }
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci   syncObj = _mesa_get_and_ref_sync(ctx, (void*)ptr, true);
345bf215546Sopenharmony_ci   if (!syncObj) {
346bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)",
347bf215546Sopenharmony_ci                  callerstr);
348bf215546Sopenharmony_ci      return;
349bf215546Sopenharmony_ci   }
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci   labelPtr = &syncObj->Label;
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci   copy_label(*labelPtr, label, length, bufSize);
354bf215546Sopenharmony_ci   _mesa_unref_sync_object(ctx, syncObj, 1);
355bf215546Sopenharmony_ci}
356