int main(int argc, char** argv)
{
    DisplayEventReceiver myDisplayEvent;


    sp<Looper> loop = new Looper(false);
    loop->addFd(myDisplayEvent.getFd(), 0, ALOOPER_EVENT_INPUT, receiver,
            &myDisplayEvent);

    myDisplayEvent.setVsyncRate(1);

    do {
        //printf("about to poll...\n");
        int32_t ret = loop->pollOnce(-1);
        switch (ret) {
            case ALOOPER_POLL_WAKE:
                //("ALOOPER_POLL_WAKE\n");
                break;
            case ALOOPER_POLL_CALLBACK:
                //("ALOOPER_POLL_CALLBACK\n");
                break;
            case ALOOPER_POLL_TIMEOUT:
                printf("ALOOPER_POLL_TIMEOUT\n");
                break;
            case ALOOPER_POLL_ERROR:
                printf("ALOOPER_POLL_TIMEOUT\n");
                break;
            default:
                printf("ugh? poll returned %d\n", ret);
                break;
        }
    } while (1);

    return 0;
}
void NativeDisplayEventReceiver::dispose() {
    ALOGV("receiver %p ~ Disposing display event receiver.", this);

    if (!mReceiver.initCheck()) {
        mMessageQueue->getLooper()->removeFd(mReceiver.getFd());
    }
}
int receiver(int fd, int events, void* data)
{
    DisplayEventReceiver* q = (DisplayEventReceiver*)data;

    ssize_t n;
    DisplayEventReceiver::Event buffer[1];

    static nsecs_t oldTimeStamp = 0;

    while ((n = q->getEvents(buffer, 1)) > 0) {
        for (int i=0 ; i<n ; i++) {
            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                printf("event vsync: count=%d\t", buffer[i].vsync.count);
            }
            if (oldTimeStamp) {
                float t = float(buffer[i].header.timestamp - oldTimeStamp) / s2ns(1);
                printf("%f ms (%f Hz)\n", t*1000, 1.0/t);
            }
            oldTimeStamp = buffer[i].header.timestamp;
        }
    }
    if (n<0) {
        printf("error reading events (%s)\n", strerror(-n));
    }
    return 1;
}
status_t NativeDisplayEventReceiver::initialize() {
    status_t result = mReceiver.initCheck();
    if (result) {
        ALOGW("Failed to initialize display event receiver, status=%d", result);
        return result;
    }

    int rc = mMessageQueue->getLooper()->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
            this, NULL);
    if (rc < 0) {
        return UNKNOWN_ERROR;
    }
    return OK;
}
bool NativeDisplayEventReceiver::processPendingEvents(
        nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {
    bool gotVsync = false;
    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
    ssize_t n;
    while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
        ALOGV("receiver %p ~ Read %d events.", this, int(n));
        for (ssize_t i = 0; i < n; i++) {
            const DisplayEventReceiver::Event& ev = buf[i];
            switch (ev.header.type) {
            case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                // Later vsync events will just overwrite the info from earlier
                // ones. That's fine, we only care about the most recent.
                gotVsync = true;
                *outTimestamp = ev.header.timestamp;
                *outId = ev.header.id;
                *outCount = ev.vsync.count;
                break;
            case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);
                break;
            default:
                ALOGW("receiver %p ~ ignoring unknown event type %#x", this, ev.header.type);
                break;
            }
        }
    }
    if (n < 0) {
        ALOGW("Failed to get events from display event receiver, status=%d", status_t(n));
    }
    return gotVsync;
}
status_t NativeDisplayEventReceiver::scheduleVsync() {
    if (!mWaitingForVsync) {
        ALOGV("receiver %p ~ Scheduling vsync.", this);

        // Drain all pending events.
        nsecs_t vsyncTimestamp;
        int32_t vsyncDisplayId;
        uint32_t vsyncCount;
        processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount);

        status_t status = mReceiver.requestNextVsync();
        if (status) {
            ALOGW("Failed to request next vsync, status=%d", status);
            return status;
        }

        mWaitingForVsync = true;
    }
    return OK;
}
void * Context::threadProc(void *vrsc) {
    Context *rsc = static_cast<Context *>(vrsc);
#ifndef ANDROID_RS_SERIALIZE
    rsc->mNativeThreadId = gettid();
#ifndef RS_COMPATIBILITY_LIB
    if (!rsc->isSynchronous()) {
        setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
    }
    rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
#else
    if (!rsc->isSynchronous()) {
        setpriority(PRIO_PROCESS, rsc->mNativeThreadId, -4);
    }
    rsc->mThreadPriority = -4;
#endif
#endif //ANDROID_RS_SERIALIZE
    rsc->props.mLogTimes = getProp("debug.rs.profile") != 0;
    rsc->props.mLogScripts = getProp("debug.rs.script") != 0;
    rsc->props.mLogObjects = getProp("debug.rs.object") != 0;
    rsc->props.mLogShaders = getProp("debug.rs.shader") != 0;
    rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0;
    rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0;
    rsc->props.mLogVisual = getProp("debug.rs.visual") != 0;
    rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads");

    bool loadDefault = true;

    // Provide a mechanism for dropping in a different RS driver.
#ifndef RS_COMPATIBILITY_LIB
#ifdef OVERRIDE_RS_DRIVER
#define XSTR(S) #S
#define STR(S) XSTR(S)
#define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER)

    if (getProp("debug.rs.default-CPU-driver") != 0) {
        ALOGE("Skipping override driver and loading default CPU driver");
    } else if (rsc->mForceCpu) {
        ALOGV("Application requested CPU execution");
    } else if (rsc->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
        ALOGV("Application requested debug context");
    } else {
        if (loadRuntime(OVERRIDE_RS_DRIVER_STRING, rsc)) {
            ALOGE("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING);
            loadDefault = false;
        } else {
            ALOGE("Failed to load runtime %s, loading default", OVERRIDE_RS_DRIVER_STRING);
        }
    }

#undef XSTR
#undef STR
#endif  // OVERRIDE_RS_DRIVER

    if (loadDefault) {
        if (!loadRuntime("libRSDriver.so", rsc)) {
            ALOGE("Failed to load default runtime!");
            rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed loading RS driver");
            return NULL;
        }
    }
#else // RS_COMPATIBILITY_LIB
    if (rsdHalInit(rsc, 0, 0) != true) {
        return NULL;
    }
#endif


    rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);

#ifndef RS_COMPATIBILITY_LIB
    if (rsc->mIsGraphicsContext) {
        if (!rsc->initGLThread()) {
            rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
            return NULL;
        }

        rsc->mStateRaster.init(rsc);
        rsc->setProgramRaster(NULL);
        rsc->mStateVertex.init(rsc);
        rsc->setProgramVertex(NULL);
        rsc->mStateFragment.init(rsc);
        rsc->setProgramFragment(NULL);
        rsc->mStateFragmentStore.init(rsc);
        rsc->setProgramStore(NULL);
        rsc->mStateFont.init(rsc);
        rsc->setFont(NULL);
        rsc->mStateSampler.init(rsc);
        rsc->mFBOCache.init(rsc);
    }
#endif

    rsc->mRunning = true;

    if (rsc->isSynchronous()) {
        return NULL;
    }

    if (!rsc->mIsGraphicsContext) {
        while (!rsc->mExit) {
            rsc->mIO.playCoreCommands(rsc, -1);
        }
#ifndef RS_COMPATIBILITY_LIB
    } else {
#ifndef ANDROID_RS_SERIALIZE
        DisplayEventReceiver displayEvent;
        DisplayEventReceiver::Event eventBuffer[1];
#endif
        int vsyncRate = 0;
        int targetRate = 0;

        bool drawOnce = false;
        while (!rsc->mExit) {
            rsc->timerSet(RS_TIMER_IDLE);

#ifndef ANDROID_RS_SERIALIZE
            if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) {
                targetRate = 0;
            }

            if (vsyncRate != targetRate) {
                displayEvent.setVsyncRate(targetRate);
                vsyncRate = targetRate;
            }
            if (targetRate) {
                drawOnce |= rsc->mIO.playCoreCommands(rsc, displayEvent.getFd());
                while (displayEvent.getEvents(eventBuffer, 1) != 0) {
                    //ALOGE("vs2 time past %lld", (rsc->getTime() - eventBuffer[0].header.timestamp) / 1000000);
                }
            } else
#endif
            {
                drawOnce |= rsc->mIO.playCoreCommands(rsc, -1);
            }

            if ((rsc->mRootScript.get() != NULL) && rsc->mHasSurface &&
                (targetRate || drawOnce) && !rsc->mPaused) {

                drawOnce = false;
                targetRate = ((rsc->runRootScript() + 15) / 16);

                if (rsc->props.mLogVisual) {
                    rsc->displayDebugStats();
                }

                rsc->timerSet(RS_TIMER_CLEAR_SWAP);
                rsc->mHal.funcs.swap(rsc);
                rsc->timerFrame();
                rsc->timerSet(RS_TIMER_INTERNAL);
                rsc->timerPrint();
                rsc->timerReset();
            }
        }
#endif
    }

    //ALOGV("%p RS Thread exiting", rsc);

#ifndef RS_COMPATIBILITY_LIB
    if (rsc->mIsGraphicsContext) {
        pthread_mutex_lock(&gInitMutex);
        rsc->deinitEGL();
        pthread_mutex_unlock(&gInitMutex);
    }
#endif

    //ALOGV("%p RS Thread exited", rsc);
    return NULL;
}
示例#8
0
void * Context::threadProc(void *vrsc) {
    Context *rsc = static_cast<Context *>(vrsc);
#ifndef ANDROID_RS_SERIALIZE
    rsc->mNativeThreadId = gettid();
    setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
    rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
#endif //ANDROID_RS_SERIALIZE
    rsc->props.mLogTimes = getProp("debug.rs.profile") != 0;
    rsc->props.mLogScripts = getProp("debug.rs.script") != 0;
    rsc->props.mLogObjects = getProp("debug.rs.object") != 0;
    rsc->props.mLogShaders = getProp("debug.rs.shader") != 0;
    rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0;
    rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0;
    rsc->props.mLogVisual = getProp("debug.rs.visual") != 0;
    rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads");

    void *driverSO = NULL;

    // Provide a mechanism for dropping in a different RS driver.
#ifdef OVERRIDE_RS_DRIVER
#define XSTR(S) #S
#define STR(S) XSTR(S)
#define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER)
    if (getProp("debug.rs.default-CPU-driver") != 0) {
        ALOGE("Skipping override driver and loading default CPU driver");
    } else {
        driverSO = dlopen(OVERRIDE_RS_DRIVER_STRING, RTLD_LAZY);
        if (driverSO == NULL) {
            ALOGE("Failed loading %s: %s", OVERRIDE_RS_DRIVER_STRING,
                  dlerror());
            // Continue to attempt loading fallback driver
        }
    }

#undef XSTR
#undef STR
#endif  // OVERRIDE_RS_DRIVER

    // Attempt to load the reference RS driver (if necessary).
    if (driverSO == NULL) {
        driverSO = dlopen("libRSDriver.so", RTLD_LAZY);
        if (driverSO == NULL) {
            rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed loading RS driver");
            ALOGE("Failed loading RS driver: %s", dlerror());
            return NULL;
        }
    }

    // Need to call dlerror() to clear buffer before using it for dlsym().
    (void) dlerror();
    typedef bool (*HalSig)(Context*, uint32_t, uint32_t);
    HalSig halInit = (HalSig) dlsym(driverSO, "rsdHalInit");

    // If we can't find the C variant, we go looking for the C++ version.
    if (halInit == NULL) {
        ALOGW("Falling back to find C++ rsdHalInit: %s", dlerror());
        halInit = (HalSig) dlsym(driverSO,
                "_Z10rsdHalInitPN7android12renderscript7ContextEjj");
    }

    if (halInit == NULL) {
        rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed to find rsdHalInit");
        dlclose(driverSO);
        ALOGE("Failed to find rsdHalInit: %s", dlerror());
        return NULL;
    }

    if (!(*halInit)(rsc, 0, 0)) {
        rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed initializing RS Driver");
        dlclose(driverSO);
        ALOGE("Hal init failed");
        return NULL;
    }
    rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);

    if (rsc->mIsGraphicsContext) {
        if (!rsc->initGLThread()) {
            rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
            return NULL;
        }

        rsc->mStateRaster.init(rsc);
        rsc->setProgramRaster(NULL);
        rsc->mStateVertex.init(rsc);
        rsc->setProgramVertex(NULL);
        rsc->mStateFragment.init(rsc);
        rsc->setProgramFragment(NULL);
        rsc->mStateFragmentStore.init(rsc);
        rsc->setProgramStore(NULL);
        rsc->mStateFont.init(rsc);
        rsc->setFont(NULL);
        rsc->mStateSampler.init(rsc);
        rsc->mFBOCache.init(rsc);
    }

    rsc->mRunning = true;
    if (!rsc->mIsGraphicsContext) {
        while (!rsc->mExit) {
            rsc->mIO.playCoreCommands(rsc, -1);
        }
    } else {
#ifndef ANDROID_RS_SERIALIZE
        DisplayEventReceiver displayEvent;
        DisplayEventReceiver::Event eventBuffer[1];
#endif
        int vsyncRate = 0;
        int targetRate = 0;

        bool drawOnce = false;
        while (!rsc->mExit) {
            rsc->timerSet(RS_TIMER_IDLE);

#ifndef ANDROID_RS_SERIALIZE
            if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) {
                targetRate = 0;
            }

            if (vsyncRate != targetRate) {
                displayEvent.setVsyncRate(targetRate);
                vsyncRate = targetRate;
            }
            if (targetRate) {
                drawOnce |= rsc->mIO.playCoreCommands(rsc, displayEvent.getFd());
                while (displayEvent.getEvents(eventBuffer, 1) != 0) {
                    //ALOGE("vs2 time past %lld", (rsc->getTime() - eventBuffer[0].header.timestamp) / 1000000);
                }
            } else
#endif
            {
                drawOnce |= rsc->mIO.playCoreCommands(rsc, -1);
            }

            if ((rsc->mRootScript.get() != NULL) && rsc->mHasSurface &&
                (targetRate || drawOnce) && !rsc->mPaused) {

                drawOnce = false;
                targetRate = ((rsc->runRootScript() + 15) / 16);

                if (rsc->props.mLogVisual) {
                    rsc->displayDebugStats();
                }

                rsc->timerSet(RS_TIMER_CLEAR_SWAP);
                rsc->mHal.funcs.swap(rsc);
                rsc->timerFrame();
                rsc->timerSet(RS_TIMER_INTERNAL);
                rsc->timerPrint();
                rsc->timerReset();
            }
        }
    }

    ALOGV("%p RS Thread exiting", rsc);

    if (rsc->mIsGraphicsContext) {
        pthread_mutex_lock(&gInitMutex);
        rsc->deinitEGL();
        pthread_mutex_unlock(&gInitMutex);
    }

    ALOGV("%p RS Thread exited", rsc);
    return NULL;
}