status_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item, nsecs_t presentWhen) { status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen); if (err != NO_ERROR) { return err; } int slot = item->mBuf; bool destroyEglImage = false; if (mEglSlots[slot].mEglImage != EGL_NO_IMAGE_KHR) { if (item->mGraphicBuffer != NULL) { // This buffer has not been acquired before, so we must assume // that any EGLImage in mEglSlots is stale. destroyEglImage = true; } else if (mEglSlots[slot].mCropRect != item->mCrop) { // We've already seen this buffer before, but it now has a // different crop rect, so we'll need to recreate the EGLImage if // we're using the EGL_ANDROID_image_crop extension. destroyEglImage = hasEglAndroidImageCrop(); } } if (destroyEglImage) { if (!eglDestroyImageKHR(mEglDisplay, mEglSlots[slot].mEglImage)) { ST_LOGW("acquireBufferLocked: eglDestroyImageKHR failed for slot=%d", slot); // keep going } mEglSlots[slot].mEglImage = EGL_NO_IMAGE_KHR; } return NO_ERROR; }
status_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, const Rect& cropRect, bool forceCreation) { // If there's an image and it's no longer valid, destroy it. bool haveImage = mEglImage != EGL_NO_IMAGE_KHR; bool displayInvalid = mEglDisplay != eglDisplay; bool cropInvalid = hasEglAndroidImageCrop() && mCropRect != cropRect; if (haveImage && (displayInvalid || cropInvalid || forceCreation)) { if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { ALOGE("createIfNeeded: eglDestroyImageKHR failed"); } eglTerminate(mEglDisplay); mEglImage = EGL_NO_IMAGE_KHR; mEglDisplay = EGL_NO_DISPLAY; } // If there's no image, create one. if (mEglImage == EGL_NO_IMAGE_KHR) { mEglDisplay = eglDisplay; mCropRect = cropRect; mEglImage = createImage(mEglDisplay, mGraphicBuffer, mCropRect); } // Fail if we can't create a valid image. if (mEglImage == EGL_NO_IMAGE_KHR) { mEglDisplay = EGL_NO_DISPLAY; mCropRect.makeInvalid(); const sp<GraphicBuffer>& buffer = mGraphicBuffer; ALOGE("Failed to create image. size=%ux%u st=%u usage=0x%x fmt=%d", buffer->getWidth(), buffer->getHeight(), buffer->getStride(), buffer->getUsage(), buffer->getPixelFormat()); return UNKNOWN_ERROR; } return OK; }
static bool isEglImageCroppable(const Rect& crop) { return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0); }