123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "rsContext.h"
- #include "rsThreadIO.h"
- #include "rsgApiStructs.h"
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <fcntl.h>
- #include <poll.h>
- namespace android {
- namespace renderscript {
- ThreadIO::ThreadIO() {
- mRunning = true;
- mMaxInlineSize = 1024;
- }
- ThreadIO::~ThreadIO() {
- }
- bool ThreadIO::init() {
- return mToClient.init() && mToCore.init();
- }
- void ThreadIO::shutdown() {
- mRunning = false;
- mToCore.shutdown();
- }
- void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
- //ALOGE("coreHeader %i %i", cmdID, dataLen);
- CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0];
- hdr->bytes = dataLen;
- hdr->cmdID = cmdID;
- mSendLen = dataLen + sizeof(CoreCmdHeader);
- //mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
- //ALOGE("coreHeader ret ");
- return &mSendBuffer[sizeof(CoreCmdHeader)];
- }
- void ThreadIO::coreCommit() {
- mToCore.writeAsync(&mSendBuffer, mSendLen);
- }
- void ThreadIO::clientShutdown() {
- mToClient.shutdown();
- }
- void ThreadIO::coreWrite(const void *data, size_t len) {
- //ALOGV("core write %p %i", data, (int)len);
- mToCore.writeAsync(data, len, true);
- }
- void ThreadIO::coreRead(void *data, size_t len) {
- //ALOGV("core read %p %i", data, (int)len);
- mToCore.read(data, len);
- }
- void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
- uint32_t buf;
- if (data == nullptr) {
- data = &buf;
- dataLen = sizeof(buf);
- }
- mToCore.readReturn(data, dataLen);
- }
- void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
- uint32_t buf;
- if (data == nullptr) {
- data = &buf;
- dataLen = sizeof(buf);
- }
- mToCore.writeWaitReturn(data, dataLen);
- }
- void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) {
- //mToCore.setTimeoutCallback(cb, dat, timeout);
- }
- bool ThreadIO::playCoreCommands(Context *con, int waitFd) {
- bool ret = false;
- uint8_t buf[2 * 1024];
- const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0];
- const void * data = (const void *)&buf[sizeof(CoreCmdHeader)];
- struct pollfd p[2];
- p[0].fd = mToCore.getReadFd();
- p[0].events = POLLIN;
- p[0].revents = 0;
- p[1].fd = waitFd;
- p[1].events = POLLIN;
- p[1].revents = 0;
- int pollCount = 1;
- if (waitFd >= 0) {
- pollCount = 2;
- }
- if (con->props.mLogTimes) {
- con->timerSet(Context::RS_TIMER_IDLE);
- }
- int waitTime = -1;
- while (mRunning) {
- int pr = poll(p, pollCount, waitTime);
- if (pr <= 0) {
- break;
- }
- if (p[0].revents) {
- size_t r = 0;
- r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
- mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
- if (r != sizeof(CoreCmdHeader)) {
- // exception or timeout occurred.
- break;
- }
- ret = true;
- if (con->props.mLogTimes) {
- con->timerSet(Context::RS_TIMER_INTERNAL);
- }
- //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes);
- if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
- rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
- ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID);
- }
- gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
- if (con->props.mLogTimes) {
- con->timerSet(Context::RS_TIMER_IDLE);
- }
- if (waitFd < 0) {
- // If we don't have a secondary wait object we should stop blocking now
- // that at least one command has been processed.
- waitTime = 0;
- }
- }
- if (p[1].revents && !p[0].revents) {
- // We want to finish processing fifo events before processing the vsync.
- // Otherwise we can end up falling behind and having tremendous lag.
- break;
- }
- }
- return ret;
- }
- RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
- //ALOGE("getClientHeader");
- mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader));
- receiveLen[0] = mLastClientHeader.bytes;
- usrID[0] = mLastClientHeader.userID;
- //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]);
- return (RsMessageToClientType)mLastClientHeader.cmdID;
- }
- RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
- uint32_t *usrID, size_t bufferLen) {
- //ALOGE("getClientPayload");
- receiveLen[0] = mLastClientHeader.bytes;
- usrID[0] = mLastClientHeader.userID;
- if (bufferLen < mLastClientHeader.bytes) {
- return RS_MESSAGE_TO_CLIENT_RESIZE;
- }
- if (receiveLen[0]) {
- mToClient.read(data, receiveLen[0]);
- }
- //ALOGE("getClientPayload x");
- return (RsMessageToClientType)mLastClientHeader.cmdID;
- }
- bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
- size_t dataLen, bool waitForSpace) {
- //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen);
- ClientCmdHeader hdr;
- hdr.bytes = (uint32_t)dataLen;
- hdr.cmdID = cmdID;
- hdr.userID = usrID;
- mToClient.writeAsync(&hdr, sizeof(hdr));
- if (dataLen) {
- mToClient.writeAsync(data, dataLen);
- }
- //ALOGE("sendToClient x");
- return true;
- }
- } // namespace renderscript
- } // namespace android
|