Merge "gui: CpuConsumer::lockNextBuffer change return code when too many bufs acquired" into klp-dev
diff --git a/cmds/flatland/Composers.cpp b/cmds/flatland/Composers.cpp
index 8365a31..15cdb29 100644
--- a/cmds/flatland/Composers.cpp
+++ b/cmds/flatland/Composers.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
#include "Flatland.h"
#include "GLHelper.h"
diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp
index 3928039..42694b3 100644
--- a/cmds/flatland/GLHelper.cpp
+++ b/cmds/flatland/GLHelper.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
#include <ui/DisplayInfo.h>
#include <gui/SurfaceComposerClient.h>
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index e5e2dc0..c01725d 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -82,6 +82,7 @@
"EGL_KHR_image_base " // mandatory
"EGL_KHR_image_pixmap "
"EGL_KHR_lock_surface "
+ "EGL_KHR_gl_colorspace "
"EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
@@ -365,6 +366,33 @@
// surfaces
// ----------------------------------------------------------------------------
+// The EGL_KHR_gl_colorspace spec hasn't been published yet, so these haven't
+// been added to the Khronos egl.h.
+#define EGL_GL_COLORSPACE_KHR EGL_VG_COLORSPACE
+#define EGL_GL_COLORSPACE_SRGB_KHR EGL_VG_COLORSPACE_sRGB
+#define EGL_GL_COLORSPACE_LINEAR_KHR EGL_VG_COLORSPACE_LINEAR
+
+// Turn linear formats into corresponding sRGB formats when colorspace is
+// EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
+// formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
+// the modification isn't possible, the original format is returned.
+static int modifyFormatColorspace(int fmt, EGLint colorspace) {
+ if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
+ switch (fmt) {
+ case HAL_PIXEL_FORMAT_sRGB_A_8888: return HAL_PIXEL_FORMAT_RGBA_8888;
+ case HAL_PIXEL_FORMAT_sRGB_888: return HAL_PIXEL_FORMAT_RGB_888;
+ }
+ } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
+ switch (fmt) {
+ case HAL_PIXEL_FORMAT_RGBA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
+ case HAL_PIXEL_FORMAT_RGBX_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
+ case HAL_PIXEL_FORMAT_BGRA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
+ case HAL_PIXEL_FORMAT_RGB_888: return HAL_PIXEL_FORMAT_sRGB_888;
+ }
+ }
+ return fmt;
+}
+
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
NativeWindowType window,
const EGLint *attrib_list)
@@ -375,7 +403,6 @@
egl_display_ptr dp = validate_display_connection(dpy, cnx);
if (dp) {
EGLDisplay iDpy = dp->disp.dpy;
- EGLint format;
if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
ALOGE("EGLNativeWindowType %p already connected to another API",
@@ -383,19 +410,36 @@
return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
- // set the native window's buffers format to match this config
- if (cnx->egl.eglGetConfigAttrib(iDpy,
- config, EGL_NATIVE_VISUAL_ID, &format)) {
- if (format != 0) {
- int err = native_window_set_buffers_format(window, format);
- if (err != 0) {
- ALOGE("error setting native window pixel format: %s (%d)",
- strerror(-err), err);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
- return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ // Set the native window's buffers format to match this config.
+ // Whether to use sRGB gamma is not part of the EGLconfig, but is part
+ // of our native format. So if sRGB gamma is requested, we have to
+ // modify the EGLconfig's format before setting the native window's
+ // format.
+ EGLint format;
+ if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
+ &format)) {
+ ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
+ eglGetError());
+ format = 0;
+ }
+ if (attrib_list) {
+ for (const EGLint* attr = attrib_list; *attr != EGL_NONE;
+ attr += 2) {
+ if (*attr == EGL_GL_COLORSPACE_KHR &&
+ dp->haveExtension("EGL_KHR_gl_colorspace")) {
+ format = modifyFormatColorspace(format, *(attr+1));
}
}
}
+ if (format != 0) {
+ int err = native_window_set_buffers_format(window, format);
+ if (err != 0) {
+ ALOGE("error setting native window pixel format: %s (%d)",
+ strerror(-err), err);
+ native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+ }
// the EGL spec requires that a new EGLSurface default to swap interval
// 1, so explicitly set that on the window here.
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 8d7890b..0380521 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -44,6 +44,16 @@
// ----------------------------------------------------------------------------
+static bool findExtension(const char* exts, const char* name, size_t nameLen) {
+ if (exts) {
+ const char* match = strstr(exts, name);
+ if (match && (match[nameLen] == '\0' || match[nameLen] == ' ')) {
+ return true;
+ }
+ }
+ return false;
+}
+
egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
egl_display_t::egl_display_t() :
@@ -196,14 +206,9 @@
if (len) {
// NOTE: we could avoid the copy if we had strnstr.
const String8 ext(start, len);
- // now look for this extension
- if (disp.queryString.extensions) {
- // if we find it, add this extension string to our list
- // (and don't forget the space)
- const char* match = strstr(disp.queryString.extensions, ext.string());
- if (match && (match[len] == ' ' || match[len] == 0)) {
- mExtensionString.append(start, len+1);
- }
+ if (findExtension(disp.queryString.extensions, ext.string(),
+ len)) {
+ mExtensionString.append(start, len+1);
}
}
// process the next extension string, and skip the space.
@@ -367,6 +372,13 @@
return result;
}
+bool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
+ if (!nameLen) {
+ nameLen = strlen(name);
+ }
+ return findExtension(mExtensionString.string(), name, nameLen);
+}
+
// ----------------------------------------------------------------------------
bool egl_display_t::HibernationMachine::incWakeCount(WakeRefStrength strength) {
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 754085c..87f27f8 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -99,6 +99,8 @@
char const * getClientApiString() const { return mClientApiString.string(); }
char const * getExtensionString() const { return mExtensionString.string(); }
+ bool haveExtension(const char* name, size_t nameLen = 0) const;
+
inline uint32_t getRefsCount() const { return refs; }
struct strings_t {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a63a80a..531db20 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -572,6 +572,7 @@
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
return false;
}
// in all other case, we have no blending (also for unknown formats)
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index 428cdb8..19f17df 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -15,12 +15,12 @@
*/
#include <GLES/gl.h>
+#include <GLES/glext.h>
#include <utils/String8.h>
#include <cutils/compiler.h>
#include "GLES11RenderEngine.h"
-#include "GLExtensions.h"
#include "Mesh.h"
// ---------------------------------------------------------------------------
@@ -183,6 +183,31 @@
glDisable(GL_BLEND);
}
+void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
+ uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+ GLuint tname, name;
+ // turn our EGLImage into a texture
+ glGenTextures(1, &tname);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+
+ // create a Framebuffer Object to render into
+ glGenFramebuffersOES(1, &name);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+ glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+ GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+
+ *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+ *texName = tname;
+ *fbName = name;
+}
+
+void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ glDeleteFramebuffersOES(1, &fbName);
+ glDeleteTextures(1, &texName);
+}
+
void GLES11RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) {
glColor4f(r, g, b, a);
glDisable(GL_TEXTURE_EXTERNAL_OES);
@@ -219,14 +244,13 @@
}
void GLES11RenderEngine::dump(String8& result) {
- const GLExtensions& extensions(GLExtensions::getInstance());
- result.appendFormat("GLES: %s, %s, %s\n",
- extensions.getVendor(),
- extensions.getRenderer(),
- extensions.getVersion());
- result.appendFormat("%s\n", extensions.getExtension());
+ RenderEngine::dump(result);
}
// ---------------------------------------------------------------------------
}; // namespace android
// ---------------------------------------------------------------------------
+
+#if defined(__gl2_h_)
+#error "don't include gl2/gl2.h in this file"
+#endif
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 8bb7ed1..d20ff1c 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -37,6 +37,10 @@
GLint mMaxViewportDims[2];
GLint mMaxTextureSize;
+ virtual void bindImageAsFramebuffer(EGLImageKHR image,
+ uint32_t* texName, uint32_t* fbName, uint32_t* status);
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+
public:
GLES11RenderEngine();
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 9be12bf..4add66b 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -17,6 +17,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <utils/String8.h>
#include <utils/Trace.h>
@@ -24,7 +25,6 @@
#include <cutils/compiler.h>
#include "GLES20RenderEngine.h"
-#include "GLExtensions.h"
#include "Program.h"
#include "ProgramCache.h"
#include "Description.h"
@@ -157,6 +157,32 @@
glDisable(GL_BLEND);
}
+
+void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
+ uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+ GLuint tname, name;
+ // turn our EGLImage into a texture
+ glGenTextures(1, &tname);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+
+ // create a Framebuffer Object to render into
+ glGenFramebuffers(1, &name);
+ glBindFramebuffer(GL_FRAMEBUFFER, name);
+ glFramebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
+
+ *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ *texName = tname;
+ *fbName = name;
+}
+
+void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &fbName);
+ glDeleteTextures(1, &texName);
+}
+
void GLES20RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) {
mState.setColor(r, g, b, a);
disableTexturing();
@@ -200,14 +226,13 @@
}
void GLES20RenderEngine::dump(String8& result) {
- const GLExtensions& extensions(GLExtensions::getInstance());
- result.appendFormat("GLES: %s, %s, %s\n",
- extensions.getVendor(),
- extensions.getRenderer(),
- extensions.getVersion());
- result.appendFormat("%s\n", extensions.getExtension());
+ RenderEngine::dump(result);
}
// ---------------------------------------------------------------------------
}; // namespace android
// ---------------------------------------------------------------------------
+
+#if defined(__gl_h_)
+#error "don't include gl/gl.h in this file"
+#endif
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 873a6435..2998874 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -41,6 +41,10 @@
Description mState;
+ virtual void bindImageAsFramebuffer(EGLImageKHR image,
+ uint32_t* texName, uint32_t* fbName, uint32_t* status);
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+
public:
GLES20RenderEngine();
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 835ed8a..4911609 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -43,6 +43,8 @@
friend Formatter& indent(Formatter& f);
friend Formatter& dedent(Formatter& f);
public:
+ Formatter() : mIndent(0) {}
+
String8 getString() const {
return mString;
}
@@ -120,6 +122,10 @@
if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
fs << "#extension GL_OES_EGL_image_external : require";
}
+
+ // default precision is required-ish in fragment shaders
+ fs << "precision mediump float;";
+
if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
fs << "uniform samplerExternalOES sampler;"
<< "varying vec2 outTexCoords;";
@@ -138,28 +144,16 @@
} else {
fs << "gl_FragColor = color;";
}
+ if (needs.isOpaque()) {
+ fs << "gl_FragColor.a = 1.0;";
+ }
if (needs.hasPlaneAlpha()) {
// modulate the alpha value with planeAlpha
if (needs.isPremultiplied()) {
// ... and the color too if we're premultiplied
- if (needs.isOpaque()) {
- // ... we're opaque, only premultiply the color component
- fs << "gl_FragColor.rgb *= alphaPlane;"
- << "gl_FragColor.a = alphaPlane;";
- } else {
- fs << "gl_FragColor *= alphaPlane;";
- }
+ fs << "gl_FragColor *= alphaPlane;";
} else {
- // not premultiplied
- if (needs.isOpaque()) {
- fs << "gl_FragColor.a = alphaPlane;";
- } else {
- fs << "gl_FragColor.a *= alphaPlane;";
- }
- }
- } else {
- if (needs.isOpaque()) {
- fs << "gl_FragColor.a = 1.0;";
+ fs << "gl_FragColor.a *= alphaPlane;";
}
}
fs << dedent << "}";
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index ee51bd9..063be2e 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -190,34 +190,29 @@
glDeleteTextures(count, names);
}
+void RenderEngine::dump(String8& result) {
+ const GLExtensions& extensions(GLExtensions::getInstance());
+ result.appendFormat("GLES: %s, %s, %s\n",
+ extensions.getVendor(),
+ extensions.getRenderer(),
+ extensions.getVersion());
+ result.appendFormat("%s\n", extensions.getExtension());
+}
+
// ---------------------------------------------------------------------------
RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
RenderEngine& engine, EGLImageKHR image) : mEngine(engine)
{
- GLuint tname, name;
- // turn our EGLImage into a texture
- glGenTextures(1, &tname);
- glBindTexture(GL_TEXTURE_2D, tname);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
- // create a Framebuffer Object to render into
- glGenFramebuffersOES(1, &name);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
- glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
- GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
- mStatus = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+ mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus);
+
ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
"glCheckFramebufferStatusOES error %d", mStatus);
- mTexName = tname;
- mFbName = name;
}
RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
// back to main framebuffer
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
- glDeleteFramebuffersOES(1, &mFbName);
- glDeleteTextures(1, &mTexName);
-
+ mEngine.unbindFramebuffer(mTexName, mFbName);
}
status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index f4fa30b..3c2b2ea 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -45,6 +45,9 @@
EGLContext mEGLContext;
void setEGLContext(EGLContext ctxt);
+ virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
+
protected:
RenderEngine();
virtual ~RenderEngine() = 0;
@@ -52,6 +55,9 @@
public:
static RenderEngine* create(EGLDisplay display, EGLConfig config);
+ // dump the extension strings. always call the base class.
+ virtual void dump(String8& result);
+
// helpers
void clearWithColor(float red, float green, float blue, float alpha);
void fillRegionWithColor(const Region& region, uint32_t height,
@@ -65,8 +71,8 @@
class BindImageAsFramebuffer {
RenderEngine& mEngine;
- unsigned int mTexName, mFbName;
- unsigned int mStatus;
+ uint32_t mTexName, mFbName;
+ uint32_t mStatus;
public:
BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image);
~BindImageAsFramebuffer();
@@ -75,7 +81,6 @@
// set-up
virtual void checkErrors() const;
- virtual void dump(String8& result) = 0;
virtual void setViewportAndProjection(size_t vpw, size_t vph, size_t w, size_t h, bool yswap) = 0;
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
virtual void setupDimLayerBlending(int alpha) = 0;