1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/* 2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project 3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License. 6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at 7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * http://www.apache.org/licenses/LICENSE-2.0 9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software 11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and 14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License. 15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */ 16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsContext.h" 18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsThreadIO.h" 194edf030cbb7c6ac08dc563335c2af73c20f6e2e5Alex Sakhartchouk#include "rsgApiStructs.h" 20326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 215f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams#include <unistd.h> 225f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams#include <sys/types.h> 235f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams#include <sys/socket.h> 245f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 255f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams#include <fcntl.h> 265f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams#include <poll.h> 275f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 285f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 29326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android; 30326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript; 31326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 325f27d6fb0b0b9184ba9820c629fc1354a635e515Jason SamsThreadIO::ThreadIO() { 335f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mRunning = true; 34bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams mMaxInlineSize = 1024; 35326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 36326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 37afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukThreadIO::~ThreadIO() { 38326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 39326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 405f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Samsvoid ThreadIO::init() { 415f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToClient.init(); 425f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToCore.init(); 431a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 441a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 45afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ThreadIO::shutdown() { 465f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mRunning = false; 478c0ee6567b3c874dd472843eb7918ae68d1b9739Jason Sams mToCore.shutdown(); 481a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 491a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 501a4efa363916977ef9aeab756725b3bdc880a15bJason Samsvoid * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) { 51af12ac6a08651464f8d823add667c706f993b587Steve Block //ALOGE("coreHeader %i %i", cmdID, dataLen); 525f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0]; 535f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams hdr->bytes = dataLen; 545f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams hdr->cmdID = cmdID; 555f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mSendLen = dataLen + sizeof(CoreCmdHeader); 565f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //mToCoreSocket.writeAsync(&hdr, sizeof(hdr)); 575f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("coreHeader ret "); 585f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams return &mSendBuffer[sizeof(CoreCmdHeader)]; 591a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 601a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 611a4efa363916977ef9aeab756725b3bdc880a15bJason Samsvoid ThreadIO::coreCommit() { 625f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToCore.writeAsync(&mSendBuffer, mSendLen); 631a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 641a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 651a4efa363916977ef9aeab756725b3bdc880a15bJason Samsvoid ThreadIO::clientShutdown() { 661a4efa363916977ef9aeab756725b3bdc880a15bJason Sams mToClient.shutdown(); 671a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 681a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 69bda75a977726835d74b2380d7e92360ed2a1ff7aJason Samsvoid ThreadIO::coreWrite(const void *data, size_t len) { 70bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams //ALOGV("core write %p %i", data, (int)len); 71bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams mToCore.writeAsync(data, len, true); 72bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams} 73bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams 74bda75a977726835d74b2380d7e92360ed2a1ff7aJason Samsvoid ThreadIO::coreRead(void *data, size_t len) { 75bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams //ALOGV("core read %p %i", data, (int)len); 76bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams mToCore.read(data, len); 77bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams} 78bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams 791a4efa363916977ef9aeab756725b3bdc880a15bJason Samsvoid ThreadIO::coreSetReturn(const void *data, size_t dataLen) { 805f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams uint32_t buf; 8144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes if (data == nullptr) { 825f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams data = &buf; 835f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams dataLen = sizeof(buf); 845f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 855f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 865f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToCore.readReturn(data, dataLen); 871a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 881a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 891a4efa363916977ef9aeab756725b3bdc880a15bJason Samsvoid ThreadIO::coreGetReturn(void *data, size_t dataLen) { 905f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams uint32_t buf; 9144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes if (data == nullptr) { 925f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams data = &buf; 935f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams dataLen = sizeof(buf); 945f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 951a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 965f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToCore.writeWaitReturn(data, dataLen); 972382aba4a55c6ae74789c478eead8fbd96593321Jason Sams} 982382aba4a55c6ae74789c478eead8fbd96593321Jason Sams 995f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Samsvoid ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) { 1005f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //mToCore.setTimeoutCallback(cb, dat, timeout); 1015f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams} 1021a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 103963a2fb9f03c88633bc67c4a1789429b9a482091Jason Samsbool ThreadIO::playCoreCommands(Context *con, int waitFd) { 104a44cb29164726cd9d812117819abdd7b60dfdd93Jason Sams bool ret = false; 105e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams 1065f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams uint8_t buf[2 * 1024]; 1075f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0]; 1085f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams const void * data = (const void *)&buf[sizeof(CoreCmdHeader)]; 1095f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 1105f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams struct pollfd p[2]; 1115f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams p[0].fd = mToCore.getReadFd(); 1125f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams p[0].events = POLLIN; 1135f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams p[0].revents = 0; 1145f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams p[1].fd = waitFd; 1155f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams p[1].events = POLLIN; 1165f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams p[1].revents = 0; 1175f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams int pollCount = 1; 1185f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (waitFd >= 0) { 1195f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams pollCount = 2; 1205f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 121e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams 1225f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (con->props.mLogTimes) { 1235f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams con->timerSet(Context::RS_TIMER_IDLE); 1245f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 12536838469a96b984fa27b61288ca1043b664af370Stephen Hines 1265f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams int waitTime = -1; 1275f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams while (mRunning) { 1285f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams int pr = poll(p, pollCount, waitTime); 1295f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (pr <= 0) { 13036838469a96b984fa27b61288ca1043b664af370Stephen Hines break; 13136838469a96b984fa27b61288ca1043b664af370Stephen Hines } 13236838469a96b984fa27b61288ca1043b664af370Stephen Hines 1335f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (p[0].revents) { 134bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams size_t r = 0; 135b74514df6be14fd898ddd7906bc70408dc3bb63cMatt Wala r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); 136b74514df6be14fd898ddd7906bc70408dc3bb63cMatt Wala mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); 137b74514df6be14fd898ddd7906bc70408dc3bb63cMatt Wala if (r != sizeof(CoreCmdHeader)) { 138b74514df6be14fd898ddd7906bc70408dc3bb63cMatt Wala // exception or timeout occurred. 139b74514df6be14fd898ddd7906bc70408dc3bb63cMatt Wala break; 1405f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 1415f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 1425f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams ret = true; 1435f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (con->props.mLogTimes) { 1445f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams con->timerSet(Context::RS_TIMER_INTERNAL); 1455f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 1465f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes); 1475f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 1485f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { 1495f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); 1505f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID); 1515f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 152bda75a977726835d74b2380d7e92360ed2a1ff7aJason Sams 153b74514df6be14fd898ddd7906bc70408dc3bb63cMatt Wala gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); 1545f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 1555f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (con->props.mLogTimes) { 1565f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams con->timerSet(Context::RS_TIMER_IDLE); 1575f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 1585f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 1595f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (waitFd < 0) { 1605f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams // If we don't have a secondary wait object we should stop blocking now 1615f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams // that at least one command has been processed. 1625f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams waitTime = 0; 1635f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams } 16476371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato } 165326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 1665f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (p[1].revents && !p[0].revents) { 1675f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams // We want to finish processing fifo events before processing the vsync. 1685f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams // Otherwise we can end up falling behind and having tremendous lag. 1695f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams break; 170185b8b01f417488e2fbf6e6c00dfbd3d1d43d98aJason Sams } 171326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 172a44cb29164726cd9d812117819abdd7b60dfdd93Jason Sams return ret; 173326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 174326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 1751a4efa363916977ef9aeab756725b3bdc880a15bJason SamsRsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) { 1765f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("getClientHeader"); 1775f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader)); 1785f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 1791a4efa363916977ef9aeab756725b3bdc880a15bJason Sams receiveLen[0] = mLastClientHeader.bytes; 1801a4efa363916977ef9aeab756725b3bdc880a15bJason Sams usrID[0] = mLastClientHeader.userID; 1815f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]); 1821a4efa363916977ef9aeab756725b3bdc880a15bJason Sams return (RsMessageToClientType)mLastClientHeader.cmdID; 1831a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 1841a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 1851a4efa363916977ef9aeab756725b3bdc880a15bJason SamsRsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen, 1861a4efa363916977ef9aeab756725b3bdc880a15bJason Sams uint32_t *usrID, size_t bufferLen) { 1875f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("getClientPayload"); 1881a4efa363916977ef9aeab756725b3bdc880a15bJason Sams receiveLen[0] = mLastClientHeader.bytes; 1891a4efa363916977ef9aeab756725b3bdc880a15bJason Sams usrID[0] = mLastClientHeader.userID; 1901a4efa363916977ef9aeab756725b3bdc880a15bJason Sams if (bufferLen < mLastClientHeader.bytes) { 1911a4efa363916977ef9aeab756725b3bdc880a15bJason Sams return RS_MESSAGE_TO_CLIENT_RESIZE; 1921a4efa363916977ef9aeab756725b3bdc880a15bJason Sams } 1935f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (receiveLen[0]) { 1945f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToClient.read(data, receiveLen[0]); 1951a4efa363916977ef9aeab756725b3bdc880a15bJason Sams } 1965f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("getClientPayload x"); 1975f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams return (RsMessageToClientType)mLastClientHeader.cmdID; 1981a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 1991a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 2001a4efa363916977ef9aeab756725b3bdc880a15bJason Samsbool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data, 2011a4efa363916977ef9aeab756725b3bdc880a15bJason Sams size_t dataLen, bool waitForSpace) { 2025f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 2035f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen); 2041a4efa363916977ef9aeab756725b3bdc880a15bJason Sams ClientCmdHeader hdr; 205e4ed0873cda11a0442176027f9c599d9e41538e1Tim Murray hdr.bytes = (uint32_t)dataLen; 2061a4efa363916977ef9aeab756725b3bdc880a15bJason Sams hdr.cmdID = cmdID; 2071a4efa363916977ef9aeab756725b3bdc880a15bJason Sams hdr.userID = usrID; 2081a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 2095f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToClient.writeAsync(&hdr, sizeof(hdr)); 2105f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams if (dataLen) { 2115f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams mToClient.writeAsync(data, dataLen); 2121a4efa363916977ef9aeab756725b3bdc880a15bJason Sams } 2135f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams 2145f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams //ALOGE("sendToClient x"); 2155f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams return true; 2161a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 217326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 218