PDA

View Full Version : glTexImage2D is too slow on android with nexus one



killpig
11-19-2010, 10:38 PM
when draw YUV frame use opengl 2.0 and shader on nexus one,but the
function glTexImage2D is too slow ,cost 40-60 ms
who can fix it ? the key codes:
-------------------------------------------------

int CreateSimpleTexture2D()
{
int err, i;



for (i=0; i<3;i++)
{
glGenTextures(1, &amp;userData.textureId[i]);
if (err = glGetError()) {
// NSLog(@"Error: Could not generate
texture: %d", err);

__android_log_print(ANDROID_LOG_ERROR,"CreateSimpleTexture2D","Error:
Could not generate texture: %d", err);
return 0;
}

glBindTexture(GL_TEXTURE_2D, userData.textureId[i]);
if (err = glGetError()) {
// NSLog(@"Error: Could not bind texture: %d", err);

__android_log_print(ANDROID_LOG_ERROR,"CreateSimpleTexture2D","Error:
Could not bind texture: %d", err);
return 0;
}
}

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (err = glGetError()) {
//NSLog(@"Error: Could not set texture
minimization filter: %d", err);

__android_log_print(ANDROID_LOG_ERROR,"CreateSimpleTexture2D","Error:
Could not set texture minimization filter: %d", err);
return 0;
}

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (err = glGetError()) {
// NSLog(@"Error: Could not set texture
magnification filter: %d", err);
__android_log_print(ANDROID_LOG_ERROR,"CreateSimpleTexture2D","Error:
Could not set texture magnification filter: %d", err);
return 0;
}

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
glGenerateMipmap(GL_TEXTURE_2D);
return 1;
}


---------------------------------------render frame
-------------------------------------------------
glViewport ( 0, 0, g_WindowsWidth, g_WindowsHeight );
checkGlError("glViewport");
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
// Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT );
checkGlError("glClear");
// Use the program object
glUseProgram ( userData.programObject );
checkGlError("glUseProgram");
// Load the vertex position
glVertexAttribPointer ( userData.positionLoc, 3, GL_FLOAT,
GL_FALSE, 5
* sizeof(GLfloat), vVertices );
// Load the texture coordinate
glVertexAttribPointer ( userData.texCoordLoc, 2, GL_FLOAT,
GL_FALSE, 5
* sizeof(GLfloat), &amp;vVertices[3] );

glEnableVertexAttribArray ( userData.positionLoc );
glEnableVertexAttribArray ( userData.texCoordLoc );

long long ttttttt=av_gettime();
// Bind the texture
glActiveTexture ( GL_TEXTURE1 );
glBindTexture ( GL_TEXTURE_2D, userData.textureId[1] );
glUniform1i ( userData.samplerLocU, 1);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,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);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

//glPixelStorei(GL_UNPACK_ALIGNMENT,1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width/2,
height/2, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, pict->data[1]);
checkGlError("glTexImage2D....pict->data[1]");
//glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width*0.5,
height*0.5, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pict->data[1]);


// Bind the texture
glActiveTexture ( GL_TEXTURE2 );
glBindTexture ( GL_TEXTURE_2D, userData.textureId[2] );
glUniform1i ( userData.samplerLocV, 2);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,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);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glPixelStorei(GL_UNPACK_ALIGNMENT,1);


glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,width/2, height/2, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, pict->data[2]);

checkGlError("glTexImage2D....pict->data[2]");
// Set the sampler texture unit to 0
glActiveTexture ( GL_TEXTURE0 );
glBindTexture ( GL_TEXTURE_2D, userData.textureId[0] );
glUniform1i ( userData.samplerLocY, 0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,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);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glPixelStorei(GL_UNPACK_ALIGNMENT,1);


glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, pict->data[0]);
__android_log_print(ANDROID_LOG_ERROR,"GPU","%lld",(av_gettime()-ttttttt)/1000);
checkGlError("glTexImage2D....pict->data[0]");
glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );

killpig
12-07-2010, 07:16 PM
who can help me ?

ZbuffeR
12-08-2010, 03:21 AM
- are you sure you benchmark correctly ?
- use smaller texture ?
- try to benchmark different combinations of parameters for glTexImage2D, to find the fastest paths
- try to pack 4 YUV 4:1:1 pixels into 3 RGBA8 texels, is that fast ?
- do you have access to any compressed texture format on your platform ?
- use PBO for streaming texture data ?

Advice : try to avoid throwing a bunch of code on the forum without any [ code ] blocks, it is very hard to read.

Alfonse Reinheart
12-08-2010, 03:37 AM
You may also want to try glTexSubImage rather than glTexImage.

mhagain
12-08-2010, 08:09 AM
Yeah, as a general rule you shouldn't be calling glTexImage2D at runtime, because - in addition to needing to transfer the data from system memory to GPU - it also fully respecifies the texture, which may or may not include swapping other objects out of video RAM. Both of those are expensive operations.

So you should call glTexImage2D once - during startup - then call glTexSubImage2D at runtime, which will reuse the original texture object but just update it's data.

Also, make certain that the format and type parameters you choose are optimal for your hardware, otherwise you may be going through software stages in the driver as part of the upload.

Gissepe
12-08-2010, 07:13 PM
We have also met this issue.
with PowerVR GPU has no this issue, but with Adreno200, the upload speed is so so slow.

yep, if we change the format to RGBA, the upload speed will a litter faster, but it is not as fast as PowerVR GPU.

Gissepe
12-09-2010, 05:54 AM
Ignore this, duplicated

Gissepe
12-09-2010, 05:55 AM
What do you mean "benchmark correctly"?
Do you mean the third parameter of the glTexImage2D?

We have tried that GL_RGBA will be faster than GL_LUMINANCE, but there needs a extra time to do parse in the shader.

The compressed texture has only RGBA format, no LUMINANCE format. and it not supports PBO currently.