Commit a829c0b9 by Jonah Ryan-Davis Committed by Commit Bot

Expose EGL_CHROMIUM_sync_control via GLX_OML_sync_control

On GLX, we can expose the EGL_CHROMIUM_sync_control extension by forwarding to GLX_OML_sync_control when it's available. This will help with accurate vsync times for Chrome Bug: 1020252 Change-Id: I9b1e8cf0f8b1a548cc7cc7202fac2d0cdb01d74d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1918104 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent e4aa7235
...@@ -1236,7 +1236,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1236,7 +1236,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings); InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings); InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings);
InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings); InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
InsertExtensionString("EGL_CHROMIUM_sync_control", getSyncValues, &extensionStrings); InsertExtensionString("EGL_CHROMIUM_sync_control", syncControlCHROMIUM, &extensionStrings);
InsertExtensionString("EGL_KHR_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings); InsertExtensionString("EGL_KHR_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings);
InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings); InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings);
InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings); InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
......
...@@ -882,8 +882,8 @@ struct DisplayExtensions ...@@ -882,8 +882,8 @@ struct DisplayExtensions
// EGL_CHROMIUM_create_context_bind_generates_resource // EGL_CHROMIUM_create_context_bind_generates_resource
bool createContextBindGeneratesResource = false; bool createContextBindGeneratesResource = false;
// EGL_CHROMIUM_get_sync_values // EGL_CHROMIUM_sync_control
bool getSyncValues = false; bool syncControlCHROMIUM = false;
// EGL_KHR_swap_buffers_with_damage // EGL_KHR_swap_buffers_with_damage
bool swapBuffersWithDamage = false; bool swapBuffersWithDamage = false;
......
...@@ -26,8 +26,14 @@ namespace egl ...@@ -26,8 +26,14 @@ namespace egl
{ {
SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn) SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
: label(nullptr), config(configIn), attributes(attributesIn), timestampsEnabled(false) : label(nullptr),
{} config(configIn),
attributes(attributesIn),
timestampsEnabled(false),
directComposition(false)
{
directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE;
}
SurfaceState::~SurfaceState() = default; SurfaceState::~SurfaceState() = default;
...@@ -84,8 +90,6 @@ Surface::Surface(EGLint surfaceType, ...@@ -84,8 +90,6 @@ Surface::Surface(EGLint surfaceType,
mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB)); mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE); mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE);
mRobustResourceInitialization = mRobustResourceInitialization =
(attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
if (mRobustResourceInitialization) if (mRobustResourceInitialization)
......
...@@ -55,6 +55,7 @@ struct SurfaceState final : private angle::NonCopyable ...@@ -55,6 +55,7 @@ struct SurfaceState final : private angle::NonCopyable
bool timestampsEnabled; bool timestampsEnabled;
SupportedCompositorTiming supportedCompositorTimings; SupportedCompositorTiming supportedCompositorTimings;
SupportedTimestamps supportedTimestamps; SupportedTimestamps supportedTimestamps;
bool directComposition;
}; };
class Surface : public LabeledObject, public gl::FramebufferAttachmentObject class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
...@@ -142,7 +143,7 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject ...@@ -142,7 +143,7 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
} }
EGLint getOrientation() const { return mOrientation; } EGLint getOrientation() const { return mOrientation; }
bool directComposition() const { return mDirectComposition; } bool directComposition() const { return mState.directComposition; }
gl::InitState initState(const gl::ImageIndex &imageIndex) const override; gl::InitState initState(const gl::ImageIndex &imageIndex) const override;
void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override; void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override;
...@@ -206,8 +207,6 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject ...@@ -206,8 +207,6 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
size_t mFixedWidth; size_t mFixedWidth;
size_t mFixedHeight; size_t mFixedHeight;
bool mDirectComposition;
bool mRobustResourceInitialization; bool mRobustResourceInitialization;
TextureFormat mTextureFormat; TextureFormat mTextureFormat;
......
...@@ -160,6 +160,12 @@ egl::Error SurfaceD3D::releaseTexImage(const gl::Context *, EGLint) ...@@ -160,6 +160,12 @@ egl::Error SurfaceD3D::releaseTexImage(const gl::Context *, EGLint)
egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
{ {
if (!mState.directComposition)
{
return egl::EglBadSurface()
<< "getSyncValues: surface requires Direct Composition to be enabled";
}
return mSwapChain->getSyncValues(ust, msc, sbc); return mSwapChain->getSyncValues(ust, msc, sbc);
} }
......
...@@ -1245,8 +1245,8 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions ...@@ -1245,8 +1245,8 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
// Contexts are virtualized so textures can be shared globally // Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true; outExtensions->displayTextureShareGroup = true;
// getSyncValues requires direct composition. // syncControlCHROMIUM requires direct composition.
outExtensions->getSyncValues = outExtensions->directComposition; outExtensions->syncControlCHROMIUM = outExtensions->directComposition;
// D3D11 can be used without a swap chain // D3D11 can be used without a swap chain
outExtensions->surfacelessContext = true; outExtensions->surfacelessContext = true;
......
...@@ -837,6 +837,8 @@ void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -837,6 +837,8 @@ void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->surfacelessContext = true; outExtensions->surfacelessContext = true;
outExtensions->syncControlCHROMIUM = mGLX.hasExtension("GLX_OML_sync_control");
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }
......
...@@ -59,7 +59,8 @@ struct FunctionsGLX::GLXFunctionTable ...@@ -59,7 +59,8 @@ struct FunctionsGLX::GLXFunctionTable
createContextAttribsARBPtr(nullptr), createContextAttribsARBPtr(nullptr),
swapIntervalEXTPtr(nullptr), swapIntervalEXTPtr(nullptr),
swapIntervalMESAPtr(nullptr), swapIntervalMESAPtr(nullptr),
swapIntervalSGIPtr(nullptr) swapIntervalSGIPtr(nullptr),
getSyncValuesOMLPtr(nullptr)
{} {}
// GLX 1.0 // GLX 1.0
...@@ -100,6 +101,9 @@ struct FunctionsGLX::GLXFunctionTable ...@@ -100,6 +101,9 @@ struct FunctionsGLX::GLXFunctionTable
// GLX_SGI_swap_control // GLX_SGI_swap_control
PFNGLXSWAPINTERVALSGIPROC swapIntervalSGIPtr; PFNGLXSWAPINTERVALSGIPROC swapIntervalSGIPtr;
// GLX_OML_sync_control
PFNGLXGETSYNCVALUESOMLPROC getSyncValuesOMLPtr;
}; };
FunctionsGLX::FunctionsGLX() FunctionsGLX::FunctionsGLX()
...@@ -240,6 +244,10 @@ bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorS ...@@ -240,6 +244,10 @@ bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorS
{ {
GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalSGIPtr, glXSwapIntervalSGI); GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalSGIPtr, glXSwapIntervalSGI);
} }
if (hasExtension("GLX_OML_sync_control"))
{
GET_PROC_OR_ERROR(&mFnPtrs->getSyncValuesOMLPtr, glXGetSyncValuesOML);
}
#undef GET_FNPTR_OR_ERROR #undef GET_FNPTR_OR_ERROR
#undef GET_PROC_OR_ERROR #undef GET_PROC_OR_ERROR
...@@ -400,4 +408,12 @@ int FunctionsGLX::swapIntervalSGI(int intervals) const ...@@ -400,4 +408,12 @@ int FunctionsGLX::swapIntervalSGI(int intervals) const
return mFnPtrs->swapIntervalSGIPtr(intervals); return mFnPtrs->swapIntervalSGIPtr(intervals);
} }
bool FunctionsGLX::getSyncValuesOML(glx::Drawable drawable,
int64_t *ust,
int64_t *msc,
int64_t *sbc) const
{
return mFnPtrs->getSyncValuesOMLPtr(mXDisplay, drawable, ust, msc, sbc);
}
} // namespace rx } // namespace rx
...@@ -78,6 +78,9 @@ class FunctionsGLX ...@@ -78,6 +78,9 @@ class FunctionsGLX
// GLX_SGI_swap_control // GLX_SGI_swap_control
int swapIntervalSGI(int interval) const; int swapIntervalSGI(int interval) const;
// GLX_OML_sync_control
bool getSyncValuesOML(glx::Drawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc) const;
private: private:
// So as to isolate GLX from angle we do not include angleutils.h and cannot // So as to isolate GLX from angle we do not include angleutils.h and cannot
// use angle::NonCopyable so we replicated it here instead. // use angle::NonCopyable so we replicated it here instead.
......
...@@ -245,4 +245,14 @@ bool WindowSurfaceGLX::getWindowDimensions(Window window, ...@@ -245,4 +245,14 @@ bool WindowSurfaceGLX::getWindowDimensions(Window window,
return XGetGeometry(mDisplay, window, &root, &x, &y, width, height, &border, &depth) != 0; return XGetGeometry(mDisplay, window, &root, &x, &y, width, height, &border, &depth) != 0;
} }
egl::Error WindowSurfaceGLX::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
{
if (!mGLX.getSyncValuesOML(mGLXWindow, reinterpret_cast<int64_t *>(ust),
reinterpret_cast<int64_t *>(msc), reinterpret_cast<int64_t *>(sbc)))
{
return egl::EglBadSurface() << "glXGetSyncValuesOML failed.";
}
return egl::NoError();
}
} // namespace rx } // namespace rx
...@@ -55,6 +55,8 @@ class WindowSurfaceGLX : public SurfaceGLX ...@@ -55,6 +55,8 @@ class WindowSurfaceGLX : public SurfaceGLX
egl::Error checkForResize() override; egl::Error checkForResize() override;
glx::Drawable getDrawable() const override; glx::Drawable getDrawable() const override;
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
private: private:
bool getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const; bool getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const;
......
...@@ -3025,44 +3025,28 @@ Error ValidateStreamPostD3DTextureANGLE(const Display *display, ...@@ -3025,44 +3025,28 @@ Error ValidateStreamPostD3DTextureANGLE(const Display *display,
} }
Error ValidateGetSyncValuesCHROMIUM(const Display *display, Error ValidateGetSyncValuesCHROMIUM(const Display *display,
const Surface *surface, const Surface *eglSurface,
const EGLuint64KHR *ust, const EGLuint64KHR *ust,
const EGLuint64KHR *msc, const EGLuint64KHR *msc,
const EGLuint64KHR *sbc) const EGLuint64KHR *sbc)
{ {
ANGLE_TRY(ValidateDisplay(display)); ANGLE_TRY(ValidateDisplay(display));
ANGLE_TRY(ValidateSurface(display, eglSurface));
const DisplayExtensions &displayExtensions = display->getExtensions(); const DisplayExtensions &displayExtensions = display->getExtensions();
if (!displayExtensions.getSyncValues) if (!displayExtensions.syncControlCHROMIUM)
{
return EglBadAccess() << "getSyncValues extension not active";
}
if (display->isDeviceLost())
{ {
return EglContextLost() << "Context is lost."; return EglBadAccess() << "syncControlCHROMIUM extension not active";
}
if (surface == EGL_NO_SURFACE)
{
return EglBadSurface() << "getSyncValues surface cannot be EGL_NO_SURFACE";
}
if (!surface->directComposition())
{
return EglBadSurface() << "getSyncValues surface requires Direct Composition to be enabled";
} }
if (ust == nullptr) if (ust == nullptr)
{ {
return EglBadParameter() << "ust is null"; return EglBadParameter() << "ust is null";
} }
if (msc == nullptr) if (msc == nullptr)
{ {
return EglBadParameter() << "msc is null"; return EglBadParameter() << "msc is null";
} }
if (sbc == nullptr) if (sbc == nullptr)
{ {
return EglBadParameter() << "sbc is null"; return EglBadParameter() << "sbc is null";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment