Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 1 | /* |
| 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" |
| 18 | |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 19 | #include "rsThreadIO.h" |
| 20 | |
| 21 | using namespace android; |
| 22 | using namespace android::renderscript; |
| 23 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 24 | ThreadIO::ThreadIO() { |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 25 | mToCore.init(16 * 1024); |
| 26 | } |
| 27 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 28 | ThreadIO::~ThreadIO() { |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 29 | } |
| 30 | |
Jason Sams | edbfabd | 2011-05-17 15:01:29 -0700 | [diff] [blame^] | 31 | void ThreadIO::init(bool useSocket) { |
| 32 | mUsingSocket = useSocket; |
| 33 | |
| 34 | if (mUsingSocket) { |
| 35 | mToClientSocket.init(); |
| 36 | mToCoreSocket.init(); |
| 37 | } else { |
| 38 | mToClient.init(1024); |
| 39 | } |
Jason Sams | f5b4596 | 2009-08-25 14:49:07 -0700 | [diff] [blame] | 40 | } |
| 41 | |
Jason Sams | edbfabd | 2011-05-17 15:01:29 -0700 | [diff] [blame^] | 42 | void ThreadIO::shutdown() { |
| 43 | //LOGE("shutdown 1"); |
| 44 | mToCore.shutdown(); |
| 45 | //LOGE("shutdown 2"); |
| 46 | } |
| 47 | |
| 48 | void ThreadIO::coreFlush() { |
| 49 | //LOGE("coreFlush 1"); |
| 50 | if (mUsingSocket) { |
| 51 | } else { |
| 52 | mToCore.flush(); |
| 53 | } |
| 54 | //LOGE("coreFlush 2"); |
| 55 | } |
| 56 | |
| 57 | void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) { |
| 58 | //LOGE("coreHeader %i %i", cmdID, dataLen); |
| 59 | if (mUsingSocket) { |
| 60 | CoreCmdHeader hdr; |
| 61 | hdr.bytes = dataLen; |
| 62 | hdr.cmdID = cmdID; |
| 63 | mToCoreSocket.writeAsync(&hdr, sizeof(hdr)); |
| 64 | } else { |
| 65 | mCoreCommandSize = dataLen; |
| 66 | mCoreCommandID = cmdID; |
| 67 | mCoreDataPtr = (uint8_t *)mToCore.reserve(dataLen); |
| 68 | mCoreDataBasePtr = mCoreDataPtr; |
| 69 | } |
| 70 | //LOGE("coreHeader ret %p", mCoreDataPtr); |
| 71 | return mCoreDataPtr; |
| 72 | } |
| 73 | |
| 74 | void ThreadIO::coreData(const void *data, size_t dataLen) { |
| 75 | //LOGE("coreData %p %i", data, dataLen); |
| 76 | mToCoreSocket.writeAsync(data, dataLen); |
| 77 | //LOGE("coreData ret %p", mCoreDataPtr); |
| 78 | } |
| 79 | |
| 80 | void ThreadIO::coreCommit() { |
| 81 | //LOGE("coreCommit %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize); |
| 82 | if (mUsingSocket) { |
| 83 | } else { |
| 84 | rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize); |
| 85 | mToCore.commit(mCoreCommandID, mCoreCommandSize); |
| 86 | } |
| 87 | //LOGE("coreCommit ret"); |
| 88 | } |
| 89 | |
| 90 | void ThreadIO::coreCommitSync() { |
| 91 | //LOGE("coreCommitSync %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize); |
| 92 | if (mUsingSocket) { |
| 93 | } else { |
| 94 | rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize); |
| 95 | mToCore.commitSync(mCoreCommandID, mCoreCommandSize); |
| 96 | } |
| 97 | //LOGE("coreCommitSync ret"); |
| 98 | } |
| 99 | |
| 100 | void ThreadIO::clientShutdown() { |
| 101 | //LOGE("coreShutdown 1"); |
| 102 | mToClient.shutdown(); |
| 103 | //LOGE("coreShutdown 2"); |
| 104 | } |
| 105 | |
| 106 | void ThreadIO::coreSetReturn(const void *data, size_t dataLen) { |
| 107 | rsAssert(dataLen <= sizeof(mToCoreRet)); |
| 108 | memcpy(&mToCoreRet, data, dataLen); |
| 109 | } |
| 110 | |
| 111 | void ThreadIO::coreGetReturn(void *data, size_t dataLen) { |
| 112 | memcpy(data, &mToCoreRet, dataLen); |
| 113 | } |
| 114 | |
| 115 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 116 | bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { |
Jason Sams | a09f11d | 2009-06-04 17:58:03 -0700 | [diff] [blame] | 117 | bool ret = false; |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 118 | while (!mToCore.isEmpty() || waitForCommand) { |
Jason Sams | f4d1606 | 2009-08-19 12:17:14 -0700 | [diff] [blame] | 119 | uint32_t cmdID = 0; |
| 120 | uint32_t cmdSize = 0; |
Jason Sams | a09f11d | 2009-06-04 17:58:03 -0700 | [diff] [blame] | 121 | ret = true; |
Jason Sams | 66b2771 | 2009-09-25 15:25:00 -0700 | [diff] [blame] | 122 | if (con->props.mLogTimes) { |
Joe Onorato | 9ac2c66 | 2009-09-23 16:37:36 -0700 | [diff] [blame] | 123 | con->timerSet(Context::RS_TIMER_IDLE); |
| 124 | } |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 125 | const void * data = mToCore.get(&cmdID, &cmdSize); |
Jason Sams | a9e7a05 | 2009-09-25 14:51:22 -0700 | [diff] [blame] | 126 | if (!cmdSize) { |
| 127 | // exception occured, probably shutdown. |
| 128 | return false; |
| 129 | } |
Jason Sams | 66b2771 | 2009-09-25 15:25:00 -0700 | [diff] [blame] | 130 | if (con->props.mLogTimes) { |
Joe Onorato | 9ac2c66 | 2009-09-23 16:37:36 -0700 | [diff] [blame] | 131 | con->timerSet(Context::RS_TIMER_INTERNAL); |
| 132 | } |
Jason Sams | 5f7fc27 | 2009-06-18 16:58:42 -0700 | [diff] [blame] | 133 | waitForCommand = false; |
Jason Sams | f29ca50 | 2009-06-23 12:22:47 -0700 | [diff] [blame] | 134 | //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize); |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 135 | |
Jason Sams | 300406a | 2011-01-16 14:54:28 -0800 | [diff] [blame] | 136 | if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { |
| 137 | rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); |
| 138 | LOGE("playCoreCommands error con %p, cmd %i", con, cmdID); |
Jason Sams | d1ac981 | 2011-01-18 18:12:26 -0800 | [diff] [blame] | 139 | mToCore.printDebugData(); |
Jason Sams | 300406a | 2011-01-16 14:54:28 -0800 | [diff] [blame] | 140 | } |
Jason Sams | a08526a | 2011-04-27 15:12:49 -0700 | [diff] [blame] | 141 | gPlaybackFuncs[cmdID](con, data, cmdSize << 2); |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 142 | mToCore.next(); |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 143 | } |
Jason Sams | a09f11d | 2009-06-04 17:58:03 -0700 | [diff] [blame] | 144 | return ret; |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 145 | } |
| 146 | |
Jason Sams | edbfabd | 2011-05-17 15:01:29 -0700 | [diff] [blame^] | 147 | RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) { |
| 148 | if (mUsingSocket) { |
| 149 | mToClientSocket.read(&mLastClientHeader, sizeof(mLastClientHeader)); |
| 150 | } else { |
| 151 | size_t bytesData = 0; |
| 152 | const uint32_t *d = (const uint32_t *)mToClient.get(&mLastClientHeader.cmdID, &bytesData); |
| 153 | if (bytesData >= sizeof(uint32_t)) { |
| 154 | mLastClientHeader.userID = d[0]; |
| 155 | mLastClientHeader.bytes = bytesData - sizeof(uint32_t); |
| 156 | } else { |
| 157 | mLastClientHeader.userID = 0; |
| 158 | mLastClientHeader.bytes = 0; |
| 159 | } |
| 160 | } |
| 161 | receiveLen[0] = mLastClientHeader.bytes; |
| 162 | usrID[0] = mLastClientHeader.userID; |
| 163 | return (RsMessageToClientType)mLastClientHeader.cmdID; |
| 164 | } |
| 165 | |
| 166 | RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen, |
| 167 | uint32_t *usrID, size_t bufferLen) { |
| 168 | receiveLen[0] = mLastClientHeader.bytes; |
| 169 | usrID[0] = mLastClientHeader.userID; |
| 170 | if (bufferLen < mLastClientHeader.bytes) { |
| 171 | return RS_MESSAGE_TO_CLIENT_RESIZE; |
| 172 | } |
| 173 | if (mUsingSocket) { |
| 174 | if (receiveLen[0]) { |
| 175 | mToClientSocket.read(data, receiveLen[0]); |
| 176 | } |
| 177 | return (RsMessageToClientType)mLastClientHeader.cmdID; |
| 178 | } else { |
| 179 | uint32_t bytesData = 0; |
| 180 | uint32_t commandID = 0; |
| 181 | const uint32_t *d = (const uint32_t *)mToClient.get(&commandID, &bytesData); |
| 182 | //LOGE("getMessageToClient 3 %i %i", commandID, bytesData); |
| 183 | //LOGE("getMessageToClient %i %i", commandID, *subID); |
| 184 | if (bufferLen >= receiveLen[0]) { |
| 185 | memcpy(data, d+1, receiveLen[0]); |
| 186 | mToClient.next(); |
| 187 | return (RsMessageToClientType)commandID; |
| 188 | } |
| 189 | } |
| 190 | return RS_MESSAGE_TO_CLIENT_RESIZE; |
| 191 | } |
| 192 | |
| 193 | bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data, |
| 194 | size_t dataLen, bool waitForSpace) { |
| 195 | ClientCmdHeader hdr; |
| 196 | hdr.bytes = dataLen; |
| 197 | hdr.cmdID = cmdID; |
| 198 | hdr.userID = usrID; |
| 199 | if (mUsingSocket) { |
| 200 | mToClientSocket.writeAsync(&hdr, sizeof(hdr)); |
| 201 | if (dataLen) { |
| 202 | mToClientSocket.writeAsync(data, dataLen); |
| 203 | } |
| 204 | return true; |
| 205 | } else { |
| 206 | if (!waitForSpace) { |
| 207 | if (!mToClient.makeSpaceNonBlocking(dataLen + sizeof(hdr))) { |
| 208 | // Not enough room, and not waiting. |
| 209 | return false; |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | //LOGE("sendMessageToClient 2"); |
| 214 | uint32_t *p = (uint32_t *)mToClient.reserve(dataLen + sizeof(usrID)); |
| 215 | p[0] = usrID; |
| 216 | if (dataLen > 0) { |
| 217 | memcpy(p+1, data, dataLen); |
| 218 | } |
| 219 | mToClient.commit(cmdID, dataLen + sizeof(usrID)); |
| 220 | //LOGE("sendMessageToClient 3"); |
| 221 | return true; |
| 222 | } |
| 223 | return false; |
| 224 | } |
Jason Sams | d19f10d | 2009-05-22 14:03:28 -0700 | [diff] [blame] | 225 | |