rsThreadIO.cpp revision 6b0c00414a532e2ea22f66cf89578cc8c8a45293
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 19#include "rsThreadIO.h" 20 21using namespace android; 22using namespace android::renderscript; 23 24ThreadIO::ThreadIO() : mUsingSocket(false) { 25} 26 27ThreadIO::~ThreadIO() { 28} 29 30void ThreadIO::init(bool useSocket) { 31 mUsingSocket = useSocket; 32 mToCore.init(16 * 1024); 33 34 if (mUsingSocket) { 35 mToClientSocket.init(); 36 mToCoreSocket.init(); 37 } else { 38 mToClient.init(1024); 39 } 40} 41 42void ThreadIO::shutdown() { 43 //LOGE("shutdown 1"); 44 mToCore.shutdown(); 45 //LOGE("shutdown 2"); 46} 47 48void ThreadIO::coreFlush() { 49 //LOGE("coreFlush 1"); 50 if (mUsingSocket) { 51 } else { 52 mToCore.flush(); 53 } 54 //LOGE("coreFlush 2"); 55} 56 57void * 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 74void 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 80void 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 90void 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 100void ThreadIO::clientShutdown() { 101 //LOGE("coreShutdown 1"); 102 mToClient.shutdown(); 103 //LOGE("coreShutdown 2"); 104} 105 106void ThreadIO::coreSetReturn(const void *data, size_t dataLen) { 107 rsAssert(dataLen <= sizeof(mToCoreRet)); 108 memcpy(&mToCoreRet, data, dataLen); 109} 110 111void ThreadIO::coreGetReturn(void *data, size_t dataLen) { 112 memcpy(data, &mToCoreRet, dataLen); 113} 114 115 116bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { 117 bool ret = false; 118 while (!mToCore.isEmpty() || waitForCommand) { 119 uint32_t cmdID = 0; 120 uint32_t cmdSize = 0; 121 ret = true; 122 if (con->props.mLogTimes) { 123 con->timerSet(Context::RS_TIMER_IDLE); 124 } 125 const void * data = mToCore.get(&cmdID, &cmdSize); 126 if (!cmdSize) { 127 // exception occured, probably shutdown. 128 return false; 129 } 130 if (con->props.mLogTimes) { 131 con->timerSet(Context::RS_TIMER_INTERNAL); 132 } 133 waitForCommand = false; 134 //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize); 135 136 if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { 137 rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); 138 LOGE("playCoreCommands error con %p, cmd %i", con, cmdID); 139 mToCore.printDebugData(); 140 } 141 gPlaybackFuncs[cmdID](con, data, cmdSize << 2); 142 mToCore.next(); 143 } 144 return ret; 145} 146 147RsMessageToClientType 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, (uint32_t*)&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 166RsMessageToClientType 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 193bool 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} 225 226