Merge "Implement per-display EGLConfig and configless EGLContext"

This commit is contained in:
Jesse Hall 2014-01-03 18:25:07 +00:00 committed by Gerrit Code Review
commit b6c2100458
6 changed files with 60 additions and 16 deletions

View File

@ -53,6 +53,7 @@ DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
DisplayType type,
int32_t hwcId,
int format,
bool isSecure,
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
@ -76,9 +77,6 @@ DisplayDevice::DisplayDevice(
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
int format;
window->query(window, NATIVE_WINDOW_FORMAT, &format);
// Make sure that composition can never be stalled by a virtual display
// consumer that isn't processing buffers fast enough. We have to do this
// in two places:
@ -96,6 +94,9 @@ DisplayDevice::DisplayDevice(
EGLSurface surface;
EGLint w, h;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
surface = eglCreateWindowSurface(display, config, window, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);

View File

@ -75,6 +75,7 @@ public:
const sp<SurfaceFlinger>& flinger,
DisplayType type,
int32_t hwcId, // negative for non-HWC-composited displays
int format,
bool isSecure,
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,

View File

@ -455,7 +455,11 @@ uint32_t HWComposer::getHeight(int disp) const {
}
uint32_t HWComposer::getFormat(int disp) const {
return mDisplayData[disp].format;
if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) {
return HAL_PIXEL_FORMAT_RGBA_8888;
} else {
return mDisplayData[disp].format;
}
}
float HWComposer::getDpiX(int disp) const {
@ -1147,7 +1151,7 @@ bool HWComposer::VSyncThread::threadLoop() {
}
HWComposer::DisplayData::DisplayData()
: width(0), height(0), format(0),
: width(0), height(0), format(HAL_PIXEL_FORMAT_RGBA_8888),
xdpi(0.0f), ydpi(0.0f),
refresh(0),
connected(false),

View File

@ -25,21 +25,51 @@
#include "GLExtensions.h"
#include "Mesh.h"
EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
EGLConfig config = chooseEglConfig(display, hwcFormat);
static bool findExtension(const char* exts, const char* name) {
if (!exts)
return false;
size_t len = strlen(name);
EGLint renderableType = 0;
EGLint contextClientVersion = 0;
// query the renderable type, setting the EGL_CONTEXT_CLIENT_VERSION accordingly
if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {
LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
const char* pos = exts;
while ((pos = strstr(pos, name)) != NULL) {
if (pos[len] == '\0' || pos[len] == ' ')
return true;
pos += len;
}
return false;
}
RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
// EGL_ANDROIDX_no_config_context is an experimental extension with no
// written specification. It will be replaced by something more formal.
// SurfaceFlinger is using it to allow a single EGLContext to render to
// both a 16-bit primary display framebuffer and a 32-bit virtual display
// framebuffer.
//
// The code assumes that ES2 or later is available if this extension is
// supported.
EGLConfig config = EGL_NO_CONFIG;
if (!findExtension(
eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS),
"EGL_ANDROIDX_no_config_context")) {
config = chooseEglConfig(display, hwcFormat);
}
EGLint renderableType = 0;
if (config == EGL_NO_CONFIG) {
renderableType = EGL_OPENGL_ES2_BIT;
} else if (!eglGetConfigAttrib(display, config,
EGL_RENDERABLE_TYPE, &renderableType)) {
LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
}
EGLint contextClientVersion = 0;
if (renderableType & EGL_OPENGL_ES2_BIT) {
contextClientVersion = 2;
} else if (renderableType & EGL_OPENGL_ES_BIT) {
@ -68,8 +98,12 @@ RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
// now figure out what version of GL did we actually get
// NOTE: a dummy surface is not needed if KHR_create_context is supported
EGLConfig dummyConfig = config;
if (dummyConfig == EGL_NO_CONFIG) {
dummyConfig = chooseEglConfig(display, hwcFormat);
}
EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE };
EGLSurface dummy = eglCreatePbufferSurface(display, config, attribs);
EGLSurface dummy = eglCreatePbufferSurface(display, dummyConfig, attribs);
LOG_ALWAYS_FATAL_IF(dummy==EGL_NO_SURFACE, "can't create dummy pbuffer");
EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");

View File

@ -25,6 +25,8 @@
#include <EGL/eglext.h>
#include <ui/mat4.h>
#define EGL_NO_CONFIG ((EGLConfig)0)
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------

View File

@ -420,8 +420,9 @@ void SurfaceFlinger::init() {
sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
int32_t hwcId = allocateHwcDisplayId(type);
sp<DisplayDevice> hw = new DisplayDevice(this,
type, allocateHwcDisplayId(type), isSecure, token,
type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
fbs, bq,
mRenderEngine->getEGLConfig());
if (i > DisplayDevice::DISPLAY_PRIMARY) {
@ -1185,7 +1186,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
const wp<IBinder>& display(curr.keyAt(i));
if (dispSurface != NULL) {
sp<DisplayDevice> hw = new DisplayDevice(this,
state.type, hwcDisplayId, state.isSecure,
state.type, hwcDisplayId,
mHwc->getFormat(hwcDisplayId), state.isSecure,
display, dispSurface, producer,
mRenderEngine->getEGLConfig());
hw->setLayerStack(state.layerStack);