Switch SurfaceFlinger to HWC 2.0
Enables SurfaceFlinger to speak to version 2.0 of the Hardware Composer
HAL instead of version 1.x (also removing support for the framebuffer
HAL). By default, however, this functionality is disabled. In order to
enable it, USE_HWC2 must be set to true in Android.mk.
Change-Id: I4589e02ac2165236b10ff2f7cb772f87e0d3daab
diff --git a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp
index 9a47568..579affb 100644
--- a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp
@@ -28,13 +28,25 @@
}
void GLES10RenderEngine::setupLayerBlending(
+#ifdef USE_HWC2
+ bool premultipliedAlpha, bool opaque, float alpha) {
+#else
bool premultipliedAlpha, bool opaque, int alpha) {
+#endif
// OpenGL ES 1.0 doesn't support texture combiners.
// This path doesn't properly handle opaque layers that have non-opaque
// alpha values. The alpha channel will be copied into the framebuffer or
// screenshot, so if the framebuffer or screenshot is blended on top of
// something else, whatever is below the window will incorrectly show
// through.
+#ifdef USE_HWC2
+ if (CC_UNLIKELY(alpha < 1.0f)) {
+ if (premultipliedAlpha) {
+ glColor4f(alpha, alpha, alpha, alpha);
+ } else {
+ glColor4f(1.0f, 1.0f, 1.0f, alpha);
+ }
+#else
if (CC_UNLIKELY(alpha < 0xFF)) {
GLfloat floatAlpha = alpha * (1.0f / 255.0f);
if (premultipliedAlpha) {
@@ -42,12 +54,17 @@
} else {
glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
}
+#endif
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
} else {
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
+#ifdef USE_HWC2
+ if (alpha < 1.0f || !opaque) {
+#else
if (alpha < 0xFF || !opaque) {
+#endif
glEnable(GL_BLEND);
glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA);
diff --git a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h
index f9c7c04..61abd6a 100644
--- a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h
@@ -30,7 +30,12 @@
class GLES10RenderEngine : public GLES11RenderEngine {
virtual ~GLES10RenderEngine();
protected:
+#ifdef USE_HWC2
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
+ float alpha) override;
+#else
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
+#endif
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index 1a9f59b..847cdb3 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -107,20 +107,33 @@
glMatrixMode(GL_MODELVIEW);
}
+#ifdef USE_HWC2
+void GLES11RenderEngine::setupLayerBlending(bool premultipliedAlpha,
+ bool opaque, float alpha) {
+#else
void GLES11RenderEngine::setupLayerBlending(
bool premultipliedAlpha, bool opaque, int alpha) {
+#endif
GLenum combineRGB;
GLenum combineAlpha;
GLenum src0Alpha;
GLfloat envColor[4];
+#ifdef USE_HWC2
+ if (CC_UNLIKELY(alpha < 1.0f)) {
+#else
if (CC_UNLIKELY(alpha < 0xFF)) {
+#endif
// Cv = premultiplied ? Cs*alpha : Cs
// Av = !opaque ? As*alpha : As
combineRGB = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
combineAlpha = !opaque ? GL_MODULATE : GL_REPLACE;
src0Alpha = GL_CONSTANT;
+#ifdef USE_HWC2
+ envColor[0] = alpha;
+#else
envColor[0] = alpha * (1.0f / 255.0f);
+#endif
} else {
// Cv = Cs
// Av = opaque ? 1.0 : As
@@ -152,7 +165,11 @@
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
}
+#ifdef USE_HWC2
+ if (alpha < 1.0f || !opaque) {
+#else
if (alpha < 0xFF || !opaque) {
+#endif
glEnable(GL_BLEND);
glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA);
@@ -161,16 +178,28 @@
}
}
+#ifdef USE_HWC2
+void GLES11RenderEngine::setupDimLayerBlending(float alpha) {
+#else
void GLES11RenderEngine::setupDimLayerBlending(int alpha) {
+#endif
glDisable(GL_TEXTURE_EXTERNAL_OES);
glDisable(GL_TEXTURE_2D);
+#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
+ glColor4f(0, 0, 0, alpha);
+#else
glColor4f(0, 0, 0, alpha/255.0f);
+#endif
}
void GLES11RenderEngine::setupLayerTexturing(const Texture& texture) {
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 08de646..4cd968d 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -51,9 +51,17 @@
virtual void dump(String8& result);
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
+ 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;
+#else
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
+ int alpha);
virtual void setupDimLayerBlending(int alpha);
+#endif
virtual void setupLayerTexturing(const Texture& texture);
virtual void setupLayerBlackedOut();
virtual void setupFillWithColor(float r, float g, float b, float a) ;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 1fabaf5..406e611 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -117,14 +117,25 @@
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
mState.setPremultipliedAlpha(premultipliedAlpha);
mState.setOpaque(opaque);
+#ifdef USE_HWC2
+ mState.setPlaneAlpha(alpha);
+
+ if (alpha < 1.0f || !opaque) {
+#else
mState.setPlaneAlpha(alpha / 255.0f);
if (alpha < 0xFF || !opaque) {
+#endif
glEnable(GL_BLEND);
glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} else {
@@ -132,14 +143,26 @@
}
}
+#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);
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 819356a..7c3f9b5 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -66,9 +66,17 @@
virtual void dump(String8& result);
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
- virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
+ 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;
+#else
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
+ int alpha);
virtual void setupDimLayerBlending(int alpha);
+#endif
virtual void setupLayerTexturing(const Texture& texture);
virtual void setupLayerBlackedOut();
virtual void setupFillWithColor(float r, float g, float b, float a);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 31a961e..9cc1ed7 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -93,8 +93,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;
+#ifdef USE_HWC2
+ virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, float alpha) = 0;
+ virtual void setupDimLayerBlending(float alpha) = 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;
virtual void setupFillWithColor(float r, float g, float b, float a) = 0;