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