2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 * Custom functions for marshalling GL calls from the main thread to a worker
27 * thread when automatic code generation isn't appropriate.
30 #include "main/enums.h"
31 #include "main/macros.h"
35 struct marshal_cmd_ShaderSource
37 struct marshal_cmd_base cmd_base
;
40 /* Followed by GLint length[count], then the contents of all strings,
47 _mesa_unmarshal_ShaderSource(struct gl_context
*ctx
,
48 const struct marshal_cmd_ShaderSource
*cmd
)
50 const GLint
*cmd_length
= (const GLint
*) (cmd
+ 1);
51 const GLchar
*cmd_strings
= (const GLchar
*) (cmd_length
+ cmd
->count
);
52 /* TODO: how to deal with malloc failure? */
53 const GLchar
* *string
= malloc(cmd
->count
* sizeof(const GLchar
*));
56 for (i
= 0; i
< cmd
->count
; ++i
) {
57 string
[i
] = cmd_strings
;
58 cmd_strings
+= cmd_length
[i
];
60 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
61 (cmd
->shader
, cmd
->count
, string
, cmd_length
));
67 measure_ShaderSource_strings(GLsizei count
, const GLchar
* const *string
,
68 const GLint
*length_in
, GLint
*length_out
)
71 size_t total_string_length
= 0;
73 for (i
= 0; i
< count
; ++i
) {
74 if (length_in
== NULL
|| length_in
[i
] < 0) {
76 length_out
[i
] = strlen(string
[i
]);
78 length_out
[i
] = length_in
[i
];
80 total_string_length
+= length_out
[i
];
82 return total_string_length
;
87 _mesa_marshal_ShaderSource(GLuint shader
, GLsizei count
,
88 const GLchar
* const *string
, const GLint
*length
)
90 /* TODO: how to report an error if count < 0? */
92 GET_CURRENT_CONTEXT(ctx
);
93 /* TODO: how to deal with malloc failure? */
94 const size_t fixed_cmd_size
= sizeof(struct marshal_cmd_ShaderSource
);
95 STATIC_ASSERT(sizeof(struct marshal_cmd_ShaderSource
) % sizeof(GLint
) == 0);
96 size_t length_size
= count
* sizeof(GLint
);
97 GLint
*length_tmp
= malloc(length_size
);
98 size_t total_string_length
=
99 measure_ShaderSource_strings(count
, string
, length
, length_tmp
);
100 size_t total_cmd_size
= fixed_cmd_size
+ length_size
+ total_string_length
;
102 if (total_cmd_size
<= MARSHAL_MAX_CMD_SIZE
&& count
> 0) {
103 struct marshal_cmd_ShaderSource
*cmd
=
104 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_ShaderSource
,
106 GLint
*cmd_length
= (GLint
*) (cmd
+ 1);
107 GLchar
*cmd_strings
= (GLchar
*) (cmd_length
+ count
);
110 cmd
->shader
= shader
;
112 memcpy(cmd_length
, length_tmp
, length_size
);
113 for (i
= 0; i
< count
; ++i
) {
114 memcpy(cmd_strings
, string
[i
], cmd_length
[i
]);
115 cmd_strings
+= cmd_length
[i
];
118 _mesa_glthread_finish(ctx
);
119 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
120 (shader
, count
, string
, length_tmp
));