Added native functionality to create a color layer.
Added a new layer that can draw a specified color and specified
alpha. This will replace creating a dim layer and allow any colors,
not just black, to be set for this layer.
Test: Added tests to Transaction_test.cpp to test with a color
and a color layer with alpha.
Change-Id: I00a38d1bbc01093026f088c3347454281bdc2b8c
diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp
index 57ddde0..d3dc16d 100644
--- a/libs/gui/LayerDebugInfo.cpp
+++ b/libs/gui/LayerDebugInfo.cpp
@@ -43,7 +43,10 @@
RETURN_ON_ERROR(parcel->writeInt32(mHeight));
RETURN_ON_ERROR(parcel->write(mCrop));
RETURN_ON_ERROR(parcel->write(mFinalCrop));
- RETURN_ON_ERROR(parcel->writeFloat(mAlpha));
+ RETURN_ON_ERROR(parcel->writeFloat(mColor.r));
+ RETURN_ON_ERROR(parcel->writeFloat(mColor.g));
+ RETURN_ON_ERROR(parcel->writeFloat(mColor.b));
+ RETURN_ON_ERROR(parcel->writeFloat(mColor.a));
RETURN_ON_ERROR(parcel->writeUint32(mFlags));
RETURN_ON_ERROR(parcel->writeInt32(mPixelFormat));
RETURN_ON_ERROR(parcel->writeUint32(static_cast<uint32_t>(mDataSpace)));
@@ -79,7 +82,14 @@
RETURN_ON_ERROR(parcel->readInt32(&mHeight));
RETURN_ON_ERROR(parcel->read(mCrop));
RETURN_ON_ERROR(parcel->read(mFinalCrop));
- RETURN_ON_ERROR(parcel->readFloat(&mAlpha));
+ mColor.r = parcel->readFloat();
+ RETURN_ON_ERROR(parcel->errorCheck());
+ mColor.g = parcel->readFloat();
+ RETURN_ON_ERROR(parcel->errorCheck());
+ mColor.b = parcel->readFloat();
+ RETURN_ON_ERROR(parcel->errorCheck());
+ mColor.a = parcel->readFloat();
+ RETURN_ON_ERROR(parcel->errorCheck());
RETURN_ON_ERROR(parcel->readUint32(&mFlags));
RETURN_ON_ERROR(parcel->readInt32(&mPixelFormat));
// \todo [2017-07-25 kraita]: Static casting mDataSpace pointer to an uint32 does work. Better ways?
@@ -116,8 +126,10 @@
result.appendFormat("isOpaque=%1d, invalidate=%1d, ", info.mIsOpaque, info.mContentDirty);
result.appendFormat("dataspace=%s, ", dataspaceDetails(info.mDataSpace).c_str());
result.appendFormat("pixelformat=%s, ", decodePixelFormat(info.mPixelFormat).c_str());
- result.appendFormat("alpha=%.3f, flags=0x%08x, ",
- static_cast<double>(info.mAlpha), info.mFlags);
+ result.appendFormat("color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
+ static_cast<double>(info.mColor.r), static_cast<double>(info.mColor.g),
+ static_cast<double>(info.mColor.b), static_cast<double>(info.mColor.a),
+ info.mFlags);
result.appendFormat("tr=[%.2f, %.2f][%.2f, %.2f]",
static_cast<double>(info.mMatrix[0][0]), static_cast<double>(info.mMatrix[0][1]),
static_cast<double>(info.mMatrix[1][0]), static_cast<double>(info.mMatrix[1][1]));
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 3418a49..fcee73f 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -46,6 +46,9 @@
output.writeStrongBinder(IInterface::asBinder(barrierGbp));
output.writeStrongBinder(relativeLayerHandle);
output.writeStrongBinder(parentHandleForChild);
+ output.writeFloat(color.r);
+ output.writeFloat(color.g);
+ output.writeFloat(color.b);
output.write(transparentRegion);
return NO_ERROR;
}
@@ -79,6 +82,9 @@
interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
relativeLayerHandle = input.readStrongBinder();
parentHandleForChild = input.readStrongBinder();
+ color.r = input.readFloat();
+ color.g = input.readFloat();
+ color.b = input.readFloat();
input.read(transparentRegion);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index be7b1d2..c5a4389 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -158,6 +158,8 @@
const Region& transparentRegion);
status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float alpha);
+ status_t setColor(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+ const half3& color);
status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float dsdx, float dtdx, float dtdy, float dsdy);
status_t setOrientation(int orientation);
@@ -402,6 +404,17 @@
return NO_ERROR;
}
+status_t Composer::setColor(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, const half3& color) {
+ Mutex::Autolock _l(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s)
+ return BAD_INDEX;
+ s->what |= layer_state_t::eColorChanged;
+ s->color = color;
+ return NO_ERROR;
+}
+
status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, uint32_t layerStack) {
Mutex::Autolock _l(mLock);
@@ -822,6 +835,10 @@
return getComposer().setAlpha(this, id, alpha);
}
+status_t SurfaceComposerClient::setColor(const sp<IBinder>& id, const half3& color) {
+ return getComposer().setColor(this, id, color);
+}
+
status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) {
return getComposer().setLayerStack(this, id, layerStack);
}
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index d801d12..9e1d7b6 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -155,6 +155,11 @@
if (err < 0) return err;
return mClient->setAlpha(mHandle, alpha);
}
+status_t SurfaceControl::setColor(const half3& color) {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->setColor(mHandle, color);
+}
status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
status_t err = validate();
if (err < 0) return err;
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index 2c613ea..d5bbef2 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -41,7 +41,7 @@
eCursorWindow = 0x00002000,
eFXSurfaceNormal = 0x00000000,
- eFXSurfaceDim = 0x00020000,
+ eFXSurfaceColor = 0x00020000,
eFXSurfaceMask = 0x000F0000,
};
diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h
index 8453e04..92bd8c5 100644
--- a/libs/gui/include/gui/LayerDebugInfo.h
+++ b/libs/gui/include/gui/LayerDebugInfo.h
@@ -22,6 +22,7 @@
#include <ui/Region.h>
#include <string>
+#include <math/vec4.h>
namespace android {
@@ -52,7 +53,7 @@
int32_t mHeight = -1;
Rect mCrop = Rect::INVALID_RECT;
Rect mFinalCrop = Rect::INVALID_RECT;
- float mAlpha = 0.f;
+ half4 mColor = half4(1.0_hf, 1.0_hf, 1.0_hf, 0.0_hf);
uint32_t mFlags = 0;
PixelFormat mPixelFormat = PIXEL_FORMAT_NONE;
android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index cf2ff5b..1718143 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -32,6 +32,7 @@
#include <gui/CpuConsumer.h>
#include <gui/SurfaceControl.h>
+#include <math/vec3.h>
namespace android {
@@ -149,6 +150,7 @@
status_t setRelativeLayer(const sp<IBinder>& id,
const sp<IBinder>& relativeTo, int32_t layer);
status_t setAlpha(const sp<IBinder>& id, float alpha=1.0f);
+ status_t setColor(const sp<IBinder>& id, const half3& color);
status_t setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dtdy, float dsdy);
status_t setPosition(const sp<IBinder>& id, float x, float y);
status_t setSize(const sp<IBinder>& id, uint32_t w, uint32_t h);
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index b506e00..e98e26a 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -29,6 +29,7 @@
#include <ui/Region.h>
#include <gui/ISurfaceComposerClient.h>
+#include <math/vec3.h>
namespace android {
@@ -90,6 +91,7 @@
status_t setFlags(uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(const Region& transparent);
status_t setAlpha(float alpha=1.0f);
+ status_t setColor(const half3& color);
// Experimentarily it appears that the matrix transforms the
// on-screen rectangle and it's contents before the position is
diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h
index 4ff2e5e..bd42634 100644
--- a/libs/gui/include/private/gui/LayerState.h
+++ b/libs/gui/include/private/gui/LayerState.h
@@ -25,6 +25,7 @@
#include <ui/Region.h>
#include <ui/Rect.h>
#include <gui/IGraphicBufferProducer.h>
+#include <math/vec3.h>
namespace android {
@@ -60,7 +61,8 @@
eReparentChildren = 0x00002000,
eDetachChildren = 0x00004000,
eRelativeLayerChanged = 0x00008000,
- eReparent = 0x00010000
+ eReparent = 0x00010000,
+ eColorChanged = 0x00020000
};
layer_state_t()
@@ -110,6 +112,8 @@
sp<IBinder> parentHandleForChild;
+ half3 color;
+
// non POD must be last. see write/read
Region transparentRegion;
};
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 38529b6..1f4427a 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -14,7 +14,7 @@
FrameTracker.cpp \
GpuService.cpp \
Layer.cpp \
- LayerDim.cpp \
+ ColorLayer.cpp \
LayerRejecter.cpp \
LayerVector.cpp \
MessageQueue.cpp \
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/ColorLayer.cpp
similarity index 79%
rename from services/surfaceflinger/LayerDim.cpp
rename to services/surfaceflinger/ColorLayer.cpp
index daebf8a..6923782 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -16,7 +16,7 @@
// #define LOG_NDEBUG 0
#undef LOG_TAG
-#define LOG_TAG "LayerDim"
+#define LOG_TAG "ColorLayer"
#include <stdlib.h>
#include <stdint.h>
@@ -27,7 +27,7 @@
#include <ui/GraphicBuffer.h>
-#include "LayerDim.h"
+#include "ColorLayer.h"
#include "SurfaceFlinger.h"
#include "DisplayDevice.h"
#include "RenderEngine/RenderEngine.h"
@@ -35,31 +35,29 @@
namespace android {
// ---------------------------------------------------------------------------
-LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
+ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
: Layer(flinger, client, name, w, h, flags) {
}
-LayerDim::~LayerDim() {
-}
-
-void LayerDim::onDraw(const sp<const DisplayDevice>& hw,
+void ColorLayer::onDraw(const sp<const DisplayDevice>& hw,
const Region& /* clip */, bool useIdentityTransform) const
{
const State& s(getDrawingState());
- if (s.alpha>0) {
+ if (s.color.a>0) {
Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
computeGeometry(hw, mesh, useIdentityTransform);
RenderEngine& engine(mFlinger->getRenderEngine());
- engine.setupDimLayerBlending(s.alpha);
+ engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
+ true /* disableTexture */, s.color);
engine.drawMesh(mesh);
engine.disableBlending();
}
}
-bool LayerDim::isVisible() const {
+bool ColorLayer::isVisible() const {
const Layer::State& s(getDrawingState());
- return !isHiddenByPolicy() && s.alpha;
+ return !isHiddenByPolicy() && s.color.a;
}
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/ColorLayer.h
similarity index 81%
rename from services/surfaceflinger/LayerDim.h
rename to services/surfaceflinger/ColorLayer.h
index a0cfca9..ac3e2a9 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_LAYER_DIM_H
-#define ANDROID_LAYER_DIM_H
+#ifndef ANDROID_COLOR_LAYER_H
+#define ANDROID_COLOR_LAYER_H
#include <stdint.h>
#include <sys/types.h>
@@ -26,14 +26,14 @@
namespace android {
-class LayerDim : public Layer
+class ColorLayer : public Layer
{
public:
- LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
+ ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags);
- virtual ~LayerDim();
+ virtual ~ColorLayer() = default;
- virtual const char* getTypeId() const { return "LayerDim"; }
+ virtual const char* getTypeId() const { return "ColorLayer"; }
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
bool useIdentityTransform) const;
virtual bool isOpaque(const Layer::State&) const { return false; }
@@ -46,4 +46,4 @@
}; // namespace android
-#endif // ANDROID_LAYER_DIM_H
+#endif // ANDROID_COLOR_LAYER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index fd30e16..8734ee1 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -137,11 +137,7 @@
mCurrentState.requestedFinalCrop = mCurrentState.finalCrop;
mCurrentState.requestedCrop = mCurrentState.crop;
mCurrentState.z = 0;
-#ifdef USE_HWC2
- mCurrentState.alpha = 1.0f;
-#else
- mCurrentState.alpha = 0xFF;
-#endif
+ mCurrentState.color.a = 1.0f;
mCurrentState.layerStack = 0;
mCurrentState.flags = layerFlags;
mCurrentState.sequence = 0;
@@ -334,6 +330,10 @@
return mName;
}
+bool Layer::getPremultipledAlpha() const {
+ return mPremultipliedAlpha;
+}
+
status_t Layer::setBuffers( uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags)
{
@@ -683,7 +683,7 @@
" %s (%d)", mName.string(), to_string(blendMode).c_str(),
to_string(error).c_str(), static_cast<int32_t>(error));
#else
- if (!isOpaque(s) || getAlpha() != 0xFF) {
+ if (!isOpaque(s) || getAlpha() != 1.0f) {
layer.setBlending(mPremultipliedAlpha ?
HWC_BLENDING_PREMULT :
HWC_BLENDING_COVERAGE);
@@ -757,7 +757,7 @@
hwcInfo.sourceCrop = sourceCrop;
}
- float alpha = getAlpha();
+ float alpha = static_cast<float>(getAlpha());
error = hwcLayer->setPlaneAlpha(alpha);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
"%s (%d)", mName.string(), alpha, to_string(error).c_str(),
@@ -787,7 +787,7 @@
const Transform& tr(hw->getTransform());
layer.setFrame(tr.transform(frame));
layer.setCrop(computeCrop(hw));
- layer.setPlaneAlpha(getAlpha());
+ layer.setPlaneAlpha(static_cast<uint8_t>(std::round(255.0f*getAlpha())));
#endif
/*
@@ -904,8 +904,11 @@
if (mActiveBuffer == nullptr) {
setCompositionType(hwcId, HWC2::Composition::SolidColor);
- // For now, we only support black for DimLayer
- error = hwcLayer->setColor({0, 0, 0, 255});
+ half4 color = getColor();
+ error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f*color.r)),
+ static_cast<uint8_t>(std::round(255.0f * color.g)),
+ static_cast<uint8_t>(std::round(255.0f * color.b)),
+ 255});
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set color: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -1254,7 +1257,8 @@
texCoords[3] = vec2(right, 1.0f - top);
RenderEngine& engine(mFlinger->getRenderEngine());
- engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), getAlpha());
+ engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s),
+ false /* disableTexture */, getColor());
#ifdef USE_HWC2
engine.setSourceDataSpace(mCurrentState.dataSpace);
#endif
@@ -1877,19 +1881,30 @@
setTransactionFlags(eTransactionNeeded);
return true;
}
-#ifdef USE_HWC2
bool Layer::setAlpha(float alpha) {
-#else
-bool Layer::setAlpha(uint8_t alpha) {
-#endif
- if (mCurrentState.alpha == alpha)
+ if (mCurrentState.color.a == alpha)
return false;
mCurrentState.sequence++;
- mCurrentState.alpha = alpha;
+ mCurrentState.color.a = alpha;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
+
+bool Layer::setColor(const half3& color) {
+ if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g
+ && color.b == mCurrentState.color.b)
+ return false;
+
+ mCurrentState.sequence++;
+ mCurrentState.color.r = color.r;
+ mCurrentState.color.g = color.g;
+ mCurrentState.color.b = color.b;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
mCurrentState.sequence++;
mCurrentState.requested.transform.set(
@@ -2141,13 +2156,8 @@
}
bool Layer::isVisible() const {
-#ifdef USE_HWC2
return !(isHiddenByPolicy()) && getAlpha() > 0.0f
&& (mActiveBuffer != NULL || mSidebandStream != NULL);
-#else
- return !(isHiddenByPolicy()) && getAlpha()
- && (mActiveBuffer != NULL || mSidebandStream != NULL);
-#endif
}
bool Layer::allTransactionsSignaled() {
@@ -2439,7 +2449,7 @@
info.mHeight = ds.active.h;
info.mCrop = ds.crop;
info.mFinalCrop = ds.finalCrop;
- info.mAlpha = ds.alpha;
+ info.mColor = ds.color;
info.mFlags = ds.flags;
info.mPixelFormat = getPixelFormat();
info.mDataSpace = getDataSpace();
@@ -2467,7 +2477,6 @@
info.mContentDirty = contentDirty;
return info;
}
-
#ifdef USE_HWC2
void Layer::miniDumpHeader(String8& result) {
result.append("----------------------------------------");
@@ -2791,23 +2800,17 @@
return t * getDrawingState().active.transform;
}
-#ifdef USE_HWC2
-float Layer::getAlpha() const {
+half Layer::getAlpha() const {
const auto& p = mDrawingParent.promote();
- float parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0;
- return parentAlpha * getDrawingState().alpha;
+ half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
+ return parentAlpha * getDrawingState().color.a;
}
-#else
-uint8_t Layer::getAlpha() const {
- const auto& p = mDrawingParent.promote();
- float parentAlpha = (p != nullptr) ? (p->getAlpha() / 255.0f) : 1.0;
- float drawingAlpha = getDrawingState().alpha / 255.0f;
- drawingAlpha = drawingAlpha * parentAlpha;
- return static_cast<uint8_t>(std::round(drawingAlpha * 255));
+half4 Layer::getColor() const {
+ const half4 color(getDrawingState().color);
+ return half4(color.r, color.g, color.b, getAlpha());
}
-#endif
void Layer::commitChildList() {
for (size_t i = 0; i < mCurrentChildren.size(); i++) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e7ece45..921492b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -51,6 +51,8 @@
#include "RenderEngine/Mesh.h"
#include "RenderEngine/Texture.h"
+#include <math/vec4.h>
+
namespace android {
// ---------------------------------------------------------------------------
@@ -119,11 +121,6 @@
// to achieve mirroring.
uint32_t layerStack;
-#ifdef USE_HWC2
- float alpha;
-#else
- uint8_t alpha;
-#endif
uint8_t flags;
uint8_t mask;
uint8_t reserved[2];
@@ -158,6 +155,8 @@
// A list of surfaces whose Z-order is interpreted relative to ours.
SortedVector<wp<Layer>> zOrderRelatives;
+
+ half4 color;
};
// -----------------------------------------------------------------------
@@ -225,11 +224,8 @@
bool setLayer(int32_t z);
bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
-#ifdef USE_HWC2
bool setAlpha(float alpha);
-#else
- bool setAlpha(uint8_t alpha);
-#endif
+ bool setColor(const half3& color);
bool setTransparentRegionHint(const Region& transparent);
bool setFlags(uint8_t flags, uint8_t mask);
bool setLayerStack(uint32_t layerStack);
@@ -509,11 +505,8 @@
// Returns the Alpha of the Surface, accounting for the Alpha
// of parent Surfaces in the hierarchy (alpha's will be multiplied
// down the hierarchy).
-#ifdef USE_HWC2
- float getAlpha() const;
-#else
- uint8_t getAlpha() const;
-#endif
+ half getAlpha() const;
+ half4 getColor() const;
void traverseInReverseZOrder(LayerVector::StateSet stateSet,
const LayerVector::Visitor& visitor);
@@ -683,9 +676,8 @@
sp<IGraphicBufferProducer> getProducer() const;
const String8& getName() const;
void notifyAvailableFrames();
-
PixelFormat getPixelFormat() const { return mFormat; }
-
+ bool getPremultipledAlpha() const;
private:
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index effd319..706960c 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -27,22 +27,15 @@
namespace android {
Description::Description() {
- mPlaneAlpha = 1.0f;
mPremultipliedAlpha = false;
mOpaque = true;
mTextureEnabled = false;
mColorMatrixEnabled = false;
-
- memset(mColor, 0, sizeof(mColor));
}
Description::~Description() {
}
-void Description::setPlaneAlpha(GLclampf planeAlpha) {
- mPlaneAlpha = planeAlpha;
-}
-
void Description::setPremultipliedAlpha(bool premultipliedAlpha) {
mPremultipliedAlpha = premultipliedAlpha;
}
@@ -60,11 +53,8 @@
mTextureEnabled = false;
}
-void Description::setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
- mColor[0] = red;
- mColor[1] = green;
- mColor[2] = blue;
- mColor[3] = alpha;
+void Description::setColor(const half4& color) {
+ mColor = color;
}
void Description::setProjectionMatrix(const mat4& mtx) {
diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h
index 3beffdf..cbac855 100644
--- a/services/surfaceflinger/RenderEngine/Description.h
+++ b/services/surfaceflinger/RenderEngine/Description.h
@@ -35,8 +35,6 @@
friend class Program;
friend class ProgramCache;
- // value of the plane-alpha, between 0 and 1
- GLclampf mPlaneAlpha;
// whether textures are premultiplied
bool mPremultipliedAlpha;
// whether this layer is marked as opaque
@@ -46,8 +44,8 @@
Texture mTexture;
bool mTextureEnabled;
- // color used when texturing is disabled
- GLclampf mColor[4];
+ // color used when texturing is disabled or when setting alpha.
+ half4 mColor;
// projection matrix
mat4 mProjectionMatrix;
@@ -60,12 +58,11 @@
Description();
~Description();
- void setPlaneAlpha(GLclampf planeAlpha);
void setPremultipliedAlpha(bool premultipliedAlpha);
void setOpaque(bool opaque);
void setTexture(const Texture& texture);
void disableTexture();
- void setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void setColor(const half4& color);
void setProjectionMatrix(const mat4& mtx);
void setColorMatrix(const mat4& mtx);
const mat4& getColorMatrix() const;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 37a530b..daaa11e 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -204,25 +204,17 @@
mVpHeight = vph;
}
-#ifdef USE_HWC2
void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha,
- bool opaque, float alpha) {
-#else
-void GLES20RenderEngine::setupLayerBlending(
- bool premultipliedAlpha, bool opaque, int alpha) {
-#endif
-
+ bool opaque, bool disableTexture, const half4& color) {
mState.setPremultipliedAlpha(premultipliedAlpha);
mState.setOpaque(opaque);
-#ifdef USE_HWC2
- mState.setPlaneAlpha(alpha);
+ mState.setColor(color);
- if (alpha < 1.0f || !opaque) {
-#else
- mState.setPlaneAlpha(alpha / 255.0f);
+ if (disableTexture) {
+ mState.disableTexture();
+ }
- if (alpha < 0xFF || !opaque) {
-#endif
+ if (color.a < 1.0f || !opaque) {
glEnable(GL_BLEND);
glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} else {
@@ -231,33 +223,6 @@
}
#ifdef USE_HWC2
-void GLES20RenderEngine::setupDimLayerBlending(float alpha) {
-#else
-void GLES20RenderEngine::setupDimLayerBlending(int alpha) {
-#endif
- mState.setPlaneAlpha(1.0f);
- mState.setPremultipliedAlpha(true);
- mState.setOpaque(false);
-#ifdef USE_HWC2
- mState.setColor(0, 0, 0, alpha);
-#else
- mState.setColor(0, 0, 0, alpha/255.0f);
-#endif
- mState.disableTexture();
-
-#ifdef USE_HWC2
- if (alpha == 1.0f) {
-#else
- if (alpha == 0xFF) {
-#endif
- glDisable(GL_BLEND);
- } else {
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- }
-}
-
-#ifdef USE_HWC2
void GLES20RenderEngine::setColorMode(android_color_mode mode) {
ALOGV("setColorMode: %s (0x%x)", decodeColorMode(mode).c_str(), mode);
@@ -355,10 +320,9 @@
}
void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
- mState.setPlaneAlpha(1.0f);
mState.setPremultipliedAlpha(true);
mState.setOpaque(false);
- mState.setColor(r, g, b, a);
+ mState.setColor(half4(r, g, b, a));
mState.disableTexture();
glDisable(GL_BLEND);
}
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index eaf94af..5ac12fc 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -68,10 +68,9 @@
virtual void setViewportAndProjection(size_t vpw, size_t vph,
Rect sourceCrop, size_t hwh, bool yswap,
Transform::orientation_flags rotation);
-#ifdef USE_HWC2
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
- float alpha) override;
- virtual void setupDimLayerBlending(float alpha) override;
+ bool disableTexture, const half4& color) override;
+#ifdef USE_HWC2
// Color management related functions and state
void setColorMode(android_color_mode mode);
@@ -92,10 +91,6 @@
// Currently only supporting sRGB and DisplayP3 color spaces
mat4 mSrgbToDisplayP3;
-#else
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
- int alpha);
- virtual void setupDimLayerBlending(int alpha);
#endif
bool mPlatformHasWideColor = false;
diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp
index 48a8da5..e95a6c5 100644
--- a/services/surfaceflinger/RenderEngine/Program.cpp
+++ b/services/surfaceflinger/RenderEngine/Program.cpp
@@ -22,6 +22,7 @@
#include "Program.h"
#include "ProgramCache.h"
#include "Description.h"
+#include <math/mat4.h>
namespace android {
@@ -63,7 +64,6 @@
mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
mSamplerLoc = glGetUniformLocation(programId, "sampler");
mColorLoc = glGetUniformLocation(programId, "color");
- mAlphaPlaneLoc = glGetUniformLocation(programId, "alphaPlane");
// set-up the default values for our uniforms
glUseProgram(programId);
@@ -132,11 +132,9 @@
glUniform1i(mSamplerLoc, 0);
glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTexture.getMatrix().asArray());
}
- if (mAlphaPlaneLoc >= 0) {
- glUniform1f(mAlphaPlaneLoc, desc.mPlaneAlpha);
- }
if (mColorLoc >= 0) {
- glUniform4fv(mColorLoc, 1, desc.mColor);
+ const float* color = &static_cast<details::TVec4<float> const &>(desc.mColor)[0];
+ glUniform4fv(mColorLoc, 1, color);
}
if (mColorMatrixLoc >= 0) {
glUniformMatrix4fv(mColorMatrixLoc, 1, GL_FALSE, desc.mColorMatrix.asArray());
diff --git a/services/surfaceflinger/RenderEngine/Program.h b/services/surfaceflinger/RenderEngine/Program.h
index 36bd120..a2ae2ee 100644
--- a/services/surfaceflinger/RenderEngine/Program.h
+++ b/services/surfaceflinger/RenderEngine/Program.h
@@ -79,9 +79,6 @@
/* location of the sampler uniform */
GLint mSamplerLoc;
- /* location of the alpha plane uniform */
- GLint mAlphaPlaneLoc;
-
/* location of the color uniform */
GLint mColorLoc;
};
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 06b2252..b437545 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -89,7 +89,7 @@
void ProgramCache::primeCache() {
uint32_t shaderCount = 0;
uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK |
- Key::PLANE_ALPHA_MASK | Key::TEXTURE_MASK;
+ Key::ALPHA_MASK | Key::TEXTURE_MASK;
// Prime the cache for all combinations of the above masks,
// leaving off the experimental color matrix mask options.
@@ -122,8 +122,8 @@
description.mTexture.getTextureTarget() == GL_TEXTURE_EXTERNAL_OES ? Key::TEXTURE_EXT :
description.mTexture.getTextureTarget() == GL_TEXTURE_2D ? Key::TEXTURE_2D :
Key::TEXTURE_OFF)
- .set(Key::PLANE_ALPHA_MASK,
- (description.mPlaneAlpha < 1) ? Key::PLANE_ALPHA_LT_ONE : Key::PLANE_ALPHA_EQ_ONE)
+ .set(Key::ALPHA_MASK,
+ (description.mColor.a < 1) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE)
.set(Key::BLEND_MASK,
description.mPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL)
.set(Key::OPACITY_MASK,
@@ -168,12 +168,12 @@
} else if (needs.getTextureTarget() == Key::TEXTURE_2D) {
fs << "uniform sampler2D sampler;"
<< "varying vec2 outTexCoords;";
- } else if (needs.getTextureTarget() == Key::TEXTURE_OFF) {
+ }
+
+ if (needs.getTextureTarget() == Key::TEXTURE_OFF || needs.hasAlpha()) {
fs << "uniform vec4 color;";
}
- if (needs.hasPlaneAlpha()) {
- fs << "uniform float alphaPlane;";
- }
+
if (needs.hasColorMatrix()) {
fs << "uniform mat4 colorMatrix;";
}
@@ -225,18 +225,19 @@
if (needs.isTexturing()) {
fs << "gl_FragColor = texture2D(sampler, outTexCoords);";
} else {
- fs << "gl_FragColor = color;";
+ fs << "gl_FragColor.rgb = color.rgb;";
+ fs << "gl_FragColor.a = 1.0;";
}
if (needs.isOpaque()) {
fs << "gl_FragColor.a = 1.0;";
}
- if (needs.hasPlaneAlpha()) {
- // modulate the alpha value with planeAlpha
+ if (needs.hasAlpha()) {
+ // modulate the current alpha value with alpha set
if (needs.isPremultiplied()) {
// ... and the color too if we're premultiplied
- fs << "gl_FragColor *= alphaPlane;";
+ fs << "gl_FragColor *= color.a;";
} else {
- fs << "gl_FragColor.a *= alphaPlane;";
+ fs << "gl_FragColor.a *= color.a;";
}
}
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h
index 5b0fbcd..ff5cf0f 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.h
@@ -57,9 +57,9 @@
OPACITY_TRANSLUCENT = 0x00000000,
OPACITY_MASK = 0x00000002,
- PLANE_ALPHA_LT_ONE = 0x00000004,
- PLANE_ALPHA_EQ_ONE = 0x00000000,
- PLANE_ALPHA_MASK = 0x00000004,
+ ALPHA_LT_ONE = 0x00000004,
+ ALPHA_EQ_ONE = 0x00000000,
+ ALPHA_MASK = 0x00000004,
TEXTURE_OFF = 0x00000000,
TEXTURE_EXT = 0x00000008,
@@ -95,8 +95,8 @@
inline bool isOpaque() const {
return (mKey & OPACITY_MASK) == OPACITY_OPAQUE;
}
- inline bool hasPlaneAlpha() const {
- return (mKey & PLANE_ALPHA_MASK) == PLANE_ALPHA_LT_ONE;
+ inline bool hasAlpha() const {
+ return (mKey & ALPHA_MASK) == ALPHA_LT_ONE;
}
inline bool hasColorMatrix() const {
return (mKey & COLOR_MATRIX_MASK) == COLOR_MATRIX_ON;
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 9544579..fa65979 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -25,6 +25,7 @@
#include <EGL/eglext.h>
#include <math/mat4.h>
#include <Transform.h>
+#include <gui/SurfaceControl.h>
#define EGL_NO_CONFIG ((EGLConfig)0)
@@ -98,16 +99,13 @@
virtual void checkErrors() const;
virtual void setViewportAndProjection(size_t vpw, size_t vph,
Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
+ bool disableTexture, const half4& color) = 0;
#ifdef USE_HWC2
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, float alpha) = 0;
- virtual void setupDimLayerBlending(float alpha) = 0;
virtual void setColorMode(android_color_mode mode) = 0;
virtual void setSourceDataSpace(android_dataspace source) = 0;
virtual void setWideColor(bool hasWideColor) = 0;
virtual bool usesWideColor() = 0;
-#else
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
- virtual void setupDimLayerBlending(int alpha) = 0;
#endif
virtual void setupLayerTexturing(const Texture& texture) = 0;
virtual void setupLayerBlackedOut() = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e21379c..a7e7008 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -73,7 +73,7 @@
#include "EventThread.h"
#include "Layer.h"
#include "LayerVector.h"
-#include "LayerDim.h"
+#include "ColorLayer.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
@@ -2725,7 +2725,7 @@
case HWC2::Composition::SolidColor: {
const Layer::State& state(layer->getDrawingState());
if (layer->getClearClientTarget(hwcId) && !firstLayer &&
- layer->isOpaque(state) && (state.alpha == 1.0f)
+ layer->isOpaque(state) && (state.color.a == 1.0f)
&& hasClientComposition) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared
@@ -3065,6 +3065,10 @@
if (layer->setAlpha(s.alpha))
flags |= eTraversalNeeded;
}
+ if (what & layer_state_t::eColorChanged) {
+ if (layer->setColor(s.color))
+ flags |= eTraversalNeeded;
+ }
if (what & layer_state_t::eMatrixChanged) {
if (layer->setMatrix(s.matrix))
flags |= eTraversalNeeded;
@@ -3168,8 +3172,8 @@
uniqueName, w, h, flags, format,
handle, gbp, &layer);
break;
- case ISurfaceComposerClient::eFXSurfaceDim:
- result = createDimLayer(client,
+ case ISurfaceComposerClient::eFXSurfaceColor:
+ result = createColorLayer(client,
uniqueName, w, h, flags,
handle, gbp, &layer);
break;
@@ -3251,11 +3255,11 @@
return err;
}
-status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
+status_t SurfaceFlinger::createColorLayer(const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
- *outLayer = new LayerDim(this, client, name, w, h, flags);
+ *outLayer = new ColorLayer(this, client, name, w, h, flags);
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
return NO_ERROR;
@@ -4594,7 +4598,7 @@
ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
layer->isVisible() ? '+' : '-',
i, layer->getName().string(), layer->getLayerStack(), state.z,
- layer->isVisible(), state.flags, state.alpha);
+ layer->isVisible(), state.flags, static_cast<float>(state.color.a));
i++;
});
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1b77aaf..e87d35f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -84,7 +84,7 @@
class DisplayEventConnection;
class EventThread;
class Layer;
-class LayerDim;
+class ColorLayer;
class Surface;
class RenderEngine;
class EventControlThread;
@@ -410,7 +410,7 @@
sp<IBinder>* outHandle, sp<IGraphicBufferProducer>* outGbp,
sp<Layer>* outLayer);
- status_t createDimLayer(const sp<Client>& client, const String8& name,
+ status_t createColorLayer(const sp<Client>& client, const String8& name,
uint32_t w, uint32_t h, uint32_t flags, sp<IBinder>* outHandle,
sp<IGraphicBufferProducer>* outGbp, sp<Layer>* outLayer);
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index b1c8c0a..b002138 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -71,7 +71,7 @@
#include "EventThread.h"
#include "Layer.h"
#include "LayerVector.h"
-#include "LayerDim.h"
+#include "ColorLayer.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
@@ -2024,7 +2024,7 @@
// compute the opaque region
const int32_t layerOrientation = tr.getOrientation();
- if (s.alpha==255 && !translucent &&
+ if (layer->getAlpha()==1.0f && !translucent &&
((layerOrientation & Transform::ROT_INVALID) == false)) {
// the opaque region is the layer's footprint
opaqueRegion = visibleRegion;
@@ -2297,7 +2297,7 @@
const Layer::State& state(layer->getDrawingState());
if ((cur->getHints() & HWC_HINT_CLEAR_FB)
&& i
- && layer->isOpaque(state) && (state.alpha == 0xFF)
+ && layer->isOpaque(state) && (state.color.a == 1.0f)
&& hasGlesComposition) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared
@@ -2622,9 +2622,14 @@
}
}
if (what & layer_state_t::eAlphaChanged) {
- if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
+ if (layer->setAlpha(s.alpha))
flags |= eTraversalNeeded;
}
+ if (what & layer_state_t::eColorChanged) {
+ if (layer->setColor(s.color)) {
+ flags |= eTraversalNeeded;
+ }
+ }
if (what & layer_state_t::eMatrixChanged) {
if (layer->setMatrix(s.matrix))
flags |= eTraversalNeeded;
@@ -2728,8 +2733,8 @@
uniqueName, w, h, flags, format,
handle, gbp, &layer);
break;
- case ISurfaceComposerClient::eFXSurfaceDim:
- result = createDimLayer(client,
+ case ISurfaceComposerClient::eFXSurfaceColor:
+ result = createColorLayer(client,
uniqueName, w, h, flags,
handle, gbp, &layer);
break;
@@ -2804,11 +2809,11 @@
return err;
}
-status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
+status_t SurfaceFlinger::createColorLayer(const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
- *outLayer = new LayerDim(this, client, name, w, h, flags);
+ *outLayer = new ColorLayer(this, client, name, w, h, flags);
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
return NO_ERROR;
@@ -4089,10 +4094,10 @@
if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ &&
state.z <= maxLayerZ) {
layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
- ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
+ ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
layer->isVisible() ? '+' : '-',
i, layer->getName().string(), layer->getLayerStack(), state.z,
- layer->isVisible(), state.flags, state.alpha);
+ layer->isVisible(), state.flags, static_cast<float>(state.color.a));
i++;
});
}
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index db489b2..eeb4929 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -98,7 +98,7 @@
addPositionLocked(transaction, layerId, layer->mCurrentState.active.transform.tx(),
layer->mCurrentState.active.transform.ty());
addDepthLocked(transaction, layerId, layer->mCurrentState.z);
- addAlphaLocked(transaction, layerId, layer->mCurrentState.alpha);
+ addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a);
addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion);
addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
addCropLocked(transaction, layerId, layer->mCurrentState.crop);
diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
index 6be708a..5c188dc 100644
--- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter
+++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
@@ -1,5 +1,5 @@
{
"presubmit": {
- "filter": "LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*"
+ "filter": "LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:LayerColorTest.*"
}
}
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 2119492..8900a4d 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -28,6 +28,7 @@
#include <ui/DisplayInfo.h>
#include <math.h>
+#include <math/vec3.h>
namespace android {
@@ -1276,4 +1277,97 @@
}
}
+class LayerColorTest : public LayerUpdateTest {
+ protected:
+ void SetUp() override {
+ LayerUpdateTest::SetUp();
+
+ mLayerColorControl = mComposerClient->createSurface(
+ String8("Layer color surface"),
+ 128, 128, PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceColor);
+
+ ASSERT_TRUE(mLayerColorControl != NULL);
+ ASSERT_TRUE(mLayerColorControl->isValid());
+
+ SurfaceComposerClient::openGlobalTransaction();
+ ASSERT_EQ(NO_ERROR, mLayerColorControl->setLayer(INT32_MAX-1));
+ ASSERT_EQ(NO_ERROR, mLayerColorControl->setPosition(140, 140));
+ ASSERT_EQ(NO_ERROR, mLayerColorControl->hide());
+ ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide());
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ }
+
+ void TearDown() override {
+ LayerUpdateTest::TearDown();
+ mLayerColorControl = 0;
+ }
+
+ sp<SurfaceControl> mLayerColorControl;
+};
+
+TEST_F(LayerColorTest, ColorLayerNoAlpha) {
+ sp<ScreenCapture> sc;
+
+ {
+ SCOPED_TRACE("before setColor");
+ ScreenCapture::captureScreen(&sc);
+ sc->expectBGColor(145, 145);
+ }
+
+
+ SurfaceComposerClient::openGlobalTransaction();
+ half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f);
+ mLayerColorControl->setColor(color);
+ mLayerColorControl->show();
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ {
+ // There should now be a color
+ SCOPED_TRACE("after setColor");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(145, 145, 43, 207, 131);
+ }
+}
+
+TEST_F(LayerColorTest, ColorLayerWithAlpha) {
+ sp<ScreenCapture> sc;
+ {
+ SCOPED_TRACE("before setColor");
+ ScreenCapture::captureScreen(&sc);
+ sc->expectBGColor(145, 145);
+ }
+
+ SurfaceComposerClient::openGlobalTransaction();
+ half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f);
+ mLayerColorControl->setColor(color);
+ mLayerColorControl->setAlpha(.75f);
+ mLayerColorControl->show();
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ {
+ // There should now be a color with .75 alpha
+ SCOPED_TRACE("after setColor");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(145, 145, 48, 171, 147);
+ }
+}
+
+TEST_F(LayerColorTest, ColorLayerWithNoColor) {
+ sp<ScreenCapture> sc;
+ {
+ SCOPED_TRACE("before setColor");
+ ScreenCapture::captureScreen(&sc);
+ sc->expectBGColor(145, 145);
+ }
+
+ SurfaceComposerClient::openGlobalTransaction();
+ mLayerColorControl->show();
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ {
+ // There should now be set to 0,0,0 (black) as default.
+ SCOPED_TRACE("after setColor");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(145, 145, 0, 0, 0);
+ }
+}
+
}