xref: /aosp_15_r20/frameworks/rs/rsThreadIO.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2009 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker #include "rsContext.h"
18*e1eccf28SAndroid Build Coastguard Worker #include "rsThreadIO.h"
19*e1eccf28SAndroid Build Coastguard Worker #include "rsgApiStructs.h"
20*e1eccf28SAndroid Build Coastguard Worker 
21*e1eccf28SAndroid Build Coastguard Worker #include <unistd.h>
22*e1eccf28SAndroid Build Coastguard Worker #include <sys/types.h>
23*e1eccf28SAndroid Build Coastguard Worker #include <sys/socket.h>
24*e1eccf28SAndroid Build Coastguard Worker 
25*e1eccf28SAndroid Build Coastguard Worker #include <fcntl.h>
26*e1eccf28SAndroid Build Coastguard Worker #include <poll.h>
27*e1eccf28SAndroid Build Coastguard Worker 
28*e1eccf28SAndroid Build Coastguard Worker 
29*e1eccf28SAndroid Build Coastguard Worker namespace android {
30*e1eccf28SAndroid Build Coastguard Worker namespace renderscript {
31*e1eccf28SAndroid Build Coastguard Worker 
ThreadIO()32*e1eccf28SAndroid Build Coastguard Worker ThreadIO::ThreadIO() {
33*e1eccf28SAndroid Build Coastguard Worker     mRunning = true;
34*e1eccf28SAndroid Build Coastguard Worker     mMaxInlineSize = 1024;
35*e1eccf28SAndroid Build Coastguard Worker }
36*e1eccf28SAndroid Build Coastguard Worker 
~ThreadIO()37*e1eccf28SAndroid Build Coastguard Worker ThreadIO::~ThreadIO() {
38*e1eccf28SAndroid Build Coastguard Worker }
39*e1eccf28SAndroid Build Coastguard Worker 
init()40*e1eccf28SAndroid Build Coastguard Worker bool ThreadIO::init() {
41*e1eccf28SAndroid Build Coastguard Worker     return mToClient.init() && mToCore.init();
42*e1eccf28SAndroid Build Coastguard Worker }
43*e1eccf28SAndroid Build Coastguard Worker 
shutdown()44*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::shutdown() {
45*e1eccf28SAndroid Build Coastguard Worker     mRunning = false;
46*e1eccf28SAndroid Build Coastguard Worker     mToCore.shutdown();
47*e1eccf28SAndroid Build Coastguard Worker }
48*e1eccf28SAndroid Build Coastguard Worker 
coreHeader(uint32_t cmdID,size_t dataLen)49*e1eccf28SAndroid Build Coastguard Worker void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
50*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("coreHeader %i %i", cmdID, dataLen);
51*e1eccf28SAndroid Build Coastguard Worker     CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0];
52*e1eccf28SAndroid Build Coastguard Worker     hdr->bytes = dataLen;
53*e1eccf28SAndroid Build Coastguard Worker     hdr->cmdID = cmdID;
54*e1eccf28SAndroid Build Coastguard Worker     mSendLen = dataLen + sizeof(CoreCmdHeader);
55*e1eccf28SAndroid Build Coastguard Worker     //mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
56*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("coreHeader ret ");
57*e1eccf28SAndroid Build Coastguard Worker     return &mSendBuffer[sizeof(CoreCmdHeader)];
58*e1eccf28SAndroid Build Coastguard Worker }
59*e1eccf28SAndroid Build Coastguard Worker 
coreCommit()60*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::coreCommit() {
61*e1eccf28SAndroid Build Coastguard Worker     mToCore.writeAsync(&mSendBuffer, mSendLen);
62*e1eccf28SAndroid Build Coastguard Worker }
63*e1eccf28SAndroid Build Coastguard Worker 
clientShutdown()64*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::clientShutdown() {
65*e1eccf28SAndroid Build Coastguard Worker     mToClient.shutdown();
66*e1eccf28SAndroid Build Coastguard Worker }
67*e1eccf28SAndroid Build Coastguard Worker 
coreWrite(const void * data,size_t len)68*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::coreWrite(const void *data, size_t len) {
69*e1eccf28SAndroid Build Coastguard Worker     //ALOGV("core write %p %i", data, (int)len);
70*e1eccf28SAndroid Build Coastguard Worker     mToCore.writeAsync(data, len, true);
71*e1eccf28SAndroid Build Coastguard Worker }
72*e1eccf28SAndroid Build Coastguard Worker 
coreRead(void * data,size_t len)73*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::coreRead(void *data, size_t len) {
74*e1eccf28SAndroid Build Coastguard Worker     //ALOGV("core read %p %i", data, (int)len);
75*e1eccf28SAndroid Build Coastguard Worker     mToCore.read(data, len);
76*e1eccf28SAndroid Build Coastguard Worker }
77*e1eccf28SAndroid Build Coastguard Worker 
coreSetReturn(const void * data,size_t dataLen)78*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
79*e1eccf28SAndroid Build Coastguard Worker     uint32_t buf;
80*e1eccf28SAndroid Build Coastguard Worker     if (data == nullptr) {
81*e1eccf28SAndroid Build Coastguard Worker         data = &buf;
82*e1eccf28SAndroid Build Coastguard Worker         dataLen = sizeof(buf);
83*e1eccf28SAndroid Build Coastguard Worker     }
84*e1eccf28SAndroid Build Coastguard Worker 
85*e1eccf28SAndroid Build Coastguard Worker     mToCore.readReturn(data, dataLen);
86*e1eccf28SAndroid Build Coastguard Worker }
87*e1eccf28SAndroid Build Coastguard Worker 
coreGetReturn(void * data,size_t dataLen)88*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
89*e1eccf28SAndroid Build Coastguard Worker     uint32_t buf;
90*e1eccf28SAndroid Build Coastguard Worker     if (data == nullptr) {
91*e1eccf28SAndroid Build Coastguard Worker         data = &buf;
92*e1eccf28SAndroid Build Coastguard Worker         dataLen = sizeof(buf);
93*e1eccf28SAndroid Build Coastguard Worker     }
94*e1eccf28SAndroid Build Coastguard Worker 
95*e1eccf28SAndroid Build Coastguard Worker     mToCore.writeWaitReturn(data, dataLen);
96*e1eccf28SAndroid Build Coastguard Worker }
97*e1eccf28SAndroid Build Coastguard Worker 
setTimeoutCallback(void (* cb)(void *),void * dat,uint64_t timeout)98*e1eccf28SAndroid Build Coastguard Worker void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) {
99*e1eccf28SAndroid Build Coastguard Worker     //mToCore.setTimeoutCallback(cb, dat, timeout);
100*e1eccf28SAndroid Build Coastguard Worker }
101*e1eccf28SAndroid Build Coastguard Worker 
playCoreCommands(Context * con,int waitFd)102*e1eccf28SAndroid Build Coastguard Worker bool ThreadIO::playCoreCommands(Context *con, int waitFd) {
103*e1eccf28SAndroid Build Coastguard Worker     bool ret = false;
104*e1eccf28SAndroid Build Coastguard Worker 
105*e1eccf28SAndroid Build Coastguard Worker     uint8_t buf[2 * 1024];
106*e1eccf28SAndroid Build Coastguard Worker     const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0];
107*e1eccf28SAndroid Build Coastguard Worker     const void * data = (const void *)&buf[sizeof(CoreCmdHeader)];
108*e1eccf28SAndroid Build Coastguard Worker 
109*e1eccf28SAndroid Build Coastguard Worker     struct pollfd p[2];
110*e1eccf28SAndroid Build Coastguard Worker     p[0].fd = mToCore.getReadFd();
111*e1eccf28SAndroid Build Coastguard Worker     p[0].events = POLLIN;
112*e1eccf28SAndroid Build Coastguard Worker     p[0].revents = 0;
113*e1eccf28SAndroid Build Coastguard Worker     p[1].fd = waitFd;
114*e1eccf28SAndroid Build Coastguard Worker     p[1].events = POLLIN;
115*e1eccf28SAndroid Build Coastguard Worker     p[1].revents = 0;
116*e1eccf28SAndroid Build Coastguard Worker     int pollCount = 1;
117*e1eccf28SAndroid Build Coastguard Worker     if (waitFd >= 0) {
118*e1eccf28SAndroid Build Coastguard Worker         pollCount = 2;
119*e1eccf28SAndroid Build Coastguard Worker     }
120*e1eccf28SAndroid Build Coastguard Worker 
121*e1eccf28SAndroid Build Coastguard Worker     if (con->props.mLogTimes) {
122*e1eccf28SAndroid Build Coastguard Worker         con->timerSet(Context::RS_TIMER_IDLE);
123*e1eccf28SAndroid Build Coastguard Worker     }
124*e1eccf28SAndroid Build Coastguard Worker 
125*e1eccf28SAndroid Build Coastguard Worker     int waitTime = -1;
126*e1eccf28SAndroid Build Coastguard Worker     while (mRunning) {
127*e1eccf28SAndroid Build Coastguard Worker         int pr = poll(p, pollCount, waitTime);
128*e1eccf28SAndroid Build Coastguard Worker         if (pr <= 0) {
129*e1eccf28SAndroid Build Coastguard Worker             break;
130*e1eccf28SAndroid Build Coastguard Worker         }
131*e1eccf28SAndroid Build Coastguard Worker 
132*e1eccf28SAndroid Build Coastguard Worker         if (p[0].revents) {
133*e1eccf28SAndroid Build Coastguard Worker             size_t r = 0;
134*e1eccf28SAndroid Build Coastguard Worker             r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
135*e1eccf28SAndroid Build Coastguard Worker             mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
136*e1eccf28SAndroid Build Coastguard Worker             if (r != sizeof(CoreCmdHeader)) {
137*e1eccf28SAndroid Build Coastguard Worker               // exception or timeout occurred.
138*e1eccf28SAndroid Build Coastguard Worker               break;
139*e1eccf28SAndroid Build Coastguard Worker             }
140*e1eccf28SAndroid Build Coastguard Worker 
141*e1eccf28SAndroid Build Coastguard Worker             ret = true;
142*e1eccf28SAndroid Build Coastguard Worker             if (con->props.mLogTimes) {
143*e1eccf28SAndroid Build Coastguard Worker                 con->timerSet(Context::RS_TIMER_INTERNAL);
144*e1eccf28SAndroid Build Coastguard Worker             }
145*e1eccf28SAndroid Build Coastguard Worker             //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes);
146*e1eccf28SAndroid Build Coastguard Worker 
147*e1eccf28SAndroid Build Coastguard Worker             if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
148*e1eccf28SAndroid Build Coastguard Worker                 rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
149*e1eccf28SAndroid Build Coastguard Worker                 ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID);
150*e1eccf28SAndroid Build Coastguard Worker             }
151*e1eccf28SAndroid Build Coastguard Worker 
152*e1eccf28SAndroid Build Coastguard Worker             gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
153*e1eccf28SAndroid Build Coastguard Worker 
154*e1eccf28SAndroid Build Coastguard Worker             if (con->props.mLogTimes) {
155*e1eccf28SAndroid Build Coastguard Worker                 con->timerSet(Context::RS_TIMER_IDLE);
156*e1eccf28SAndroid Build Coastguard Worker             }
157*e1eccf28SAndroid Build Coastguard Worker 
158*e1eccf28SAndroid Build Coastguard Worker             if (waitFd < 0) {
159*e1eccf28SAndroid Build Coastguard Worker                 // If we don't have a secondary wait object we should stop blocking now
160*e1eccf28SAndroid Build Coastguard Worker                 // that at least one command has been processed.
161*e1eccf28SAndroid Build Coastguard Worker                 waitTime = 0;
162*e1eccf28SAndroid Build Coastguard Worker             }
163*e1eccf28SAndroid Build Coastguard Worker         }
164*e1eccf28SAndroid Build Coastguard Worker 
165*e1eccf28SAndroid Build Coastguard Worker         if (p[1].revents && !p[0].revents) {
166*e1eccf28SAndroid Build Coastguard Worker             // We want to finish processing fifo events before processing the vsync.
167*e1eccf28SAndroid Build Coastguard Worker             // Otherwise we can end up falling behind and having tremendous lag.
168*e1eccf28SAndroid Build Coastguard Worker             break;
169*e1eccf28SAndroid Build Coastguard Worker         }
170*e1eccf28SAndroid Build Coastguard Worker     }
171*e1eccf28SAndroid Build Coastguard Worker     return ret;
172*e1eccf28SAndroid Build Coastguard Worker }
173*e1eccf28SAndroid Build Coastguard Worker 
getClientHeader(size_t * receiveLen,uint32_t * usrID)174*e1eccf28SAndroid Build Coastguard Worker RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
175*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("getClientHeader");
176*e1eccf28SAndroid Build Coastguard Worker     mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader));
177*e1eccf28SAndroid Build Coastguard Worker 
178*e1eccf28SAndroid Build Coastguard Worker     receiveLen[0] = mLastClientHeader.bytes;
179*e1eccf28SAndroid Build Coastguard Worker     usrID[0] = mLastClientHeader.userID;
180*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]);
181*e1eccf28SAndroid Build Coastguard Worker     return (RsMessageToClientType)mLastClientHeader.cmdID;
182*e1eccf28SAndroid Build Coastguard Worker }
183*e1eccf28SAndroid Build Coastguard Worker 
getClientPayload(void * data,size_t * receiveLen,uint32_t * usrID,size_t bufferLen)184*e1eccf28SAndroid Build Coastguard Worker RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
185*e1eccf28SAndroid Build Coastguard Worker                                 uint32_t *usrID, size_t bufferLen) {
186*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("getClientPayload");
187*e1eccf28SAndroid Build Coastguard Worker     receiveLen[0] = mLastClientHeader.bytes;
188*e1eccf28SAndroid Build Coastguard Worker     usrID[0] = mLastClientHeader.userID;
189*e1eccf28SAndroid Build Coastguard Worker     if (bufferLen < mLastClientHeader.bytes) {
190*e1eccf28SAndroid Build Coastguard Worker         return RS_MESSAGE_TO_CLIENT_RESIZE;
191*e1eccf28SAndroid Build Coastguard Worker     }
192*e1eccf28SAndroid Build Coastguard Worker     if (receiveLen[0]) {
193*e1eccf28SAndroid Build Coastguard Worker         mToClient.read(data, receiveLen[0]);
194*e1eccf28SAndroid Build Coastguard Worker     }
195*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("getClientPayload x");
196*e1eccf28SAndroid Build Coastguard Worker     return (RsMessageToClientType)mLastClientHeader.cmdID;
197*e1eccf28SAndroid Build Coastguard Worker }
198*e1eccf28SAndroid Build Coastguard Worker 
sendToClient(RsMessageToClientType cmdID,uint32_t usrID,const void * data,size_t dataLen,bool waitForSpace)199*e1eccf28SAndroid Build Coastguard Worker bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
200*e1eccf28SAndroid Build Coastguard Worker                             size_t dataLen, bool waitForSpace) {
201*e1eccf28SAndroid Build Coastguard Worker 
202*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen);
203*e1eccf28SAndroid Build Coastguard Worker     ClientCmdHeader hdr;
204*e1eccf28SAndroid Build Coastguard Worker     hdr.bytes = (uint32_t)dataLen;
205*e1eccf28SAndroid Build Coastguard Worker     hdr.cmdID = cmdID;
206*e1eccf28SAndroid Build Coastguard Worker     hdr.userID = usrID;
207*e1eccf28SAndroid Build Coastguard Worker 
208*e1eccf28SAndroid Build Coastguard Worker     mToClient.writeAsync(&hdr, sizeof(hdr));
209*e1eccf28SAndroid Build Coastguard Worker     if (dataLen) {
210*e1eccf28SAndroid Build Coastguard Worker         mToClient.writeAsync(data, dataLen);
211*e1eccf28SAndroid Build Coastguard Worker     }
212*e1eccf28SAndroid Build Coastguard Worker 
213*e1eccf28SAndroid Build Coastguard Worker     //ALOGE("sendToClient x");
214*e1eccf28SAndroid Build Coastguard Worker     return true;
215*e1eccf28SAndroid Build Coastguard Worker }
216*e1eccf28SAndroid Build Coastguard Worker 
217*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript
218*e1eccf28SAndroid Build Coastguard Worker } // namespace android
219