mesa: Add infrastructure for a worker thread to process GL commands.
[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 /**
85 * A single batch of commands queued up for later execution by a thread pool
86 * task.
87 */
88 struct glthread_batch
89 {
90 /**
91 * Next batch of commands to execute after this batch, or NULL if this is
92 * the last set of commands queued. Protected by ctx->Marshal.Mutex.
93 */
94 struct glthread_batch *next;
95
96 /**
97 * Points to the first command in the batch.
98 */
99 uint8_t *buffer;
100
101 /**
102 * Amount of data used by batch commands, in bytes.
103 */
104 size_t used;
105 };
106
107 void _mesa_glthread_init(struct gl_context *ctx);
108 void _mesa_glthread_destroy(struct gl_context *ctx);
109
110 void _mesa_glthread_flush_batch(struct gl_context *ctx);
111 void _mesa_glthread_finish(struct gl_context *ctx);
112
113 #else /* HAVE_PTHREAD */
114
115 static inline void
116 _mesa_glthread_init(struct gl_context *ctx)
117 {
118 }
119
120 static inline void
121 _mesa_glthread_destroy(struct gl_context *ctx)
122 {
123 }
124
125 static inline void
126 _mesa_glthread_finish(struct gl_context *ctx)
127 {
128 }
129 #endif /* !HAVE_PTHREAD */
130 #endif /* _GLTHREAD_H*/