diff options
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 35 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 7 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/font/CacheTexture.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/font/CacheTexture.h | 2 |
7 files changed, 40 insertions, 13 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 26c7e5d..44dc731 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -31,6 +31,7 @@ #include "Caches.h" #include "Debug.h" +#include "Extensions.h" #include "FontRenderer.h" #include "Rect.h" @@ -375,34 +376,60 @@ void FontRenderer::checkTextureUpdate() { Caches& caches = Caches::getInstance(); GLuint lastTextureId = 0; + + // OpenGL ES 3.0+ lets us specify the row length for unpack operations such + // as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture. + // With OpenGL ES 2.0 we have to upload entire stripes instead. + const bool hasUnpackRowLength = Extensions::getInstance().getMajorGlVersion() >= 3; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // Iterate over all the cache textures and see which ones need to be updated for (uint32_t i = 0; i < mCacheTextures.size(); i++) { CacheTexture* cacheTexture = mCacheTextures[i]; if (cacheTexture->isDirty() && cacheTexture->getTexture()) { - // Can't copy inner rect; glTexSubimage expects pointer to deal with entire buffer - // of data. So expand the dirty rect to the encompassing horizontal stripe. const Rect* dirtyRect = cacheTexture->getDirtyRect(); - uint32_t x = 0; + uint32_t x = hasUnpackRowLength ? dirtyRect->left : 0; uint32_t y = dirtyRect->top; uint32_t width = cacheTexture->getWidth(); uint32_t height = dirtyRect->getHeight(); - void* textureData = cacheTexture->getTexture() + y * width; + void* textureData = cacheTexture->getTexture() + y * width + x; if (cacheTexture->getTextureId() != lastTextureId) { lastTextureId = cacheTexture->getTextureId(); caches.activeTexture(0); glBindTexture(GL_TEXTURE_2D, lastTextureId); + + // The unpack row length only needs to be specified when a new + // texture is bound + if (hasUnpackRowLength) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, width); + } + } + + // If we can upload a sub-rectangle, use the dirty rect width + // instead of the width of the entire texture + if (hasUnpackRowLength) { + width = dirtyRect->getWidth(); } + #if DEBUG_FONT_RENDERER ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d", i, x, y, width, height); #endif + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, textureData); + cacheTexture->setDirty(false); } } + // Reset to default unpack row length to avoid affecting texture + // uploads in other parts of the renderer + if (hasUnpackRowLength) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } + mUploadTexture = false; } diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index d257110..a718294 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -90,7 +90,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) { if (fbo) { Caches::getInstance().activeTexture(0); bindTexture(); - allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE); + allocateTexture(); if (glGetError() != GL_NO_ERROR) { setSize(oldWidth, oldHeight); diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 27e0cf1..715dfa4 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -255,13 +255,14 @@ struct Layer { texture.id = 0; } - inline void allocateTexture(GLenum format, GLenum storage) { + inline void allocateTexture() { #if DEBUG_LAYERS ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); #endif if (texture.id) { - glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, - format, storage, NULL); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 8451048..3e55fff 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -256,7 +256,7 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque // Initialize the texture if needed if (layer->isEmpty()) { layer->setEmpty(false); - layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE); + layer->allocateTexture(); // This should only happen if we run out of memory if (glGetError() != GL_NO_ERROR) { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index d34246d..3730017 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -922,7 +922,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui // Initialize the texture if needed if (layer->isEmpty()) { - layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE); + layer->allocateTexture(); layer->setEmpty(false); } diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp index 1096642..577f463 100644 --- a/libs/hwui/font/CacheTexture.cpp +++ b/libs/hwui/font/CacheTexture.cpp @@ -15,10 +15,9 @@ */ #include <SkGlyph.h> -#include <utils/Log.h> -#include "Debug.h" #include "CacheTexture.h" +#include "../Debug.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h index 5742941..e7fb474 100644 --- a/libs/hwui/font/CacheTexture.h +++ b/libs/hwui/font/CacheTexture.h @@ -17,7 +17,7 @@ #ifndef ANDROID_HWUI_CACHE_TEXTURE_H #define ANDROID_HWUI_CACHE_TEXTURE_H -#include <GLES2/gl2.h> +#include <GLES3/gl3.h> #include <SkScalerContext.h> |