Beispiel #1
0
/*  private native int _eglCopyBuffers ( int display , int surface , Graphics target ) ; */
KNIEXPORT KNI_RETURNTYPE_INT
Java_javax_microedition_khronos_egl_EGL10Impl__1eglCopyBuffers() {
    EGLDisplay display = (EGLDisplay) KNI_GetParameterAsInt(1);
    EGLSurface surface = (EGLSurface) KNI_GetParameterAsInt(2);
    jint width = KNI_GetParameterAsInt(4);
    jint height = KNI_GetParameterAsInt(5);
    jint flip = 0;

    JSR239_Pixmap *pixmap = (JSR239_Pixmap *) 0;
    EGLBoolean returnValue = EGL_FALSE;
    
    KNI_StartHandles(1);
    KNI_DeclareHandle(graphicsHandle);
    KNI_GetParameterAsObject(3, graphicsHandle);

    returnValue = (jint)eglCopyBuffers((EGLDisplay) display,
                                       (EGLSurface) surface,
                                       (NativePixmapType) pixmap);

#ifdef DEBUG
    printf("eglCopyBuffers(0x%x, 0x%x, 0x%x) = %d\n",
           display, surface, pixmap, returnValue);
#endif
        
    /* Workaround - use glReadPixels if eglCopyBuffers fails. */
    if (returnValue == EGL_FALSE) {
    
        pixmap = JSR239_getImagePixmap(graphicsHandle,
                                   width, height,
                                   4, 8, 8, 8, 8);
        if (!pixmap) {
            KNI_ThrowNew("java.lang.OutOfMemoryException", "eglCopyBuffers");
            goto exit;
        }
    
        // Enforce RGBA order of glReadPixels
        pixmap->aOffset = 24;
        pixmap->bOffset = 16;
        pixmap->gOffset = 8;
        pixmap->rOffset = 0;
    
        returnValue = eglCopyBuffersWorkaround((EGLDisplay) display,
                                               (EGLSurface) surface,
                                               pixmap);
        flip = 1;
    }
    
    if (returnValue == EGL_TRUE) {
        JSR239_putWindowContents(graphicsHandle, pixmap, flip);
    }

    if (pixmap) {
        JSR239_destroyPixmap(pixmap);
    }

 exit:
        
    KNI_EndHandles();
    KNI_ReturnInt((jint)returnValue);
}
/* private native int destroyPixmap( int pixmapPtr ) ; */
KNIEXPORT KNI_RETURNTYPE_VOID
Java_javax_microedition_khronos_egl_EGL10Impl__1destroyPixmap() {

    jint pixmapPtr = KNI_GetParameterAsInt(1);

    JSR239_destroyPixmap((JSR239_Pixmap *)pixmapPtr);
#ifdef DEBUG
    printf("JSR239_destroyPixmap(0x%x)\n", pixmapPtr);
#endif

    KNI_ReturnVoid();
}
KNIEXPORT KNI_RETURNTYPE_VOID
Java_javax_microedition_khronos_egl_EGLSurfaceImpl_finalize() {
    _eglsurface_impl* surface;
    jint pixmap_pointer;

    KNI_StartHandles(1);
    KNI_DeclareHandle(thisObject);
    KNI_GetThisPointer(thisObject);

    surface = GET_EGL_SURFACE(thisObject);
    pixmap_pointer = surface->pixmapPointer;

    JSR239_destroyPixmap((JSR239_Pixmap *)pixmap_pointer);

    KNI_EndHandles();
    KNI_ReturnVoid();
}
/*  private native int _eglCopyBuffers ( int display , int surface , Graphics target ) ; */
KNIEXPORT KNI_RETURNTYPE_INT
Java_javax_microedition_khronos_egl_EGL10Impl__1eglCopyBuffers() {
    EGLDisplay display = (EGLDisplay) KNI_GetParameterAsInt(1);
    EGLSurface surface = (EGLSurface) KNI_GetParameterAsInt(2);
    jint width = KNI_GetParameterAsInt(4);
    jint height = KNI_GetParameterAsInt(5);
    jint delta_height = KNI_GetParameterAsInt(6);
    jint clipX = KNI_GetParameterAsInt(7);
    jint clipY = KNI_GetParameterAsInt(8);
    jint clipWidth = KNI_GetParameterAsInt(9);
    jint clipHeight = KNI_GetParameterAsInt(10);
    JSR239_Pixmap* pixmap;

    // eglCopyBuffers copies the EGL surface color buffer to a native pixmap.
    // As the native pixmaps the Graphics opbject are used. Thus eglCopyBuffers
    // can not be used as the destination buffer can be of a different size as
    // the source surface. In these case call to eglCopyBuffers may lead to
    // the memory corruption.
    // Of course it is more efficient ot use eglCopyBuffers instead of workaround
    // with glReadPixels, but we should do additional checks to do it safely.

    // Let glReadPixels return the data in the following format: 
    const jint bytesPerPixel = 4;
    
    // for data type for glReadPixels we use GL_UNSIGNED_BYTE, one
    // byte for each component
    const jint alphaSize = 8;
    const jint redSize = 8;
    const jint greenSize = 8;
    const jint blueSize = 8;

    KNI_StartHandles(1);
    KNI_DeclareHandle(graphicsHandle);
    KNI_GetParameterAsObject(3, graphicsHandle);

    pixmap = JSR239_getImagePixmap(graphicsHandle, width, height,
                                   bytesPerPixel,
                                   alphaSize, redSize, greenSize, blueSize);

    if (!pixmap) {
        KNI_ThrowNew("java.lang.OutOfMemoryException", "eglCopyBuffers");
        goto exit;
    }

    // Enforce RGBA order of glReadPixels
    pixmap->aOffset = redSize + greenSize + blueSize;
    pixmap->bOffset = greenSize + blueSize;
    pixmap->gOffset = blueSize;
    pixmap->rOffset = 0;

    eglCopyBuffersWorkaround((EGLDisplay)display, (EGLSurface)surface, pixmap);

    // glReadPixels returns pixel data from the color buffer, starting with the
    // pixel whose lower left corner is at location (x, y), into client memory
    // starting at location pixels. Thus we should flip the data returned by
    // glReadPixels
    JSR239_putWindowContents(graphicsHandle, delta_height, 
                             pixmap, 
                             clipX, clipY, clipWidth, clipHeight,
                             1 /*should do flip*/);
    JSR239_destroyPixmap(pixmap);
    
 exit:
    KNI_EndHandles();
    KNI_ReturnInt(EGL_TRUE);
}