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
InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &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_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings);
InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
......
......@@ -882,8 +882,8 @@ struct DisplayExtensions
// EGL_CHROMIUM_create_context_bind_generates_resource
bool createContextBindGeneratesResource = false;
// EGL_CHROMIUM_get_sync_values
bool getSyncValues = false;
// EGL_CHROMIUM_sync_control
bool syncControlCHROMIUM = false;
// EGL_KHR_swap_buffers_with_damage
bool swapBuffersWithDamage = false;
......
......@@ -26,8 +26,14 @@ namespace egl
{
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;
......@@ -84,8 +90,6 @@ Surface::Surface(EGLint surfaceType,
mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE);
mRobustResourceInitialization =
(attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
if (mRobustResourceInitialization)
......
......@@ -55,6 +55,7 @@ struct SurfaceState final : private angle::NonCopyable
bool timestampsEnabled;
SupportedCompositorTiming supportedCompositorTimings;
SupportedTimestamps supportedTimestamps;
bool directComposition;
};
class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
......@@ -142,7 +143,7 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
}
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;
void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override;
......@@ -206,8 +207,6 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
size_t mFixedWidth;
size_t mFixedHeight;
bool mDirectComposition;
bool mRobustResourceInitialization;
TextureFormat mTextureFormat;
......
......@@ -160,6 +160,12 @@ egl::Error SurfaceD3D::releaseTexImage(const gl::Context *, EGLint)
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);
}
......
......@@ -1245,8 +1245,8 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// getSyncValues requires direct composition.
outExtensions->getSyncValues = outExtensions->directComposition;
// syncControlCHROMIUM requires direct composition.
outExtensions->syncControlCHROMIUM = outExtensions->directComposition;
// D3D11 can be used without a swap chain
outExtensions->surfacelessContext = true;
......
......@@ -837,6 +837,8 @@ void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->surfacelessContext = true;
outExtensions->syncControlCHROMIUM = mGLX.hasExtension("GLX_OML_sync_control");
DisplayGL::generateExtensions(outExtensions);
}
......
......@@ -59,7 +59,8 @@ struct FunctionsGLX::GLXFunctionTable
createContextAttribsARBPtr(nullptr),
swapIntervalEXTPtr(nullptr),
swapIntervalMESAPtr(nullptr),
swapIntervalSGIPtr(nullptr)
swapIntervalSGIPtr(nullptr),
getSyncValuesOMLPtr(nullptr)
{}
// GLX 1.0
......@@ -100,6 +101,9 @@ struct FunctionsGLX::GLXFunctionTable
// GLX_SGI_swap_control
PFNGLXSWAPINTERVALSGIPROC swapIntervalSGIPtr;
// GLX_OML_sync_control
PFNGLXGETSYNCVALUESOMLPROC getSyncValuesOMLPtr;
};
FunctionsGLX::FunctionsGLX()
......@@ -240,6 +244,10 @@ bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorS
{
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_PROC_OR_ERROR
......@@ -400,4 +408,12 @@ int FunctionsGLX::swapIntervalSGI(int intervals) const
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
......@@ -78,6 +78,9 @@ class FunctionsGLX
// GLX_SGI_swap_control
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:
// So as to isolate GLX from angle we do not include angleutils.h and cannot
// use angle::NonCopyable so we replicated it here instead.
......
......@@ -245,4 +245,14 @@ bool WindowSurfaceGLX::getWindowDimensions(Window window,
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
......@@ -55,6 +55,8 @@ class WindowSurfaceGLX : public SurfaceGLX
egl::Error checkForResize() override;
glx::Drawable getDrawable() const override;
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
private:
bool getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const;
......
......@@ -3025,44 +3025,28 @@ Error ValidateStreamPostD3DTextureANGLE(const Display *display,
}
Error ValidateGetSyncValuesCHROMIUM(const Display *display,
const Surface *surface,
const Surface *eglSurface,
const EGLuint64KHR *ust,
const EGLuint64KHR *msc,
const EGLuint64KHR *sbc)
{
ANGLE_TRY(ValidateDisplay(display));
ANGLE_TRY(ValidateSurface(display, eglSurface));
const DisplayExtensions &displayExtensions = display->getExtensions();
if (!displayExtensions.getSyncValues)
{
return EglBadAccess() << "getSyncValues extension not active";
}
if (display->isDeviceLost())
if (!displayExtensions.syncControlCHROMIUM)
{
return EglContextLost() << "Context is lost.";
}
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";
return EglBadAccess() << "syncControlCHROMIUM extension not active";
}
if (ust == nullptr)
{
return EglBadParameter() << "ust is null";
}
if (msc == nullptr)
{
return EglBadParameter() << "msc is null";
}
if (sbc == nullptr)
{
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