diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLDebugRenderer.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/OpenGLDebugRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 19 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 129 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.h | 25 | ||||
-rw-r--r-- | libs/rs/java/Samples/res/raw/multitexf.glsl | 2 | ||||
-rw-r--r-- | libs/rs/java/tests/src/com/android/rs/test/primitives.rs | 10 | ||||
-rw-r--r-- | libs/rs/rsFont.cpp | 2 | ||||
-rw-r--r-- | libs/rs/rsProgramFragment.cpp | 2 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 5 | ||||
-rw-r--r-- | libs/surfaceflinger_client/SharedBufferStack.cpp | 30 | ||||
-rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 34 | ||||
-rw-r--r-- | libs/ui/InputDispatcher.cpp | 57 |
17 files changed, 196 insertions, 144 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index ce85d46..61e5408 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -342,7 +342,7 @@ void DisplayListRenderer::setViewport(int width, int height) { mHeight = height; } -void DisplayListRenderer::prepare() { +void DisplayListRenderer::prepare(bool opaque) { mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSaveCount = 1; diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 5d02bd7..0fbfce1 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -209,7 +209,7 @@ public: ~DisplayListRenderer(); void setViewport(int width, int height); - void prepare(); + void prepare(bool opaque); void acquireContext(); void releaseContext(); diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp index 4e5123e..b9583e5 100644 --- a/libs/hwui/OpenGLDebugRenderer.cpp +++ b/libs/hwui/OpenGLDebugRenderer.cpp @@ -23,10 +23,10 @@ namespace android { namespace uirenderer { -void OpenGLDebugRenderer::prepare() { +void OpenGLDebugRenderer::prepare(bool opaque) { mPrimitivesCount = 0; LOGD("========= Frame start ========="); - OpenGLRenderer::prepare(); + OpenGLRenderer::prepare(opaque); } void OpenGLDebugRenderer::finish() { diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h index ce15512..2ac19ae 100644 --- a/libs/hwui/OpenGLDebugRenderer.h +++ b/libs/hwui/OpenGLDebugRenderer.h @@ -34,7 +34,7 @@ public: ~OpenGLDebugRenderer() { } - void prepare(); + void prepare(bool opaque); void finish(); int saveLayer(float left, float top, float right, float bottom, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index ee5fe22..5399668 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -150,7 +150,7 @@ void OpenGLRenderer::setViewport(int width, int height) { mFirstSnapshot->viewport.set(0, 0, width, height); } -void OpenGLRenderer::prepare() { +void OpenGLRenderer::prepare(bool opaque) { mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSaveCount = 1; @@ -160,8 +160,10 @@ void OpenGLRenderer::prepare() { glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); + if (!opaque) { + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + } glEnable(GL_SCISSOR_TEST); glScissor(0, 0, mWidth, mHeight); @@ -325,7 +327,10 @@ int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bot * - Issue the drawing * * Switching rendering target n + 1 times per drawn primitive is extremely costly. - * To avoid this, layers are implemented in a different way here. + * To avoid this, layers are implemented in a different way here, at least in the + * general case. FBOs are used, as an optimization, when the "clip to layer" flag + * is set. When this flag is set we can redirect all drawing operations into a + * single FBO. * * This implementation relies on the frame buffer being at least RGBA 8888. When * a layer is created, only a texture is created, not an FBO. The content of the diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index e3d4653..4caa8fb 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -67,7 +67,7 @@ public: virtual void setViewport(int width, int height); - virtual void prepare(); + virtual void prepare(bool opaque); virtual void finish(); virtual void acquireContext(); diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 3e9412c..439e6fb 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -35,17 +35,10 @@ const char* gVS_Header_Uniforms = "uniform mat4 transform;\n"; const char* gVS_Header_Uniforms_HasGradient[3] = { // Linear - "uniform float gradientLength;\n" - "uniform vec2 gradient;\n" - "uniform vec2 gradientStart;\n" "uniform mat4 screenSpace;\n", // Circular - "uniform vec2 gradientStart;\n" - "uniform mat4 gradientMatrix;\n" "uniform mat4 screenSpace;\n", // Sweep - "uniform vec2 gradientStart;\n" - "uniform mat4 gradientMatrix;\n" "uniform mat4 screenSpace;\n" }; const char* gVS_Header_Uniforms_HasBitmap = @@ -69,14 +62,11 @@ const char* gVS_Main_OutTexCoords = " outTexCoords = texCoords;\n"; const char* gVS_Main_OutGradient[3] = { // Linear - " vec4 location = screenSpace * position;\n" - " index = dot(location.xy - gradientStart, gradient) * gradientLength;\n", + " index = (screenSpace * position).x;\n", // Circular - " vec4 location = screenSpace * position;\n" - " circular = (gradientMatrix * vec4(location.xy - gradientStart, 0.0, 0.0)).xy;\n", + " circular = (screenSpace * position).xy;\n", // Sweep - " vec4 location = screenSpace * position;\n" - " sweep = (gradientMatrix * vec4(location.xy - gradientStart, 0.0, 0.0)).xy;\n" + " sweep = (screenSpace * position).xy;\n" }; const char* gVS_Main_OutBitmapTexCoords = " vec4 bitmapCoords = textureTransform * position;\n" @@ -102,7 +92,6 @@ const char* gFS_Uniforms_GradientSampler[3] = { // Linear "uniform sampler2D gradientSampler;\n", // Circular - "uniform float gradientRadius;\n" "uniform sampler2D gradientSampler;\n", // Sweep "uniform sampler2D gradientSampler;\n" @@ -134,7 +123,7 @@ const char* gFS_Main_FetchGradient[3] = { // Linear " vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n", // Circular - " float index = length(circular) * gradientRadius;\n" + " float index = length(circular);\n" " vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n", // Sweep " float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n" diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 165c0da..fa85d20 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -49,7 +49,8 @@ static const GLint gTileModes[] = { SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix, bool blend): - mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mMatrix(matrix), mBlend(blend) { + mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) { + setMatrix(matrix); } SkiaShader::~SkiaShader() { @@ -69,6 +70,11 @@ void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); } +void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) { + screenSpace.loadMultiply(mUnitMatrix, mShaderMatrix); + screenSpace.multiply(modelView); +} + /////////////////////////////////////////////////////////////////////////////// // Bitmap shader /////////////////////////////////////////////////////////////////////////////// @@ -76,6 +82,7 @@ void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix, bool blend): SkiaShader(kBitmap, key, tileX, tileY, matrix, blend), mBitmap(bitmap), mTexture(NULL) { + updateLocalMatrix(matrix); } void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { @@ -116,14 +123,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, const float height = texture->height; mat4 textureTransform; - if (mMatrix) { - SkMatrix inverse; - mMatrix->invert(&inverse); - textureTransform.load(inverse); - textureTransform.multiply(modelView); - } else { - textureTransform.load(modelView); - } + computeScreenSpaceMatrix(textureTransform, modelView); // Uniforms bindTexture(texture->id, mWrapS, mWrapT, textureSlot); @@ -136,15 +136,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, void SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot) { mat4 textureTransform; - if (mMatrix) { - SkMatrix inverse; - mMatrix->invert(&inverse); - textureTransform.load(inverse); - textureTransform.multiply(modelView); - } else { - textureTransform.load(modelView); - } - + computeScreenSpaceMatrix(textureTransform, modelView); glUniformMatrix4fv(program->getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); } @@ -153,11 +145,31 @@ void SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView, // Linear gradient shader /////////////////////////////////////////////////////////////////////////////// +static void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { + SkVector vec = pts[1] - pts[0]; + const float mag = vec.length(); + const float inv = mag ? 1.0f / mag : 0; + + vec.scale(inv); + matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); + matrix->postTranslate(-pts[0].fX, -pts[0].fY); + matrix->postScale(inv, inv); +} + SkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend): SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend), mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) { + SkPoint points[2]; + points[0].set(bounds[0], bounds[1]); + points[1].set(bounds[2], bounds[3]); + + SkMatrix unitMatrix; + toUnitMatrix(points, &unitMatrix); + mUnitMatrix.load(unitMatrix); + + updateLocalMatrix(matrix); } SkiaLinearGradientShader::~SkiaLinearGradientShader() { @@ -182,34 +194,19 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX); } - Rect start(mBounds[0], mBounds[1], mBounds[2], mBounds[3]); - if (mMatrix) { - mat4 shaderMatrix(*mMatrix); - shaderMatrix.mapPoint(start.left, start.top); - shaderMatrix.mapPoint(start.right, start.bottom); - } - snapshot.transform->mapRect(start); - - const float gradientX = start.right - start.left; - const float gradientY = start.bottom - start.top; - - mat4 screenSpace(*snapshot.transform); - screenSpace.multiply(modelView); + mat4 screenSpace; + computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); - glUniform2f(program->getUniform("gradientStart"), start.left, start.top); - glUniform2f(program->getUniform("gradient"), gradientX, gradientY); - glUniform1f(program->getUniform("gradientLength"), - 1.0f / (gradientX * gradientX + gradientY * gradientY)); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } void SkiaLinearGradientShader::updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot) { - mat4 screenSpace(*snapshot.transform); - screenSpace.multiply(modelView); + mat4 screenSpace; + computeScreenSpaceMatrix(screenSpace, modelView); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } @@ -217,12 +214,23 @@ void SkiaLinearGradientShader::updateTransforms(Program* program, const mat4& mo // Circular gradient shader /////////////////////////////////////////////////////////////////////////////// +static void toCircularUnitMatrix(const float x, const float y, const float radius, + SkMatrix* matrix) { + const float inv = 1.0f / radius; + matrix->setTranslate(-x, -y); + matrix->postScale(inv, inv); +} + SkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend): SkiaSweepGradientShader(kCircularGradient, x, y, colors, positions, count, key, - tileMode, matrix, blend), - mRadius(radius) { + tileMode, matrix, blend) { + SkMatrix unitMatrix; + toCircularUnitMatrix(x, y, radius, &unitMatrix); + mUnitMatrix.load(unitMatrix); + + updateLocalMatrix(matrix); } void SkiaCircularGradientShader::describe(ProgramDescription& description, @@ -231,28 +239,31 @@ void SkiaCircularGradientShader::describe(ProgramDescription& description, description.gradientType = ProgramDescription::kGradientCircular; } -void SkiaCircularGradientShader::setupProgram(Program* program, const mat4& modelView, - const Snapshot& snapshot, GLuint* textureUnit) { - SkiaSweepGradientShader::setupProgram(program, modelView, snapshot, textureUnit); - glUniform1f(program->getUniform("gradientRadius"), 1.0f / mRadius); -} - /////////////////////////////////////////////////////////////////////////////// // Sweep gradient shader /////////////////////////////////////////////////////////////////////////////// +static void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { + matrix->setTranslate(-x, -y); +} + SkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend): SkiaShader(kSweepGradient, key, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, matrix, blend), - mX(x), mY(y), mColors(colors), mPositions(positions), mCount(count) { + mColors(colors), mPositions(positions), mCount(count) { + SkMatrix unitMatrix; + toSweepUnitMatrix(x, y, &unitMatrix); + mUnitMatrix.load(unitMatrix); + + updateLocalMatrix(matrix); } SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend): SkiaShader(type, key, tileMode, tileMode, matrix, blend), - mX(x), mY(y), mColors(colors), mPositions(positions), mCount(count) { + mColors(colors), mPositions(positions), mCount(count) { } SkiaSweepGradientShader::~SkiaSweepGradientShader() { @@ -276,35 +287,19 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount); } - float left = mX; - float top = mY; - - mat4 shaderMatrix; - if (mMatrix) { - shaderMatrix.load(*mMatrix); - shaderMatrix.mapPoint(left, top); - } - - mat4 copy(shaderMatrix); - shaderMatrix.loadInverse(copy); - - snapshot.transform->mapPoint(left, top); - - mat4 screenSpace(*snapshot.transform); - screenSpace.multiply(modelView); + mat4 screenSpace; + computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); - glUniformMatrix4fv(program->getUniform("gradientMatrix"), 1, GL_FALSE, &shaderMatrix.data[0]); - glUniform2f(program->getUniform("gradientStart"), left, top); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } void SkiaSweepGradientShader::updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot) { - mat4 screenSpace(*snapshot.transform); - screenSpace.multiply(modelView); + mat4 screenSpace; + computeScreenSpaceMatrix(screenSpace, modelView); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 9f8778f..2565e65 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -78,9 +78,20 @@ struct SkiaShader { } void setMatrix(SkMatrix* matrix) { - mMatrix = matrix; + updateLocalMatrix(matrix); } + void updateLocalMatrix(const SkMatrix* matrix) { + if (matrix) { + mat4 localMatrix(*matrix); + mShaderMatrix.loadInverse(localMatrix); + } else { + mShaderMatrix.loadIdentity(); + } + } + + void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); + protected: inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); @@ -88,11 +99,13 @@ protected: SkShader* mKey; SkShader::TileMode mTileX; SkShader::TileMode mTileY; - SkMatrix* mMatrix; bool mBlend; TextureCache* mTextureCache; GradientCache* mGradientCache; + + mat4 mUnitMatrix; + mat4 mShaderMatrix; }; // struct SkiaShader @@ -155,7 +168,7 @@ struct SkiaSweepGradientShader: public SkiaShader { ~SkiaSweepGradientShader(); virtual void describe(ProgramDescription& description, const Extensions& extensions); - virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, + void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, GLuint* textureUnit); void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); @@ -163,7 +176,6 @@ protected: SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); - float mX, mY; uint32_t* mColors; float* mPositions; int mCount; @@ -177,11 +189,6 @@ struct SkiaCircularGradientShader: public SkiaSweepGradientShader { int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); void describe(ProgramDescription& description, const Extensions& extensions); - void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); - -private: - float mRadius; }; // struct SkiaCircularGradientShader /** diff --git a/libs/rs/java/Samples/res/raw/multitexf.glsl b/libs/rs/java/Samples/res/raw/multitexf.glsl index 91151ad..351ff9b 100644 --- a/libs/rs/java/Samples/res/raw/multitexf.glsl +++ b/libs/rs/java/Samples/res/raw/multitexf.glsl @@ -1,4 +1,4 @@ -varying vec4 varTex0; +varying vec2 varTex0; void main() { vec2 t0 = varTex0.xy; diff --git a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs index 5312bcc..012af9c 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs +++ b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs @@ -2,15 +2,21 @@ #pragma rs export_func(primitives_test) +#pragma rs export_var(floatTest, doubleTest, charTest, shortTest, intTest, longTest, longlongTest) + // Testing primitive types static float floatTest = 1.99f; static double doubleTest = 2.05; static char charTest = -8; static short shortTest = -16; static int intTest = -32; +static long longTest = 17179869184l; // 1 << 34 +static long long longlongTest = 68719476736l; // 1 << 36 + static uchar ucharTest = 8; static ushort ushortTest = 16; static uint uintTest = 32; +static int64_t int64_tTest = -17179869184l; // - 1 << 34 static bool test_primitive_types(uint32_t index) { bool failed = false; @@ -21,9 +27,13 @@ static bool test_primitive_types(uint32_t index) { _RS_ASSERT(charTest == -8); _RS_ASSERT(shortTest == -16); _RS_ASSERT(intTest == -32); + _RS_ASSERT(longTest == 17179869184l); + _RS_ASSERT(longlongTest == 68719476736l); + _RS_ASSERT(ucharTest == 8); _RS_ASSERT(ushortTest == 16); _RS_ASSERT(uintTest == 32); + _RS_ASSERT(int64_tTest == -17179869184l); float time = end(index); diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index b9de7e1..a951005 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -497,7 +497,7 @@ bool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *r void FontState::initRenderState() { - String8 shaderString("varying vec4 varTex0;\n"); + String8 shaderString("varying vec2 varTex0;\n"); shaderString.append("void main() {\n"); shaderString.append(" lowp vec4 col = UNI_Color;\n"); shaderString.append(" col.a = texture2D(UNI_Tex0, varTex0.xy).a;\n"); diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index c94f294..81b4fa4 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -190,7 +190,7 @@ void ProgramFragmentState::init(Context *rsc) { String8 shaderString(RS_SHADER_INTERNAL); shaderString.append("varying lowp vec4 varColor;\n"); - shaderString.append("varying vec4 varTex0;\n"); + shaderString.append("varying vec2 varTex0;\n"); shaderString.append("void main() {\n"); shaderString.append(" lowp vec4 col = UNI_Color;\n"); shaderString.append(" gl_FragColor = col;\n"); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index d3dbfb2..a785262 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -242,6 +242,7 @@ ProgramVertexState::~ProgramVertexState() void ProgramVertexState::init(Context *rsc) { const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1); + const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2); const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); @@ -256,7 +257,7 @@ void ProgramVertexState::init(Context *rsc) rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1); rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1); rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1); - rsc->mStateElement.elementBuilderAdd(f4Elem, "texture0", 1); + rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1); const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc); Type *inputType = new Type(rsc); @@ -266,7 +267,7 @@ void ProgramVertexState::init(Context *rsc) String8 shaderString(RS_SHADER_INTERNAL); shaderString.append("varying vec4 varColor;\n"); - shaderString.append("varying vec4 varTex0;\n"); + shaderString.append("varying vec2 varTex0;\n"); shaderString.append("void main() {\n"); shaderString.append(" gl_Position = UNI_MVP * ATTRIB_position;\n"); shaderString.append(" gl_PointSize = 1.0;\n"); diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp index a43b440..8f583f0 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -285,10 +285,12 @@ ssize_t SharedBufferClient::DequeueUpdate::operator()() { return NO_ERROR; } -SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb) - : UpdateBase(sbb) { +SharedBufferClient::CancelUpdate::CancelUpdate(SharedBufferBase* sbb, + int tail, int buf) + : UpdateBase(sbb), tail(tail), buf(buf) { } -ssize_t SharedBufferClient::UndoDequeueUpdate::operator()() { +ssize_t SharedBufferClient::CancelUpdate::operator()() { + stack.index[tail] = buf; android_atomic_inc(&stack.available); return NO_ERROR; } @@ -319,7 +321,7 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() { return BAD_VALUE; // Preventively lock the current buffer before updating queued. - android_atomic_write(stack.index[head], &stack.inUse); + android_atomic_write(stack.headBuf, &stack.inUse); // Decrement the number of queued buffers int32_t queued; @@ -334,7 +336,9 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() { // the buffer we preventively locked upon entering this function head = (head + 1) % numBuffers; - android_atomic_write(stack.index[head], &stack.inUse); + const int8_t headBuf = stack.index[head]; + stack.headBuf = headBuf; + android_atomic_write(headBuf, &stack.inUse); // head is only modified here, so we don't need to use cmpxchg android_atomic_write(head, &stack.head); @@ -359,7 +363,7 @@ ssize_t SharedBufferServer::StatusUpdate::operator()() { SharedBufferClient::SharedBufferClient(SharedClient* sharedClient, int surface, int num, int32_t identity) : SharedBufferBase(sharedClient, surface, identity), - mNumBuffers(num), tail(0), undoDequeueTail(0) + mNumBuffers(num), tail(0) { SharedBufferStack& stack( *mSharedStack ); tail = computeTail(); @@ -390,7 +394,6 @@ ssize_t SharedBufferClient::dequeue() DequeueUpdate update(this); updateCondition( update ); - undoDequeueTail = tail; int dequeued = stack.index[tail]; tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1); LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail++=%d, %s", @@ -403,14 +406,19 @@ ssize_t SharedBufferClient::dequeue() status_t SharedBufferClient::undoDequeue(int buf) { + return cancel(buf); +} + +status_t SharedBufferClient::cancel(int buf) +{ RWLock::AutoRLock _rd(mLock); - // TODO: we can only undo the previous dequeue, we should - // enforce that in the api - UndoDequeueUpdate update(this); + // calculate the new position of the tail index (essentially tail--) + int localTail = (tail + mNumBuffers - 1) % mNumBuffers; + CancelUpdate update(this, localTail, buf); status_t err = updateCondition( update ); if (err == NO_ERROR) { - tail = undoDequeueTail; + tail = localTail; } return err; } diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index c77d48e..ebb0cc9 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -416,6 +416,7 @@ void Surface::init() { ANativeWindow::setSwapInterval = setSwapInterval; ANativeWindow::dequeueBuffer = dequeueBuffer; + ANativeWindow::cancelBuffer = cancelBuffer; ANativeWindow::lockBuffer = lockBuffer; ANativeWindow::queueBuffer = queueBuffer; ANativeWindow::query = query; @@ -527,6 +528,12 @@ int Surface::dequeueBuffer(ANativeWindow* window, return self->dequeueBuffer(buffer); } +int Surface::cancelBuffer(ANativeWindow* window, + android_native_buffer_t* buffer) { + Surface* self = getSelf(window); + return self->cancelBuffer(buffer); +} + int Surface::lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer) { Surface* self = getSelf(window); @@ -627,6 +634,33 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) return err; } +int Surface::cancelBuffer(android_native_buffer_t* buffer) +{ + status_t err = validate(); + switch (err) { + case NO_ERROR: + // no error, common case + break; + case INVALID_OPERATION: + // legitimate errors here + return err; + default: + // other errors happen because the surface is now invalid, + // for instance because it has been destroyed. In this case, + // we just fail silently (canceling a buffer is not technically + // an error at this point) + return NO_ERROR; + } + + int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer)); + + err = mSharedBufferClient->cancel(bufIdx); + + LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err)); + return err; +} + + int Surface::lockBuffer(android_native_buffer_t* buffer) { status_t err = validate(); diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index a6f5a1b..75b2294 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -134,18 +134,21 @@ static bool validateMotionEvent(int32_t action, size_t pointerCount, // --- InputWindow --- -bool InputWindow::visibleFrameIntersects(const InputWindow* other) const { - return visibleFrameRight > other->visibleFrameLeft - && visibleFrameLeft < other->visibleFrameRight - && visibleFrameBottom > other->visibleFrameTop - && visibleFrameTop < other->visibleFrameBottom; -} - bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const { return x >= touchableAreaLeft && x <= touchableAreaRight && y >= touchableAreaTop && y <= touchableAreaBottom; } +bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const { + return x >= frameLeft && x <= frameRight + && y >= frameTop && y <= frameBottom; +} + +bool InputWindow::isTrustedOverlay() const { + return layoutParamsType == TYPE_INPUT_METHOD + || layoutParamsType == TYPE_INPUT_METHOD_DIALOG; +} + // --- InputDispatcher --- @@ -1053,8 +1056,12 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, if (maskedAction == AMOTION_EVENT_ACTION_DOWN && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) { - mTempTouchState.addOrUpdateWindow(window, - InputTarget::FLAG_OUTSIDE, BitSet32(0)); + int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE; + if (isWindowObscuredAtPointLocked(window, x, y)) { + outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; + } + + mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0)); } } } @@ -1083,10 +1090,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, // (May be NULL which is why we put this code block before the next check.) newTouchedWindow = mTempTouchState.getFirstForegroundWindow(); } - int32_t targetFlags = InputTarget::FLAG_FOREGROUND; - if (isSplit) { - targetFlags |= InputTarget::FLAG_SPLIT; - } // If we did not find a touched window then fail. if (! newTouchedWindow) { @@ -1106,6 +1109,15 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, goto Failed; } + // Set target flags. + int32_t targetFlags = InputTarget::FLAG_FOREGROUND; + if (isSplit) { + targetFlags |= InputTarget::FLAG_SPLIT; + } + if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) { + targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; + } + // Update the temporary touch state. BitSet32 pointerIds; if (isSplit) { @@ -1186,23 +1198,13 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, for (size_t i = 0; i < mWindows.size(); i++) { const InputWindow* window = & mWindows[i]; if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) { - mTempTouchState.addOrUpdateWindow(window, 0, BitSet32(0)); + mTempTouchState.addOrUpdateWindow(window, + InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0)); } } } } - // If a touched window has been obscured at any point during the touch gesture, set - // the appropriate flag so we remember it for the entire gesture. - for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { - TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i); - if ((touchedWindow.targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) == 0) { - if (isWindowObscuredLocked(touchedWindow.window)) { - touchedWindow.targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; - } - } - } - // Success! Output targets. injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; @@ -1326,14 +1328,15 @@ bool InputDispatcher::checkInjectionPermission(const InputWindow* window, return true; } -bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) { +bool InputDispatcher::isWindowObscuredAtPointLocked( + const InputWindow* window, int32_t x, int32_t y) const { size_t numWindows = mWindows.size(); for (size_t i = 0; i < numWindows; i++) { const InputWindow* other = & mWindows.itemAt(i); if (other == window) { break; } - if (other->visible && window->visibleFrameIntersects(other)) { + if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) { return true; } } |