Merge vk-gl-cts/opengl-cts-4.6.0 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / executor / xeCallQueue.hpp
1 #ifndef _XECALLQUEUE_HPP
2 #define _XECALLQUEUE_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Test Executor
5  * ------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Cross-thread function call dispatcher.
24  *//*--------------------------------------------------------------------*/
25
26 #include "xeDefs.hpp"
27 #include "deMutex.hpp"
28 #include "deSemaphore.hpp"
29 #include "deRingBuffer.hpp"
30
31 #include <vector>
32
33 namespace xe
34 {
35
36 class Call;
37 class CallReader;
38 class CallWriter;
39 class CallQueue;
40
41 // \todo [2012-07-10 pyry] Optimize memory management in Call
42 // \todo [2012-07-10 pyry] CallQueue API could be improved to match TestLog API more closely.
43 //                                                 In order to do that, reference counting system for call object management is needed.
44
45 class Call
46 {
47 public:
48         typedef void (*Function) (CallReader& data);
49
50                                                                 Call                            (void);
51                                                                 ~Call                           (void);
52
53         void                                            clear                           (void);
54
55         Function                                        getFunction                     (void) const    { return m_func;                                }
56         void                                            setFunction                     (Function func) { m_func = func;                                }
57
58         size_t                                          getDataSize                     (void) const    { return m_data.size();                 }
59         void                                            setDataSize                     (size_t size)   { m_data.resize(size);                  }
60
61         const deUint8*                          getData                         (void) const    { return m_data.empty() ? DE_NULL : &m_data[0]; }
62         deUint8*                                        getData                         (void)                  { return m_data.empty() ? DE_NULL : &m_data[0]; }
63
64 private:
65         Function                                        m_func;
66         std::vector<deUint8>            m_data;
67 };
68
69 class CallReader
70 {
71 public:
72                                         CallReader                      (Call* call);
73                                         CallReader                      (void) : m_call(DE_NULL), m_curPos(0) {}
74
75         void                    read                            (deUint8* bytes, size_t numBytes);
76         const deUint8*  getDataBlock            (size_t numBytes);                                      //!< \note Valid only during call.
77         bool                    isDataConsumed          (void) const;                                           //!< all data has been consumed
78
79 private:
80                                         CallReader                      (const CallReader& other);      //!< disallowed
81         CallReader&             operator=                       (const CallReader& other);      //!< disallowed
82
83         Call*                   m_call;
84         size_t                  m_curPos;
85 };
86
87 class CallWriter
88 {
89 public:
90                                         CallWriter                      (CallQueue* queue, Call::Function function);
91                                         ~CallWriter                     (void);
92
93         void                    write                           (const deUint8* bytes, size_t numBytes);
94         void                    enqueue                         (void);
95
96 private:
97                                         CallWriter                      (const CallWriter& other);
98         CallWriter&             operator=                       (const CallWriter& other);
99
100         CallQueue*              m_queue;
101         Call*                   m_call;
102         bool                    m_enqueued;
103 };
104
105 class CallQueue
106 {
107 public:
108                                                         CallQueue                       (void);
109                                                         ~CallQueue                      (void);
110
111         void                                    callNext                        (void); //!< Executes and removes first call in queue. Will block if queue is empty.
112
113         Call*                                   getEmptyCall            (void);
114         void                                    enqueue                         (Call* call);
115         void                                    freeCall                        (Call* call);
116         void                                    cancel                          (void);
117
118 private:
119                                                         CallQueue                       (const CallQueue& other);
120         CallQueue&                              operator=                       (const CallQueue& other);
121
122         bool                                    m_canceled;
123         de::Semaphore                   m_callSem;
124
125         de::Mutex                               m_lock;
126         std::vector<Call*>              m_calls;
127         std::vector<Call*>              m_freeCalls;
128         de::RingBuffer<Call*>   m_callQueue;
129 };
130
131 // Stream operators for call reader / writer.
132
133 CallReader&             operator>>      (CallReader& reader, std::string& value);
134 CallWriter&             operator<<      (CallWriter& writer, const char* str);
135
136 template <typename T>
137 CallReader& operator>> (CallReader& reader, T& value)
138 {
139         reader.read((deUint8*)&value, sizeof(T));
140         return reader;
141 }
142
143 template <typename T>
144 CallWriter& operator<< (CallWriter& writer, T& value)
145 {
146         writer.write((const deUint8*)&value, sizeof(T));
147         return writer;
148 }
149
150 } // xe
151
152 #endif // _XECALLQUEUE_HPP