Commit 6ba22ee1 by Geoff Lang Committed by Commit Bot

GL: Implement EGL_ANDROID_get_frame_timestamps.

BUG=angleproject:2936 Change-Id: I758d797d185b2de330cce3401bfeef76c7df590e Reviewed-on: https://chromium-review.googlesource.com/c/1302836 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 99d0463c
......@@ -84,17 +84,17 @@
"Vulkan mandatory format support table:src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json":
"fa2bd54c1bb0ab2cf1d386061a4bc5c5",
"Vulkan mandatory format support table:third_party/vulkan-headers/src/registry/vk.xml":
"36d0ec2733888108d2acb56134df6b22",
"cd73387d7cdaa5d403eab411194342b3",
"packed enum:src/common/gen_packed_gl_enums.py":
"a9b1c38b4e4d8a1038e743be323f1a51",
"packed enum:src/common/packed_egl_enums.json":
"0389a8a565ccee99163bd0cf3ca146d3",
"5f591d220ee53b6e54a27d1523a3ab79",
"packed enum:src/common/packed_gl_enums.json":
"7338a2a11c679aeb8efe2b415dbd4810",
"proc table:src/libGLESv2/gen_proc_table.py":
"027bfd5a8a8dffe91f492bf199029cde",
"proc table:src/libGLESv2/proc_table_data.json":
"9bc7a48223f99e16f11b14ccaeedb09d",
"78d7d15862b563adf3fe957672ca1845",
"uniform type:src/common/gen_uniform_type_table.py":
"59cb4ffd0f584c4bd37f2f4ff59a2b93"
}
\ No newline at end of file
......@@ -16,6 +16,38 @@ namespace egl
{
template <>
CompositorTiming FromEGLenum<CompositorTiming>(EGLenum from)
{
switch (from)
{
case EGL_COMPOSITE_DEADLINE_ANDROID:
return CompositorTiming::CompositeDeadline;
case EGL_COMPOSITE_INTERVAL_ANDROID:
return CompositorTiming::CompositInterval;
case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
return CompositorTiming::CompositToPresentLatency;
default:
return CompositorTiming::InvalidEnum;
}
}
EGLenum ToEGLenum(CompositorTiming from)
{
switch (from)
{
case CompositorTiming::CompositeDeadline:
return EGL_COMPOSITE_DEADLINE_ANDROID;
case CompositorTiming::CompositInterval:
return EGL_COMPOSITE_INTERVAL_ANDROID;
case CompositorTiming::CompositToPresentLatency:
return EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID;
default:
UNREACHABLE();
return 0;
}
}
template <>
MessageType FromEGLenum<MessageType>(EGLenum from)
{
switch (from)
......@@ -131,4 +163,60 @@ EGLenum ToEGLenum(TextureFormat from)
}
}
template <>
Timestamp FromEGLenum<Timestamp>(EGLenum from)
{
switch (from)
{
case EGL_REQUESTED_PRESENT_TIME_ANDROID:
return Timestamp::RequestedPresentTime;
case EGL_RENDERING_COMPLETE_TIME_ANDROID:
return Timestamp::RenderingCompleteTime;
case EGL_COMPOSITION_LATCH_TIME_ANDROID:
return Timestamp::CompositionLatchTime;
case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
return Timestamp::FirstCompositionStartTime;
case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
return Timestamp::LastCompositionStartTime;
case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
return Timestamp::FirstCompositionGPUFinishedTime;
case EGL_DISPLAY_PRESENT_TIME_ANDROID:
return Timestamp::DisplayPresentTime;
case EGL_DEQUEUE_READY_TIME_ANDROID:
return Timestamp::DequeueReadyTime;
case EGL_READS_DONE_TIME_ANDROID:
return Timestamp::ReadsDoneTime;
default:
return Timestamp::InvalidEnum;
}
}
EGLenum ToEGLenum(Timestamp from)
{
switch (from)
{
case Timestamp::RequestedPresentTime:
return EGL_REQUESTED_PRESENT_TIME_ANDROID;
case Timestamp::RenderingCompleteTime:
return EGL_RENDERING_COMPLETE_TIME_ANDROID;
case Timestamp::CompositionLatchTime:
return EGL_COMPOSITION_LATCH_TIME_ANDROID;
case Timestamp::FirstCompositionStartTime:
return EGL_FIRST_COMPOSITION_START_TIME_ANDROID;
case Timestamp::LastCompositionStartTime:
return EGL_LAST_COMPOSITION_START_TIME_ANDROID;
case Timestamp::FirstCompositionGPUFinishedTime:
return EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID;
case Timestamp::DisplayPresentTime:
return EGL_DISPLAY_PRESENT_TIME_ANDROID;
case Timestamp::DequeueReadyTime:
return EGL_DEQUEUE_READY_TIME_ANDROID;
case Timestamp::ReadsDoneTime:
return EGL_READS_DONE_TIME_ANDROID;
default:
UNREACHABLE();
return 0;
}
}
} // namespace egl
......@@ -24,6 +24,20 @@ namespace egl
template <typename Enum>
Enum FromEGLenum(EGLenum from);
enum class CompositorTiming : uint8_t
{
CompositeDeadline = 0,
CompositInterval = 1,
CompositToPresentLatency = 2,
InvalidEnum = 3,
EnumCount = 3,
};
template <>
CompositorTiming FromEGLenum<CompositorTiming>(EGLenum from);
EGLenum ToEGLenum(CompositorTiming from);
enum class MessageType : uint8_t
{
Critical = 0,
......@@ -71,6 +85,26 @@ template <>
TextureFormat FromEGLenum<TextureFormat>(EGLenum from);
EGLenum ToEGLenum(TextureFormat from);
enum class Timestamp : uint8_t
{
RequestedPresentTime = 0,
RenderingCompleteTime = 1,
CompositionLatchTime = 2,
FirstCompositionStartTime = 3,
LastCompositionStartTime = 4,
FirstCompositionGPUFinishedTime = 5,
DisplayPresentTime = 6,
DequeueReadyTime = 7,
ReadsDoneTime = 8,
InvalidEnum = 9,
EnumCount = 9,
};
template <>
Timestamp FromEGLenum<Timestamp>(EGLenum from);
EGLenum ToEGLenum(Timestamp from);
} // namespace egl
#endif // COMMON_PACKEDEGLENUMS_AUTOGEN_H_
......@@ -21,5 +21,23 @@
"Error": "EGL_DEBUG_MSG_ERROR_KHR",
"Warn": "EGL_DEBUG_MSG_WARN_KHR",
"Info": "EGL_DEBUG_MSG_INFO_KHR"
},
"CompositorTiming":
{
"CompositeDeadline": "EGL_COMPOSITE_DEADLINE_ANDROID",
"CompositInterval": "EGL_COMPOSITE_INTERVAL_ANDROID",
"CompositToPresentLatency": "EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID"
},
"Timestamp":
{
"RequestedPresentTime": "EGL_REQUESTED_PRESENT_TIME_ANDROID",
"RenderingCompleteTime": "EGL_RENDERING_COMPLETE_TIME_ANDROID",
"CompositionLatchTime": "EGL_COMPOSITION_LATCH_TIME_ANDROID",
"FirstCompositionStartTime": "EGL_FIRST_COMPOSITION_START_TIME_ANDROID",
"LastCompositionStartTime": "EGL_LAST_COMPOSITION_START_TIME_ANDROID",
"FirstCompositionGPUFinishedTime": "EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID",
"DisplayPresentTime": "EGL_DISPLAY_PRESENT_TIME_ANDROID",
"DequeueReadyTime": "EGL_DEQUEUE_READY_TIME_ANDROID",
"ReadsDoneTime": "EGL_READS_DONE_TIME_ANDROID"
}
}
......@@ -1362,7 +1362,8 @@ DisplayExtensions::DisplayExtensions()
createContextExtensionsEnabled(false),
presentationTime(false),
blobCache(false),
imageNativeBuffer(false)
imageNativeBuffer(false),
getFrameTimestamps(false)
{
}
......@@ -1413,6 +1414,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings);
InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings);
InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings);
InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings);
// TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on
......
......@@ -813,6 +813,9 @@ struct DisplayExtensions
// EGL_ANDROID_image_native_buffer
bool imageNativeBuffer;
// EGL_ANDROID_get_frame_timestamps
bool getFrameTimestamps;
};
struct DeviceExtensions
......
......@@ -26,7 +26,7 @@ namespace egl
{
SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
: label(nullptr), config(configIn), attributes(attributesIn)
: label(nullptr), config(configIn), attributes(attributesIn), timestampsEnabled(false)
{
}
......@@ -169,6 +169,12 @@ Error Surface::initialize(const Display *display)
}
}
if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
{
mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
mState.supportedTimestamps = mImplementation->getSupportedTimestamps();
}
return NoError();
}
......@@ -481,6 +487,47 @@ void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState
mInitState = initState;
}
void Surface::setTimestampsEnabled(bool enabled)
{
mImplementation->setTimestampsEnabled(enabled);
mState.timestampsEnabled = enabled;
}
bool Surface::isTimestampsEnabled() const
{
return mState.timestampsEnabled;
}
const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
{
return mState.supportedCompositorTimings;
}
Error Surface::getCompositorTiming(EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const
{
return mImplementation->getCompositorTiming(numTimestamps, names, values);
}
Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
{
return mImplementation->getNextFrameId(frameId);
}
const SupportedTimestamps &Surface::getSupportedTimestamps() const
{
return mState.supportedTimestamps;
}
Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const
{
return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
}
WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
const egl::Config *config,
EGLNativeWindowType window,
......
......@@ -40,6 +40,9 @@ namespace egl
class Display;
struct Config;
using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>;
using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>;
struct SurfaceState final : private angle::NonCopyable
{
SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
......@@ -47,6 +50,10 @@ struct SurfaceState final : private angle::NonCopyable
EGLLabelKHR label;
const egl::Config *config;
AttributeMap attributes;
bool timestampsEnabled;
SupportedCompositorTiming supportedCompositorTimings;
SupportedTimestamps supportedTimestamps;
};
class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
......@@ -140,6 +147,22 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
const gl::Format &getBindTexImageFormat() const { return mColorFormat; }
// EGL_ANDROID_get_frame_timestamps entry points
void setTimestampsEnabled(bool enabled);
bool isTimestampsEnabled() const;
const SupportedCompositorTiming &getSupportedCompositorTimings() const;
Error getCompositorTiming(EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const;
Error getNextFrameId(EGLuint64KHR *frameId) const;
const SupportedTimestamps &getSupportedTimestamps() const;
Error getFrameTimestamps(EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const;
protected:
Surface(EGLint surfaceType,
const egl::Config *config,
......
......@@ -2988,6 +2988,9 @@ void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value)
case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
*value = surface->isRobustResourceInitEnabled();
break;
case EGL_TIMESTAMPS_ANDROID:
*value = surface->isTimestampsEnabled();
break;
default:
UNREACHABLE();
break;
......@@ -3013,6 +3016,9 @@ void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
case EGL_HEIGHT:
surface->setFixedHeight(value);
break;
case EGL_TIMESTAMPS_ANDROID:
surface->setTimestampsEnabled(value != EGL_FALSE);
break;
default:
UNREACHABLE();
break;
......
......@@ -34,6 +34,9 @@ class Display;
struct Config;
struct SurfaceState;
class Thread;
using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>;
using SupportedCompositorTimings = angle::PackedEnumBitSet<CompositorTiming>;
}
namespace rx
......@@ -58,22 +61,22 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl
EGLint width,
EGLint height) = 0;
virtual egl::Error setPresentationTime(EGLnsecsANDROID time);
virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0;
virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0;
virtual egl::Error bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint buffer) = 0;
virtual egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) = 0;
virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0;
virtual void setSwapInterval(EGLint interval) = 0;
virtual void setSwapInterval(EGLint interval) = 0;
virtual void setFixedWidth(EGLint width);
virtual void setFixedHeight(EGLint height);
// width and height can change with client window resizing
virtual EGLint getWidth() const = 0;
virtual EGLint getWidth() const = 0;
virtual EGLint getHeight() const = 0;
virtual EGLint isPostSubBufferSupported() const = 0;
virtual EGLint getSwapBehavior() const = 0;
virtual EGLint getSwapBehavior() const = 0;
// Used to query color format from pbuffers created from D3D textures.
virtual const angle::Format *getD3DTextureColorFormat() const
......@@ -82,11 +85,44 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl
return nullptr;
}
// EGL_ANDROID_get_frame_timestamps
virtual void setTimestampsEnabled(bool enabled) { UNREACHABLE(); }
virtual egl::SupportedCompositorTimings getSupportedCompositorTimings() const
{
UNREACHABLE();
return egl::SupportedCompositorTimings();
}
virtual egl::Error getCompositorTiming(EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const
{
UNREACHABLE();
return egl::EglBadDisplay();
}
virtual egl::Error getNextFrameId(EGLuint64KHR *frameId) const
{
UNREACHABLE();
return egl::EglBadDisplay();
}
virtual egl::SupportedTimestamps getSupportedTimestamps() const
{
UNREACHABLE();
return egl::SupportedTimestamps();
}
virtual egl::Error getFrameTimestamps(EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const
{
UNREACHABLE();
return egl::EglBadDisplay();
}
protected:
const egl::SurfaceState &mState;
};
}
#endif // LIBANGLE_RENDERER_SURFACEIMPL_H_
#endif // LIBANGLE_RENDERER_SURFACEIMPL_H_
......@@ -112,8 +112,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
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");
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;
......@@ -133,6 +133,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->imageNativeBuffer = mEGL->hasExtension("EGL_ANDROID_image_native_buffer");
outExtensions->getFrameTimestamps = mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps");
DisplayGL::generateExtensions(outExtensions);
}
......
......@@ -10,9 +10,9 @@
#include <algorithm>
#include "common/string_utils.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
#include "common/string_utils.h"
namespace
{
......@@ -54,6 +54,7 @@ struct FunctionsEGL::EGLDispatchTable
bindTexImagePtr(nullptr),
releaseTexImagePtr(nullptr),
surfaceAttribPtr(nullptr),
swapIntervalPtr(nullptr),
createImageKHRPtr(nullptr),
......@@ -68,7 +69,13 @@ struct FunctionsEGL::EGLDispatchTable
presentationTimeANDROIDPtr(nullptr),
setBlobCacheFuncsANDROIDPtr(nullptr)
setBlobCacheFuncsANDROIDPtr(nullptr),
getCompositorTimingSupportedANDROIDPtr(nullptr),
getCompositorTimingANDROIDPtr(nullptr),
getNextFrameIdANDROIDPtr(nullptr),
getFrameTimestampSupportedANDROIDPtr(nullptr),
getFrameTimestampsANDROIDPtr(nullptr)
{
}
......@@ -93,6 +100,7 @@ struct FunctionsEGL::EGLDispatchTable
// 1.1
PFNEGLBINDTEXIMAGEPROC bindTexImagePtr;
PFNEGLRELEASETEXIMAGEPROC releaseTexImagePtr;
PFNEGLSURFACEATTRIBPROC surfaceAttribPtr;
PFNEGLSWAPINTERVALPROC swapIntervalPtr;
// EGL_KHR_image
......@@ -113,6 +121,13 @@ struct FunctionsEGL::EGLDispatchTable
// EGL_ANDROID_blob_cache
PFNEGLSETBLOBCACHEFUNCSANDROIDPROC setBlobCacheFuncsANDROIDPtr;
// EGL_ANDROID_get_frame_timestamps
PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC getCompositorTimingSupportedANDROIDPtr;
PFNEGLGETCOMPOSITORTIMINGANDROIDPROC getCompositorTimingANDROIDPtr;
PFNEGLGETNEXTFRAMEIDANDROIDPROC getNextFrameIdANDROIDPtr;
PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC getFrameTimestampSupportedANDROIDPtr;
PFNEGLGETFRAMETIMESTAMPSANDROIDPROC getFrameTimestampsANDROIDPtr;
};
FunctionsEGL::FunctionsEGL()
......@@ -152,6 +167,7 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindTexImagePtr, eglBindTexImage);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->releaseTexImagePtr, eglReleaseTexImage);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->surfaceAttribPtr, eglSurfaceAttrib);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalPtr, eglSwapInterval);
mEGLDisplay = mFnPtrs->getDisplayPtr(nativeDisplay);
......@@ -207,6 +223,19 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->setBlobCacheFuncsANDROIDPtr, eglSetBlobCacheFuncsANDROID);
}
if (hasExtension("EGL_ANDROID_get_frame_timestamps"))
{
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getCompositorTimingSupportedANDROIDPtr,
eglGetCompositorTimingSupportedANDROID);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getCompositorTimingANDROIDPtr,
eglGetCompositorTimingANDROID);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getNextFrameIdANDROIDPtr, eglGetNextFrameIdANDROID);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getFrameTimestampSupportedANDROIDPtr,
eglGetFrameTimestampSupportedANDROID);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getFrameTimestampsANDROIDPtr,
eglGetFrameTimestampsANDROID);
}
#undef ANGLE_GET_PROC_OR_ERROR
return egl::NoError();
......@@ -330,6 +359,11 @@ EGLBoolean FunctionsEGL::releaseTexImage(EGLSurface surface, EGLint buffer) cons
return mFnPtrs->releaseTexImagePtr(mEGLDisplay, surface, buffer);
}
EGLBoolean FunctionsEGL::surfaceAttrib(EGLSurface surface, EGLint attribute, EGLint value) const
{
return mFnPtrs->surfaceAttribPtr(mEGLDisplay, surface, attribute, value);
}
EGLBoolean FunctionsEGL::swapInterval(EGLint interval) const
{
return mFnPtrs->swapIntervalPtr(mEGLDisplay, interval);
......@@ -385,4 +419,40 @@ void FunctionsEGL::setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set,
{
return mFnPtrs->setBlobCacheFuncsANDROIDPtr(mEGLDisplay, set, get);
}
EGLBoolean FunctionsEGL::getCompositorTimingSupportedANDROID(EGLSurface surface, EGLint name) const
{
return mFnPtrs->getCompositorTimingSupportedANDROIDPtr(mEGLDisplay, surface, name);
}
EGLBoolean FunctionsEGL::getCompositorTimingANDROID(EGLSurface surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const
{
return mFnPtrs->getCompositorTimingANDROIDPtr(mEGLDisplay, surface, numTimestamps, names,
values);
}
EGLBoolean FunctionsEGL::getNextFrameIdANDROID(EGLSurface surface, EGLuint64KHR *frameId) const
{
return mFnPtrs->getNextFrameIdANDROIDPtr(mEGLDisplay, surface, frameId);
}
EGLBoolean FunctionsEGL::getFrameTimestampSupportedANDROID(EGLSurface surface,
EGLint timestamp) const
{
return mFnPtrs->getFrameTimestampSupportedANDROIDPtr(mEGLDisplay, surface, timestamp);
}
EGLBoolean FunctionsEGL::getFrameTimestampsANDROID(EGLSurface surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const
{
return mFnPtrs->getFrameTimestampsANDROIDPtr(mEGLDisplay, surface, frameId, numTimestamps,
timestamps, values);
}
} // namespace rx
......@@ -62,6 +62,7 @@ class FunctionsEGL
EGLBoolean bindTexImage(EGLSurface surface, EGLint buffer) const;
EGLBoolean releaseTexImage(EGLSurface surface, EGLint buffer) const;
EGLBoolean surfaceAttrib(EGLSurface surface, EGLint attribute, EGLint value) const;
EGLBoolean swapInterval(EGLint interval) const;
EGLImageKHR createImageKHR(EGLContext context,
......@@ -81,6 +82,19 @@ class FunctionsEGL
void setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) const;
EGLBoolean getCompositorTimingSupportedANDROID(EGLSurface surface, EGLint name) const;
EGLBoolean getCompositorTimingANDROID(EGLSurface surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const;
EGLBoolean getNextFrameIdANDROID(EGLSurface surface, EGLuint64KHR *frameId) const;
EGLBoolean getFrameTimestampSupportedANDROID(EGLSurface surface, EGLint timestamp) const;
EGLBoolean getFrameTimestampsANDROID(EGLSurface surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const;
private:
// So as to isolate from angle we do not include angleutils.h and cannot
// use angle::NonCopyable so we replicated it here instead.
......
......@@ -156,4 +156,84 @@ EGLSurface SurfaceEGL::getSurface() const
return mSurface;
}
void SurfaceEGL::setTimestampsEnabled(bool enabled)
{
ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
EGLBoolean success =
mEGL->surfaceAttrib(mSurface, EGL_TIMESTAMPS_ANDROID, enabled ? EGL_TRUE : EGL_FALSE);
if (success == EGL_FALSE)
{
ERR() << "eglSurfaceAttribute failed: " << egl::Error(mEGL->getError());
}
}
egl::SupportedCompositorTimings SurfaceEGL::getSupportedCompositorTimings() const
{
ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
egl::SupportedCompositorTimings result;
for (egl::CompositorTiming name : angle::AllEnums<egl::CompositorTiming>())
{
result[name] = mEGL->getCompositorTimingSupportedANDROID(mSurface, egl::ToEGLenum(name));
}
return result;
}
egl::Error SurfaceEGL::getCompositorTiming(EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const
{
ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
EGLBoolean success = mEGL->getCompositorTimingANDROID(mSurface, numTimestamps, names, values);
if (success == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglGetCompositorTimingANDROID failed");
}
return egl::NoError();
}
egl::Error SurfaceEGL::getNextFrameId(EGLuint64KHR *frameId) const
{
ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
EGLBoolean success = mEGL->getNextFrameIdANDROID(mSurface, frameId);
if (success == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglGetNextFrameId failed");
}
return egl::NoError();
}
egl::SupportedTimestamps SurfaceEGL::getSupportedTimestamps() const
{
ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
egl::SupportedTimestamps result;
for (egl::Timestamp timestamp : angle::AllEnums<egl::Timestamp>())
{
result[timestamp] =
mEGL->getFrameTimestampSupportedANDROID(mSurface, egl::ToEGLenum(timestamp));
}
return result;
}
egl::Error SurfaceEGL::getFrameTimestamps(EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const
{
ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
// The driver may return EGL_BAD_ACCESS at any time if the requested frame is no longer stored.
EGLBoolean success =
mEGL->getFrameTimestampsANDROID(mSurface, frameId, numTimestamps, timestamps, values);
if (success == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglGetFrameTimestampsANDROID failed");
}
return egl::NoError();
}
} // namespace rx
......@@ -43,6 +43,18 @@ class SurfaceEGL : public SurfaceGL
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
void setTimestampsEnabled(bool enabled) override;
egl::SupportedCompositorTimings getSupportedCompositorTimings() const override;
egl::Error getCompositorTiming(EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values) const override;
egl::Error getNextFrameId(EGLuint64KHR *frameId) const override;
egl::SupportedTimestamps getSupportedTimestamps() const override;
egl::Error getFrameTimestamps(EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const override;
EGLSurface getSurface() const;
protected:
......
......@@ -625,7 +625,41 @@ Error ValidateDisplayPointer(const Display *display)
return NoError();
}
} // namespace
bool ValidCompositorTimingName(CompositorTiming name)
{
switch (name)
{
case CompositorTiming::CompositeDeadline:
case CompositorTiming::CompositInterval:
case CompositorTiming::CompositToPresentLatency:
return true;
default:
return false;
}
}
bool ValidTimestampType(Timestamp timestamp)
{
switch (timestamp)
{
case Timestamp::RequestedPresentTime:
case Timestamp::RenderingCompleteTime:
case Timestamp::CompositionLatchTime:
case Timestamp::FirstCompositionStartTime:
case Timestamp::LastCompositionStartTime:
case Timestamp::FirstCompositionGPUFinishedTime:
case Timestamp::DisplayPresentTime:
case Timestamp::DequeueReadyTime:
case Timestamp::ReadsDoneTime:
return true;
default:
return false;
}
}
} // anonymous namespace
Error ValidateDisplay(const Display *display)
{
......@@ -3024,6 +3058,23 @@ Error ValidateSurfaceAttrib(const Display *display,
}
break;
case EGL_TIMESTAMPS_ANDROID:
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadAttribute() << "EGL_TIMESTAMPS_ANDROID cannot be used without "
"EGL_ANDROID_get_frame_timestamps support.";
}
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
break;
default:
return EglBadAttribute() << "Invalid value.";
}
break;
default:
return EglBadAttribute() << "Invalid surface attribute.";
}
......@@ -3117,6 +3168,14 @@ Error ValidateQuerySurface(const Display *display,
}
break;
case EGL_TIMESTAMPS_ANDROID:
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadAttribute() << "EGL_TIMESTAMPS_ANDROID cannot be used without "
"EGL_ANDROID_get_frame_timestamps support.";
}
break;
default:
return EglBadAttribute() << "Invalid surface attribute.";
}
......@@ -3225,4 +3284,169 @@ Error ValidateLabelObjectKHR(Thread *thread,
return NoError();
}
Error ValidateGetCompositorTimingSupportedANDROID(const Display *display,
const Surface *surface,
CompositorTiming name)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadDisplay() << "EGL_ANDROID_get_frame_timestamps extension is not available.";
}
ANGLE_TRY(ValidateSurface(display, surface));
if (!ValidCompositorTimingName(name))
{
return EglBadParameter() << "invalid timing name.";
}
return NoError();
}
Error ValidateGetCompositorTimingANDROID(const Display *display,
const Surface *surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadDisplay() << "EGL_ANDROID_get_frame_timestamps extension is not available.";
}
ANGLE_TRY(ValidateSurface(display, surface));
if (names == nullptr && numTimestamps > 0)
{
return EglBadParameter() << "names is NULL.";
}
if (values == nullptr && numTimestamps > 0)
{
return EglBadParameter() << "values is NULL.";
}
if (numTimestamps < 0)
{
return EglBadParameter() << "numTimestamps must be at least 0.";
}
for (EGLint i = 0; i < numTimestamps; i++)
{
CompositorTiming name = FromEGLenum<CompositorTiming>(names[i]);
if (!ValidCompositorTimingName(name))
{
return EglBadParameter() << "invalid compositor timing.";
}
if (!surface->getSupportedCompositorTimings().test(name))
{
return EglBadParameter() << "compositor timing not supported by surface.";
}
}
return NoError();
}
Error ValidateGetNextFrameIdANDROID(const Display *display,
const Surface *surface,
EGLuint64KHR *frameId)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadDisplay() << "EGL_ANDROID_get_frame_timestamps extension is not available.";
}
ANGLE_TRY(ValidateSurface(display, surface));
if (frameId == nullptr)
{
return EglBadParameter() << "frameId is NULL.";
}
return NoError();
}
Error ValidateGetFrameTimestampSupportedANDROID(const Display *display,
const Surface *surface,
Timestamp timestamp)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadDisplay() << "EGL_ANDROID_get_frame_timestamps extension is not available.";
}
ANGLE_TRY(ValidateSurface(display, surface));
if (!ValidTimestampType(timestamp))
{
return EglBadParameter() << "invalid timestamp type.";
}
return NoError();
}
Error ValidateGetFrameTimestampsANDROID(const Display *display,
const Surface *surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().getFrameTimestamps)
{
return EglBadDisplay() << "EGL_ANDROID_get_frame_timestamps extension is not available.";
}
ANGLE_TRY(ValidateSurface(display, surface));
if (!surface->isTimestampsEnabled())
{
return EglBadSurface() << "timestamp collection is not enabled for this surface.";
}
if (timestamps == nullptr && numTimestamps > 0)
{
return EglBadParameter() << "timestamps is NULL.";
}
if (values == nullptr && numTimestamps > 0)
{
return EglBadParameter() << "values is NULL.";
}
if (numTimestamps < 0)
{
return EglBadParameter() << "numTimestamps must be at least 0.";
}
for (EGLint i = 0; i < numTimestamps; i++)
{
Timestamp timestamp = FromEGLenum<Timestamp>(timestamps[i]);
if (!ValidTimestampType(timestamp))
{
return EglBadParameter() << "invalid timestamp type.";
}
if (!surface->getSupportedTimestamps().test(timestamp))
{
return EglBadParameter() << "timestamp not supported by surface.";
}
}
return NoError();
}
} // namespace egl
......@@ -248,6 +248,32 @@ Error ValidateLabelObjectKHR(Thread *thread,
EGLObjectKHR object,
EGLLabelKHR label);
// ANDROID_get_frame_timestamps
Error ValidateGetCompositorTimingSupportedANDROID(const Display *display,
const Surface *surface,
CompositorTiming name);
Error ValidateGetCompositorTimingANDROID(const Display *display,
const Surface *surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values);
Error ValidateGetNextFrameIdANDROID(const Display *display,
const Surface *surface,
EGLuint64KHR *frameId);
Error ValidateGetFrameTimestampSupportedANDROID(const Display *display,
const Surface *surface,
Timestamp timestamp);
Error ValidateGetFrameTimestampsANDROID(const Display *display,
const Surface *surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values);
} // namespace egl
#define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \
......
......@@ -518,4 +518,44 @@ void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
return egl::SetBlobCacheFuncsANDROID(dpy, set, get);
}
EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint name)
{
return egl::GetCompositorTimingSupportedANDROID(dpy, surface, name);
}
EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values)
{
return egl::GetCompositorTimingANDROID(dpy, surface, numTimestamps, names, values);
}
EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLuint64KHR *frameId)
{
return egl::GetNextFrameIdANDROID(dpy, surface, frameId);
}
EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint timestamp)
{
return egl::GetFrameTimestampSupportedANDROID(dpy, surface, timestamp);
}
EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values)
{
return egl::GetFrameTimestampsANDROID(dpy, surface, frameId, numTimestamps, timestamps, values);
}
} // extern "C"
......@@ -1135,7 +1135,7 @@ EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay dpy,
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR
"f, EGLenum objectType = 0x%X, EGLObjectKHR object = 0x%016" PRIxPTR
", EGLenum objectType = 0x%X, EGLObjectKHR object = 0x%016" PRIxPTR
", "
"EGLLabelKHR label = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, objectType, (uintptr_t)object, (uintptr_t)label);
......@@ -1161,4 +1161,125 @@ EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay dpy,
return EGL_SUCCESS;
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetCompositorTimingSupportedANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint name)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
", EGLint name = 0x%X)",
(uintptr_t)dpy, (uintptr_t)surface, name);
Display *display = static_cast<Display *>(dpy);
Surface *eglSurface = static_cast<Surface *>(surface);
Thread *thread = GetCurrentThread();
CompositorTiming nameInternal = FromEGLenum<CompositorTiming>(name);
ANGLE_EGL_TRY_RETURN(
thread, ValidateGetCompositorTimingSupportedANDROID(display, eglSurface, nameInternal),
"eglQueryTimestampSupportedANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
return eglSurface->getSupportedCompositorTimings().test(nameInternal);
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetCompositorTimingANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
", EGLint numTimestamps = %d, const EGLint *names = 0x%016" PRIxPTR
", EGLnsecsANDROID *values = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)surface, numTimestamps, (uintptr_t)names, (uintptr_t)values);
Display *display = static_cast<Display *>(dpy);
Surface *eglSurface = static_cast<Surface *>(surface);
Thread *thread = GetCurrentThread();
ANGLE_EGL_TRY_RETURN(
thread,
ValidateGetCompositorTimingANDROID(display, eglSurface, numTimestamps, names, values),
"eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->getCompositorTiming(numTimestamps, names, values),
"eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
return EGL_TRUE;
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetNextFrameIdANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLuint64KHR *frameId)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
", EGLuint64KHR *frameId = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)frameId);
Display *display = static_cast<Display *>(dpy);
Surface *eglSurface = static_cast<Surface *>(surface);
Thread *thread = GetCurrentThread();
ANGLE_EGL_TRY_RETURN(thread, ValidateGetNextFrameIdANDROID(display, eglSurface, frameId),
"eglGetNextFrameIdANDROID", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->getNextFrameId(frameId), "eglGetNextFrameIdANDROID",
GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
return EGL_TRUE;
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetFrameTimestampSupportedANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint timestamp)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
", EGLint timestamp = 0x%X)",
(uintptr_t)dpy, (uintptr_t)surface, timestamp);
Display *display = static_cast<Display *>(dpy);
Surface *eglSurface = static_cast<Surface *>(surface);
Thread *thread = GetCurrentThread();
Timestamp timestampInternal = FromEGLenum<Timestamp>(timestamp);
ANGLE_EGL_TRY_RETURN(
thread, ValidateGetFrameTimestampSupportedANDROID(display, eglSurface, timestampInternal),
"eglQueryTimestampSupportedANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
return eglSurface->getSupportedTimestamps().test(timestampInternal);
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetFrameTimestampsANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
", EGLuint64KHR frameId = %llu, EGLint numTimestamps = %d, const EGLint *timestamps = "
"0x%016" PRIxPTR ", EGLnsecsANDROID *values = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)surface, (unsigned long long)frameId, numTimestamps,
(uintptr_t)timestamps, (uintptr_t)values);
Display *display = static_cast<Display *>(dpy);
Surface *eglSurface = static_cast<Surface *>(surface);
Thread *thread = GetCurrentThread();
ANGLE_EGL_TRY_RETURN(thread,
ValidateGetFrameTimestampsANDROID(display, eglSurface, frameId,
numTimestamps, timestamps, values),
"eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
ANGLE_EGL_TRY_RETURN(
thread, eglSurface->getFrameTimestamps(frameId, numTimestamps, timestamps, values),
"eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
return EGL_TRUE;
}
} // namespace egl
......@@ -151,6 +151,32 @@ ANGLE_EXPORT EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay display,
EGLObjectKHR object,
EGLLabelKHR label);
// ANDROID_get_frame_timestamps
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetCompositorTimingSupportedANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint name);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetCompositorTimingANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint numTimestamps,
const EGLint *names,
EGLnsecsANDROID *values);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetNextFrameIdANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLuint64KHR *frameId);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetFrameTimestampSupportedANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLint timestamp);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetFrameTimestampsANDROID(EGLDisplay dpy,
EGLSurface surface,
EGLuint64KHR frameId,
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values);
} // namespace egl
#endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_
......@@ -54,6 +54,8 @@ ProcEntry g_procTable[] = {
{"eglDestroyStreamKHR", P(egl::DestroyStreamKHR)},
{"eglDestroySurface", P(egl::DestroySurface)},
{"eglDestroySync", P(egl::DestroySync)},
{"eglGetCompositorTimingANDROID", P(egl::GetCompositorTimingANDROID)},
{"eglGetCompositorTimingSupportedANDROID", P(egl::GetCompositorTimingSupportedANDROID)},
{"eglGetConfigAttrib", P(egl::GetConfigAttrib)},
{"eglGetConfigs", P(egl::GetConfigs)},
{"eglGetCurrentContext", P(egl::GetCurrentContext)},
......@@ -61,6 +63,9 @@ ProcEntry g_procTable[] = {
{"eglGetCurrentSurface", P(egl::GetCurrentSurface)},
{"eglGetDisplay", P(egl::GetDisplay)},
{"eglGetError", P(egl::GetError)},
{"eglGetFrameTimestampSupportedANDROID", P(egl::GetFrameTimestampSupportedANDROID)},
{"eglGetFrameTimestampsANDROID", P(egl::GetFrameTimestampsANDROID)},
{"eglGetNextFrameIdANDROID", P(egl::GetNextFrameIdANDROID)},
{"eglGetPlatformDisplay", P(egl::GetPlatformDisplay)},
{"eglGetPlatformDisplayEXT", P(egl::GetPlatformDisplayEXT)},
{"eglGetProcAddress", P(egl::GetProcAddress)},
......@@ -1268,5 +1273,5 @@ ProcEntry g_procTable[] = {
{"glWeightPointerOES", P(gl::WeightPointerOES)},
{"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}};
size_t g_numProcs = 1200;
size_t g_numProcs = 1205;
} // namespace egl
......@@ -879,6 +879,14 @@
"eglLabelObjectKHR"
],
"EGL_ANDROID_get_frame_timestamps": [
"eglGetCompositorTimingSupportedANDROID",
"eglGetCompositorTimingANDROID",
"eglGetNextFrameIdANDROID",
"eglGetFrameTimestampSupportedANDROID",
"eglGetFrameTimestampsANDROID"
],
"angle::Platform related entry points": [
"ANGLEGetDisplayPlatform",
"ANGLEResetDisplayPlatform"
......
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