Hope this will not be too obvious (or worse unsolvable based on info I've provided),
but am struggling to understand what is going on...
I am working on a DVD player that must support BD-J. The problem is that
the bd-j xlet programs run almost on an on-demand approach. The result is that I have
a Draw function that will draw a Pixmap or Rectangle onto an offscreen buffer
whenever the bd-j xlet wants.
Below is the code that is the essence of this xlet driven Draw approach. If we do not
do a glGenFramebuffers each time, but just do it once in an initialisation routine, yet
do a glBindFramebuffer for each Draw invocation then we get an inverted screen. We have to use
"opposite" coordinates as they are documented. The RectToScreen should be, in our parlance, a
call to RectToScreenInv, but that inverts the screen.
What I've found to work, but is way too slow to be useable, is the following approach, until I
try to reuse the offscreen fbo (comment out glGenFramebuffers), then end up with inverted display:
I ask the experts here what I'm missing?? I've burned wayyy too much time to improve performance
and can't understand what is wrong!
Thanks so much for your time!
-------------------------------------------------
*** glGenFramebuffers(1, &m_offscreen_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_offscreen_fbo);
glViewport(0, 0, dest_width, dest_height);
glActiveTexture(GL_TEXTURE0);
glUseProgram(m_program[SHADER_PROGRAM_PIXMAP]);
VDVDOpenGLESPixmap *pEGLPixmap = dynamic_cast(OffscreenPixmap.pDst);
glGenTextures(1, &texture);
EGLImageKHR eglImage = pEGLPixmap->GetEGLImage();
// bind the egl image if we have one, otherwise upload with glTexImage2D
glEGLImageTargetTexture2D(GL_TEXTURE_2D, eglImage);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if ( (flags & VDVD_PIXMAP_BLEND_SRC_COLOR) && !(flags & VDVD_PIXMAP_BLEND_SRC_ALPHA))
glEnable(GL_BLEND);
// use source alpha channel and color alpha as global alpha
if ((flags & VDVD_PIXMAP_BLEND_SRC_COLOR) || (flags & VDVD_PIXMAP_BLEND_SRC_ALPHA))
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
// global color must be this when no blit flags are set
VDVDColorARGB32 global_color = {0xff, 0xff, 0xff, 0xff};
// coloralpha: blend the alpha component from the draw color into the bitmap on the draw
if (flags & VDVD_PIXMAP_BLEND_SRC_COLOR)
global_color.a = color.a;
// colorize: multiply the current draw color into the colors in the bitmap on the draw (colorize)
if (flags & VDVD_PIXMAP_BLEND_MOD_SRC_COLOR)
{
global_color.r = (color.r * global_color.a) / 255;
global_color.g = (color.g * global_color.a) / 255;
global_color.b = (color.b * global_color.a) / 255;
}
// premultiply the draw color alpha into the color being blended into the bitmap on the draw
if (flags & VDVD_PIXMAP_BLEND_COLOR_ALPHA_PREMULT)
{
// extra alpha case. multiply the draw color alpha into the image on the draw.
global_color.r = (uint8_t)(((unsigned int)global_color.r * (unsigned int)color.a) / 255);
global_color.g = (uint8_t)(((unsigned int)global_color.g * (unsigned int)color.a) / 255);
global_color.b = (uint8_t)(((unsigned int)global_color.b * (unsigned int)color.a) / 255);
}
// translate to directfb porterduff
glBlendFunc(blendToSourceFactor(model), blendToDestFactor(model));
GLfloat shader_color[4];
color_premult(shader_color, global_color);
glVertexAttrib4fv(m_color_attr_pos, shader_color);
// texture coordinates
GLfloat const tx_min = (GLfloat)event.OffscreenPixmap.SrcRect.x / (GLfloat)event.OffscreenPixmap.pSrc->Width();
GLfloat const ty_min = (GLfloat)event.OffscreenPixmap.SrcRect.y / (GLfloat)event.OffscreenPixmap.pSrc->Height();
GLfloat const tx_max = ((GLfloat)event.OffscreenPixmap.SrcRect.x + (GLfloat)event.OffscreenPixmap.SrcRect.w)
/ (GLfloat)event.OffscreenPixmap.pSrc->Width();
GLfloat const ty_max = ((GLfloat)event.OffscreenPixmap.SrcRect.y + (GLfloat)event.OffscreenPixmap.SrcRect.h)
float x1, y1, x2, y2;
RectToScreen(event.OffscreenPixmap.DestRect, x1, y1, x2, y2, dest_width, dest_height);
GLfloat attribs[] = {x1, y2, tx_min, ty_max, /* bottom left */
x2, y2, tx_max, ty_max, /* bottom right */
x1, y1, tx_min, ty_min, /* top left */
x2, y1, tx_max, ty_min}; /* top right */
// load vertex attribs and enable their positions
glVertexAttribPointer(m_vertex_attr_pos, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), &attribs[0]);
glVertexAttribPointer(m_texture_attr_pos, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), &attribs[2]);
glEnableVertexAttribArray(m_vertex_attr_pos);
glEnableVertexAttribArray(m_texture_attr_pos);
// Bind the texture to texture_0 and sampler to sampler 0
glUniform1i(m_sampler_location, 0);
GLubyte indices[] = {0, 1, 2, 1, 3, 2};
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
glFinish();
glDeleteTextures(1, &texture);
return DRAW_SUCCESS;