Merge "First OpenGL ES 3.0 based optimization" into jb-mr2-dev
This commit is contained in:
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "Caches.h"
|
#include "Caches.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
#include "Extensions.h"
|
||||||
#include "FontRenderer.h"
|
#include "FontRenderer.h"
|
||||||
#include "Rect.h"
|
#include "Rect.h"
|
||||||
|
|
||||||
@ -375,34 +376,60 @@ void FontRenderer::checkTextureUpdate() {
|
|||||||
|
|
||||||
Caches& caches = Caches::getInstance();
|
Caches& caches = Caches::getInstance();
|
||||||
GLuint lastTextureId = 0;
|
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
|
// Iterate over all the cache textures and see which ones need to be updated
|
||||||
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
|
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
|
||||||
CacheTexture* cacheTexture = mCacheTextures[i];
|
CacheTexture* cacheTexture = mCacheTextures[i];
|
||||||
if (cacheTexture->isDirty() && cacheTexture->getTexture()) {
|
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();
|
const Rect* dirtyRect = cacheTexture->getDirtyRect();
|
||||||
uint32_t x = 0;
|
uint32_t x = hasUnpackRowLength ? dirtyRect->left : 0;
|
||||||
uint32_t y = dirtyRect->top;
|
uint32_t y = dirtyRect->top;
|
||||||
uint32_t width = cacheTexture->getWidth();
|
uint32_t width = cacheTexture->getWidth();
|
||||||
uint32_t height = dirtyRect->getHeight();
|
uint32_t height = dirtyRect->getHeight();
|
||||||
void* textureData = cacheTexture->getTexture() + y * width;
|
void* textureData = cacheTexture->getTexture() + y * width + x;
|
||||||
|
|
||||||
if (cacheTexture->getTextureId() != lastTextureId) {
|
if (cacheTexture->getTextureId() != lastTextureId) {
|
||||||
lastTextureId = cacheTexture->getTextureId();
|
lastTextureId = cacheTexture->getTextureId();
|
||||||
caches.activeTexture(0);
|
caches.activeTexture(0);
|
||||||
glBindTexture(GL_TEXTURE_2D, lastTextureId);
|
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
|
#if DEBUG_FONT_RENDERER
|
||||||
ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d",
|
ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d",
|
||||||
i, x, y, width, height);
|
i, x, y, width, height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
|
||||||
GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
|
GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
|
||||||
|
|
||||||
cacheTexture->setDirty(false);
|
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;
|
mUploadTexture = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) {
|
|||||||
if (fbo) {
|
if (fbo) {
|
||||||
Caches::getInstance().activeTexture(0);
|
Caches::getInstance().activeTexture(0);
|
||||||
bindTexture();
|
bindTexture();
|
||||||
allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
|
allocateTexture();
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
setSize(oldWidth, oldHeight);
|
setSize(oldWidth, oldHeight);
|
||||||
|
@ -255,13 +255,14 @@ struct Layer {
|
|||||||
texture.id = 0;
|
texture.id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void allocateTexture(GLenum format, GLenum storage) {
|
inline void allocateTexture() {
|
||||||
#if DEBUG_LAYERS
|
#if DEBUG_LAYERS
|
||||||
ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
|
ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
|
||||||
#endif
|
#endif
|
||||||
if (texture.id) {
|
if (texture.id) {
|
||||||
glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
format, storage, NULL);
|
glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
|
|||||||
// Initialize the texture if needed
|
// Initialize the texture if needed
|
||||||
if (layer->isEmpty()) {
|
if (layer->isEmpty()) {
|
||||||
layer->setEmpty(false);
|
layer->setEmpty(false);
|
||||||
layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
|
layer->allocateTexture();
|
||||||
|
|
||||||
// This should only happen if we run out of memory
|
// This should only happen if we run out of memory
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
|
@ -922,7 +922,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui
|
|||||||
|
|
||||||
// Initialize the texture if needed
|
// Initialize the texture if needed
|
||||||
if (layer->isEmpty()) {
|
if (layer->isEmpty()) {
|
||||||
layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
|
layer->allocateTexture();
|
||||||
layer->setEmpty(false);
|
layer->setEmpty(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <SkGlyph.h>
|
#include <SkGlyph.h>
|
||||||
#include <utils/Log.h>
|
|
||||||
|
|
||||||
#include "Debug.h"
|
|
||||||
#include "CacheTexture.h"
|
#include "CacheTexture.h"
|
||||||
|
#include "../Debug.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#ifndef ANDROID_HWUI_CACHE_TEXTURE_H
|
#ifndef ANDROID_HWUI_CACHE_TEXTURE_H
|
||||||
#define ANDROID_HWUI_CACHE_TEXTURE_H
|
#define ANDROID_HWUI_CACHE_TEXTURE_H
|
||||||
|
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES3/gl3.h>
|
||||||
|
|
||||||
#include <SkScalerContext.h>
|
#include <SkScalerContext.h>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user