rsThreadIO.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. #include "rsContext.h"
  17. #include "rsThreadIO.h"
  18. #include "rsgApiStructs.h"
  19. #include <unistd.h>
  20. #include <sys/types.h>
  21. #include <sys/socket.h>
  22. #include <fcntl.h>
  23. #include <poll.h>
  24. namespace android {
  25. namespace renderscript {
  26. ThreadIO::ThreadIO() {
  27. mRunning = true;
  28. mMaxInlineSize = 1024;
  29. }
  30. ThreadIO::~ThreadIO() {
  31. }
  32. bool ThreadIO::init() {
  33. return mToClient.init() && mToCore.init();
  34. }
  35. void ThreadIO::shutdown() {
  36. mRunning = false;
  37. mToCore.shutdown();
  38. }
  39. void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
  40. //ALOGE("coreHeader %i %i", cmdID, dataLen);
  41. CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0];
  42. hdr->bytes = dataLen;
  43. hdr->cmdID = cmdID;
  44. mSendLen = dataLen + sizeof(CoreCmdHeader);
  45. //mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
  46. //ALOGE("coreHeader ret ");
  47. return &mSendBuffer[sizeof(CoreCmdHeader)];
  48. }
  49. void ThreadIO::coreCommit() {
  50. mToCore.writeAsync(&mSendBuffer, mSendLen);
  51. }
  52. void ThreadIO::clientShutdown() {
  53. mToClient.shutdown();
  54. }
  55. void ThreadIO::coreWrite(const void *data, size_t len) {
  56. //ALOGV("core write %p %i", data, (int)len);
  57. mToCore.writeAsync(data, len, true);
  58. }
  59. void ThreadIO::coreRead(void *data, size_t len) {
  60. //ALOGV("core read %p %i", data, (int)len);
  61. mToCore.read(data, len);
  62. }
  63. void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
  64. uint32_t buf;
  65. if (data == nullptr) {
  66. data = &buf;
  67. dataLen = sizeof(buf);
  68. }
  69. mToCore.readReturn(data, dataLen);
  70. }
  71. void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
  72. uint32_t buf;
  73. if (data == nullptr) {
  74. data = &buf;
  75. dataLen = sizeof(buf);
  76. }
  77. mToCore.writeWaitReturn(data, dataLen);
  78. }
  79. void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) {
  80. //mToCore.setTimeoutCallback(cb, dat, timeout);
  81. }
  82. bool ThreadIO::playCoreCommands(Context *con, int waitFd) {
  83. bool ret = false;
  84. uint8_t buf[2 * 1024];
  85. const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0];
  86. const void * data = (const void *)&buf[sizeof(CoreCmdHeader)];
  87. struct pollfd p[2];
  88. p[0].fd = mToCore.getReadFd();
  89. p[0].events = POLLIN;
  90. p[0].revents = 0;
  91. p[1].fd = waitFd;
  92. p[1].events = POLLIN;
  93. p[1].revents = 0;
  94. int pollCount = 1;
  95. if (waitFd >= 0) {
  96. pollCount = 2;
  97. }
  98. if (con->props.mLogTimes) {
  99. con->timerSet(Context::RS_TIMER_IDLE);
  100. }
  101. int waitTime = -1;
  102. while (mRunning) {
  103. int pr = poll(p, pollCount, waitTime);
  104. if (pr <= 0) {
  105. break;
  106. }
  107. if (p[0].revents) {
  108. size_t r = 0;
  109. r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
  110. mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
  111. if (r != sizeof(CoreCmdHeader)) {
  112. // exception or timeout occurred.
  113. break;
  114. }
  115. ret = true;
  116. if (con->props.mLogTimes) {
  117. con->timerSet(Context::RS_TIMER_INTERNAL);
  118. }
  119. //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes);
  120. if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
  121. rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
  122. ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID);
  123. }
  124. gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
  125. if (con->props.mLogTimes) {
  126. con->timerSet(Context::RS_TIMER_IDLE);
  127. }
  128. if (waitFd < 0) {
  129. // If we don't have a secondary wait object we should stop blocking now
  130. // that at least one command has been processed.
  131. waitTime = 0;
  132. }
  133. }
  134. if (p[1].revents && !p[0].revents) {
  135. // We want to finish processing fifo events before processing the vsync.
  136. // Otherwise we can end up falling behind and having tremendous lag.
  137. break;
  138. }
  139. }
  140. return ret;
  141. }
  142. RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
  143. //ALOGE("getClientHeader");
  144. mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader));
  145. receiveLen[0] = mLastClientHeader.bytes;
  146. usrID[0] = mLastClientHeader.userID;
  147. //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]);
  148. return (RsMessageToClientType)mLastClientHeader.cmdID;
  149. }
  150. RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
  151. uint32_t *usrID, size_t bufferLen) {
  152. //ALOGE("getClientPayload");
  153. receiveLen[0] = mLastClientHeader.bytes;
  154. usrID[0] = mLastClientHeader.userID;
  155. if (bufferLen < mLastClientHeader.bytes) {
  156. return RS_MESSAGE_TO_CLIENT_RESIZE;
  157. }
  158. if (receiveLen[0]) {
  159. mToClient.read(data, receiveLen[0]);
  160. }
  161. //ALOGE("getClientPayload x");
  162. return (RsMessageToClientType)mLastClientHeader.cmdID;
  163. }
  164. bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
  165. size_t dataLen, bool waitForSpace) {
  166. //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen);
  167. ClientCmdHeader hdr;
  168. hdr.bytes = (uint32_t)dataLen;
  169. hdr.cmdID = cmdID;
  170. hdr.userID = usrID;
  171. mToClient.writeAsync(&hdr, sizeof(hdr));
  172. if (dataLen) {
  173. mToClient.writeAsync(data, dataLen);
  174. }
  175. //ALOGE("sendToClient x");
  176. return true;
  177. }
  178. } // namespace renderscript
  179. } // namespace android