summaryrefslogtreecommitdiff
path: root/libs/surfaceflinger/LayerBase.cpp
diff options
context:
space:
mode:
author Mathias Agopian <mathias@google.com> 2009-10-05 17:07:12 -0700
committer Mathias Agopian <mathias@google.com> 2009-10-06 17:00:25 -0700
commit3330b203039dea366d4981db1408a460134b2d2c (patch)
treef165f7801f2ee8034ad1edfd34e2b554fdaf662f /libs/surfaceflinger/LayerBase.cpp
parent0ad3f9f4009c76b56f41da5d26eb7712dee938f1 (diff)
fix [2167050] glTexImage2D code path buggy in SurfaceFlinger
When EGLImage extension is not available, SurfaceFlinger will fallback to using glTexImage2D and glTexSubImage2D instead, which requires 50% more memory and an extra copy. However this code path has never been exercised and had some bugs which this patch fix. Mainly the scale factor wasn't computed right when falling back on glDrawElements. We also fallback to this mode of operation if a buffer doesn't have the adequate usage bits for EGLImage usage. This changes only code that is currently not executed. Some refactoring was needed to keep the change clean. This doesn't change anything functionaly.
Diffstat (limited to 'libs/surfaceflinger/LayerBase.cpp')
-rw-r--r--libs/surfaceflinger/LayerBase.cpp95
1 files changed, 40 insertions, 55 deletions
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 83814ccf9a..b376e72aa1 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -449,17 +449,9 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
glTranslatef(0, 1, 0);
glRotatef(-90, 0, 0, 1);
}
-
- if (!(mFlags & (DisplayHardware::NPOT_EXTENSION |
- DisplayHardware::DIRECT_TEXTURE))) {
- // find the smallest power-of-two that will accommodate our surface
- GLuint tw = 1 << (31 - clz(width));
- GLuint th = 1 << (31 - clz(height));
- if (tw < width) tw <<= 1;
- if (th < height) th <<= 1;
- GLfloat ws = GLfloat(width) /tw;
- GLfloat hs = GLfloat(height)/th;
- glScalef(ws, hs, 1.0f);
+
+ if (texture.NPOTAdjust) {
+ glScalef(texture.wScale, texture.hScale, 1.0f);
}
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -508,21 +500,15 @@ void LayerBase::validateTexture(GLint textureName) const
}
}
-void LayerBase::loadTexture(Texture* texture, GLint textureName,
+void LayerBase::loadTexture(Texture* texture,
const Region& dirty, const GGLSurface& t) const
{
- // TODO: defer the actual texture reload until LayerBase::validateTexture
- // is called.
-
- texture->name = textureName;
- GLuint& textureWidth(texture->width);
- GLuint& textureHeight(texture->height);
+ if (texture->name == -1U) {
+ // uh?
+ return;
+ }
- uint32_t flags = mFlags;
- glBindTexture(GL_TEXTURE_2D, textureName);
-
- GLuint tw = t.width;
- GLuint th = t.height;
+ glBindTexture(GL_TEXTURE_2D, texture->name);
/*
* In OpenGL ES we can't specify a stride with glTexImage2D (however,
@@ -547,64 +533,63 @@ void LayerBase::loadTexture(Texture* texture, GLint textureName,
/*
* round to POT if needed
*/
+ if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
+ texture->NPOTAdjust = true;
+ }
- GLuint texture_w = tw;
- GLuint texture_h = th;
- if (!(flags & DisplayHardware::NPOT_EXTENSION)) {
+ if (texture->NPOTAdjust) {
// find the smallest power-of-two that will accommodate our surface
- texture_w = 1 << (31 - clz(t.width));
- texture_h = 1 << (31 - clz(t.height));
- if (texture_w < t.width) texture_w <<= 1;
- if (texture_h < t.height) texture_h <<= 1;
+ texture->potWidth = 1 << (31 - clz(t.width));
+ texture->potHeight = 1 << (31 - clz(t.height));
+ if (texture->potWidth < t.width) texture->potWidth <<= 1;
+ if (texture->potHeight < t.height) texture->potHeight <<= 1;
+ texture->wScale = float(t.width) / texture->potWidth;
+ texture->hScale = float(t.height) / texture->potHeight;
+ } else {
+ texture->potWidth = t.width;
+ texture->potHeight = t.height;
}
-
-regular:
+
Rect bounds(dirty.bounds());
GLvoid* data = 0;
- if (texture_w!=textureWidth || texture_h!=textureHeight) {
- // texture size changed, we need to create a new one
+ if (texture->width != t.width || texture->height != t.height) {
+ texture->width = t.width;
+ texture->height = t.height;
- if (!textureWidth || !textureHeight) {
- // this is the first time, load the whole texture
- if (texture_w==tw && texture_h==th) {
- // we can do it one pass
- data = t.data;
- } else {
- // we have to create the texture first because it
- // doesn't match the size of the buffer
- bounds.set(Rect(tw, th));
- }
+ // texture size changed, we need to create a new one
+ bounds.set(Rect(t.width, t.height));
+ if (t.width == texture->potWidth &&
+ t.height == texture->potHeight) {
+ // we can do it one pass
+ data = t.data;
}
-
+
if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGB, texture_w, texture_h, 0,
+ GL_RGB, texture->potWidth, texture->potHeight, 0,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
} else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture_w, texture_h, 0,
+ GL_RGBA, texture->potWidth, texture->potHeight, 0,
GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
} else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888 ||
t.format == GGL_PIXEL_FORMAT_RGBX_8888) {
glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture_w, texture_h, 0,
+ GL_RGBA, texture->potWidth, texture->potHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);
} else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
// just show the Y plane of YUV buffers
glTexImage2D(GL_TEXTURE_2D, 0,
- GL_LUMINANCE, texture_w, texture_h, 0,
+ GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
} else {
// oops, we don't handle this format!
LOGE("layer %p, texture=%d, using format %d, which is not "
- "supported by the GL", this, textureName, t.format);
- textureName = -1;
+ "supported by the GL", this, texture->name, t.format);
}
- textureWidth = texture_w;
- textureHeight = texture_h;
}
- if (!data && textureName>=0) {
+ if (!data) {
if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, bounds.top, t.width, bounds.height(),
@@ -747,7 +732,7 @@ status_t LayerBaseClient::Surface::onTransact(
return BnSurface::onTransact(code, data, reply, flags);
}
-sp<SurfaceBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage)
+sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage)
{
return NULL;
}