Merge "Add hinge angle sensor enum docs"
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 7c989f6..6459805 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -61,11 +61,15 @@
static std::vector<apex::ApexFile> ActivateApexPackages() {
// The logic here is (partially) copied and adapted from
- // system/apex/apexd/apexd_main.cpp.
+ // system/apex/apexd/apexd.cpp.
//
- // Only scan the APEX directory under /system (within the chroot dir).
- // Cast call to void to suppress warn_unused_result.
- static_cast<void>(apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir));
+ // Only scan the APEX directory under /system, /system_ext and /vendor (within the chroot dir).
+ std::vector<const char*> apex_dirs{apex::kApexPackageSystemDir, apex::kApexPackageSystemExtDir,
+ apex::kApexPackageVendorDir};
+ for (const auto& dir : apex_dirs) {
+ // Cast call to void to suppress warn_unused_result.
+ static_cast<void>(apex::scanPackagesDirAndActivate(dir));
+ }
return apex::getActivePackages();
}
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 02416e4..acd833f 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -180,9 +180,9 @@
}
mPendingReleaseItem.item = std::move(mSubmitted.front());
mSubmitted.pop();
- if (mNextTransaction == nullptr) {
- processNextBufferLocked();
- }
+
+ processNextBufferLocked();
+
mCallbackCV.notify_all();
decStrong((void*)transactionCallbackThunk);
}
@@ -201,7 +201,7 @@
SurfaceComposerClient::Transaction localTransaction;
bool applyTransaction = true;
SurfaceComposerClient::Transaction* t = &localTransaction;
- if (mNextTransaction != nullptr) {
+ if (mNextTransaction != nullptr && mUseNextTransaction) {
t = mNextTransaction;
mNextTransaction = nullptr;
applyTransaction = false;
@@ -263,9 +263,10 @@
std::unique_lock _lock{mMutex};
if (mNextTransaction != nullptr) {
- while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS) {
+ while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
mCallbackCV.wait(_lock);
}
+ mUseNextTransaction = true;
}
// add to shadow queue
mNumFrameAvailable++;
@@ -274,6 +275,7 @@
void BLASTBufferQueue::setNextTransaction(SurfaceComposerClient::Transaction* t) {
std::lock_guard _lock{mMutex};
+ mUseNextTransaction = false;
mNextTransaction = t;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7017b7c..ff8b719 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -526,21 +526,6 @@
mDesiredPresentTime = -1;
}
-void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- Vector<ComposerState> composerStates;
- Vector<DisplayState> displayStates;
-
- ComposerState s;
- s.state.surface = handle;
- s.state.what |= layer_state_t::eReparent;
- s.state.parentHandleForChild = nullptr;
-
- composerStates.add(s);
- sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
- sf->setTransactionState(composerStates, displayStates, 0, applyToken, {}, -1, {}, false, {});
-}
-
void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
@@ -1558,7 +1543,7 @@
}
ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err));
if (err == NO_ERROR) {
- return new SurfaceControl(this, handle, gbp, true /* owned */, transformHint);
+ return new SurfaceControl(this, handle, gbp, transformHint);
}
}
return nullptr;
@@ -1589,7 +1574,7 @@
}
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
- *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */, transformHint);
+ *outSurface = new SurfaceControl(this, handle, gbp, transformHint);
}
}
return err;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 6292388..a332a1f 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -46,34 +46,22 @@
// ============================================================================
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
- const sp<IGraphicBufferProducer>& gbp, bool owned,
+ const sp<IGraphicBufferProducer>& gbp,
uint32_t transform)
: mClient(client),
mHandle(handle),
mGraphicBufferProducer(gbp),
- mOwned(owned),
mTransformHint(transform) {}
SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
mClient = other->mClient;
mHandle = other->mHandle;
mGraphicBufferProducer = other->mGraphicBufferProducer;
- mOwned = false;
mTransformHint = other->mTransformHint;
}
SurfaceControl::~SurfaceControl()
{
- // Avoid reparenting the server-side surface to null if we are not the owner of it,
- // meaning that we retrieved it from another process.
- if (mHandle != nullptr && mOwned) {
- SurfaceComposerClient::doDropReferenceTransaction(mHandle);
- }
- release();
-}
-
-void SurfaceControl::release()
-{
// Trigger an IPC now, to make sure things
// happen without delay, since these resources are quite heavy.
mClient.clear();
@@ -157,7 +145,6 @@
sp<IBinder> SurfaceControl::getHandle() const
{
- Mutex::Autolock lock(mLock);
return mHandle;
}
@@ -206,7 +193,7 @@
return new SurfaceControl(new SurfaceComposerClient(
interface_cast<ISurfaceComposerClient>(client)),
handle.get(), interface_cast<IGraphicBufferProducer>(gbp),
- false /* owned */, transformHint);
+ transformHint);
}
// ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 1b22df2..64c21e0 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -123,6 +123,8 @@
sp<BLASTBufferItemConsumer> mBufferItemConsumer;
SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex);
+
+ bool mUseNextTransaction = false;
};
} // namespace android
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index d0bb6a3..27877bb 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -184,12 +184,6 @@
static bool getProtectedContentSupport();
/**
- * Called from SurfaceControl d'tor to 'destroy' the surface (or rather, reparent it
- * to null), but without needing an sp<SurfaceControl> to avoid infinite ressurection.
- */
- static void doDropReferenceTransaction(const sp<IBinder>& handle);
-
- /**
* Uncaches a buffer in ISurfaceComposer. It must be uncached via a transaction so that it is
* in order with other transactions that use buffers.
*/
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 7bc7c68..ac2bbcc 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -58,10 +58,6 @@
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
- // Release the handles assosciated with the SurfaceControl, without reparenting
- // them off-screen. At the moment if this isn't executed before ~SurfaceControl
- // is called then the destructor will reparent the layer off-screen for you.
- void release();
// Reparent off-screen and release. This is invoked by the destructor.
void destroy();
@@ -89,7 +85,7 @@
explicit SurfaceControl(const sp<SurfaceControl>& other);
SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
- const sp<IGraphicBufferProducer>& gbp, bool owned, uint32_t transformHint = 0);
+ const sp<IGraphicBufferProducer>& gbp, uint32_t transformHint = 0);
private:
// can't be copied
@@ -109,7 +105,6 @@
sp<IGraphicBufferProducer> mGraphicBufferProducer;
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData;
- bool mOwned;
uint32_t mTransformHint;
};
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp
index b1a84bd..eb66c8f 100644
--- a/libs/renderengine/gl/filters/BlurFilter.cpp
+++ b/libs/renderengine/gl/filters/BlurFilter.cpp
@@ -132,8 +132,7 @@
}
string BlurFilter::getVertexShader() const {
- return R"SHADER(
- #version 310 es
+ return R"SHADER(#version 310 es
in vec2 aPosition;
in highp vec2 aUV;
@@ -147,8 +146,7 @@
}
string BlurFilter::getMixFragShader() const {
- string shader = R"SHADER(
- #version 310 es
+ string shader = R"SHADER(#version 310 es
precision mediump float;
in highp vec2 vUV;
diff --git a/libs/renderengine/gl/filters/GaussianBlurFilter.cpp b/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
index 4d7bf44..a0d7af8 100644
--- a/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
+++ b/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
@@ -43,7 +43,7 @@
mVPosLoc = mVerticalProgram.getAttributeLocation("aPosition");
mVUvLoc = mVerticalProgram.getAttributeLocation("aUV");
mVTextureLoc = mVerticalProgram.getUniformLocation("uTexture");
- mVIncrementLoc = mVerticalProgram.getUniformLocation("uIncrement");
+ mVGaussianOffsetLoc = mVerticalProgram.getUniformLocation("uGaussianOffsets");
mVNumSamplesLoc = mVerticalProgram.getUniformLocation("uSamples");
mVGaussianWeightLoc = mVerticalProgram.getUniformLocation("uGaussianWeights");
@@ -51,7 +51,7 @@
mHPosLoc = mHorizontalProgram.getAttributeLocation("aPosition");
mHUvLoc = mHorizontalProgram.getAttributeLocation("aUV");
mHTextureLoc = mHorizontalProgram.getUniformLocation("uTexture");
- mHIncrementLoc = mHorizontalProgram.getUniformLocation("uIncrement");
+ mHGaussianOffsetLoc = mHorizontalProgram.getUniformLocation("uGaussianOffsets");
mHNumSamplesLoc = mHorizontalProgram.getUniformLocation("uSamples");
mHGaussianWeightLoc = mHorizontalProgram.getUniformLocation("uGaussianWeights");
}
@@ -60,6 +60,36 @@
mVerticalPassFbo.allocateBuffers(mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight());
}
+static void calculateLinearGaussian(uint32_t samples, double dimension,
+ GLfloat* gaussianLinearOffsets, GLfloat* gaussianWeights,
+ GLfloat* gaussianLinearWeights) {
+ // The central point in the symmetric bell curve is not offset.
+ // This decision allows one less sampling in the GPU.
+ gaussianLinearWeights[0] = gaussianWeights[0];
+ gaussianLinearOffsets[0] = 0.0;
+
+ // Calculate the linear weights.
+ // This is a vector reduction where an element of the packed reduced array
+ // contains the sum of two adjacent members of the original packed array.
+ // We start preserving the element 1 of the array and then perform sum for
+ // every other (i+=2) element of the gaussianWeights array.
+ gaussianLinearWeights[1] = gaussianWeights[1];
+ const auto start = 1 + ((samples - 1) & 0x1);
+ for (size_t i = start; i < samples; i += 2) {
+ gaussianLinearWeights[start + i / 2] = gaussianWeights[i] + gaussianWeights[i + 1];
+ }
+
+ // Calculate the texture coordinates offsets as an average of the initial offsets,
+ // weighted by the Gaussian weights as described in the original article.
+ gaussianLinearOffsets[1] = 1.0 / dimension;
+ for (size_t i = start; i < samples; i += 2) {
+ GLfloat offset_1 = float(i) / dimension;
+ GLfloat offset_2 = float(i + 1) / dimension;
+ gaussianLinearOffsets[start + i / 2] =
+ (offset_1 * gaussianWeights[i] + offset_2 * gaussianWeights[i + 1]) /
+ gaussianLinearWeights[start + i / 2];
+ }
+}
status_t GaussianBlurFilter::prepare() {
ATRACE_NAME("GaussianBlurFilter::prepare");
@@ -88,27 +118,47 @@
mVerticalPassFbo.bind();
mVerticalProgram.useProgram();
- // Precompute gaussian bell curve, and send it to the shader to avoid
- // unnecessary computations.
- auto samples = min(mRadius, kNumSamples);
+ // Precompute gaussian bell curve, and send it to the shader to avoid unnecessary computations.
+ double radiusD = fmax(1.0, mRadius * kFboScale);
+ auto samples = int(fmin(radiusD, kNumSamples));
GLfloat gaussianWeights[kNumSamples] = {};
- for (size_t i = 0; i < samples; i++) {
- float normalized = float(i) / samples;
+
+ gaussianWeights[0] = 1.0f;
+ auto totalWeight = gaussianWeights[0];
+
+ // Gaussian weights calculation.
+ for (size_t i = 1; i < samples; i++) {
+ const double normalized = i / radiusD;
gaussianWeights[i] = (float)exp(-K * normalized * normalized);
+ totalWeight += 2.0 * gaussianWeights[i];
}
- // set uniforms
+ // Gaussian weights normalization to avoid work in the GPU.
+ for (size_t i = 0; i < samples; i++) {
+ gaussianWeights[i] /= totalWeight;
+ }
+
auto width = mVerticalPassFbo.getBufferWidth();
auto height = mVerticalPassFbo.getBufferHeight();
- auto radiusF = fmax(1.0f, mRadius * kFboScale);
glViewport(0, 0, width, height);
+
+ // Allocate space for the corrected Gaussian weights and offsets.
+ // We could use less space, but let's keep the code simple.
+ GLfloat gaussianLinearWeights[kNumSamples] = {};
+ GLfloat gaussianLinearOffsets[kNumSamples] = {};
+
+ // Calculate the weights and offsets for the vertical pass.
+ // This only need to be called every time mRadius or height changes, so it could be optimized.
+ calculateLinearGaussian(samples, double(height), gaussianLinearOffsets, gaussianWeights,
+ gaussianLinearWeights);
+ // set uniforms
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName());
glUniform1i(mVTextureLoc, 0);
- glUniform2f(mVIncrementLoc, radiusF / (width * 2.0f), radiusF / (height * 2.0f));
- glUniform1i(mVNumSamplesLoc, samples);
- glUniform1fv(mVGaussianWeightLoc, kNumSamples, gaussianWeights);
- mEngine.checkErrors("Setting vertical-diagonal pass uniforms");
+ glUniform1i(mVNumSamplesLoc, 1 + (samples + 1) / 2);
+ glUniform1fv(mVGaussianWeightLoc, kNumSamples, gaussianLinearWeights);
+ glUniform1fv(mVGaussianOffsetLoc, kNumSamples, gaussianLinearOffsets);
+ mEngine.checkErrors("Setting vertical pass uniforms");
drawMesh(mVUvLoc, mVPosLoc);
@@ -116,14 +166,18 @@
mBlurredFbo.bind();
mHorizontalProgram.useProgram();
+ // Calculate the weights and offsets for the horizontal pass.
+ // This only needs to be called every time mRadius or width change, so it could be optimized.
+ calculateLinearGaussian(samples, double(width), gaussianLinearOffsets, gaussianWeights,
+ gaussianLinearWeights);
// set uniforms
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mVerticalPassFbo.getTextureName());
glUniform1i(mHTextureLoc, 0);
- glUniform2f(mHIncrementLoc, radiusF / (width * 2.0f), radiusF / (height * 2.0f));
- glUniform1i(mHNumSamplesLoc, samples);
- glUniform1fv(mHGaussianWeightLoc, kNumSamples, gaussianWeights);
- mEngine.checkErrors("Setting vertical pass uniforms");
+ glUniform1i(mHNumSamplesLoc, 1 + (samples + 1) / 2);
+ glUniform1fv(mHGaussianWeightLoc, kNumSamples, gaussianLinearWeights);
+ glUniform1fv(mHGaussianOffsetLoc, kNumSamples, gaussianLinearOffsets);
+ mEngine.checkErrors("Setting horizontal pass uniforms");
drawMesh(mHUvLoc, mHPosLoc);
@@ -142,43 +196,37 @@
stringstream shader;
shader << "#version 310 es\n"
<< "#define DIRECTION " << (horizontal ? "1" : "0") << "\n"
- << "#define NUM_SAMPLES " << kNumSamples <<
+ << "#define NUM_SAMPLES " << 1 + (kNumSamples + 1) / 2 <<
R"SHADER(
precision mediump float;
uniform sampler2D uTexture;
- uniform vec2 uIncrement;
uniform float[NUM_SAMPLES] uGaussianWeights;
+ uniform float[NUM_SAMPLES] uGaussianOffsets;
uniform int uSamples;
highp in vec2 vUV;
out vec4 fragColor;
- vec3 gaussianBlur(sampler2D texture, highp vec2 uv, float inc, vec2 direction) {
- float totalWeight = 0.0;
- vec3 blurred = vec3(0.0);
- float fSamples = 1.0 / float(uSamples);
-
- for (int i = -uSamples; i <= uSamples; i++) {
- float weight = uGaussianWeights[abs(i)];
- float normalized = float(i) * fSamples;
- float radInc = inc * normalized;
- blurred += weight * (texture(texture, radInc * direction + uv, 0.0)).rgb;
- totalWeight += weight;
- }
-
- return blurred / totalWeight;
- }
-
void main() {
#if DIRECTION == 1
- vec3 color = gaussianBlur(uTexture, vUV, uIncrement.x, vec2(1.0, 0.0));
+ const vec2 direction = vec2(1.0, 0.0);
#else
- vec3 color = gaussianBlur(uTexture, vUV, uIncrement.y, vec2(0.0, 1.0));
+ const vec2 direction = vec2(0.0, 1.0);
#endif
- fragColor = vec4(color, 1.0);
- }
+ // Iteration zero outside loop to avoid sampling the central point twice.
+ vec4 blurred = uGaussianWeights[0] * (texture(uTexture, vUV, 0.0));
+
+ // Iterate one side of the bell to halve the loop iterations.
+ for (int i = 1; i <= uSamples; i++) {
+ vec2 offset = uGaussianOffsets[i] * direction;
+ blurred += uGaussianWeights[i] * (texture(uTexture, vUV + offset, 0.0));
+ blurred += uGaussianWeights[i] * (texture(uTexture, vUV - offset, 0.0));
+ }
+
+ fragColor = vec4(blurred.rgb, 1.0);
+ }
)SHADER";
return shader.str();
}
diff --git a/libs/renderengine/gl/filters/GaussianBlurFilter.h b/libs/renderengine/gl/filters/GaussianBlurFilter.h
index 8580522..44f5fde 100644
--- a/libs/renderengine/gl/filters/GaussianBlurFilter.h
+++ b/libs/renderengine/gl/filters/GaussianBlurFilter.h
@@ -28,9 +28,12 @@
namespace renderengine {
namespace gl {
+// Class that implements a Gaussian Filter that uses Linear Sampling
+// to halve the number of samples and reduce runtime by 40% as described in:
+// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling
class GaussianBlurFilter : public BlurFilter {
public:
- static constexpr uint32_t kNumSamples = 12;
+ static constexpr uint32_t kNumSamples = 22;
explicit GaussianBlurFilter(GLESRenderEngine& engine);
status_t prepare() override;
@@ -47,7 +50,7 @@
GLuint mVPosLoc;
GLuint mVUvLoc;
GLuint mVTextureLoc;
- GLuint mVIncrementLoc;
+ GLuint mVGaussianOffsetLoc;
GLuint mVNumSamplesLoc;
GLuint mVGaussianWeightLoc;
@@ -56,7 +59,7 @@
GLuint mHPosLoc;
GLuint mHUvLoc;
GLuint mHTextureLoc;
- GLuint mHIncrementLoc;
+ GLuint mHGaussianOffsetLoc;
GLuint mHNumSamplesLoc;
GLuint mHGaussianWeightLoc;
};
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index dbace11..2fd2579 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -92,7 +92,8 @@
.setRelativeLayer(layerG, layerR->getHandle(), 1)
.apply();
- layerG.clear();
+ Transaction().reparent(layerG, nullptr).apply();
+
// layerG should have been removed
getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
}
diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp
index cf3f8e8..cdd9d92 100644
--- a/services/surfaceflinger/tests/LayerUpdate_test.cpp
+++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp
@@ -542,6 +542,7 @@
mCapture->checkPixel(64, 64, 111, 111, 111);
}
+ Transaction().reparent(mChild, nullptr).apply();
mChild.clear();
{
@@ -1702,6 +1703,7 @@
ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
auto redLayerHandle = redLayer->getHandle();
+ Transaction().reparent(redLayer, nullptr).apply();
redLayer.clear();
SurfaceComposerClient::Transaction().apply(true);