This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

glReadPixels

Note: This was originally posted on 9th March 2012 at http://forums.arm.com

Hi all,

i try to render scene in an off screen  way, controlling the location of my pixels (the pointer is fixed by myself).
It seems that MALI400 is not supporting eglCreatePixmapSurface, interface that would allows me to create a  surface that will use pixels in the location i want.

As it is not working i have to use the API glReadPixels which is very very slow (compare to other GPU).

So i'm wondering if there is a reason for such bad perf for ReadPixels and if someone knows a way with MALI to render a scene at place (pixel buffer address) you want.

Thanks for your help.

BR

Seb
Parents
  • Note: This was originally posted on 12th March 2012 at http://forums.arm.com

    Hi Karthik,

    thanks a lot for answering me.

    The error i get is 12298 -> 0x300A -> EGL_BAD_NATIVE_PIXMAP
    For infromation i'm working on ANdroid and using Galaxy S2

    the code i wrote is the following one:
    on native side:

    #define PIXEL_FORMAT_RGB_565 4
    typedef struct egl_native_pixmap_t
    {
    int32_t  version; /* must be 32 */
    int32_t  width;
    int32_t  height;
    int32_t  stride;
    uint8_t* data;
    uint8_t  format;
    uint8_t  rfu[3];
    union {
         uint32_t compressedFormat;
         int32_t  vstride;
    };
    int32_t  reserved;
    } egl_native_pixmap_t;


    JNIEXPORT void JNICALL
    Java_com_vmware_mvp_vm_handlers_gpu_PixelBuffer_createPixmapSurface(JNIEnv *_env, jobject _this, jobject out_sur,
         jobject display, jobject config, jobject native_pixmap,
         jintArray attrib_list)
    {
    jfieldID gBitmap_NativeBitmapFieldID;
    jfieldID gSurface_EGLSurfaceFieldID;
    //jfieldID gSurface_NativePixelRefFieldID;

    EGLDisplay dpy = getDisplay(_env, display);
    EGLConfig  cnf = getConfig(_env, config);
    jint* base = 0;

    jclass bitmap_class = _env->FindClass("android/graphics/Bitmap");
    gBitmap_NativeBitmapFieldID = _env->GetFieldID(bitmap_class, "mNativeBitmap", "I");

    jclass gSurface_class = _env->FindClass( "com/google/android/gles_jni/EGLSurfaceImpl");
    gSurface_EGLSurfaceFieldID = _env->GetFieldID(gSurface_class, "mEGLSurface", "I");

    //gSurface_NativePixelRefFieldID = _env->GetFieldID(gSurface_class, "mNativePixelRef", "I");

    SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(native_pixmap,
                     gBitmap_NativeBitmapFieldID);


    egl_native_pixmap_t pixmap;
    pixmap.version = sizeof(pixmap);
    pixmap.width  = nativeBitmap->width();
    pixmap.height = nativeBitmap->height();
    pixmap.stride = nativeBitmap->rowBytes() / nativeBitmap->bytesPerPixel();
    pixmap.format = PIXEL_FORMAT_RGB_565;
    pixmap.data   = (uint8_t*)nativeBitmap->getPixels();

        
    if (attrib_list) {
         // XXX: if array is malformed, we should return an NPE instead of segfault
         base = (jint *)_env->GetPrimitiveArrayCritical(attrib_list, (jboolean *)0);
    }
    EGLSurface sur = eglCreatePixmapSurface(dpy, cnf, &pixmap, base);

    if(sur == EGL_NO_SURFACE)
    {
       int error = eglGetError();
       LogErr("Error (%d) Creating the Pixmap Surface.\n",error);
    }
    if (attrib_list) {
         _env->ReleasePrimitiveArrayCritical(attrib_list, base, JNI_ABORT);
    }

    if (sur != EGL_NO_SURFACE) {
         _env->SetIntField(out_sur, gSurface_EGLSurfaceFieldID, (int)sur);
    }
    }

    on Android side declaration is done as follow
       private native void createPixmapSurface(EGLSurface sur,
                                   EGLDisplay display, EGLConfig config,
                                   Object native_pixmap, int[] attrib_list);



    On Android side call is done as folllow.
      mNativePixmap = Bitmap.createBitmap(mWidth, mHeight,Bitmap.Config.RGB_565);
      
      MY_EGLSurfaceImpl sur = new MY_EGLSurfaceImpl();
      createPixmapSurface(sur,mEGLDisplay, mEGLConfig, mNativePixmap, null);
      mEGLSurface = sur;



    For information i was told by some STE people that PixmapSurface is not supported by MALI400 for Android. But i don't know if it is really true.
    If it is the case then i'm wondering what i can use to remove the need to call glReadPixels.

    I would need to be able to force the place where to render the 3D Scene and as Pixmap is not working then i do have to use glReadPixels.
    I tried FBO also and even if i'm able to render into a texture, then after i also face the problem to get access to texture pixels and have to use glReadPixels.

    As you said perfs seems very bad as soon as you are using glReadPixels so i definitively need a way to bypass such call.

    Again thanks for your help.

    BR

    Seb
Reply
  • Note: This was originally posted on 12th March 2012 at http://forums.arm.com

    Hi Karthik,

    thanks a lot for answering me.

    The error i get is 12298 -> 0x300A -> EGL_BAD_NATIVE_PIXMAP
    For infromation i'm working on ANdroid and using Galaxy S2

    the code i wrote is the following one:
    on native side:

    #define PIXEL_FORMAT_RGB_565 4
    typedef struct egl_native_pixmap_t
    {
    int32_t  version; /* must be 32 */
    int32_t  width;
    int32_t  height;
    int32_t  stride;
    uint8_t* data;
    uint8_t  format;
    uint8_t  rfu[3];
    union {
         uint32_t compressedFormat;
         int32_t  vstride;
    };
    int32_t  reserved;
    } egl_native_pixmap_t;


    JNIEXPORT void JNICALL
    Java_com_vmware_mvp_vm_handlers_gpu_PixelBuffer_createPixmapSurface(JNIEnv *_env, jobject _this, jobject out_sur,
         jobject display, jobject config, jobject native_pixmap,
         jintArray attrib_list)
    {
    jfieldID gBitmap_NativeBitmapFieldID;
    jfieldID gSurface_EGLSurfaceFieldID;
    //jfieldID gSurface_NativePixelRefFieldID;

    EGLDisplay dpy = getDisplay(_env, display);
    EGLConfig  cnf = getConfig(_env, config);
    jint* base = 0;

    jclass bitmap_class = _env->FindClass("android/graphics/Bitmap");
    gBitmap_NativeBitmapFieldID = _env->GetFieldID(bitmap_class, "mNativeBitmap", "I");

    jclass gSurface_class = _env->FindClass( "com/google/android/gles_jni/EGLSurfaceImpl");
    gSurface_EGLSurfaceFieldID = _env->GetFieldID(gSurface_class, "mEGLSurface", "I");

    //gSurface_NativePixelRefFieldID = _env->GetFieldID(gSurface_class, "mNativePixelRef", "I");

    SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(native_pixmap,
                     gBitmap_NativeBitmapFieldID);


    egl_native_pixmap_t pixmap;
    pixmap.version = sizeof(pixmap);
    pixmap.width  = nativeBitmap->width();
    pixmap.height = nativeBitmap->height();
    pixmap.stride = nativeBitmap->rowBytes() / nativeBitmap->bytesPerPixel();
    pixmap.format = PIXEL_FORMAT_RGB_565;
    pixmap.data   = (uint8_t*)nativeBitmap->getPixels();

        
    if (attrib_list) {
         // XXX: if array is malformed, we should return an NPE instead of segfault
         base = (jint *)_env->GetPrimitiveArrayCritical(attrib_list, (jboolean *)0);
    }
    EGLSurface sur = eglCreatePixmapSurface(dpy, cnf, &pixmap, base);

    if(sur == EGL_NO_SURFACE)
    {
       int error = eglGetError();
       LogErr("Error (%d) Creating the Pixmap Surface.\n",error);
    }
    if (attrib_list) {
         _env->ReleasePrimitiveArrayCritical(attrib_list, base, JNI_ABORT);
    }

    if (sur != EGL_NO_SURFACE) {
         _env->SetIntField(out_sur, gSurface_EGLSurfaceFieldID, (int)sur);
    }
    }

    on Android side declaration is done as follow
       private native void createPixmapSurface(EGLSurface sur,
                                   EGLDisplay display, EGLConfig config,
                                   Object native_pixmap, int[] attrib_list);



    On Android side call is done as folllow.
      mNativePixmap = Bitmap.createBitmap(mWidth, mHeight,Bitmap.Config.RGB_565);
      
      MY_EGLSurfaceImpl sur = new MY_EGLSurfaceImpl();
      createPixmapSurface(sur,mEGLDisplay, mEGLConfig, mNativePixmap, null);
      mEGLSurface = sur;



    For information i was told by some STE people that PixmapSurface is not supported by MALI400 for Android. But i don't know if it is really true.
    If it is the case then i'm wondering what i can use to remove the need to call glReadPixels.

    I would need to be able to force the place where to render the 3D Scene and as Pixmap is not working then i do have to use glReadPixels.
    I tried FBO also and even if i'm able to render into a texture, then after i also face the problem to get access to texture pixels and have to use glReadPixels.

    As you said perfs seems very bad as soon as you are using glReadPixels so i definitively need a way to bypass such call.

    Again thanks for your help.

    BR

    Seb
Children
No data