Render an EGL pbuffer (getting eglBindTexImage to work)

940 views
Skip to first unread message

Matthias

unread,
Jul 1, 2016, 8:44:47 AM7/1/16
to paint-dev
Hi all.

I'm working on a plugin (trusted nacl) which allows to render a D3D texture (created by a 3rd party app) into the chrome window.
Sharing the texture between the D3D app and chrome plugin process works.
Rendering a gl texture bound with glTexImage2D inside the plugin also works, but can't get the D3D bound to the texture.
If I try it, I end up with the following message:

[3168:1176:0701/140007:INFO:CONSOLE(0)] "[.PPAPIContext]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have inco
mpatible texture filtering.", source: file:///F:/src/Chromium/src/ppapi/examples/d3d_texture_client//d3d_texture_client.html (0)
[13244:6400:0701/140007:ERROR:gles2_cmd_decoder.cc(8439)] [.PPAPIContext]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-o
f-2 and have incompatible texture filtering.

This is my code to create the texture:

    eglMakeCurrent(m_display, m_surface, m_surface, m_context);

   
EGLint pbuffer_attributes[] =
   
{
        EGL_WIDTH
,  cx,
        EGL_HEIGHT
,  cy,
        EGL_TEXTURE_TARGET
, EGL_TEXTURE_2D,
        EGL_TEXTURE_FORMAT
, EGL_TEXTURE_RGBA,
        EGL_MIPMAP_TEXTURE
, EGL_TRUE,
        EGL_NONE
   
};

   
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(
        m_display
,
        EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE
,
       
(EGLClientBuffer)d3d_tex_handle,
        m_config
,
        pbuffer_attributes
);

    glGenTextures
(1, &m_gl_texture);

    glBindTexture
(GL_TEXTURE_2D, m_gl_texture);

    glTexParameterf
(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf
(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf
(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf
(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

   
// 1)
   
// using this ends up on black rect and error message:
    eglBindTexImage
(m_display, surface, EGL_BACK_BUFFER);

   
// 2)
   
// using this works, I can see a yellow rect as expected:
    glTexImage2D
(GL_TEXTURE_2D,
       
0,
        GL_RGBA
,
        cx
,
        cy
,
       
0,
        GL_RGBA
,
        GL_UNSIGNED_BYTE
,
        textdata
);
   

Using glTexImage2D works fine. Using eglBindTexImage causes the error.

That's the rendering:

static const GLfloat squareVertices[] = {
       
-0.5f, -0.5f,
       
0.5f, -0.5f,
       
-0.5f,  0.5f,
       
0.5f,  0.5f,
   
};

   
static const GLfloat textureVertices[] = {
       
1.0f, 1.0f,
       
1.0f, 0.0f,
       
0.0f,  1.0f,
       
0.0f,  0.0f,
   
};

    glUseProgram
(m_gl_progam);

    glActiveTexture
(GL_TEXTURE0);

    glBindTexture
(GL_TEXTURE_2D, m_gl_texture);

    glUniform1i
(glGetUniformLocation(m_gl_progam, "external_texture"), 0);

    glVertexAttribPointer
(0, 2, GL_FLOAT, 0, 0, squareVertices);
    glEnableVertexAttribArray
(0);
    glVertexAttribPointer
(1, 2, GL_FLOAT, 0, 0, textureVertices);
    glEnableVertexAttribArray
(1);

    glDrawArrays
(GL_TRIANGLE_STRIP, 0, 4);

    glBindTexture
(GL_TEXTURE_2D, 0);

Fragment shader:

varying highp vec2 textureCoordinate;
uniform sampler2D external_texture
;
void main()
{
    gl_FragColor
= texture2D(videoFrame, external_texture);
};

During stepping through the code, I noticed that the texture create with eglBindTexImage does not have any mip levels.
Because of that, the render condition of the texture is on CAN_RENDER_NEVER, which causes the error from above.
If I set an breakpoint on Texture::GetCanRenderCondition() (src/gpu/command_buffer/service/texture_manager.cc) I can see that width and height of the first face is 0 always.
That is not case when using glTextImage2D. In this case there is a width and height on the first face and so render condition is CAN_RENDER_NEEDS_VALIDATION

I'm not sure if my approach isn't working at all, or if do something wrong / miss any calls.
I'm happy for any help.

btw. I don't need to create a ANGLE / gl texture from the D3D shared handle necessarily.
It would be also ok for get the D3D shared handled from a texture owned by chrome / ANGLE and shared this one with the external app.
But I did not had any luck with this neither. Instead of eglCreatePbufferFromClientBuffer, I used eglCreatePbufferSurface, but also there same issue.
I cannot bind to a gl texture correctly. Using eglBindTexImage causes same behavior no matter is the buffer was created with eglCreatePbufferFromClientBuffer or eglCreatePbufferSurface.
 
Thanks!
Matthias


zpm.ps...@gmail.com

unread,
Jul 1, 2016, 11:13:39 AM7/1/16
to paint-dev, zpm.ps...@gmail.com
Some more input from debugging:
Just for testing I tried to call glTexStorage2DEXT to manually specify the size, which failed because there was no texture bound to GL_TEXTURE_2D (what?? I did call glBindTexture just before and it succeeded).
So did some more investigation and I it looks like my code is talking to two different render backends.

glBindTexture(GL_TEXTURE_2D, m_gl_texture);

This call from my plugin ends on the ppapi ppb_opengles2_shared.cc which calls to the gles2 command buffer client.

    PFNGLBINDTEXTUREPROC glBindTextureDyn =
       
(PFNGLBINDTEXTUREPROC) eglGetProcAddress("glBindTexture");

    glBindTextureDyn
(GL_TEXTURE_2D, m_gl_texture);

This call ends up on src/angle/libGLESv2/entry_points_gles_2_0_ext.cpp

Means if you use the glBindTexture from the ppapi lib, it end up on a different context then if you call glBindTexture as reported by eglGetProcAddress.

Can someone explain my what's the deal with EGL on NACI/PPAPI plugins?
My assumption is that the code from above could work, but the glXXX and eglXXX functions operate on different contexts (why???). Means glBindTexture binds to context A, but eglBindTexImage binds on context B. So there is no texture bound on glDraw which explain the error message. Just assumption... it's friday and I'm tired..
thanks & have nice weekend ;)




simon....@gmail.com

unread,
Mar 28, 2017, 5:20:50 AM3/28/17
to paint-dev, zpm.ps...@gmail.com
Hi Matthias,

I'm trying to achieve the same thing here and end up with the same error message. Did you have any luck getting this to work?

Thanks for your help,
Simon
Reply all
Reply to author
Forward
0 new messages