factor EGL/GL and surface creation out of DisplayHardware
Change-Id: Icd85a6a4caad06f056578008af3e21666fa8b1f4
diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp
index fdde15a..af33a89 100644
--- a/services/surfaceflinger/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware.cpp
@@ -31,6 +31,7 @@
#include <EGL/eglext.h>
#include <hardware/gralloc.h>
+#include <private/gui/SharedBufferStack.h>
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/DisplayHardwareBase.h"
@@ -40,8 +41,9 @@
#include "GLExtensions.h"
#include "SurfaceFlinger.h"
+// ----------------------------------------------------------------------------
using namespace android;
-
+// ----------------------------------------------------------------------------
static __attribute__((noinline))
void checkGLErrors()
@@ -88,6 +90,8 @@
}
}
+// ----------------------------------------------------------------------------
+
/*
* Initialize the display to the specified values.
*
@@ -95,79 +99,78 @@
DisplayHardware::DisplayHardware(
const sp<SurfaceFlinger>& flinger,
- uint32_t dpy)
- : DisplayHardwareBase(flinger, dpy),
- mFlinger(flinger), mFlags(0), mHwc(0), mSecureLayerVisible(false)
+ int display,
+ const sp<SurfaceTextureClient>& surface,
+ EGLConfig config)
+ : DisplayHardwareBase(flinger, display),
+ mFlinger(flinger),
+ mDisplayId(display),
+ mHwc(0),
+ mNativeWindow(surface),
+ mFlags(0),
+ mSecureLayerVisible(false)
{
- init(dpy);
+ init(config);
}
-DisplayHardware::~DisplayHardware()
-{
- fini();
+DisplayHardware::~DisplayHardware() {
}
-float DisplayHardware::getDpiX() const { return mDpiX; }
-float DisplayHardware::getDpiY() const { return mDpiY; }
-float DisplayHardware::getDensity() const { return mDensity; }
-float DisplayHardware::getRefreshRate() const { return mRefreshRate; }
-int DisplayHardware::getWidth() const { return mDisplayWidth; }
-int DisplayHardware::getHeight() const { return mDisplayHeight; }
-PixelFormat DisplayHardware::getFormat() const { return mFormat; }
-uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
-
-uint32_t DisplayHardware::getMaxViewportDims() const {
- return mMaxViewportDims[0] < mMaxViewportDims[1] ?
- mMaxViewportDims[0] : mMaxViewportDims[1];
+float DisplayHardware::getDpiX() const {
+ return mDpiX;
}
-static status_t selectConfigForPixelFormat(
- EGLDisplay dpy,
- EGLint const* attrs,
- PixelFormat format,
- EGLConfig* outConfig)
-{
- EGLConfig config = NULL;
- EGLint numConfigs = -1, n=0;
- eglGetConfigs(dpy, NULL, 0, &numConfigs);
- EGLConfig* const configs = new EGLConfig[numConfigs];
- eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
- for (int i=0 ; i<n ; i++) {
- EGLint nativeVisualId = 0;
- eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
- if (nativeVisualId>0 && format == nativeVisualId) {
- *outConfig = configs[i];
- delete [] configs;
- return NO_ERROR;
- }
- }
- delete [] configs;
- return NAME_NOT_FOUND;
+float DisplayHardware::getDpiY() const {
+ return mDpiY;
}
+float DisplayHardware::getDensity() const {
+ return mDensity;
+}
-void DisplayHardware::init(uint32_t dpy)
+float DisplayHardware::getRefreshRate() const {
+ return mRefreshRate;
+}
+
+int DisplayHardware::getWidth() const {
+ return mDisplayWidth;
+}
+
+int DisplayHardware::getHeight() const {
+ return mDisplayHeight;
+}
+
+PixelFormat DisplayHardware::getFormat() const {
+ return mFormat;
+}
+
+EGLSurface DisplayHardware::getEGLSurface() const {
+ return mSurface;
+}
+
+void DisplayHardware::init(EGLConfig config)
{
- mNativeWindow = new FramebufferSurface();
- framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
- if (!fbDev) {
- ALOGE("Display subsystem failed to initialize. check logs. exiting...");
- exit(0);
+ ANativeWindow* const window = mNativeWindow.get();
+
+ int concreteType;
+ window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType);
+ if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) {
+ mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get());
}
int format;
- ANativeWindow const * const window = mNativeWindow.get();
window->query(window, NATIVE_WINDOW_FORMAT, &format);
- mDpiX = mNativeWindow->xdpi;
- mDpiY = mNativeWindow->ydpi;
- mRefreshRate = fbDev->fps;
-
- if (mDpiX == 0 || mDpiY == 0) {
- ALOGE("invalid screen resolution from fb HAL (xdpi=%f, ydpi=%f), "
- "defaulting to 160 dpi", mDpiX, mDpiY);
- mDpiX = mDpiY = 160;
+ mDpiX = window->xdpi;
+ mDpiY = window->ydpi;
+ if (mFramebufferSurface != NULL) {
+ mRefreshRate = mFramebufferSurface->getRefreshRate();
+ } else {
+ mRefreshRate = 60;
}
+ mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
+
+ // TODO: Not sure if display density should handled by SF any longer
class Density {
static int getDensityFromProperty(char const* propName) {
char property[PROPERTY_VALUE_MAX];
@@ -183,173 +186,52 @@
static int getBuildDensity() {
return getDensityFromProperty("ro.sf.lcd_density"); }
};
-
-
// The density of the device is provided by a build property
mDensity = Density::getBuildDensity() / 160.0f;
-
if (mDensity == 0) {
// the build doesn't provide a density -- this is wrong!
// use xdpi instead
ALOGE("ro.sf.lcd_density must be defined as a build property");
mDensity = mDpiX / 160.0f;
}
-
if (Density::getEmuDensity()) {
// if "qemu.sf.lcd_density" is specified, it overrides everything
mDpiX = mDpiY = mDensity = Density::getEmuDensity();
mDensity /= 160.0f;
}
-
-
- /* FIXME: this is a temporary HACK until we are able to report the refresh rate
- * properly from the HAL. The WindowManagerService now relies on this value.
- */
-#ifndef REFRESH_RATE
- mRefreshRate = fbDev->fps;
-#else
- mRefreshRate = REFRESH_RATE;
-#warning "refresh rate set via makefile to REFRESH_RATE"
-#endif
-
- mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
-
- EGLint w, h, dummy;
- EGLint numConfigs=0;
- EGLSurface surface;
- EGLContext context;
- EGLBoolean result;
- status_t err;
-
- // initialize EGL
- EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RECORDABLE_ANDROID, EGL_TRUE,
- EGL_NONE
- };
-
- // TODO: all the extensions below should be queried through
- // eglGetProcAddress().
-
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(display, NULL, NULL);
- eglGetConfigs(display, NULL, 0, &numConfigs);
-
- EGLConfig config = NULL;
- err = selectConfigForPixelFormat(display, attribs, format, &config);
- if (err) {
- // maybe we failed because of EGL_RECORDABLE_ANDROID
- ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
- attribs[2] = EGL_NONE;
- err = selectConfigForPixelFormat(display, attribs, format, &config);
- }
-
- ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
-
- EGLint r,g,b,a;
- eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r);
- eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b);
- eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
-
- if (mNativeWindow->isUpdateOnDemand()) {
- mFlags |= PARTIAL_UPDATES;
- }
-
- if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
- if (dummy == EGL_SLOW_CONFIG)
- mFlags |= SLOW_CONFIG;
- }
-
/*
- * Create our main surface
+ * Create our display's surface
*/
- surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+ EGLSurface surface;
+ EGLint w, h;
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ surface = eglCreateWindowSurface(display, config, window, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
- if (mFlags & PARTIAL_UPDATES) {
- // if we have partial updates, we definitely don't need to
- // preserve the backbuffer, which may be costly.
- eglSurfaceAttrib(display, surface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+ if (mFramebufferSurface != NULL) {
+ if (mFramebufferSurface->isUpdateOnDemand()) {
+ mFlags |= PARTIAL_UPDATES;
+ // if we have partial updates, we definitely don't need to
+ // preserve the backbuffer, which may be costly.
+ eglSurfaceAttrib(display, surface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+ }
}
- /*
- * Create our OpenGL ES context
- */
-
- EGLint contextAttributes[] = {
-#ifdef EGL_IMG_context_priority
-#ifdef HAS_CONTEXT_PRIORITY
-#warning "using EGL_IMG_context_priority"
- EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
-#endif
-#endif
- EGL_NONE, EGL_NONE
- };
- context = eglCreateContext(display, config, NULL, contextAttributes);
-
mDisplay = display;
- mConfig = config;
mSurface = surface;
- mContext = context;
- mFormat = fbDev->format;
+ mFormat = format;
mPageFlipCount = 0;
- /*
- * Gather OpenGL ES extensions
- */
-
- result = eglMakeCurrent(display, surface, surface, context);
- if (!result) {
- ALOGE("Couldn't create a working GLES context. check logs. exiting...");
- exit(0);
- }
-
- GLExtensions& extensions(GLExtensions::getInstance());
- extensions.initWithGLStrings(
- glGetString(GL_VENDOR),
- glGetString(GL_RENDERER),
- glGetString(GL_VERSION),
- glGetString(GL_EXTENSIONS),
- eglQueryString(display, EGL_VENDOR),
- eglQueryString(display, EGL_VERSION),
- eglQueryString(display, EGL_EXTENSIONS));
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
- glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
-
- ALOGI("EGL informations:");
- ALOGI("# of configs : %d", numConfigs);
- ALOGI("vendor : %s", extensions.getEglVendor());
- ALOGI("version : %s", extensions.getEglVersion());
- ALOGI("extensions: %s", extensions.getEglExtension());
- ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
- ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
-
- ALOGI("OpenGL informations:");
- ALOGI("vendor : %s", extensions.getVendor());
- ALOGI("renderer : %s", extensions.getRenderer());
- ALOGI("version : %s", extensions.getVersion());
- ALOGI("extensions: %s", extensions.getExtension());
- ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
- ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
- ALOGI("flags = %08x", mFlags);
-
- // Unbind the context from this thread
- eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-
// initialize the H/W composer
mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod);
if (mHwc->initCheck() == NO_ERROR) {
mHwc->setFrameBuffer(mDisplay, mSurface);
}
-
// initialize the display orientation transform.
// it's a constant that should come from the display driver.
int displayOrientation = ISurfaceComposer::eOrientationDefault;
@@ -378,6 +260,20 @@
mLogicalDisplayHeight = h;
}
DisplayHardware::setOrientation(ISurfaceComposer::eOrientationDefault);
+
+ // initialize the shared control block
+ surface_flinger_cblk_t* const scblk = mFlinger->getControlBlock();
+ scblk->connected |= 1 << mDisplayId;
+ display_cblk_t* dcblk = &scblk->displays[mDisplayId];
+ memset(dcblk, 0, sizeof(display_cblk_t));
+ dcblk->w = w; // XXX: plane.getWidth();
+ dcblk->h = h; // XXX: plane.getHeight();
+ dcblk->format = format;
+ dcblk->orientation = ISurfaceComposer::eOrientationDefault;
+ dcblk->xdpi = mDpiX;
+ dcblk->ydpi = mDpiY;
+ dcblk->fps = mRefreshRate;
+ dcblk->density = mDensity;
}
void DisplayHardware::setVSyncHandler(const sp<VSyncHandler>& handler) {
@@ -411,19 +307,6 @@
return *mHwc;
}
-/*
- * Clean up. Throw out our local state.
- *
- * (It's entirely possible we'll never get here, since this is meant
- * for real hardware, which doesn't restart.)
- */
-
-void DisplayHardware::fini()
-{
- eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglTerminate(mDisplay);
-}
-
void DisplayHardware::releaseScreen() const
{
DisplayHardwareBase::releaseScreen();
@@ -458,7 +341,10 @@
}
status_t DisplayHardware::compositionComplete() const {
- return mNativeWindow->compositionComplete();
+ if (mFramebufferSurface == NULL) {
+ return NO_ERROR;
+ }
+ return mFramebufferSurface->compositionComplete();
}
void DisplayHardware::flip(const Region& dirty) const
@@ -478,7 +364,9 @@
#endif
if (mFlags & PARTIAL_UPDATES) {
- mNativeWindow->setUpdateRectangle(dirty.getBounds());
+ if (mFramebufferSurface != NULL) {
+ mFramebufferSurface->setUpdateRectangle(dirty.getBounds());
+ }
}
mPageFlipCount++;
@@ -489,10 +377,6 @@
eglSwapBuffers(dpy, surface);
}
checkEGLErrors("eglSwapBuffers");
-
- // for debugging
- //glClearColor(1,0,0,0);
- //glClear(GL_COLOR_BUFFER_BIT);
}
uint32_t DisplayHardware::getFlags() const
@@ -500,14 +384,11 @@
return mFlags;
}
-void DisplayHardware::makeCurrent() const
-{
- eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-}
-
void DisplayHardware::dump(String8& res) const
{
- mNativeWindow->dump(res);
+ if (mFramebufferSurface != NULL) {
+ mFramebufferSurface->dump(res);
+ }
}
// ----------------------------------------------------------------------------