summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libs/hwui/FontRenderer.cpp35
-rw-r--r--libs/hwui/Layer.cpp2
-rw-r--r--libs/hwui/Layer.h7
-rw-r--r--libs/hwui/LayerRenderer.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp2
-rw-r--r--libs/hwui/font/CacheTexture.cpp3
-rw-r--r--libs/hwui/font/CacheTexture.h2
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>