mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 731570 - Don't re-upload scrollbar texture on opacity change. r=kats
Rather than re-render the scrollbar texture and re-upload it when the opacity changes, just render/upload it once and use a shader to modify the opacity.
This commit is contained in:
parent
f8ecc16e00
commit
ac32c9beee
@ -172,8 +172,8 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
CairoImage shadowImage = new BufferedCairoImage(controller.getShadowPattern());
|
||||
mShadowLayer = new NinePatchTileLayer(shadowImage);
|
||||
|
||||
mHorizScrollLayer = ScrollbarLayer.create(false);
|
||||
mVertScrollLayer = ScrollbarLayer.create(true);
|
||||
mHorizScrollLayer = ScrollbarLayer.create(this, false);
|
||||
mVertScrollLayer = ScrollbarLayer.create(this, true);
|
||||
mFadeRunnable = new FadeRunnable();
|
||||
|
||||
mFrameTimings = new int[60];
|
||||
|
@ -71,6 +71,25 @@ public class ScrollbarLayer extends TileLayer {
|
||||
private float mOpacity;
|
||||
private boolean mFinalized = false;
|
||||
|
||||
private LayerRenderer mRenderer;
|
||||
private int mProgram;
|
||||
private int mPositionHandle;
|
||||
private int mTextureHandle;
|
||||
private int mSampleHandle;
|
||||
private int mTMatrixHandle;
|
||||
private int mOpacityHandle;
|
||||
|
||||
// Fragment shader used to draw the scroll-bar with opacity
|
||||
private static final String FRAGMENT_SHADER =
|
||||
"precision mediump float;\n" +
|
||||
"varying vec2 vTexCoord;\n" +
|
||||
"uniform sampler2D sTexture;\n" +
|
||||
"uniform float uOpacity;\n" +
|
||||
"void main() {\n" +
|
||||
" gl_FragColor = texture2D(sTexture, vec2(vTexCoord.x, 1.0 - vTexCoord.y));\n" +
|
||||
" gl_FragColor.a *= uOpacity;\n" +
|
||||
"}\n";
|
||||
|
||||
// Dimensions of the texture image
|
||||
private static final float TEX_HEIGHT = 8.0f;
|
||||
private static final float TEX_WIDTH = 8.0f;
|
||||
@ -121,14 +140,26 @@ public class ScrollbarLayer extends TileLayer {
|
||||
BAR_SIZE/TEX_WIDTH , 1.0f
|
||||
};
|
||||
|
||||
private ScrollbarLayer(CairoImage image, boolean vertical, ByteBuffer buffer) {
|
||||
private ScrollbarLayer(LayerRenderer renderer, CairoImage image, boolean vertical, ByteBuffer buffer) {
|
||||
super(false, image);
|
||||
mVertical = vertical;
|
||||
mBuffer = buffer;
|
||||
mRenderer = renderer;
|
||||
|
||||
IntSize size = image.getSize();
|
||||
mBitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
|
||||
// Paint a spot to use as the scroll indicator
|
||||
Paint foregroundPaint = new Paint();
|
||||
foregroundPaint.setAntiAlias(true);
|
||||
foregroundPaint.setStyle(Paint.Style.FILL);
|
||||
foregroundPaint.setColor(Color.argb(127, 0, 0, 0));
|
||||
|
||||
mCanvas.drawColor(Color.argb(0, 0, 0, 0), PorterDuff.Mode.CLEAR);
|
||||
mCanvas.drawCircle(CAP_RADIUS, CAP_RADIUS, CAP_RADIUS, foregroundPaint);
|
||||
|
||||
mBitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
@ -141,14 +172,55 @@ public class ScrollbarLayer extends TileLayer {
|
||||
}
|
||||
}
|
||||
|
||||
public static ScrollbarLayer create(boolean vertical) {
|
||||
public static ScrollbarLayer create(LayerRenderer renderer, boolean vertical) {
|
||||
// just create an empty image for now, it will get drawn
|
||||
// on demand anyway
|
||||
int imageSize = IntSize.nextPowerOfTwo(BAR_SIZE);
|
||||
ByteBuffer buffer = GeckoAppShell.allocateDirectBuffer(imageSize * imageSize * 4);
|
||||
CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize,
|
||||
CairoImage.FORMAT_ARGB32);
|
||||
return new ScrollbarLayer(image, vertical, buffer);
|
||||
return new ScrollbarLayer(renderer, image, vertical, buffer);
|
||||
}
|
||||
|
||||
private void createProgram() {
|
||||
int vertexShader = LayerRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
|
||||
LayerRenderer.DEFAULT_VERTEX_SHADER);
|
||||
int fragmentShader = LayerRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
|
||||
FRAGMENT_SHADER);
|
||||
|
||||
mProgram = GLES20.glCreateProgram();
|
||||
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
|
||||
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
|
||||
GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
|
||||
|
||||
// Get handles to the shaders' vPosition, aTexCoord, sTexture, and uTMatrix members.
|
||||
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
|
||||
mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord");
|
||||
mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
|
||||
mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix");
|
||||
mOpacityHandle = GLES20.glGetUniformLocation(mProgram, "uOpacity");
|
||||
}
|
||||
|
||||
private void activateProgram() {
|
||||
// Add the program to the OpenGL environment
|
||||
GLES20.glUseProgram(mProgram);
|
||||
|
||||
// Set the transformation matrix
|
||||
GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false,
|
||||
LayerRenderer.DEFAULT_TEXTURE_MATRIX, 0);
|
||||
|
||||
// Enable the arrays from which we get the vertex and texture coordinates
|
||||
GLES20.glEnableVertexAttribArray(mPositionHandle);
|
||||
GLES20.glEnableVertexAttribArray(mTextureHandle);
|
||||
|
||||
GLES20.glUniform1i(mSampleHandle, 0);
|
||||
GLES20.glUniform1f(mOpacityHandle, mOpacity);
|
||||
}
|
||||
|
||||
private void deactivateProgram() {
|
||||
GLES20.glDisableVertexAttribArray(mTextureHandle);
|
||||
GLES20.glDisableVertexAttribArray(mPositionHandle);
|
||||
GLES20.glUseProgram(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,7 +234,7 @@ public class ScrollbarLayer extends TileLayer {
|
||||
}
|
||||
beginTransaction(); // called on compositor thread
|
||||
try {
|
||||
setOpacity(Math.max(mOpacity - FADE_AMOUNT, 0.0f));
|
||||
mOpacity = Math.max(mOpacity - FADE_AMOUNT, 0.0f);
|
||||
invalidate();
|
||||
} finally {
|
||||
endTransaction();
|
||||
@ -181,7 +253,7 @@ public class ScrollbarLayer extends TileLayer {
|
||||
}
|
||||
beginTransaction(); // called on compositor thread
|
||||
try {
|
||||
setOpacity(1.0f);
|
||||
mOpacity = 1.0f;
|
||||
invalidate();
|
||||
} finally {
|
||||
endTransaction();
|
||||
@ -189,26 +261,21 @@ public class ScrollbarLayer extends TileLayer {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setOpacity(float opacity) {
|
||||
mOpacity = opacity;
|
||||
|
||||
Paint foregroundPaint = new Paint();
|
||||
foregroundPaint.setAntiAlias(true);
|
||||
foregroundPaint.setStyle(Paint.Style.FILL);
|
||||
// use a (a,r,g,b) color of (127,0,0,0), and multiply the alpha by mOpacity for fading
|
||||
foregroundPaint.setColor(Color.argb(Math.round(mOpacity * 127), 0, 0, 0));
|
||||
|
||||
mCanvas.drawColor(Color.argb(0, 0, 0, 0), PorterDuff.Mode.CLEAR);
|
||||
mCanvas.drawCircle(CAP_RADIUS, CAP_RADIUS, CAP_RADIUS, foregroundPaint);
|
||||
|
||||
mBitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(RenderContext context) {
|
||||
if (!initialized())
|
||||
return;
|
||||
|
||||
// Create the shader program, if necessary
|
||||
// XXX Can the context's LayerRenderer
|
||||
if (mProgram == 0) {
|
||||
createProgram();
|
||||
}
|
||||
|
||||
// Enable the shader program
|
||||
mRenderer.deactivateDefaultProgram();
|
||||
activateProgram();
|
||||
|
||||
GLES20.glEnable(GLES20.GL_BLEND);
|
||||
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
@ -241,8 +308,8 @@ public class ScrollbarLayer extends TileLayer {
|
||||
|
||||
// Get the buffer and handles from the context
|
||||
FloatBuffer coordBuffer = context.coordBuffer;
|
||||
int positionHandle = context.positionHandle;
|
||||
int textureHandle = context.textureHandle;
|
||||
int positionHandle = mPositionHandle;
|
||||
int textureHandle = mTextureHandle;
|
||||
|
||||
// Make sure we are at position zero in the buffer in case other draw methods did not
|
||||
// clean up after themselves
|
||||
@ -398,6 +465,10 @@ public class ScrollbarLayer extends TileLayer {
|
||||
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
// Enable the default shader program again
|
||||
deactivateProgram();
|
||||
mRenderer.activateDefaultProgram();
|
||||
}
|
||||
|
||||
private RectF getVerticalRect(RenderContext context) {
|
||||
|
Loading…
Reference in New Issue
Block a user