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 September 2012 at http://forums.arm.com

    I run the above code in SAMSUNG S3 device, is failed,

    When I try the SAMSUNG S3 run the above code, I failed.

    Here are some of my code:

    void initEGL(int width, int height, SkBitmap bitmap)
    {
    //step 1.
    const char* const driver_absolute_path = "/system/lib/egl/libEGL_mali.so";
    void* dso = dlopen(driver_absolute_path, RTLD_LAZY);
    if (dso != 0)
    {
      LOGI("dlopen: SUCCEEDED");
      _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)dlsym(dso, "eglCreateImageKHR");
      _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) dlsym(dso, "eglDestroyImageKHR");
    }
    else
    {
      LOGI("dlopen: FAILED! Loading functions in common way!");
      _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
      _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
    }

    if(_eglCreateImageKHR == NULL)
    {
      LOGE("Error: Failed to find eglCreateImageKHR at %s:%i\n", __FILE__, __LINE__);
      exit(1);
    }
    if(_eglDestroyImageKHR == NULL)
    {
      LOGE("Error: Failed to find eglDestroyImageKHR at %s:%i\n", __FILE__, __LINE__);
      exit(1);
    }
    _glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES");
    if(_glEGLImageTargetTexture2DOES == NULL)
    {
      LOGE("Error: Failed to find glEGLImageTargetTexture2DOES at %s:%i\n", __FILE__, __LINE__);
      exit(1);
    }

    //step 2. Create the Android Graphic Buffer
    GraphicBuffer* buffer = new GraphicBuffer(width, height,
       HAL_PIXEL_FORMAT_RGBA_8888,
       GraphicBuffer::USAGE_HW_TEXTURE |
       GraphicBuffer::USAGE_HW_2D |
       GRALLOC_USAGE_SW_READ_OFTEN |
       GRALLOC_USAGE_SW_WRITE_OFTEN);
    // Init the buffer
    status_t err = buffer->initCheck();
    if (err != NO_ERROR)
    {
      LOGE("Error: %s\n", strerror(-err));
      return ;
    }

    // Retrieve andorid native buffer
    android_native_buffer_t* anb = buffer->getNativeBuffer();

    //step 3. Create the EGLImage
    const EGLint attrs[] = {
       EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
       EGL_NONE, EGL_NONE
    };
    EGLImageKHR pEGLImage = _eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)anb, attrs);
    if (pEGLImage == EGL_NO_IMAGE_KHR) {
      EGLint error = eglGetError();
      LOGE("Error (%#x): Creating EGLImageKHR at %s:%i\n", error, __FILE__, __LINE__);
    }

    //setp 4. Set up the FBO with the EGLImage as target
    GLuint iFBOTex;
    GLuint iFBO;

    glViewport(0, 0, width, height);
    checkGlError("glViewport");

    glGenFramebuffers(1, &iFBO);
    checkGlError("glGenFramebuffers");
    /* Initialize FBO texture. */
    glGenTextures(1, &iFBOTex);
    checkGlError("glGenTextures");
    glBindTexture(GL_TEXTURE_2D, iFBOTex);

    /* Bind our framebuffer for rendering. */
    glBindFramebuffer(GL_FRAMEBUFFER, iFBO);
    checkGlError("glBindFramebuffer");

    /* Attach texture to the framebuffer. */
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, iFBOTex, 0);
    checkGlError("glFramebufferTexture2D");
    /* Check FBO is OK. */
    GLenum iResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(iResult != GL_FRAMEBUFFER_COMPLETE) {
      LOGE("Error (%#x): Framebuffer incomplete at %s:%i\n", iResult, __FILE__, __LINE__);
    }

    _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, pEGLImage);
    checkEGLError("glEGLImageTargetTexture2DOES");

    /* Render to framebuffer object. */
    /* Unbind framebuffer. */
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    checkGlError("glBindFramebuffer");


    //step 5. When rendering every frame, bind to the FBO and issue all glCommands, followed by unbind.
    glBindFramebuffer(GL_FRAMEBUFFER, iFBO);

    /* Set the viewport according to the FBO's texture. */
    glViewport(0, 0, width , height);

    /* Clear screen on FBO. */
    glClearColor(0.5f, 0.5f, 0.5f, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /*********************************************
      *******************************************/
    glDrawArrays(GL_TRIANGLES, 0, 3);
    /* And unbind the FrameBuffer Object so subsequent drawing calls are to the EGL window surface. */
    glBindFramebuffer(GL_FRAMEBUFFER,0);


    //setp 6. Finally use the following code for reading the buffer out from user space. Something like the following
    // Just in case the buffer was not created yet
    if (buffer == NULL)
      return;

    void* vaddr;
    // Lock the buffer and retrieve a pointer where we are going to write the data

    buffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr);
    if (vaddr == NULL)
    {
      buffer->unlock();
      return;
    }

    unsigned char* ucVaddr = (unsigned char*)vaddr;

    }

    occur error when execute the follow code fragement.
    /* Attach texture to the framebuffer. */
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, iFBOTex, 0);
    checkGlError("glFramebufferTexture2D");
    /* Check FBO is OK. */
    GLenum iResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(iResult != GL_FRAMEBUFFER_COMPLETE) {
      LOGE("Error (%#x): Framebuffer incomplete at %s:%i\n", iResult, __FILE__, __LINE__);
    }

    When the code is executed to glCheckFramebufferStatus will prompt an error, the error is: "Error (0x3008): Creating EGLImageKHR at..." and "Error (0): Framebuffer incomplete at ...."



    Thanks for your help.
Reply
  • Note: This was originally posted on 12th September 2012 at http://forums.arm.com

    I run the above code in SAMSUNG S3 device, is failed,

    When I try the SAMSUNG S3 run the above code, I failed.

    Here are some of my code:

    void initEGL(int width, int height, SkBitmap bitmap)
    {
    //step 1.
    const char* const driver_absolute_path = "/system/lib/egl/libEGL_mali.so";
    void* dso = dlopen(driver_absolute_path, RTLD_LAZY);
    if (dso != 0)
    {
      LOGI("dlopen: SUCCEEDED");
      _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)dlsym(dso, "eglCreateImageKHR");
      _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) dlsym(dso, "eglDestroyImageKHR");
    }
    else
    {
      LOGI("dlopen: FAILED! Loading functions in common way!");
      _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
      _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
    }

    if(_eglCreateImageKHR == NULL)
    {
      LOGE("Error: Failed to find eglCreateImageKHR at %s:%i\n", __FILE__, __LINE__);
      exit(1);
    }
    if(_eglDestroyImageKHR == NULL)
    {
      LOGE("Error: Failed to find eglDestroyImageKHR at %s:%i\n", __FILE__, __LINE__);
      exit(1);
    }
    _glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES");
    if(_glEGLImageTargetTexture2DOES == NULL)
    {
      LOGE("Error: Failed to find glEGLImageTargetTexture2DOES at %s:%i\n", __FILE__, __LINE__);
      exit(1);
    }

    //step 2. Create the Android Graphic Buffer
    GraphicBuffer* buffer = new GraphicBuffer(width, height,
       HAL_PIXEL_FORMAT_RGBA_8888,
       GraphicBuffer::USAGE_HW_TEXTURE |
       GraphicBuffer::USAGE_HW_2D |
       GRALLOC_USAGE_SW_READ_OFTEN |
       GRALLOC_USAGE_SW_WRITE_OFTEN);
    // Init the buffer
    status_t err = buffer->initCheck();
    if (err != NO_ERROR)
    {
      LOGE("Error: %s\n", strerror(-err));
      return ;
    }

    // Retrieve andorid native buffer
    android_native_buffer_t* anb = buffer->getNativeBuffer();

    //step 3. Create the EGLImage
    const EGLint attrs[] = {
       EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
       EGL_NONE, EGL_NONE
    };
    EGLImageKHR pEGLImage = _eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)anb, attrs);
    if (pEGLImage == EGL_NO_IMAGE_KHR) {
      EGLint error = eglGetError();
      LOGE("Error (%#x): Creating EGLImageKHR at %s:%i\n", error, __FILE__, __LINE__);
    }

    //setp 4. Set up the FBO with the EGLImage as target
    GLuint iFBOTex;
    GLuint iFBO;

    glViewport(0, 0, width, height);
    checkGlError("glViewport");

    glGenFramebuffers(1, &iFBO);
    checkGlError("glGenFramebuffers");
    /* Initialize FBO texture. */
    glGenTextures(1, &iFBOTex);
    checkGlError("glGenTextures");
    glBindTexture(GL_TEXTURE_2D, iFBOTex);

    /* Bind our framebuffer for rendering. */
    glBindFramebuffer(GL_FRAMEBUFFER, iFBO);
    checkGlError("glBindFramebuffer");

    /* Attach texture to the framebuffer. */
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, iFBOTex, 0);
    checkGlError("glFramebufferTexture2D");
    /* Check FBO is OK. */
    GLenum iResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(iResult != GL_FRAMEBUFFER_COMPLETE) {
      LOGE("Error (%#x): Framebuffer incomplete at %s:%i\n", iResult, __FILE__, __LINE__);
    }

    _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, pEGLImage);
    checkEGLError("glEGLImageTargetTexture2DOES");

    /* Render to framebuffer object. */
    /* Unbind framebuffer. */
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    checkGlError("glBindFramebuffer");


    //step 5. When rendering every frame, bind to the FBO and issue all glCommands, followed by unbind.
    glBindFramebuffer(GL_FRAMEBUFFER, iFBO);

    /* Set the viewport according to the FBO's texture. */
    glViewport(0, 0, width , height);

    /* Clear screen on FBO. */
    glClearColor(0.5f, 0.5f, 0.5f, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /*********************************************
      *******************************************/
    glDrawArrays(GL_TRIANGLES, 0, 3);
    /* And unbind the FrameBuffer Object so subsequent drawing calls are to the EGL window surface. */
    glBindFramebuffer(GL_FRAMEBUFFER,0);


    //setp 6. Finally use the following code for reading the buffer out from user space. Something like the following
    // Just in case the buffer was not created yet
    if (buffer == NULL)
      return;

    void* vaddr;
    // Lock the buffer and retrieve a pointer where we are going to write the data

    buffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr);
    if (vaddr == NULL)
    {
      buffer->unlock();
      return;
    }

    unsigned char* ucVaddr = (unsigned char*)vaddr;

    }

    occur error when execute the follow code fragement.
    /* Attach texture to the framebuffer. */
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, iFBOTex, 0);
    checkGlError("glFramebufferTexture2D");
    /* Check FBO is OK. */
    GLenum iResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(iResult != GL_FRAMEBUFFER_COMPLETE) {
      LOGE("Error (%#x): Framebuffer incomplete at %s:%i\n", iResult, __FILE__, __LINE__);
    }

    When the code is executed to glCheckFramebufferStatus will prompt an error, the error is: "Error (0x3008): Creating EGLImageKHR at..." and "Error (0): Framebuffer incomplete at ...."



    Thanks for your help.
Children
No data