Merge "Further reduce the number of GL commands sent to the driver"

This commit is contained in:
Romain Guy
2011-12-13 17:29:42 -08:00
committed by Android (Google) Code Review
7 changed files with 69 additions and 51 deletions

View File

@@ -79,6 +79,9 @@ void Caches::init() {
mTexCoordsArrayEnabled = false;
glActiveTexture(gTextureUnits[0]);
mTextureUnit = 0;
mRegionMesh = NULL;
blend = false;
@@ -301,6 +304,13 @@ void Caches::disbaleTexCoordsVertexArray() {
}
}
void Caches::activeTexture(GLuint textureUnit) {
if (mTextureUnit != textureUnit) {
glActiveTexture(gTextureUnits[textureUnit]);
mTextureUnit = textureUnit;
}
}
TextureVertex* Caches::getRegionMesh() {
// Create the mesh, 2 triangles and 4 vertices per rectangle in the region
if (!mRegionMesh) {

View File

@@ -70,6 +70,12 @@ static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float);
static const GLsizei gVertexAALengthOffset = 3 * sizeof(float);
static const GLsizei gMeshCount = 4;
static const GLenum gTextureUnits[] = {
GL_TEXTURE0,
GL_TEXTURE1,
GL_TEXTURE2
};
///////////////////////////////////////////////////////////////////////////////
// Debug
///////////////////////////////////////////////////////////////////////////////
@@ -175,6 +181,12 @@ public:
void enableTexCoordsVertexArray();
void disbaleTexCoordsVertexArray();
/**
* Activate the specified texture unit. The texture unit must
* be specified using an integer number (0 for GL_TEXTURE0 etc.)
*/
void activeTexture(GLuint textureUnit);
/**
* Returns the mesh used to draw regions. Calling this method will
* bind a VBO of type GL_ELEMENT_ARRAY_BUFFER that contains the
@@ -226,6 +238,8 @@ private:
bool mTexCoordsArrayEnabled;
GLuint mTextureUnit;
// Used to render layers
TextureVertex* mRegionMesh;
GLuint mRegionMeshIndices;

View File

@@ -20,6 +20,7 @@
#include <utils/Log.h>
#include "Caches.h"
#include "Debug.h"
#include "LayerCache.h"
#include "Properties.h"
@@ -140,7 +141,7 @@ bool LayerCache::resize(Layer* layer, const uint32_t width, const uint32_t heigh
uint32_t oldWidth = layer->getWidth();
uint32_t oldHeight = layer->getHeight();
glActiveTexture(GL_TEXTURE0);
Caches::getInstance().activeTexture(0);
layer->bindTexture();
layer->setSize(entry.mWidth, entry.mHeight);
layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);

View File

@@ -182,14 +182,15 @@ void LayerRenderer::generateMesh() {
Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) {
LAYER_RENDERER_LOGD("Requesting new render layer %dx%d", width, height);
GLuint fbo = Caches::getInstance().fboCache.get();
Caches& caches = Caches::getInstance();
GLuint fbo = caches.fboCache.get();
if (!fbo) {
LOGW("Could not obtain an FBO");
return NULL;
}
glActiveTexture(GL_TEXTURE0);
Layer* layer = Caches::getInstance().layerCache.get(width, height);
caches.activeTexture(0);
Layer* layer = caches.layerCache.get(width, height);
if (!layer) {
LOGW("Could not obtain a layer");
return NULL;
@@ -220,7 +221,7 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
fbo, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
Caches::getInstance().fboCache.put(fbo);
caches.fboCache.put(fbo);
layer->deleteTexture();
delete layer;
@@ -274,7 +275,7 @@ Layer* LayerRenderer::createTextureLayer(bool isOpaque) {
layer->region.clear();
layer->setRenderTarget(GL_NONE); // see ::updateTextureLayer()
glActiveTexture(GL_TEXTURE0);
Caches::getInstance().activeTexture(0);
layer->generateTexture();
return layer;
@@ -406,7 +407,7 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
glGenTextures(1, &texture);
if ((error = glGetError()) != GL_NO_ERROR) goto error;
glActiveTexture(GL_TEXTURE0);
caches.activeTexture(0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

View File

@@ -103,12 +103,6 @@ static const Blender gBlendsSwap[] = {
{ SkXfermode::kScreen_Mode, GL_ONE_MINUS_DST_COLOR, GL_ONE }
};
static const GLenum gTextureUnits[] = {
GL_TEXTURE0,
GL_TEXTURE1,
GL_TEXTURE2
};
///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
@@ -214,6 +208,7 @@ void OpenGLRenderer::resume() {
glEnable(GL_SCISSOR_TEST);
dirtyClip();
mCaches.activeTexture(0);
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
mCaches.blend = true;
@@ -454,7 +449,7 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
return false;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
Layer* layer = mCaches.layerCache.get(bounds.getWidth(), bounds.getHeight());
if (!layer) {
return false;
@@ -596,7 +591,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
mCaches.unbindMeshBuffer();
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
// When the layer is stored in an FBO, we can save a bit of fillrate by
// drawing only the dirty region
@@ -1377,7 +1372,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
@@ -1398,7 +1393,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
@@ -1418,7 +1413,7 @@ void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHei
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
@@ -1503,7 +1498,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
@@ -1557,7 +1552,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
@@ -2008,7 +2003,7 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot
float rx, float ry, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
right - left, bottom - top, rx, ry, paint);
drawShape(left, top, texture, paint);
@@ -2017,7 +2012,7 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot
void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
drawShape(x - radius, y - radius, texture, paint);
}
@@ -2025,7 +2020,7 @@ void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint)
void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint);
drawShape(left, top, texture, paint);
}
@@ -2039,7 +2034,7 @@ void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
startAngle, sweepAngle, useCenter, paint);
drawShape(left, top, texture, paint);
@@ -2049,7 +2044,7 @@ void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float b
SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint);
drawShape(left, top, texture, paint);
}
@@ -2147,7 +2142,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
shadowColor = 0xffffffff;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
setupDraw();
setupDrawWithTexture(true);
setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
@@ -2177,7 +2172,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
setupDraw();
setupDrawDirtyRegionsDisabled();
setupDrawWithTexture(true);
@@ -2219,7 +2214,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.pathCache.get(path, paint);
if (!texture) return;
@@ -2236,7 +2231,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
return;
}
glActiveTexture(gTextureUnits[0]);
mCaches.activeTexture(0);
int alpha;
SkXfermode::Mode mode;

View File

@@ -29,17 +29,6 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
class Rect {
static inline float min(float a, float b) { return (a<b) ? a : b; }
static inline float max(float a, float b) { return (a>b) ? a : b; }
Rect intersectWith(float l, float t, float r, float b) const {
Rect tmp;
tmp.left = max(left, l);
tmp.top = max(top, t);
tmp.right = min(right, r);
tmp.bottom = min(bottom, b);
return tmp;
}
public:
float left;
float top;
@@ -115,7 +104,7 @@ public:
}
bool intersects(float l, float t, float r, float b) const {
return !intersectWith(l,t,r,b).isEmpty();
return !intersectWith(l, t, r, b).isEmpty();
}
bool intersects(const Rect& r) const {
@@ -123,7 +112,7 @@ public:
}
bool intersect(float l, float t, float r, float b) {
Rect tmp(intersectWith(l,t,r,b));
Rect tmp(intersectWith(l, t, r, b));
if (!tmp.isEmpty()) {
set(tmp);
return true;
@@ -172,6 +161,19 @@ public:
LOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
}
private:
static inline float min(float a, float b) { return (a < b) ? a : b; }
static inline float max(float a, float b) { return (a > b) ? a : b; }
Rect intersectWith(float l, float t, float r, float b) const {
Rect tmp;
tmp.left = max(left, l);
tmp.top = max(top, t);
tmp.right = min(right, r);
tmp.bottom = min(bottom, b);
return tmp;
}
}; // class Rect
}; // namespace uirenderer

View File

@@ -20,6 +20,7 @@
#include <SkMatrix.h>
#include "Caches.h"
#include "SkiaShader.h"
#include "Texture.h"
#include "Matrix.h"
@@ -31,12 +32,6 @@ namespace uirenderer {
// Support
///////////////////////////////////////////////////////////////////////////////
static const GLenum gTextureUnitsMap[] = {
GL_TEXTURE0,
GL_TEXTURE1,
GL_TEXTURE2
};
static const GLint gTileModes[] = {
GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode
GL_REPEAT, // == SkShader::kRepeat_Mode
@@ -129,7 +124,7 @@ void SkiaBitmapShader::describe(ProgramDescription& description, const Extension
void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
Caches::getInstance().activeTexture(textureSlot);
Texture* texture = mTexture;
mTexture = NULL;
@@ -223,7 +218,7 @@ void SkiaLinearGradientShader::describe(ProgramDescription& description,
void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
Caches::getInstance().activeTexture(textureSlot);
Texture* texture = mGradientCache->get(mColors, mPositions, mCount, mTileX);
@@ -335,7 +330,7 @@ void SkiaSweepGradientShader::describe(ProgramDescription& description,
void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
Caches::getInstance().activeTexture(textureSlot);
Texture* texture = mGradientCache->get(mColors, mPositions, mCount);