04eb5ffabc46fcea7fef1f57f40fe014705b964a
[mesa.git] / src / mesa / main / glthread.h
1 /*
2 * Copyright © 2012 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 */
23
24 #ifndef _GLTHREAD_H
25 #define _GLTHREAD_H
26
27 #ifdef HAVE_PTHREAD
28
29 #include <inttypes.h>
30 #include <stdbool.h>
31 #include <pthread.h>
32 #include "main/mtypes.h"
33
34 enum marshal_dispatch_cmd_id;
35
36 /* Command size is a number of bytes stored in a short. */
37 #define MARSHAL_MAX_CMD_SIZE 65535
38
39 struct glthread_state
40 {
41 /** The worker thread that asynchronously processes our GL commands. */
42 pthread_t thread;
43
44 /**
45 * Mutex used for synchronizing between the main thread and the worker
46 * thread.
47 */
48 pthread_mutex_t mutex;
49
50 /** Condvar used for waking the worker thread. */
51 pthread_cond_t new_work;
52
53 /** Condvar used for waking the main thread. */
54 pthread_cond_t work_done;
55
56 /** Used to tell the worker thread to quit */
57 bool shutdown;
58
59 /** Indicates that the worker thread is currently processing a batch */
60 bool busy;
61
62 /**
63 * Singly-linked list of command batches that are awaiting execution by
64 * a thread pool task. NULL if empty.
65 */
66 struct glthread_batch *batch_queue;
67
68 /**
69 * Tail pointer for appending batches to the end of batch_queue. If the
70 * queue is empty, this points to batch_queue.
71 */
72 struct glthread_batch **batch_queue_tail;
73
74 /**
75 * Batch containing commands that are being prepared for insertion into
76 * batch_queue. NULL if there are no such commands.
77 *
78 * Since this is only used by the main thread, it doesn't need the mutex to
79 * be accessed.
80 */
81 struct glthread_batch *batch;
82
83 /**
84 * Tracks on the main thread side whether the current vertex array binding
85 * is in a VBO.
86 */
87 bool vertex_array_is_vbo;
88
89 /**
90 * Tracks on the main thread side whether the current element array (index
91 * buffer) binding is in a VBO.
92 */
93 bool element_array_is_vbo;
94 };
95
96 /**
97 * A single batch of commands queued up for later execution by a thread pool
98 * task.
99 */
100 struct glthread_batch
101 {
102 /**
103 * Next batch of commands to execute after this batch, or NULL if this is
104 * the last set of commands queued. Protected by ctx->Marshal.Mutex.
105 */
106 struct glthread_batch *next;
107
108 /**
109 * Amount of data used by batch commands, in bytes.
110 */
111 size_t used;
112
113 /**
114 * Data contained in the command buffer.
115 */
116 uint8_t buffer[MARSHAL_MAX_CMD_SIZE];
117 };
118
119 void _mesa_glthread_init(struct gl_context *ctx);
120 void _mesa_glthread_destroy(struct gl_context *ctx);
121
122 void _mesa_glthread_flush_batch(struct gl_context *ctx);
123 void _mesa_glthread_finish(struct gl_context *ctx);
124
125 #else /* HAVE_PTHREAD */
126
127 static inline void
128 _mesa_glthread_init(struct gl_context *ctx)
129 {
130 }
131
132 static inline void
133 _mesa_glthread_destroy(struct gl_context *ctx)
134 {
135 }
136
137 static inline void
138 _mesa_glthread_finish(struct gl_context *ctx)
139 {
140 }
141 #endif /* !HAVE_PTHREAD */
142 #endif /* _GLTHREAD_H*/