bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs, nsecs_t sysTime) const { if (mRefCount[stream] != 0) { return true; } if (inPastMs == 0) { return false; } if (sysTime == 0) { sysTime = systemTime(); } if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { return true; } return false; }
int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer) { FramebufferNativeWindow* self = getSelf(window); framebuffer_device_t* fb = self->fbDev; int index = self->mBufferHead; #ifdef GFX_TESTFRAMEWORK char eventID[TF_EVENT_ID_SIZE_MAX]; snprintf(eventID, TF_EVENT_ID_SIZE_MAX, "Dequeue-%d", index); nsecs_t start = systemTime(); TF_PRINT(TF_EVENT_START, "FBNW", eventID, "BUFFER:FBNW dequeue start"); #endif GraphicLog& logger(GraphicLog::getInstance()); logger.log(GraphicLog::SF_FB_DEQUEUE_BEFORE, index); /* The buffer is available, return it */ Mutex::Autolock _l(self->mutex); // wait if the number of free buffers <= 0 while (self->mNumFreeBuffers <= 0) { self->mCondition.wait(self->mutex); } self->mBufferHead++; if (self->mBufferHead >= self->mNumBuffers) self->mBufferHead = 0; // get this buffer self->mNumFreeBuffers--; self->mCurrentBufferIndex = index; *buffer = self->buffers[index].get(); #ifdef GFX_TESTFRAMEWORK nsecs_t end = systemTime(); int dqtime = ns2ms(end - start); TF_PRINT(TF_EVENT_STOP, "FBNW", eventID, "BUFFER:FBNW dequeue end, DequeueTime %d on buf %d", dqtime, index); #endif logger.log(GraphicLog::SF_FB_DEQUEUE_AFTER, index); return 0; }
void BufferQueueDump::dumpBuffer() const { char value[PROPERTY_VALUE_MAX]; property_get(PROP_DUMP_NAME, value, DEFAULT_DUMP_NAME); if (strstr(value, PREFIX_NODUMP) == value) { // find prefix for no dump return; } if (!((!strcmp(value, STR_DUMPALL)) || (-1 != mName.find(value)))) { // no dump for me return; } // at first, dump backup buffer if needed if (mBackupBuf.getSize() > 0) { // dump all backup buffer mBackupBuf.dump(); } String8 name; String8 prefix; getDumpFileName(name, mName); uint32_t offset = mBackupBuf.getValidSize(); // dump acquired buffers for (uint32_t i = 0; i < mAcquiredBufs.size(); i++) { if (mAcquiredBufs[i]->mGraphicBuffer != NULL) { prefix = String8::format("%s_%u_ts%lldms", name.string(), offset + i, ns2ms(mAcquiredBufs[i]->mTimeStamp)); if (mAcquiredBufs[i]->mFence != NULL) mAcquiredBufs[i]->mFence->waitForever("BufferQueue::Dump::dumpBuffer"); GraphicBufferExtra::dump(mAcquiredBufs[i]->mGraphicBuffer, prefix.string(), DUMP_FILE_PATH); ST_LOGD("dumpBuffer: dump acquired buffer %u", i); } } }
int FramebufferNativeWindow::lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer) { FramebufferNativeWindow* self = getSelf(window); framebuffer_device_t* fb = self->fbDev; int index = -1; #ifdef GFX_TESTFRAMEWORK char eventID[TF_EVENT_ID_SIZE_MAX]; index = self->mCurrentBufferIndex; snprintf(eventID, TF_EVENT_ID_SIZE_MAX, "lock-%d", index); nsecs_t start = systemTime(); TF_PRINT(TF_EVENT_START, "FBNW", eventID, "BUFFER:FBNW lock start"); #endif { Mutex::Autolock _l(self->mutex); index = self->mCurrentBufferIndex; } GraphicLog& logger(GraphicLog::getInstance()); logger.log(GraphicLog::SF_FB_LOCK_BEFORE, index); if (!fb->lockBuffer) { while (self->front == buffer) { self->mCondition.wait(self->mutex); } } else { fb->lockBuffer(fb, index); } logger.log(GraphicLog::SF_FB_LOCK_AFTER, index); #ifdef GFX_TESTFRAMEWORK nsecs_t end = systemTime(); int lktime = ns2ms(end - start); TF_PRINT(TF_EVENT_STOP, "FBNW", eventID, "BUFFER:FBNW lock end, LockTime %d on buf %d", lktime, index); #endif return NO_ERROR; }
int FramebufferNativeWindow::queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer) { FramebufferNativeWindow* self = getSelf(window); int index = -1; #ifdef GFX_TESTFRAMEWORK char eventID[TF_EVENT_ID_SIZE_MAX]; index = self->mCurrentBufferIndex; snprintf(eventID, TF_EVENT_ID_SIZE_MAX, "Queue-%d", index); nsecs_t start = systemTime(); TF_PRINT(TF_EVENT_START, "FBNW", eventID, "BUFFER:FBNW Queue start"); #endif Mutex::Autolock _l(self->mutex); framebuffer_device_t* fb = self->fbDev; buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle; index = self->mCurrentBufferIndex; GraphicLog& logger(GraphicLog::getInstance()); logger.log(GraphicLog::SF_FB_POST_BEFORE, index); int res = fb->post(fb, handle); logger.log(GraphicLog::SF_FB_POST_AFTER, index); self->front = static_cast<NativeBuffer*>(buffer); self->mNumFreeBuffers++; self->mCondition.broadcast(); #ifdef GFX_TESTFRAMEWORK nsecs_t end = systemTime(); int qtime = ns2ms(end - start); TF_PRINT(TF_EVENT_STOP, "FBNW", eventID, "BUFFER:FBNW Queue end, QueueTime %d on buf %d", qtime, index); //todo: need add detailed stats like SFClient #endif return res; }
/* * Start the Android runtime. This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". * * Passes the main function two arguments, the class name and the specified * options string. */ void AndroidRuntime::start(const char* className, const char* options) { ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n", className != NULL ? className : "(unknown)"); /* * 'startSystemServer == true' means runtime is obsolete and not run from * init.rc anymore, so we print out the boot start event here. */ if (strcmp(options, "start-system-server") == 0) { /* track our progress through the boot sequence */ const int LOG_BOOT_PROGRESS_START = 3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } const char* rootDir = getenv("ANDROID_ROOT"); if (rootDir == NULL) { rootDir = "/system"; if (!hasDir("/system")) { LOG_FATAL("No root directory specified, and /android does not exist."); return; } setenv("ANDROID_ROOT", rootDir, 1); } //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return; } onVmCreated(env); /* * Register android functions. */ if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } /* * We want to call main() with a String array with arguments in it. * At present we have two arguments, the class name and an option string. * Create an array to hold them. */ jclass stringClass; jobjectArray strArray; jstring classNameStr; jstring optionsStr; stringClass = env->FindClass("java/lang/String"); assert(stringClass != NULL); strArray = env->NewObjectArray(2, stringClass, NULL); assert(strArray != NULL); classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); optionsStr = env->NewStringUTF(options); env->SetObjectArrayElement(strArray, 1, optionsStr); /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } free(slashClassName); ALOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) ALOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) ALOGW("Warning: VM did not shut down cleanly\n"); }
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) { AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; mHandle->module->popAttenu(0); // 20100604 [email protected], No pop noise set(amp on delay) [START_LGE] mHandle->module->route(mHandle, mHandle->curDev, mHandle->curMode); //[email protected] 20100308 codec_onoff usleep(35000); //201104011 [email protected], fix sound tick noise from global B } /* check if handle is still valid, otherwise we are coming out of standby */ if(mHandle->handle == NULL) { nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); nsecs_t delta = systemTime() - previously; LOGE("1.RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } acoustic_device_t *aDev = acoustics(); // For output, we will pass the data on to the acoustics module, but the actual // data is expected to be sent to the audio device directly as well. if (aDev && aDev->write) aDev->write(aDev, buffer, bytes); #if 0 snd_pcm_sframes_t n; #else //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. snd_pcm_sframes_t n = 0; #endif size_t sent = 0; status_t err; do { //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [START] if(mHandle->handle != NULL) { //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [END] n = snd_pcm_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [START] } else{ nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); nsecs_t delta = systemTime() - previously; LOGD("2.RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [END] if (n == -EBADFD) { // Somehow the stream is in a bad state. The driver probably // has a bug and snd_pcm_recover() doesn't seem to handle this. mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); if (aDev && aDev->recover) aDev->recover(aDev, n); //bail if (n) return static_cast<ssize_t>(n); } else if (n < 0) { if (mHandle->handle) { // snd_pcm_recover() will return 0 if successful in recovering from // an error, or -errno if the error was unrecoverable. n = snd_pcm_recover(mHandle->handle, n, 1); if (aDev && aDev->recover) aDev->recover(aDev, n); if (n) return static_cast<ssize_t>(n); } } else { if(mHandle->handle){ //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. mFrameCount += n; sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [START] } else{ nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); nsecs_t delta = systemTime() - previously; LOGD("3.RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [END] } } while (mHandle->handle && sent < bytes); return sent; }
void SecTVOutService::blit2Hdmi(uint32_t w, uint32_t h, uint32_t colorFormat, uint32_t pPhyYAddr, uint32_t pPhyCbAddr, uint32_t pPhyCrAddr, uint32_t dstX, uint32_t dstY, uint32_t hdmiMode, uint32_t num_of_hwc_layer) { Mutex::Autolock _l(mLock); if (hdmiCableInserted() == false) return; int hdmiLayer = SecHdmi::HDMI_LAYER_VIDEO; #if defined(CHECK_UI_TIME) || defined(CHECK_VIDEO_TIME) nsecs_t start, end; #endif sp<MessageBase> msg; switch (hdmiMode) { case HDMI_MODE_UI : if (mHwcLayer >= 2) hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_0; else if (mHwcLayer == 1) hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_1; else #ifdef SUPPORT_G2D_UI_MODE hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_1; #else hdmiLayer = SecHdmi::HDMI_LAYER_VIDEO; #endif #ifdef SUPPORT_G2D_UI_MODE if (mHwcLayer == 0) { if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_VIDEO) == false) LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_VIDEO); if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_GRAPHIC_0) == false) LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_GRAPHIC_0); } #endif if (mUILayerMode != hdmiLayer) { if (mSecHdmi.clear(mUILayerMode) == false) LOGE("%s::mSecHdmi.clear(%d) fail", __func__, mUILayerMode); } mUILayerMode = hdmiLayer; #if !defined(BOARD_USES_HDMI_SUBTITLES) if (mHwcLayer == 0) #endif #if (DIRECT_UI_RENDERING == 1) { #ifdef CHECK_UI_TIME start = systemTime(); #endif if (mSecHdmi.flush(w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, mUILayerMode, mHwcLayer) == false) LOGE("%s::mSecHdmi.flush() on HDMI_MODE_UI fail", __func__); #ifdef CHECK_UI_TIME end = systemTime(); LOGD("[UI] mSecHdmi.flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); #endif } #else { msg = new SecHdmiEventMsg(&mSecHdmi, w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, mUILayerMode, mHwcLayer, HDMI_MODE_UI); /* post to HdmiEventQueue */ mHdmiEventQueue.postMessage(msg, 0, 0); } #endif break; case HDMI_MODE_VIDEO : #if !defined(BOARD_USES_HDMI_SUBTITLES) #ifdef SUPPORT_G2D_UI_MODE if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_GRAPHIC_0) == false) LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_GRAPHIC_0); if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_GRAPHIC_1) == false) LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_GRAPHIC_1); #endif #endif #if (DIRECT_VIDEO_RENDERING == 1) #ifdef CHECK_VIDEO_TIME start = systemTime(); #endif if (mSecHdmi.flush(w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, SecHdmi::HDMI_LAYER_VIDEO, mHwcLayer) == false) LOGE("%s::mSecHdmi.flush() on HDMI_MODE_VIDEO fail", __func__); #ifdef CHECK_VIDEO_TIME end = systemTime(); LOGD("[Video] mSecHdmi.flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); #endif #else msg = new SecHdmiEventMsg(&mSecHdmi, w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, SecHdmi::HDMI_LAYER_VIDEO, mHwcLayer, HDMI_MODE_VIDEO); /* post to HdmiEventQueue */ mHdmiEventQueue.postMessage(msg, 0, 0); #endif break; default: LOGE("unmatched HDMI_MODE : %d", hdmiMode); break; } return; }
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) { AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; usleep(35000); //201104011 [email protected], fix sound tick noise from global B } /* check if handle is still valid, otherwise we are coming out of standby */ if(mHandle->handle == NULL) { nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode, mHandle->curChannels); nsecs_t delta = systemTime() - previously; LOGE("RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } acoustic_device_t *aDev = acoustics(); // For output, we will pass the data on to the acoustics module, but the actual // data is expected to be sent to the audio device directly as well. if (aDev && aDev->write) aDev->write(aDev, buffer, bytes); snd_pcm_sframes_t n; size_t sent = 0; status_t err; while (mHandle->handle && sent < bytes) { n = snd_pcm_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); if (n == -EBADFD) { // Somehow the stream is in a bad state. The driver probably // has a bug and snd_pcm_recover() doesn't seem to handle this. mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode, mHandle->curChannels); if (aDev && aDev->recover) aDev->recover(aDev, n); } else if (n < 0) { if (mHandle->handle) { // snd_pcm_recover() will return 0 if successful in recovering from // an error, or -errno if the error was unrecoverable. n = snd_pcm_recover(mHandle->handle, n, 1); if (aDev && aDev->recover) aDev->recover(aDev, n); if (n) return static_cast<ssize_t>(n); } } else { if (mHandle->handle) { mFrameCount += n; sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); } } } return sent; }
/* * Start the Android runtime. This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". */ void AndroidRuntime::start(const char* className, const bool startSystemServer) { LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n", className != NULL ? className : "(unknown)"); char* slashClassName = NULL; char* cp; JNIEnv* env; blockSigpipe(); /* * 'startSystemServer == true' means runtime is obslete and not run from * init.rc anymore, so we print out the boot start event here. */ if (startSystemServer) { /* track our progress through the boot sequence */ const int LOG_BOOT_PROGRESS_START = 3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } const char* rootDir = getenv("ANDROID_ROOT"); if (rootDir == NULL) { rootDir = "/system"; if (!hasDir("/system")) { LOG_FATAL("No root directory specified, and /android does not exist."); goto bail; } setenv("ANDROID_ROOT", rootDir, 1); } //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); /* start the virtual machine */ if (startVm(&mJavaVM, &env) != 0) goto bail; /* * Register android functions. */ if (startReg(env) < 0) { LOGE("Unable to register all android natives\n"); goto bail; } /* * We want to call main() with a String array with arguments in it. * At present we only have one argument, the class name. Create an * array to hold it. */ jclass stringClass; jobjectArray strArray; jstring classNameStr; jstring startSystemServerStr; stringClass = env->FindClass("java/lang/String"); assert(stringClass != NULL); strArray = env->NewObjectArray(2, stringClass, NULL); assert(strArray != NULL); classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); startSystemServerStr = env->NewStringUTF(startSystemServer ? "true" : "false"); env->SetObjectArrayElement(strArray, 1, startSystemServerStr); /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ jclass startClass; jmethodID startMeth; slashClassName = strdup(className); for (cp = slashClassName; *cp != '\0'; cp++) if (*cp == '.') *cp = '/'; startClass = env->FindClass(slashClassName); if (startClass == NULL) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { LOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } LOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) LOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) LOGW("Warning: VM did not shut down cleanly\n"); bail: free(slashClassName); }
OsStatus MpidAndroid::enableDevice(unsigned samplesPerFrame, unsigned samplesPerSec, MpFrameTime currentFrameTime) { OsStatus status = OS_SUCCESS; // If the device is not valid, let the user know it's bad. if (!isDeviceValid()) { return OS_INVALID; // perhaps new OsState of OS_RESOURCE_INVALID? } if (isEnabled()) { return OS_NAME_IN_USE; } LOGI("MpidAndroid::enableDevice()"); // Start accessing non-atomic member variables AutoMutex autoLock(mLock); if (mState != DRIVER_IDLE) { LOGW("MpidAndroid::enableDevice() wrong state %d\n", mState); return OS_INVALID_STATE; } // Set some wave header stat information. mSamplesPerFrame = samplesPerFrame; mSamplesPerSec = samplesPerSec; mCurrentFrameTime = currentFrameTime; if (probeSampleRate(mSamplesPerSec, mSamplesPerFrame, mpSampleRatesList, mSampleRatesListLen)) { LOGV("MpidAndroid::enableDevice() INIT OK, time: %"PRId64"\n", ns2ms(systemTime())); } else { LOGW("MpidAndroid::enableDevice() INIT FAILED!!!\n"); return OS_INVALID_ARGUMENT; } if (mState != DRIVER_INIT) { LOGW("MpidAndroid::enableDevice() wrong state: %d\n", mState); return OS_INVALID_STATE; } // Allocate internal buffer assert(mSamplesPerFrameInternal > 0); mpBufInternal = new MpAudioSample[mSamplesPerFrameInternal]; assert(mpBufInternal != NULL); mBufInternalSamples = 0; // Create resampler if (mSamplesPerSecInternal != mSamplesPerSec) { OsSysLog::add(FAC_MP, PRI_ERR, "mSamplesPerSecInternal: %d mSamplesPerSec: %d\n", mSamplesPerSecInternal, mSamplesPerSec); LOGV("mSamplesPerSecInternal: %d mSamplesPerSec: %d\n", mSamplesPerSecInternal, mSamplesPerSec); mpResampler = MpResamplerBase::createResampler(1, mSamplesPerSecInternal, mSamplesPerSec); mpResampleBuf = new MpAudioSample[mSamplesPerFrame]; assert(mpResampler != NULL && mpResampleBuf != NULL); } mState = DRIVER_STARTING; mLock.unlock(); int startStatus = mpAudioRecord->start(); if(startStatus != NO_ERROR) { OsSysLog::add(FAC_MP, PRI_ERR, "MpidAndroid::enableDevice AudioRecord::start returned error: %d", startStatus); LOGE("MpidAndroid::enableDevice AudioRecord::start returned error: %d", startStatus); switch(startStatus) { case INVALID_OPERATION: status = OS_LIMIT_REACHED; break; default: status = OS_FAILED; break; } mState = DRIVER_IDLE; mIsEnabled = FALSE; return(status); } mLock.lock(); if (mState == DRIVER_STARTING) { LOGV("MpidAndroid::enableDevice() waiting for start callback"); status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); if (lStatus != NO_ERROR) { LOGE("MpidAndroid::enableDevice() callback timed out, status %d", lStatus); mState = DRIVER_IDLE; mIsEnabled = FALSE; return OS_WAIT_TIMEOUT; } } else { LOGW("MpidAndroid::enableDevice() state %d\n", mState); } LOGV("MpidAndroid::enableDevice() started, time %"PRId64"\n", ns2ms(systemTime())); // Indicate driver has been started. mIsEnabled = TRUE; return status; }
int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy, int fd) { int ret = 0; int acquireFd[MAX_NUM_APP_LAYERS]; int count = 0; int releaseFd = -1; int retireFd = -1; int fbFd = -1; bool swapzero = false; int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); struct mdp_buf_sync data; memset(&data, 0, sizeof(data)); //Until B-family supports sync for rotator if(mdpVersion >= qdutils::MDSS_V5) { data.flags = MDP_BUF_SYNC_FLAG_WAIT; } data.acq_fen_fd = acquireFd; data.rel_fen_fd = &releaseFd; data.retire_fen_fd = &retireFd; char property[PROPERTY_VALUE_MAX]; if(property_get("debug.egl.swapinterval", property, "1") > 0) { if(atoi(property) == 0) swapzero = true; } #ifndef MDSS_TARGET //Send acquireFenceFds to rotator if(mdpVersion < qdutils::MDSS_V5) { //A-family int rotFd = ctx->mRotMgr->getRotDevFd(); struct msm_rotator_buf_sync rotData; for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) { memset(&rotData, 0, sizeof(rotData)); int& acquireFenceFd = ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd; rotData.acq_fen_fd = acquireFenceFd; rotData.session_id = ctx->mLayerRotMap[dpy]->getRot(i)->getSessId(); ioctl(rotFd, MSM_ROTATOR_IOCTL_BUFFER_SYNC, &rotData); close(acquireFenceFd); //For MDP to wait on. acquireFenceFd = dup(rotData.rel_fen_fd); //A buffer is free to be used by producer as soon as its copied to //rotator. ctx->mLayerRotMap[dpy]->getLayer(i)->releaseFenceFd = rotData.rel_fen_fd; } } else { //TODO B-family } #endif //Accumulate acquireFenceFds for MDP for(uint32_t i = 0; i < list->numHwLayers; i++) { if(list->hwLayers[i].compositionType == HWC_OVERLAY && list->hwLayers[i].acquireFenceFd >= 0) { if(UNLIKELY(swapzero)) acquireFd[count++] = -1; else acquireFd[count++] = list->hwLayers[i].acquireFenceFd; } if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { if(UNLIKELY(swapzero)) acquireFd[count++] = -1; else if(fd >= 0) { //set the acquireFD from fd - which is coming from c2d acquireFd[count++] = fd; // Buffer sync IOCTL should be async when using c2d fence is // used data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT; } else if(list->hwLayers[i].acquireFenceFd >= 0) acquireFd[count++] = list->hwLayers[i].acquireFenceFd; } } data.acq_fen_fd_cnt = count; fbFd = ctx->dpyAttr[dpy].fd; //Waits for acquire fences, returns a release fence if(LIKELY(!swapzero)) { uint64_t start = systemTime(); ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data); ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d", __FUNCTION__, (size_t) ns2ms(systemTime() - start)); } if(ret < 0) { ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s", strerror(errno)); } for(uint32_t i = 0; i < list->numHwLayers; i++) { if(list->hwLayers[i].compositionType == HWC_OVERLAY || list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { //Populate releaseFenceFds. if(UNLIKELY(swapzero)) { list->hwLayers[i].releaseFenceFd = -1; } else if(list->hwLayers[i].releaseFenceFd < 0) { //If rotator has not already populated this field. list->hwLayers[i].releaseFenceFd = dup(releaseFd); } } } if(fd >= 0) { close(fd); fd = -1; } if (ctx->mCopyBit[dpy]) ctx->mCopyBit[dpy]->setReleaseFd(releaseFd); //A-family if(mdpVersion < qdutils::MDSS_V5) { //Signals when MDP finishes reading rotator buffers. ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd); } close(releaseFd); if(UNLIKELY(swapzero)) list->retireFenceFd = -1; else list->retireFenceFd = retireFd; return ret; }
int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy, int fd) { int ret = 0; struct mdp_buf_sync data; int acquireFd[MAX_NUM_LAYERS]; int count = 0; int releaseFd = -1; int fbFd = -1; memset(&data, 0, sizeof(data)); bool swapzero = false; data.flags = MDP_BUF_SYNC_FLAG_WAIT; data.acq_fen_fd = acquireFd; data.rel_fen_fd = &releaseFd; char property[PROPERTY_VALUE_MAX]; if(property_get("debug.egl.swapinterval", property, "1") > 0) { if(atoi(property) == 0) swapzero = true; } //Accumulate acquireFenceFds for(uint32_t i = 0; i < list->numHwLayers; i++) { if(list->hwLayers[i].compositionType == HWC_OVERLAY && list->hwLayers[i].acquireFenceFd != -1) { if(UNLIKELY(swapzero)) acquireFd[count++] = -1; else acquireFd[count++] = list->hwLayers[i].acquireFenceFd; } if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { if(UNLIKELY(swapzero)) acquireFd[count++] = -1; else if(fd != -1) { //set the acquireFD from fd - which is coming from c2d acquireFd[count++] = fd; // Buffer sync IOCTL should be async when using c2d fence is // used data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT; } else if(list->hwLayers[i].acquireFenceFd != -1) acquireFd[count++] = list->hwLayers[i].acquireFenceFd; } } data.acq_fen_fd_cnt = count; fbFd = ctx->dpyAttr[dpy].fd; //Waits for acquire fences, returns a release fence if(LIKELY(!swapzero)) { uint64_t start = systemTime(); ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data); ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d", __FUNCTION__, (size_t) ns2ms(systemTime() - start)); } if(ret < 0) { ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s", strerror(errno)); } for(uint32_t i = 0; i < list->numHwLayers; i++) { if(list->hwLayers[i].compositionType == HWC_OVERLAY || list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { //Close the acquireFenceFds if(list->hwLayers[i].acquireFenceFd >= 0) { close(list->hwLayers[i].acquireFenceFd); list->hwLayers[i].acquireFenceFd = -1; } if(fd >= 0) { close(fd); fd = -1; } //Populate releaseFenceFds. if(UNLIKELY(swapzero)) list->hwLayers[i].releaseFenceFd = -1; else list->hwLayers[i].releaseFenceFd = dup(releaseFd); } } if(UNLIKELY(swapzero)){ list->retireFenceFd = -1; close(releaseFd); } else { list->retireFenceFd = releaseFd; } return ret; }
status_t GuiExtPool::alloc(const sp<IBinder>& token, uint32_t gralloc_usage, uint32_t w, uint32_t h, uint32_t * poolId) { Mutex::Autolock _l(mLock); ATRACE_CALL(); GUIEXT_LOGD(" alloc, gralloc_usage=%x, w=%d, h=%d", gralloc_usage, w, h); const nsecs_t time_start = systemTime(); uint32_t size = mPoolList.size(); if (size >= MAX_ALLOC_SIZE) { GUIEXT_LOGW(" alloc pools size is reaching %d, can't alloc", size); *poolId = 0; return NOT_ENOUGH_DATA; } if (size == 0) { DisplayInfo dinfo; sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay( ISurfaceComposer::eDisplayIdMain); SurfaceComposerClient::getDisplayInfo(display, &dinfo); mDefaultDisplayWidth = dinfo.w; mDefaultDisplayHeight = dinfo.h; sp<DispInfo> disp = new DispInfo; disp->type = 0; disp->w = mDefaultDisplayWidth; disp->h = mDefaultDisplayHeight; disp->bufNum = MAX_HWC_DEQUEUED_NUM; mDisplayList.add((uint32_t)HWC_DISPLAY_PRIMARY, disp); GUIEXT_LOGI("pool list size=0, try to get default display(w x h) = (%d x %d)", disp->w, disp->h); } *poolId = getPoolId(); bool isHwcNeeded = gralloc_usage & GRALLOC_USAGE_HW_COMPOSER; class ProducerDeathObserver : public IBinder::DeathRecipient { GuiExtPool & mPool; virtual void binderDied(const wp<IBinder>& who) { uint32_t size = mPool.mPoolList.size(); GUIEXT_LOGI("producer died, pool size=%d, binder ptr=[%p]", size, who.unsafe_get()); if (size == 0) { GUIEXT_LOGV("producer died [%p], pool size is zero", who.unsafe_get()); } else { for (uint32_t i = size-1 ;; i--) { GUIEXT_LOGV(" [p] compare index[%d], p=[%p]", i, mPool.mPoolList[i]->mProducerToken.get()); if (mPool.mPoolList[i]->mProducerToken.get() == who.unsafe_get()) { GUIEXT_LOGW(" [p] found index[%d], p=[%p], id=%d", i, mPool.mPoolList[i]->mProducerToken.get(), mPool.mPoolList[i]->mId); mPool.mPoolList[i]->mProducerToken = NULL; mPool.mPoolList[i]->mProducerPid = -1; mPool.removePoolItem(mPool.mPoolList[i]->mId); } if (i == 0) break; } GUIEXT_LOGV("producer died done"); } } public: ProducerDeathObserver(GuiExtPool & pool) : mPool(pool) { } }; sp<IBinder::DeathRecipient> observer = new ProducerDeathObserver(*const_cast<GuiExtPool*>(this)); token->linkToDeath(observer); sp<GuiExtPoolItem> item = new GuiExtPoolItem(token, isHwcNeeded, *poolId, w, h, mDisplayList, observer); status_t err; err = item->prepareBuffer(gralloc_usage); if (err != NO_ERROR) { GUIEXT_LOGE(" alloc fail, isHWcNeeded=%d, w=%d, h=%d, usage=%x, poolId=%d", isHwcNeeded, w, h, gralloc_usage, *poolId); *poolId = 0; return err; } mPoolList.add(*poolId, item); const nsecs_t time_end = systemTime(); GUIEXT_LOGI(" alloc cost time=%" PRId64 " ms, gralloc_usage=%x, w=%d, h=%d, poolId=%d", ns2ms(time_end - time_start), gralloc_usage, w, h, *poolId); return err; }