summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/DisplayListRenderer.cpp2
-rw-r--r--libs/hwui/DisplayListRenderer.h2
-rw-r--r--libs/hwui/OpenGLDebugRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLDebugRenderer.h2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp13
-rw-r--r--libs/hwui/OpenGLRenderer.h2
-rw-r--r--libs/hwui/ProgramCache.cpp19
-rw-r--r--libs/hwui/SkiaShader.cpp129
-rw-r--r--libs/hwui/SkiaShader.h25
-rw-r--r--libs/rs/java/Samples/res/raw/multitexf.glsl2
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/primitives.rs10
-rw-r--r--libs/rs/rsFont.cpp2
-rw-r--r--libs/rs/rsProgramFragment.cpp2
-rw-r--r--libs/rs/rsProgramVertex.cpp5
-rw-r--r--libs/surfaceflinger_client/SharedBufferStack.cpp30
-rw-r--r--libs/surfaceflinger_client/Surface.cpp34
-rw-r--r--libs/ui/InputDispatcher.cpp57
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;
}
}