Merge "Don't change textures wrap modes on every draw."
This commit is contained in:
@@ -644,7 +644,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
const Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
if (!texture) return;
|
||||
const AutoTexture autoCleanup(texture);
|
||||
|
||||
@@ -661,7 +661,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
const Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
if (!texture) return;
|
||||
const AutoTexture autoCleanup(texture);
|
||||
|
||||
@@ -677,9 +677,10 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
const Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
if (!texture) return;
|
||||
const AutoTexture autoCleanup(texture);
|
||||
setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
|
||||
|
||||
const float width = texture->width;
|
||||
const float height = texture->height;
|
||||
@@ -711,9 +712,10 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
const Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
Texture* texture = mCaches.textureCache.get(bitmap);
|
||||
if (!texture) return;
|
||||
const AutoTexture autoCleanup(texture);
|
||||
setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
|
||||
|
||||
int alpha;
|
||||
SkXfermode::Mode mode;
|
||||
@@ -1046,7 +1048,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
|
||||
// Build and use the appropriate shader
|
||||
useProgram(mCaches.programCache.get(description));
|
||||
|
||||
bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
|
||||
bindTexture(texture, textureUnit);
|
||||
glUniform1i(mCaches.currentProgram->getUniform("sampler"), textureUnit);
|
||||
|
||||
int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
|
||||
@@ -1220,11 +1222,13 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
|
||||
const Texture* texture, SkPaint* paint) {
|
||||
Texture* texture, SkPaint* paint) {
|
||||
int alpha;
|
||||
SkXfermode::Mode mode;
|
||||
getAlphaAndMode(paint, &alpha, &mode);
|
||||
|
||||
setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
|
||||
|
||||
drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
|
||||
texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
|
||||
GL_TRIANGLE_STRIP, gMeshCount);
|
||||
@@ -1263,7 +1267,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
|
||||
}
|
||||
|
||||
// Texture
|
||||
bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0);
|
||||
bindTexture(texture);
|
||||
glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);
|
||||
|
||||
// Always premultiplied
|
||||
@@ -1380,11 +1384,26 @@ SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) {
|
||||
return mode->fMode;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
|
||||
void OpenGLRenderer::bindTexture(GLuint texture, GLuint textureUnit) {
|
||||
glActiveTexture(gTextureUnits[textureUnit]);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT,
|
||||
GLuint textureUnit) {
|
||||
glActiveTexture(gTextureUnits[textureUnit]);
|
||||
bool bound = false;
|
||||
if (wrapS != texture->wrapS) {
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
bound = true;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||
texture->wrapS = wrapS;
|
||||
}
|
||||
if (wrapT != texture->wrapT) {
|
||||
if (!bound) glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||
texture->wrapT = wrapT;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
@@ -231,7 +231,7 @@ private:
|
||||
* @param paint The paint containing the alpha, blending mode, etc.
|
||||
*/
|
||||
void drawTextureRect(float left, float top, float right, float bottom,
|
||||
const Texture* texture, SkPaint* paint);
|
||||
Texture* texture, SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Draws a textured mesh with the specified texture. If the indices are omitted,
|
||||
@@ -360,9 +360,11 @@ private:
|
||||
inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
|
||||
|
||||
/**
|
||||
* Binds the specified texture with the specified wrap modes.
|
||||
* Binds the specified texture to the specified texture unit.
|
||||
*/
|
||||
inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit = 0);
|
||||
inline void bindTexture(GLuint texture, GLuint textureUnit = 0);
|
||||
inline void setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT,
|
||||
GLuint textureUnit = 0);
|
||||
|
||||
/**
|
||||
* Enable or disable blending as necessary. This function sets the appropriate
|
||||
|
||||
@@ -63,11 +63,17 @@ void SkiaShader::setupProgram(Program* program, const mat4& modelView, const Sna
|
||||
GLuint* textureUnit) {
|
||||
}
|
||||
|
||||
void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
|
||||
void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
|
||||
glActiveTexture(gTextureUnitsMap[textureUnit]);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
if (wrapS != texture->wrapS) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||
texture->wrapS = wrapS;
|
||||
}
|
||||
if (wrapT != texture->wrapT) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||
texture->wrapT = wrapT;
|
||||
}
|
||||
}
|
||||
|
||||
void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
|
||||
@@ -86,7 +92,7 @@ SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::Ti
|
||||
}
|
||||
|
||||
void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) {
|
||||
const Texture* texture = mTextureCache->get(mBitmap);
|
||||
Texture* texture = mTextureCache->get(mBitmap);
|
||||
if (!texture) return;
|
||||
mTexture = texture;
|
||||
|
||||
@@ -114,7 +120,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
|
||||
GLuint textureSlot = (*textureUnit)++;
|
||||
glActiveTexture(gTextureUnitsMap[textureSlot]);
|
||||
|
||||
const Texture* texture = mTexture;
|
||||
Texture* texture = mTexture;
|
||||
mTexture = NULL;
|
||||
if (!texture) return;
|
||||
const AutoTexture autoCleanup(texture);
|
||||
@@ -126,7 +132,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
|
||||
computeScreenSpaceMatrix(textureTransform, modelView);
|
||||
|
||||
// Uniforms
|
||||
bindTexture(texture->id, mWrapS, mWrapT, textureSlot);
|
||||
bindTexture(texture, mWrapS, mWrapT, textureSlot);
|
||||
glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
|
||||
glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
|
||||
GL_FALSE, &textureTransform.data[0]);
|
||||
@@ -198,7 +204,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV
|
||||
computeScreenSpaceMatrix(screenSpace, modelView);
|
||||
|
||||
// Uniforms
|
||||
bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
|
||||
bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
|
||||
glUniform1i(program->getUniform("gradientSampler"), textureSlot);
|
||||
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
|
||||
}
|
||||
@@ -291,7 +297,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi
|
||||
computeScreenSpaceMatrix(screenSpace, modelView);
|
||||
|
||||
// Uniforms
|
||||
bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
|
||||
bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
|
||||
glUniform1i(program->getUniform("gradientSampler"), textureSlot);
|
||||
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ struct SkiaShader {
|
||||
void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
|
||||
|
||||
protected:
|
||||
inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
|
||||
inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
|
||||
|
||||
Type mType;
|
||||
SkShader* mKey;
|
||||
@@ -138,7 +138,7 @@ private:
|
||||
}
|
||||
|
||||
SkBitmap* mBitmap;
|
||||
const Texture* mTexture;
|
||||
Texture* mTexture;
|
||||
GLenum mWrapS;
|
||||
GLenum mWrapT;
|
||||
}; // struct SkiaBitmapShader
|
||||
|
||||
@@ -29,6 +29,8 @@ struct Texture {
|
||||
Texture() {
|
||||
cleanup = false;
|
||||
bitmapSize = 0;
|
||||
wrapS = GL_CLAMP_TO_EDGE;
|
||||
wrapT = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +61,12 @@ struct Texture {
|
||||
* Optional, size of the original bitmap.
|
||||
*/
|
||||
uint32_t bitmapSize;
|
||||
|
||||
/**
|
||||
* Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
|
||||
*/
|
||||
GLenum wrapS;
|
||||
GLenum wrapT;
|
||||
}; // struct Texture
|
||||
|
||||
class AutoTexture {
|
||||
|
||||
@@ -51,27 +51,28 @@ public class ShadersActivity extends Activity {
|
||||
private LinearGradient mHorGradient;
|
||||
private LinearGradient mDiagGradient;
|
||||
private LinearGradient mVertGradient;
|
||||
private Bitmap mTexture;
|
||||
|
||||
ShadersView(Context c) {
|
||||
super(c);
|
||||
|
||||
Bitmap texture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
|
||||
mTexWidth = texture.getWidth();
|
||||
mTexHeight = texture.getHeight();
|
||||
mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
|
||||
mTexWidth = mTexture.getWidth();
|
||||
mTexHeight = mTexture.getHeight();
|
||||
mDrawWidth = mTexWidth * 2.2f;
|
||||
mDrawHeight = mTexHeight * 1.2f;
|
||||
|
||||
mRepeatShader = new BitmapShader(texture, Shader.TileMode.REPEAT,
|
||||
mRepeatShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
|
||||
mTranslatedShader = new BitmapShader(texture, Shader.TileMode.REPEAT,
|
||||
mTranslatedShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
Matrix m1 = new Matrix();
|
||||
m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
|
||||
m1.postRotate(45, 0, 0);
|
||||
mTranslatedShader.setLocalMatrix(m1);
|
||||
|
||||
mScaledShader = new BitmapShader(texture, Shader.TileMode.MIRROR,
|
||||
mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR,
|
||||
Shader.TileMode.MIRROR);
|
||||
Matrix m2 = new Matrix();
|
||||
m2.setScale(0.5f, 0.5f);
|
||||
@@ -98,6 +99,7 @@ public class ShadersActivity extends Activity {
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
//canvas.drawRGB(255, 255, 255);
|
||||
canvas.drawBitmap(mTexture, 0.0f, 0.0f, null);
|
||||
|
||||
// Bitmap shaders
|
||||
canvas.save();
|
||||
|
||||
Reference in New Issue
Block a user