blob: e0418779b4d16a80d6c1b16ee04363ec32b2f05a [file] [log] [blame]
Jason Sams326e0dd2009-05-22 14:03:28 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
Jason Sams326e0dd2009-05-22 14:03:28 -070018#include "rsThreadIO.h"
Alex Sakhartchouk4edf0302012-03-09 10:47:27 -080019#include "rsgApiStructs.h"
Jason Sams326e0dd2009-05-22 14:03:28 -070020
Jason Sams5f27d6f2012-02-07 15:32:08 -080021#include <unistd.h>
22#include <sys/types.h>
23#include <sys/socket.h>
24
25#include <fcntl.h>
26#include <poll.h>
27
28
Chih-Hung Hsieh11496ac2016-11-15 15:14:05 -080029namespace android {
30namespace renderscript {
Jason Sams326e0dd2009-05-22 14:03:28 -070031
Jason Sams5f27d6f2012-02-07 15:32:08 -080032ThreadIO::ThreadIO() {
33 mRunning = true;
Jason Samsbda75a92012-02-16 17:21:32 -080034 mMaxInlineSize = 1024;
Jason Sams326e0dd2009-05-22 14:03:28 -070035}
36
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080037ThreadIO::~ThreadIO() {
Jason Sams326e0dd2009-05-22 14:03:28 -070038}
39
Yang Ni9ed983b2017-04-18 12:19:01 -070040bool ThreadIO::init() {
41 return mToClient.init() && mToCore.init();
Jason Sams8c0ee652009-08-25 14:49:07 -070042}
43
Jason Sams1a4efa32011-05-17 15:01:29 -070044void ThreadIO::shutdown() {
Jason Sams5f27d6f2012-02-07 15:32:08 -080045 mRunning = false;
Jason Sams1a4efa32011-05-17 15:01:29 -070046 mToCore.shutdown();
Jason Sams1a4efa32011-05-17 15:01:29 -070047}
48
49void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
Steve Blockaf12ac62012-01-06 19:20:56 +000050 //ALOGE("coreHeader %i %i", cmdID, dataLen);
Jason Sams5f27d6f2012-02-07 15:32:08 -080051 CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0];
52 hdr->bytes = dataLen;
53 hdr->cmdID = cmdID;
54 mSendLen = dataLen + sizeof(CoreCmdHeader);
55 //mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
56 //ALOGE("coreHeader ret ");
57 return &mSendBuffer[sizeof(CoreCmdHeader)];
Jason Sams1a4efa32011-05-17 15:01:29 -070058}
59
60void ThreadIO::coreCommit() {
Jason Sams5f27d6f2012-02-07 15:32:08 -080061 mToCore.writeAsync(&mSendBuffer, mSendLen);
Jason Sams1a4efa32011-05-17 15:01:29 -070062}
63
64void ThreadIO::clientShutdown() {
Jason Sams1a4efa32011-05-17 15:01:29 -070065 mToClient.shutdown();
Jason Sams1a4efa32011-05-17 15:01:29 -070066}
67
Jason Samsbda75a92012-02-16 17:21:32 -080068void ThreadIO::coreWrite(const void *data, size_t len) {
69 //ALOGV("core write %p %i", data, (int)len);
70 mToCore.writeAsync(data, len, true);
71}
72
73void ThreadIO::coreRead(void *data, size_t len) {
74 //ALOGV("core read %p %i", data, (int)len);
75 mToCore.read(data, len);
76}
77
Jason Sams1a4efa32011-05-17 15:01:29 -070078void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
Jason Sams5f27d6f2012-02-07 15:32:08 -080079 uint32_t buf;
Chris Wailes44bef6f2014-08-12 13:51:10 -070080 if (data == nullptr) {
Jason Sams5f27d6f2012-02-07 15:32:08 -080081 data = &buf;
82 dataLen = sizeof(buf);
83 }
84
85 mToCore.readReturn(data, dataLen);
Jason Sams1a4efa32011-05-17 15:01:29 -070086}
87
88void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
Jason Sams5f27d6f2012-02-07 15:32:08 -080089 uint32_t buf;
Chris Wailes44bef6f2014-08-12 13:51:10 -070090 if (data == nullptr) {
Jason Sams5f27d6f2012-02-07 15:32:08 -080091 data = &buf;
92 dataLen = sizeof(buf);
93 }
94
95 mToCore.writeWaitReturn(data, dataLen);
Jason Sams1a4efa32011-05-17 15:01:29 -070096}
97
Jason Sams5f27d6f2012-02-07 15:32:08 -080098void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) {
99 //mToCore.setTimeoutCallback(cb, dat, timeout);
Jason Sams2382aba2011-09-13 15:41:01 -0700100}
101
Jason Sams963a2fb2012-02-09 14:36:14 -0800102bool ThreadIO::playCoreCommands(Context *con, int waitFd) {
Jason Samsa44cb292009-06-04 17:58:03 -0700103 bool ret = false;
Jason Samse0aab4a2011-08-12 15:05:15 -0700104
Jason Sams5f27d6f2012-02-07 15:32:08 -0800105 uint8_t buf[2 * 1024];
106 const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0];
107 const void * data = (const void *)&buf[sizeof(CoreCmdHeader)];
108
109 struct pollfd p[2];
110 p[0].fd = mToCore.getReadFd();
111 p[0].events = POLLIN;
112 p[0].revents = 0;
113 p[1].fd = waitFd;
114 p[1].events = POLLIN;
115 p[1].revents = 0;
116 int pollCount = 1;
117 if (waitFd >= 0) {
118 pollCount = 2;
119 }
120
121 if (con->props.mLogTimes) {
122 con->timerSet(Context::RS_TIMER_IDLE);
123 }
124
125 int waitTime = -1;
126 while (mRunning) {
127 int pr = poll(p, pollCount, waitTime);
128 if (pr <= 0) {
129 break;
Joe Onorato76371ff2009-09-23 16:37:36 -0700130 }
Jason Samse0aab4a2011-08-12 15:05:15 -0700131
Jason Sams5f27d6f2012-02-07 15:32:08 -0800132 if (p[0].revents) {
Jason Samsbda75a92012-02-16 17:21:32 -0800133 size_t r = 0;
Matt Walab74514d2015-07-20 14:03:25 -0700134 r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
135 mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
136 if (r != sizeof(CoreCmdHeader)) {
137 // exception or timeout occurred.
138 break;
Jason Sams5f27d6f2012-02-07 15:32:08 -0800139 }
140
141 ret = true;
142 if (con->props.mLogTimes) {
143 con->timerSet(Context::RS_TIMER_INTERNAL);
144 }
Jason Sams5f27d6f2012-02-07 15:32:08 -0800145 //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes);
146
147 if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
148 rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
149 ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID);
150 }
Jason Samsbda75a92012-02-16 17:21:32 -0800151
Matt Walab74514d2015-07-20 14:03:25 -0700152 gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
Jason Sams5f27d6f2012-02-07 15:32:08 -0800153
154 if (con->props.mLogTimes) {
155 con->timerSet(Context::RS_TIMER_IDLE);
156 }
157
158 if (waitFd < 0) {
159 // If we don't have a secondary wait object we should stop blocking now
160 // that at least one command has been processed.
161 waitTime = 0;
Jason Samse0aab4a2011-08-12 15:05:15 -0700162 }
163 }
Stephen Hines36838462012-01-26 17:09:43 -0800164
Jason Sams5f27d6f2012-02-07 15:32:08 -0800165 if (p[1].revents && !p[0].revents) {
166 // We want to finish processing fifo events before processing the vsync.
167 // Otherwise we can end up falling behind and having tremendous lag.
Stephen Hines36838462012-01-26 17:09:43 -0800168 break;
169 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700170 }
Jason Samsa44cb292009-06-04 17:58:03 -0700171 return ret;
Jason Sams326e0dd2009-05-22 14:03:28 -0700172}
173
Jason Sams1a4efa32011-05-17 15:01:29 -0700174RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
Jason Sams5f27d6f2012-02-07 15:32:08 -0800175 //ALOGE("getClientHeader");
176 mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader));
177
Jason Sams1a4efa32011-05-17 15:01:29 -0700178 receiveLen[0] = mLastClientHeader.bytes;
179 usrID[0] = mLastClientHeader.userID;
Jason Sams5f27d6f2012-02-07 15:32:08 -0800180 //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]);
Jason Sams1a4efa32011-05-17 15:01:29 -0700181 return (RsMessageToClientType)mLastClientHeader.cmdID;
182}
183
184RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
185 uint32_t *usrID, size_t bufferLen) {
Jason Sams5f27d6f2012-02-07 15:32:08 -0800186 //ALOGE("getClientPayload");
Jason Sams1a4efa32011-05-17 15:01:29 -0700187 receiveLen[0] = mLastClientHeader.bytes;
188 usrID[0] = mLastClientHeader.userID;
189 if (bufferLen < mLastClientHeader.bytes) {
190 return RS_MESSAGE_TO_CLIENT_RESIZE;
191 }
Jason Sams5f27d6f2012-02-07 15:32:08 -0800192 if (receiveLen[0]) {
193 mToClient.read(data, receiveLen[0]);
Jason Sams1a4efa32011-05-17 15:01:29 -0700194 }
Jason Sams5f27d6f2012-02-07 15:32:08 -0800195 //ALOGE("getClientPayload x");
196 return (RsMessageToClientType)mLastClientHeader.cmdID;
Jason Sams1a4efa32011-05-17 15:01:29 -0700197}
198
199bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
200 size_t dataLen, bool waitForSpace) {
Jason Sams5f27d6f2012-02-07 15:32:08 -0800201
202 //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen);
Jason Sams1a4efa32011-05-17 15:01:29 -0700203 ClientCmdHeader hdr;
Tim Murraye4ed0872014-08-18 16:13:08 -0700204 hdr.bytes = (uint32_t)dataLen;
Jason Sams1a4efa32011-05-17 15:01:29 -0700205 hdr.cmdID = cmdID;
206 hdr.userID = usrID;
Jason Sams1a4efa32011-05-17 15:01:29 -0700207
Jason Sams5f27d6f2012-02-07 15:32:08 -0800208 mToClient.writeAsync(&hdr, sizeof(hdr));
209 if (dataLen) {
210 mToClient.writeAsync(data, dataLen);
Jason Sams1a4efa32011-05-17 15:01:29 -0700211 }
Jason Sams5f27d6f2012-02-07 15:32:08 -0800212
213 //ALOGE("sendToClient x");
214 return true;
Jason Sams1a4efa32011-05-17 15:01:29 -0700215}
Jason Sams326e0dd2009-05-22 14:03:28 -0700216
Chih-Hung Hsieh11496ac2016-11-15 15:14:05 -0800217} // namespace renderscript
218} // namespace android