blob: 239fcc16c84f9f52acbfe72b358a91c4e5fc7bf0 [file] [log] [blame]
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DisplayEGL.cpp: Common across EGL parts of platform specific egl::Display implementations
#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#include "libANGLE/renderer/gl/egl/ImageEGL.h"
#include "libANGLE/renderer/gl/egl/SyncEGL.h"
namespace rx
{
#define EGL_NO_CONFIG ((EGLConfig)0)
DisplayEGL::DisplayEGL(const egl::DisplayState &state)
: DisplayGL(state), mEGL(nullptr), mConfig(EGL_NO_CONFIG)
{}
DisplayEGL::~DisplayEGL() {}
ImageImpl *DisplayEGL::createImage(const egl::ImageState &state,
const gl::Context *context,
EGLenum target,
const egl::AttributeMap &attribs)
{
return new ImageEGL(state, context, target, attribs, mEGL);
}
EGLSyncImpl *DisplayEGL::createSync(const egl::AttributeMap &attribs)
{
return new SyncEGL(attribs, mEGL);
}
std::string DisplayEGL::getVendorString() const
{
const char *vendor = mEGL->queryString(EGL_VENDOR);
ASSERT(vendor);
return vendor;
}
egl::Error DisplayEGL::initializeContext(EGLContext shareContext,
const egl::AttributeMap &eglAttributes,
EGLContext *outContext,
native_egl::AttributeVector *outAttribs) const
{
gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
EGLint requestedMajor =
eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
EGLint requestedMinor =
eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
bool initializeRequested = requestedMajor != EGL_DONT_CARE && requestedMinor != EGL_DONT_CARE;
static_assert(EGL_CONTEXT_MAJOR_VERSION == EGL_CONTEXT_MAJOR_VERSION_KHR,
"Major Version define should match");
static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR,
"Minor Version define should match");
std::vector<native_egl::AttributeVector> contextAttribLists;
if (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
{
if (initializeRequested)
{
contextAttribLists.push_back({EGL_CONTEXT_MAJOR_VERSION, requestedMajor,
EGL_CONTEXT_MINOR_VERSION, requestedMinor, EGL_NONE});
}
else
{
// clang-format off
const gl::Version esVersionsFrom2_0[] = {
gl::Version(3, 2),
gl::Version(3, 1),
gl::Version(3, 0),
gl::Version(2, 0),
};
// clang-format on
for (const auto &version : esVersionsFrom2_0)
{
contextAttribLists.push_back(
{EGL_CONTEXT_MAJOR_VERSION, static_cast<EGLint>(version.major),
EGL_CONTEXT_MINOR_VERSION, static_cast<EGLint>(version.minor), EGL_NONE});
}
}
}
else
{
if (initializeRequested && (requestedMajor != 2 || requestedMinor != 0))
{
return egl::EglBadAttribute() << "Unsupported requested context version";
}
contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE});
}
EGLContext context = EGL_NO_CONTEXT;
for (const auto &attribList : contextAttribLists)
{
context = mEGL->createContext(mConfig, shareContext, attribList.data());
if (context != EGL_NO_CONTEXT)
{
*outContext = context;
*outAttribs = attribList;
return egl::NoError();
}
}
return egl::Error(mEGL->getError(), "eglCreateContext failed");
}
void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
{
gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
outExtensions->createContextRobustness =
mEGL->hasExtension("EGL_EXT_create_context_robustness");
outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented
outExtensions->presentationTime = mEGL->hasExtension("EGL_ANDROID_presentation_time");
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// We will fallback to regular swap if swapBuffersWithDamage isn't
// supported, so indicate support here to keep validation happy.
outExtensions->swapBuffersWithDamage = true;
outExtensions->image = mEGL->hasExtension("EGL_KHR_image");
outExtensions->imageBase = mEGL->hasExtension("EGL_KHR_image_base");
// Pixmaps are not supported in ANGLE's EGL implementation.
// outExtensions->imagePixmap = mEGL->hasExtension("EGL_KHR_image_pixmap");
outExtensions->glTexture2DImage = mEGL->hasExtension("EGL_KHR_gl_texture_2D_image");
outExtensions->glTextureCubemapImage = mEGL->hasExtension("EGL_KHR_gl_texture_cubemap_image");
outExtensions->glTexture3DImage = mEGL->hasExtension("EGL_KHR_gl_texture_3D_image");
outExtensions->glRenderbufferImage = mEGL->hasExtension("EGL_KHR_gl_renderbuffer_image");
outExtensions->imageNativeBuffer = mEGL->hasExtension("EGL_ANDROID_image_native_buffer");
outExtensions->getFrameTimestamps = mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps");
outExtensions->fenceSync =
eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_fence_sync");
outExtensions->waitSync =
eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_wait_sync");
outExtensions->getNativeClientBufferANDROID =
mEGL->hasExtension("EGL_ANDROID_get_native_client_buffer");
outExtensions->nativeFenceSyncANDROID = mEGL->hasExtension("EGL_ANDROID_native_fence_sync");
outExtensions->noConfigContext = mEGL->hasExtension("EGL_KHR_no_config_context");
DisplayGL::generateExtensions(outExtensions);
}
void DisplayEGL::generateCaps(egl::Caps *outCaps) const
{
outCaps->textureNPOT = true; // Since we request GLES >= 2
}
void DisplayEGL::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get)
{
if (mEGL->hasExtension("EGL_ANDROID_blob_cache"))
{
mEGL->setBlobCacheFuncsANDROID(set, get);
}
}
} // namespace rx