Merge "Implement per-display EGLConfig and configless EGLContext"
This commit is contained in:
commit
b6c2100458
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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");
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <EGL/eglext.h>
|
||||
#include <ui/mat4.h>
|
||||
|
||||
#define EGL_NO_CONFIG ((EGLConfig)0)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user