Optimize shader binding changes.

This change also cleans up the internal API a little bit by using mat4
everywhere instead of float[16] (for the ortho matrix for instance.)

Change-Id: I35924c7dc17bad17f30307118d5ed437c2ed37e0
This commit is contained in:
Romain Guy
2010-07-12 14:41:06 -07:00
parent d12315ae7e
commit 260e102162
5 changed files with 53 additions and 15 deletions

View File

@@ -118,6 +118,7 @@ OpenGLRenderer::OpenGLRenderer():
mDrawColorShader = new DrawColorProgram;
mDrawTextureShader = new DrawTextureProgram;
mCurrentShader = mDrawTextureShader;
memcpy(mDrawTextureVertices, gDrawTextureVertices, sizeof(gDrawTextureVertices));
}
@@ -136,9 +137,7 @@ OpenGLRenderer::~OpenGLRenderer() {
void OpenGLRenderer::setViewport(int width, int height) {
glViewport(0, 0, width, height);
mat4 ortho;
ortho.loadOrtho(0, width, height, 0, -1, 1);
ortho.copyTo(mOrthoMatrix);
mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
mWidth = width;
mHeight = height;
@@ -208,7 +207,7 @@ bool OpenGLRenderer::restoreSnapshot() {
sp<Snapshot> previous = mSnapshot->previous;
if (restoreOrtho) {
memcpy(mOrthoMatrix, current->orthoMatrix, sizeof(mOrthoMatrix));
mOrthoMatrix.load(current->orthoMatrix);
}
if (restoreLayer) {
@@ -333,12 +332,10 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
mSnapshot->flags = Snapshot::kFlagDirtyTransform | Snapshot::kFlagDirtyOrtho |
Snapshot::kFlagClipSet;
memcpy(mSnapshot->orthoMatrix, mOrthoMatrix, sizeof(mOrthoMatrix));
mSnapshot->orthoMatrix.load(mOrthoMatrix);
// Change the ortho projection
mat4 ortho;
ortho.loadOrtho(0.0f, right - left, bottom - top, 0.0f, 0.0f, 1.0f);
ortho.copyTo(mOrthoMatrix);
mOrthoMatrix.loadOrtho(0.0f, right - left, bottom - top, 0.0f, 0.0f, 1.0f);
return true;
}
@@ -511,7 +508,8 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
mModelView.loadTranslate(left, top, 0.0f);
mModelView.scale(right - left, bottom - top, 1.0f);
mDrawColorShader->use(&mOrthoMatrix[0], mModelView, mSnapshot->transform);
useShader(mDrawColorShader);
mDrawColorShader->set(mOrthoMatrix, mModelView, mSnapshot->transform);
const GLvoid* p = &gDrawColorVertices[0].position[0];
@@ -548,7 +546,8 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
mModelView.loadTranslate(left, top, 0.0f);
mModelView.scale(right - left, bottom - top, 1.0f);
mDrawTextureShader->use(&mOrthoMatrix[0], mModelView, mSnapshot->transform);
useShader(mDrawTextureShader);
mDrawTextureShader->set(mOrthoMatrix, mModelView, mSnapshot->transform);
chooseBlending(blend || alpha < 1.0f, mode, isPremultiplied);
@@ -606,6 +605,14 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool isPr
mBlend = blend;
}
void OpenGLRenderer::useShader(const sp<Program>& shader) {
if (!shader->isInUse()) {
mCurrentShader->remove();
shader->use();
mCurrentShader = shader;
}
}
void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) {
TextureVertex* v = &mDrawTextureVertices[0];
TextureVertex::setUV(v++, u1, v1);

View File

@@ -247,11 +247,19 @@ private:
*/
inline void chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied);
/**
* Use the specified shader with the current GL context. If the shader is already
* in use, it will not be bound again. If it is not in use, the current shader is
* marked unused and the specified shader becomes used and becomes the new
* current shader.
*/
inline void useShader(const sp<Program>& shader);
// Dimensions of the drawing surface
int mWidth, mHeight;
// Matrix used for ortho projection in shaders
float mOrthoMatrix[16];
mat4 mOrthoMatrix;
// Model-view matrix used to position/size objects
mat4 mModelView;
@@ -264,6 +272,7 @@ private:
sp<Snapshot> mSnapshot;
// Shaders
sp<Program> mCurrentShader;
sp<DrawColorProgram> mDrawColorShader;
sp<DrawTextureProgram> mDrawTextureShader;

View File

@@ -59,6 +59,8 @@ Program::Program(const char* vertex, const char* fragment) {
}
glDeleteProgram(id);
}
mUse = false;
}
Program::~Program() {
@@ -69,6 +71,11 @@ Program::~Program() {
void Program::use() {
glUseProgram(id);
mUse = true;
}
void Program::remove() {
mUse = false;
}
int Program::addAttrib(const char* name) {
@@ -130,13 +137,12 @@ void DrawColorProgram::getAttribsAndUniforms() {
transform = addUniform("transform");
}
void DrawColorProgram::use(const float* projectionMatrix, const mat4& modelViewMatrix,
void DrawColorProgram::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
const mat4& transformMatrix) {
mat4 t(projectionMatrix);
t.multiply(transformMatrix);
t.multiply(modelViewMatrix);
Program::use();
glUniformMatrix4fv(transform, 1, GL_FALSE, &t.data[0]);
}

View File

@@ -46,6 +46,20 @@ public:
*/
void use();
/**
* Marks this program as unused. This will not unbind
* the program from the GL context.
*/
void remove();
/**
* Indicates whether this program is currently in use with
* the GL context.
*/
inline bool isInUse() const {
return mUse;
}
protected:
/**
* Adds an attribute with the specified name.
@@ -87,6 +101,8 @@ private:
// Keeps track of attributes and uniforms slots
KeyedVector<const char*, int> attributes;
KeyedVector<const char*, int> uniforms;
bool mUse;
}; // class Program
/**
@@ -109,7 +125,7 @@ public:
* Binds the program with the specified projection, modelView and
* transform matrices.
*/
void use(const float* projectionMatrix, const mat4& modelViewMatrix,
void set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
const mat4& transformMatrix);
/**

View File

@@ -130,7 +130,7 @@ public:
/**
* Contains the previous ortho matrix.
*/
float orthoMatrix[16];
mat4 orthoMatrix;
private:
// Clipping rectangle mapped with the transform