blob: 2cd85476a2c9dcc4ff684c5e62065c4172239c93 [file] [log] [blame]
//
// Copyright 2015 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.
//
// DisplayGL.h: GL implementation of egl::Display
#include "libANGLE/renderer/gl/DisplayGL.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/SurfaceGL.h"
#include <EGL/eglext.h>
namespace rx
{
// On Linux with the amdgpu driver, the renderer string looks like:
//
// AMD Radeon (TM) <GPU model> Graphics (<GPUgeneration>, DRM <DRMversion>, <kernelversion>,
// LLVM <LLVMversion>) eg. AMD Radeon (TM) RX 460 Graphics (POLARIS11,
// DRM 3.35.0, 5.4.0-65-generic, LLVM 11.0.0)
//
// We also want to handle the case without GPUGeneration:
// AMD Radeon GPU model (DRM DRMversion, kernelversion, LLVM LLVMversion)
//
// Thanks to Jeff Gilbert of Mozilla for this example
// https://phabricator.services.mozilla.com/D105636
std::string SanitizeRendererString(std::string rendererString)
{
size_t pos = rendererString.find(", DRM ");
if (pos != std::string::npos)
{
rendererString.resize(pos);
rendererString.push_back(')');
return rendererString;
}
pos = rendererString.find(" (DRM ");
if (pos != std::string::npos)
{
rendererString.resize(pos);
return rendererString;
}
return rendererString;
}
// OpenGL ES requires a prefix of "OpenGL ES" for the GL_VERSION string.
// We can also add the prefix to desktop OpenGL for consistency.
std::string SanitizeVersionString(std::string versionString, bool isES, bool includeFullVersion)
{
const std::string GLString = "OpenGL ";
const std::string ESString = "ES ";
size_t openGLESPos = versionString.find(GLString);
std::ostringstream result;
if (openGLESPos == std::string::npos)
{
openGLESPos = 0;
}
else
{
openGLESPos += GLString.size() + (isES ? ESString.size() : 0);
}
result << GLString << (isES ? ESString : "");
if (includeFullVersion)
{
result << versionString.substr(openGLESPos);
}
else
{
size_t postVersionSpace = versionString.find(" ", openGLESPos);
result << versionString.substr(openGLESPos, postVersionSpace - openGLESPos);
}
return result.str();
}
DisplayGL::DisplayGL(const egl::DisplayState &state) : DisplayImpl(state) {}
DisplayGL::~DisplayGL() {}
egl::Error DisplayGL::initialize(egl::Display *display)
{
return egl::NoError();
}
void DisplayGL::terminate() {}
ImageImpl *DisplayGL::createImage(const egl::ImageState &state,
const gl::Context *context,
EGLenum target,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
return nullptr;
}
SurfaceImpl *DisplayGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
return nullptr;
}
StreamProducerImpl *DisplayGL::createStreamProducerD3DTexture(
egl::Stream::ConsumerType consumerType,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
return nullptr;
}
ShareGroupImpl *DisplayGL::createShareGroup()
{
return new ShareGroupGL();
}
egl::Error DisplayGL::makeCurrent(egl::Display *display,
egl::Surface *drawSurface,
egl::Surface *readSurface,
gl::Context *context)
{
// Ensure that the correct global DebugAnnotator is installed when the end2end tests change
// the ANGLE back-end (done frequently).
display->setGlobalDebugAnnotator();
if (!context)
{
return egl::NoError();
}
// Pause transform feedback before making a new surface current, to workaround anglebug.com/1426
ContextGL *glContext = GetImplAs<ContextGL>(context);
glContext->getStateManager()->pauseTransformFeedback();
if (drawSurface == nullptr)
{
ANGLE_TRY(makeCurrentSurfaceless(context));
}
return egl::NoError();
}
gl::Version DisplayGL::getMaxConformantESVersion() const
{
// 3.1 support is in progress.
return std::min(getMaxSupportedESVersion(), gl::Version(3, 0));
}
Optional<gl::Version> DisplayGL::getMaxSupportedDesktopVersion() const
{
return Optional<gl::Version>::Invalid();
}
void DisplayGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
{
// Advertise robust resource initialization on all OpenGL backends for testing even though it is
// not fully implemented.
outExtensions->robustResourceInitializationANGLE = true;
}
egl::Error DisplayGL::makeCurrentSurfaceless(gl::Context *context)
{
UNIMPLEMENTED();
return egl::NoError();
}
std::string DisplayGL::getRendererDescription()
{
std::string rendererString = GetRendererString(getRenderer()->getFunctions());
const angle::FeaturesGL &features = getRenderer()->getFeatures();
if (features.sanitizeAMDGPURendererString.enabled)
{
return SanitizeRendererString(rendererString);
}
return rendererString;
}
std::string DisplayGL::getVendorString()
{
return GetVendorString(getRenderer()->getFunctions());
}
std::string DisplayGL::getVersionString(bool includeFullVersion)
{
std::string versionString = GetVersionString(getRenderer()->getFunctions());
return SanitizeVersionString(versionString,
getRenderer()->getFunctions()->standard == STANDARD_GL_ES,
includeFullVersion);
}
} // namespace rx