EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy,
        const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) {
    EGLClientBuffer cbuf =
            static_cast<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;
    }
    eglInitialize(dpy, 0, 0);
    EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
            EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
    if (image == EGL_NO_IMAGE_KHR) {
        EGLint error = eglGetError();
        ALOGE("error creating EGLImage: %#x", error);
        eglTerminate(dpy);
    }
    return image;
}
Пример #2
0
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;
}
Пример #3
0
void GLConsumer::computeCurrentTransformMatrixLocked() {
    ST_LOGV("computeCurrentTransformMatrixLocked");

    float xform[16];
    for (int i = 0; i < 16; i++) {
        xform[i] = mtxIdentity[i];
    }
    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
        float result[16];
        mtxMul(result, xform, mtxFlipH);
        for (int i = 0; i < 16; i++) {
            xform[i] = result[i];
        }
    }
    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
        float result[16];
        mtxMul(result, xform, mtxFlipV);
        for (int i = 0; i < 16; i++) {
            xform[i] = result[i];
        }
    }
    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
        float result[16];
        mtxMul(result, xform, mtxRot90);
        for (int i = 0; i < 16; i++) {
            xform[i] = result[i];
        }
    }

    sp<GraphicBuffer>& buf(mCurrentTextureBuf);

    if (buf == NULL) {
        ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureBuf is NULL");
    }

    float mtxBeforeFlipV[16];
    if (!isEglImageCroppable(mCurrentCrop)) {
        Rect cropRect = mCurrentCrop;
        float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f;
        float bufferWidth = buf->getWidth();
        float bufferHeight = buf->getHeight();
        if (!cropRect.isEmpty()) {
            float shrinkAmount = 0.0f;
            if (mFilteringEnabled) {
                // In order to prevent bilinear sampling beyond the edge of the
                // crop rectangle we may need to shrink it by 2 texels in each
                // dimension.  Normally this would just need to take 1/2 a texel
                // off each end, but because the chroma channels of YUV420 images
                // are subsampled we may need to shrink the crop region by a whole
                // texel on each side.
                switch (buf->getPixelFormat()) {
                    case PIXEL_FORMAT_RGBA_8888:
                    case PIXEL_FORMAT_RGBX_8888:
                    case PIXEL_FORMAT_RGB_888:
                    case PIXEL_FORMAT_RGB_565:
                    case PIXEL_FORMAT_BGRA_8888:
                        // We know there's no subsampling of any channels, so we
                        // only need to shrink by a half a pixel.
                        shrinkAmount = 0.5;
                        break;

                    default:
                        // If we don't recognize the format, we must assume the
                        // worst case (that we care about), which is YUV420.
                        shrinkAmount = 1.0;
                        break;
                }
            }

            // Only shrink the dimensions that are not the size of the buffer.
            if (cropRect.width() < bufferWidth) {
                tx = (float(cropRect.left) + shrinkAmount) / bufferWidth;
                sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) /
                        bufferWidth;
            }
            if (cropRect.height() < bufferHeight) {
                ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) /
                        bufferHeight;
                sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) /
                        bufferHeight;
            }
        }
        float crop[16] = {
            sx, 0, 0, 0,
            0, sy, 0, 0,
            0, 0, 1, 0,
            tx, ty, 0, 1,
        };

        mtxMul(mtxBeforeFlipV, crop, xform);
    } else {
        for (int i = 0; i < 16; i++) {
            mtxBeforeFlipV[i] = xform[i];
        }
    }

    // SurfaceFlinger expects the top of its window textures to be at a Y
    // coordinate of 0, so GLConsumer must behave the same way.  We don't
    // want to expose this to applications, however, so we must add an
    // additional vertical flip to the transform after all the other transforms.
    mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV);
}