status_t GLConsumer::detachFromContext() { ATRACE_CALL(); #ifndef MTK_DEFAULT_AOSP ST_LOGI("detachFromContext"); #else ST_LOGV("detachFromContext"); #endif Mutex::Autolock lock(mMutex); if (mAbandoned) { ST_LOGE("detachFromContext: abandoned GLConsumer"); return NO_INIT; } if (!mAttached) { ST_LOGE("detachFromContext: GLConsumer is not attached to a " "context"); return INVALID_OPERATION; } EGLDisplay dpy = eglGetCurrentDisplay(); EGLContext ctx = eglGetCurrentContext(); if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { ST_LOGE("detachFromContext: invalid current EGLDisplay"); return INVALID_OPERATION; } if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { ST_LOGE("detachFromContext: invalid current EGLContext"); return INVALID_OPERATION; } if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { status_t err = syncForReleaseLocked(dpy); if (err != OK) { return err; } glDeleteTextures(1, &mTexName); } // Because we're giving up the EGLDisplay we need to free all the EGLImages // that are associated with it. They'll be recreated when the // GLConsumer gets attached to a new OpenGL ES context (and thus gets a // new EGLDisplay). for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { EGLImageKHR img = mEglSlots[i].mEglImage; if (img != EGL_NO_IMAGE_KHR) { eglDestroyImageKHR(mEglDisplay, img); mEglSlots[i].mEglImage = EGL_NO_IMAGE_KHR; } } mEglDisplay = EGL_NO_DISPLAY; mEglContext = EGL_NO_CONTEXT; mAttached = false; return OK; }
GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, uint32_t texTarget, bool useFenceSync, bool isControlledByApp) : ConsumerBase(bq, isControlledByApp), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentFence(Fence::NO_FENCE), mCurrentTimestamp(0), mCurrentFrameNumber(0), mDefaultWidth(1), mDefaultHeight(1), mFilteringEnabled(true), mTexName(tex), mUseFenceSync(useFenceSync), mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(true) { #ifndef MTK_DEFAULT_AOSP ST_LOGI("GLConsumer"); #else ST_LOGV("GLConsumer"); #endif memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix)); mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); }
status_t GLConsumer::attachToContext(uint32_t tex) { ATRACE_CALL(); #ifndef MTK_DEFAULT_AOSP ST_LOGI("attachToContext"); #else ST_LOGV("attachToContext"); #endif Mutex::Autolock lock(mMutex); if (mAbandoned) { ST_LOGE("attachToContext: abandoned GLConsumer"); return NO_INIT; } if (mAttached) { ST_LOGE("attachToContext: GLConsumer is already attached to a " "context"); return INVALID_OPERATION; } EGLDisplay dpy = eglGetCurrentDisplay(); EGLContext ctx = eglGetCurrentContext(); if (dpy == EGL_NO_DISPLAY) { ST_LOGE("attachToContext: invalid current EGLDisplay"); return INVALID_OPERATION; } if (ctx == EGL_NO_CONTEXT) { ST_LOGE("attachToContext: invalid current EGLContext"); return INVALID_OPERATION; } // We need to bind the texture regardless of whether there's a current // buffer. glBindTexture(mTexTarget, GLuint(tex)); if (mCurrentTextureBuf != NULL) { // The EGLImageKHR that was associated with the slot was destroyed when // the GLConsumer was detached from the old context, so we need to // recreate it here. status_t err = bindUnslottedBufferLocked(dpy); if (err != NO_ERROR) { return err; } } mEglDisplay = dpy; mEglContext = ctx; mTexName = tex; mAttached = true; return OK; }
status_t SurfaceTexture::forceAuxConversionLocked() { status_t err = NO_ERROR; ST_LOGI("[%s] mCurrentTexture:%d, mCurrentBuf:%p", __func__, mCurrentTexture, mCurrentTextureBuf.get()); if ((mCurrentTextureBuf != NULL) && (checkPixelFormatSupported(mCurrentTextureBuf) == OK)) { err = convertToAuxSlotLocked(true); } return err; }
void BackupBufDumper::dump() { String8 name; String8 prefix; BufferQueueDump::getDumpFileName(name, mName); for (uint32_t i = 0; i < mRingBuffer.getValidSize(); i++) { const sp<BackupBuffer>& buffer = getItem(i); prefix = String8::format("%s_%u_ts%lldms", name.string(), i, ns2ms(buffer->mTimeStamp)); GraphicBufferExtra::dump(buffer->mGraphicBuffer, prefix.string(), DUMP_FILE_PATH); ST_LOGI("dump: handle=%p", buffer->mGraphicBuffer->handle); } }
void GLConsumer::freeBufferLocked(int slotIndex) { ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); if (slotIndex == mCurrentTexture) { mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; } EGLImageKHR img = mEglSlots[slotIndex].mEglImage; if (img != EGL_NO_IMAGE_KHR) { #ifndef MTK_DEFAULT_AOSP ST_LOGI("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); #else ST_LOGV("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); #endif eglDestroyImageKHR(mEglDisplay, img); } mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; ConsumerBase::freeBufferLocked(slotIndex); }
EGLImageKHR GLConsumer::createImage(EGLDisplay dpy, const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) { EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_IMAGE_CROP_LEFT_ANDROID, crop.left, EGL_IMAGE_CROP_TOP_ANDROID, crop.top, EGL_IMAGE_CROP_RIGHT_ANDROID, crop.right, EGL_IMAGE_CROP_BOTTOM_ANDROID, crop.bottom, EGL_NONE, }; if (!crop.isValid()) { // No crop rect to set, so terminate the attrib array before the crop. attrs[2] = EGL_NONE; } else if (!isEglImageCroppable(crop)) { // The crop rect is not at the origin, so we can't set the crop on the // EGLImage because that's not allowed by the EGL_ANDROID_image_crop // extension. In the future we can add a layered extension that // removes this restriction if there is hardware that can support it. attrs[2] = EGL_NONE; } EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); if (image == EGL_NO_IMAGE_KHR) { EGLint error = eglGetError(); ST_LOGE("error creating EGLImage: %#x", error); } #ifndef MTK_DEFAULT_AOSP else { // add log for eglImage created ST_LOGI("[%s]", __func__); ALOGD(" GraphicBuffer: gb=%p handle=%p fmt=%d", graphicBuffer.get(), graphicBuffer->handle, graphicBuffer->format); ALOGD(" EGLImage: dpy=%p, img=%p", mEglDisplay, image); } #endif return image; }