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