Loading opengl/include/EGL/eglext.h +18 −0 Original line number Diff line number Diff line Loading @@ -621,6 +621,24 @@ typedef EGLAPI EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDRO #define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 #endif #ifndef EGL_ANDROID_get_frame_timestamps #define EGL_ANDROID_get_frame_timestamps 1 #define EGL_TIMESTAMPS_ANDROID 0x314D #define EGL_QUEUE_TIME_ANDROID 0x314E #define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x314F #define EGL_COMPOSITION_START_TIME_ANDROID 0x3430 #define EGL_COMPOSITION_FINISHED_TIME_ANDROID 0x3431 #define EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3432 #define EGL_READS_DONE_TIME_ANDROID 0x3433 #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); EGLAPI EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp); #else typedef EGLAPI EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); typedef EGLAPI EGLBoolean (EGLAPIENTRYP PFNEGLQUERYTIMESTAMPSUPPORTEDANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); #endif #endif #ifdef __cplusplus } #endif Loading opengl/libs/EGL/eglApi.cpp +113 −1 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ extern char const * const gBuiltinExtensionString = "EGL_KHR_swap_buffers_with_damage " "EGL_ANDROID_create_native_client_buffer " "EGL_ANDROID_front_buffer_auto_refresh " "EGL_ANDROID_get_frame_timestamps " ; extern char const * const gExtensionString = "EGL_KHR_image " // mandatory Loading Loading @@ -207,6 +208,12 @@ static const extention_map_t sExtensionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR }, { "eglCreateStreamFromFileDescriptorKHR", (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR }, // EGL_ANDROID_get_frame_timestamps { "eglGetFrameTimestampsANDROID", (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID }, { "eglQueryTimestampSupportedANDROID", (__eglMustCastToProperFunctionPointerType)&eglQueryTimestampSupportedANDROID }, }; /* Loading Loading @@ -1196,7 +1203,7 @@ EGLBoolean eglSurfaceAttrib( if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); egl_surface_t const * const s = get_surface(surface); egl_surface_t * const s = get_surface(surface); if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) { int err = native_window_set_auto_refresh(s->win.get(), Loading @@ -1205,6 +1212,11 @@ EGLBoolean eglSurfaceAttrib( setError(EGL_BAD_SURFACE, EGL_FALSE); } if (attribute == EGL_TIMESTAMPS_ANDROID) { s->enableTimestamps = value; return EGL_TRUE; } if (s->cnx->egl.eglSurfaceAttrib) { return s->cnx->egl.eglSurfaceAttrib( dp->disp.dpy, s->surface, attribute, value); Loading Loading @@ -1935,3 +1947,103 @@ EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, return EGL_FALSE; } EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values) { clearError(); const egl_display_ptr dp = validate_display(dpy); if (!dp) { setError(EGL_BAD_DISPLAY, EGL_FALSE); return EGL_FALSE; } SurfaceRef _s(dp.get(), surface); if (!_s.get()) { setError(EGL_BAD_SURFACE, EGL_FALSE); return EGL_FALSE; } egl_surface_t const * const s = get_surface(surface); if (!s->enableTimestamps) { setError(EGL_BAD_SURFACE, EGL_FALSE); return EGL_FALSE; } nsecs_t* postedTime = nullptr; nsecs_t* acquireTime = nullptr; nsecs_t* refreshStartTime = nullptr; nsecs_t* GLCompositionDoneTime = nullptr; nsecs_t* displayRetireTime = nullptr; nsecs_t* releaseTime = nullptr; for (int i = 0; i < numTimestamps; i++) { switch (timestamps[i]) { case EGL_QUEUE_TIME_ANDROID: postedTime = &values[i]; break; case EGL_RENDERING_COMPLETE_TIME_ANDROID: acquireTime = &values[i]; break; case EGL_COMPOSITION_START_TIME_ANDROID: refreshStartTime = &values[i]; break; case EGL_COMPOSITION_FINISHED_TIME_ANDROID: GLCompositionDoneTime = &values[i]; break; case EGL_DISPLAY_RETIRE_TIME_ANDROID: displayRetireTime = &values[i]; break; case EGL_READS_DONE_TIME_ANDROID: releaseTime = &values[i]; break; default: setError(EGL_BAD_PARAMETER, EGL_FALSE); return EGL_FALSE; } } status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo, postedTime, acquireTime, refreshStartTime, GLCompositionDoneTime, displayRetireTime, releaseTime); if (ret != NO_ERROR) { setError(EGL_BAD_ACCESS, EGL_FALSE); return EGL_FALSE; } return EGL_TRUE; } EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp) { clearError(); const egl_display_ptr dp = validate_display(dpy); if (!dp) { setError(EGL_BAD_DISPLAY, EGL_FALSE); return EGL_FALSE; } SurfaceRef _s(dp.get(), surface); if (!_s.get()) { setError(EGL_BAD_SURFACE, EGL_FALSE); return EGL_FALSE; } switch (timestamp) { case EGL_QUEUE_TIME_ANDROID: case EGL_RENDERING_COMPLETE_TIME_ANDROID: case EGL_COMPOSITION_START_TIME_ANDROID: case EGL_COMPOSITION_FINISHED_TIME_ANDROID: case EGL_DISPLAY_RETIRE_TIME_ANDROID: case EGL_READS_DONE_TIME_ANDROID: return EGL_TRUE; default: return EGL_FALSE; } } opengl/libs/EGL/egl_object.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, egl_connection_t const* cnx) : egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx), connected(true) enableTimestamps(false), connected(true) { if (win) { getDisplay()->onWindowSurfaceCreated(); Loading opengl/libs/EGL/egl_object.h +1 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ public: EGLConfig config; sp<ANativeWindow> win; egl_connection_t const* cnx; bool enableTimestamps; private: bool connected; void disconnect(); Loading opengl/specs/EGL_ANDROID_get_frame_timestamps.txt 0 → 100644 +145 −0 Original line number Diff line number Diff line Name ANDROID_get_frame_timestamps Name Strings EGL_ANDROID_get_frame_timestamps Contributors Pablo Ceballos Contact Pablo Ceballos, Google Inc. (pceballos 'at' google.com) Status Draft Version Version 1, May 31, 2016 Number EGL Extension #XXX Dependencies Requires EGL 1.2 This extension is written against the wording of the EGL 1.5 Specification Overview This extension allows querying various timestamps related to the composition and display of window surfaces. Some examples of how this might be used: - The display retire time can be used to calculate end-to-end latency of the entire graphics pipeline. - The queue time and rendering complete time can be used to determine how long the application's rendering took to complete. Likewise, the composition start time and finish time can be used to determine how long the compositor's rendering work took. In combination these can be used to help determine if the system is GPU or CPU bound. New Types /* * EGLnsecsANDROID is a signed integer type for representing a time in * nanoseconds. */ #include <khrplatform.h> typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; New Procedures and Functions EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp); New Tokens EGL_TIMESTAMPS_ANDROID 0x314D EGL_QUEUE_TIME_ANDROID 0x314E EGL_RENDERING_COMPLETE_TIME_ANDROID 0x314F EGL_COMPOSITION_START_TIME_ANDROID 0x3430 EGL_COMPOSITION_FINISHED_TIME_ANDROID 0x3431 EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3432 EGL_READS_DONE_TIME_ANDROID 0x3433 Add to the list of supported tokens for eglSurfaceAttrib in section 3.5.6 "Surface Attributes", page 43: If attribute is EGL_TIMESTAMPS_ANDROID, then values specifies whether to enable/disable timestamp collection for this surface. A value of EGL_TRUE enables timestamp collection, while a value of EGL_FALSE disables it. The initial value is false. If surface is not a window surface this has no effect. Changes to Chapter 3 of the EGL 1.5 Specification (EGL Functions and Errors) Add a new subsection under Section 3, "3.13 Composition and Display Timestamps The function EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); allows querying various timestamps related to the composition and display of a window surface. The framesAgo parameter indicates how many frames before the last posted frame to query. So a value of zero would indicate that the query is for the last posted frame. Note that the implementation maintains a limited history of timestamp data. If a query is made for a frame whose timestamp history no longer exists then EGL_BAD_ACCESS is generated. If timestamp collection has not been enabled for the surface then EGL_BAD_SURFACE is generated. Timestamps for events that will not occur or have not yet occurred will be zero. Timestamp queries that are not supported will generate an EGL_BAD_PARAMETER error. If any error is generated the function will return EGL_FALSE. The eglGetFrameTimestampsANDROID function takes an array of timestamps to query and returns timestamps in the corresponding indices of the values array. The possible timestamps that can be queried are: - EGL_QUEUE_TIME_ANDROID - The time this frame was queued by the application. - EGL_RENDERING_COMPLETE_TIME_ANDROID - The time when all of the application's rendering to the surface was completed. - EGL_COMPOSITION_START_TIME_ANDROID - The time at which the compositor began preparing composition for this frame. - EGL_COMPOSITION_FINISHED_TIME_ANDROID - The time at which the compositor's rendering work for this frame finished. This will be zero if composition was handled by the display and the compositor didn't do any rendering. - EGL_DISPLAY_RETIRE_TIME_ANDROID - The time at which this frame was replaced by the next frame on-screen. - EGL_READS_DONE_TIME_ANDROID - The time at which all reads for the purpose of display/composition were completed for this frame. Not all implementations may support all off the above timestamp queries. The function EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp); allows querying which timestamps are supported on the implementation." Issues None Revision History #1 (Pablo Ceballos, May 31, 2016) - Initial draft. Loading
opengl/include/EGL/eglext.h +18 −0 Original line number Diff line number Diff line Loading @@ -621,6 +621,24 @@ typedef EGLAPI EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDRO #define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 #endif #ifndef EGL_ANDROID_get_frame_timestamps #define EGL_ANDROID_get_frame_timestamps 1 #define EGL_TIMESTAMPS_ANDROID 0x314D #define EGL_QUEUE_TIME_ANDROID 0x314E #define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x314F #define EGL_COMPOSITION_START_TIME_ANDROID 0x3430 #define EGL_COMPOSITION_FINISHED_TIME_ANDROID 0x3431 #define EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3432 #define EGL_READS_DONE_TIME_ANDROID 0x3433 #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); EGLAPI EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp); #else typedef EGLAPI EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); typedef EGLAPI EGLBoolean (EGLAPIENTRYP PFNEGLQUERYTIMESTAMPSUPPORTEDANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); #endif #endif #ifdef __cplusplus } #endif Loading
opengl/libs/EGL/eglApi.cpp +113 −1 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ extern char const * const gBuiltinExtensionString = "EGL_KHR_swap_buffers_with_damage " "EGL_ANDROID_create_native_client_buffer " "EGL_ANDROID_front_buffer_auto_refresh " "EGL_ANDROID_get_frame_timestamps " ; extern char const * const gExtensionString = "EGL_KHR_image " // mandatory Loading Loading @@ -207,6 +208,12 @@ static const extention_map_t sExtensionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR }, { "eglCreateStreamFromFileDescriptorKHR", (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR }, // EGL_ANDROID_get_frame_timestamps { "eglGetFrameTimestampsANDROID", (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID }, { "eglQueryTimestampSupportedANDROID", (__eglMustCastToProperFunctionPointerType)&eglQueryTimestampSupportedANDROID }, }; /* Loading Loading @@ -1196,7 +1203,7 @@ EGLBoolean eglSurfaceAttrib( if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); egl_surface_t const * const s = get_surface(surface); egl_surface_t * const s = get_surface(surface); if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) { int err = native_window_set_auto_refresh(s->win.get(), Loading @@ -1205,6 +1212,11 @@ EGLBoolean eglSurfaceAttrib( setError(EGL_BAD_SURFACE, EGL_FALSE); } if (attribute == EGL_TIMESTAMPS_ANDROID) { s->enableTimestamps = value; return EGL_TRUE; } if (s->cnx->egl.eglSurfaceAttrib) { return s->cnx->egl.eglSurfaceAttrib( dp->disp.dpy, s->surface, attribute, value); Loading Loading @@ -1935,3 +1947,103 @@ EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, return EGL_FALSE; } EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values) { clearError(); const egl_display_ptr dp = validate_display(dpy); if (!dp) { setError(EGL_BAD_DISPLAY, EGL_FALSE); return EGL_FALSE; } SurfaceRef _s(dp.get(), surface); if (!_s.get()) { setError(EGL_BAD_SURFACE, EGL_FALSE); return EGL_FALSE; } egl_surface_t const * const s = get_surface(surface); if (!s->enableTimestamps) { setError(EGL_BAD_SURFACE, EGL_FALSE); return EGL_FALSE; } nsecs_t* postedTime = nullptr; nsecs_t* acquireTime = nullptr; nsecs_t* refreshStartTime = nullptr; nsecs_t* GLCompositionDoneTime = nullptr; nsecs_t* displayRetireTime = nullptr; nsecs_t* releaseTime = nullptr; for (int i = 0; i < numTimestamps; i++) { switch (timestamps[i]) { case EGL_QUEUE_TIME_ANDROID: postedTime = &values[i]; break; case EGL_RENDERING_COMPLETE_TIME_ANDROID: acquireTime = &values[i]; break; case EGL_COMPOSITION_START_TIME_ANDROID: refreshStartTime = &values[i]; break; case EGL_COMPOSITION_FINISHED_TIME_ANDROID: GLCompositionDoneTime = &values[i]; break; case EGL_DISPLAY_RETIRE_TIME_ANDROID: displayRetireTime = &values[i]; break; case EGL_READS_DONE_TIME_ANDROID: releaseTime = &values[i]; break; default: setError(EGL_BAD_PARAMETER, EGL_FALSE); return EGL_FALSE; } } status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo, postedTime, acquireTime, refreshStartTime, GLCompositionDoneTime, displayRetireTime, releaseTime); if (ret != NO_ERROR) { setError(EGL_BAD_ACCESS, EGL_FALSE); return EGL_FALSE; } return EGL_TRUE; } EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp) { clearError(); const egl_display_ptr dp = validate_display(dpy); if (!dp) { setError(EGL_BAD_DISPLAY, EGL_FALSE); return EGL_FALSE; } SurfaceRef _s(dp.get(), surface); if (!_s.get()) { setError(EGL_BAD_SURFACE, EGL_FALSE); return EGL_FALSE; } switch (timestamp) { case EGL_QUEUE_TIME_ANDROID: case EGL_RENDERING_COMPLETE_TIME_ANDROID: case EGL_COMPOSITION_START_TIME_ANDROID: case EGL_COMPOSITION_FINISHED_TIME_ANDROID: case EGL_DISPLAY_RETIRE_TIME_ANDROID: case EGL_READS_DONE_TIME_ANDROID: return EGL_TRUE; default: return EGL_FALSE; } }
opengl/libs/EGL/egl_object.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, egl_connection_t const* cnx) : egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx), connected(true) enableTimestamps(false), connected(true) { if (win) { getDisplay()->onWindowSurfaceCreated(); Loading
opengl/libs/EGL/egl_object.h +1 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ public: EGLConfig config; sp<ANativeWindow> win; egl_connection_t const* cnx; bool enableTimestamps; private: bool connected; void disconnect(); Loading
opengl/specs/EGL_ANDROID_get_frame_timestamps.txt 0 → 100644 +145 −0 Original line number Diff line number Diff line Name ANDROID_get_frame_timestamps Name Strings EGL_ANDROID_get_frame_timestamps Contributors Pablo Ceballos Contact Pablo Ceballos, Google Inc. (pceballos 'at' google.com) Status Draft Version Version 1, May 31, 2016 Number EGL Extension #XXX Dependencies Requires EGL 1.2 This extension is written against the wording of the EGL 1.5 Specification Overview This extension allows querying various timestamps related to the composition and display of window surfaces. Some examples of how this might be used: - The display retire time can be used to calculate end-to-end latency of the entire graphics pipeline. - The queue time and rendering complete time can be used to determine how long the application's rendering took to complete. Likewise, the composition start time and finish time can be used to determine how long the compositor's rendering work took. In combination these can be used to help determine if the system is GPU or CPU bound. New Types /* * EGLnsecsANDROID is a signed integer type for representing a time in * nanoseconds. */ #include <khrplatform.h> typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; New Procedures and Functions EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp); New Tokens EGL_TIMESTAMPS_ANDROID 0x314D EGL_QUEUE_TIME_ANDROID 0x314E EGL_RENDERING_COMPLETE_TIME_ANDROID 0x314F EGL_COMPOSITION_START_TIME_ANDROID 0x3430 EGL_COMPOSITION_FINISHED_TIME_ANDROID 0x3431 EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3432 EGL_READS_DONE_TIME_ANDROID 0x3433 Add to the list of supported tokens for eglSurfaceAttrib in section 3.5.6 "Surface Attributes", page 43: If attribute is EGL_TIMESTAMPS_ANDROID, then values specifies whether to enable/disable timestamp collection for this surface. A value of EGL_TRUE enables timestamp collection, while a value of EGL_FALSE disables it. The initial value is false. If surface is not a window surface this has no effect. Changes to Chapter 3 of the EGL 1.5 Specification (EGL Functions and Errors) Add a new subsection under Section 3, "3.13 Composition and Display Timestamps The function EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); allows querying various timestamps related to the composition and display of a window surface. The framesAgo parameter indicates how many frames before the last posted frame to query. So a value of zero would indicate that the query is for the last posted frame. Note that the implementation maintains a limited history of timestamp data. If a query is made for a frame whose timestamp history no longer exists then EGL_BAD_ACCESS is generated. If timestamp collection has not been enabled for the surface then EGL_BAD_SURFACE is generated. Timestamps for events that will not occur or have not yet occurred will be zero. Timestamp queries that are not supported will generate an EGL_BAD_PARAMETER error. If any error is generated the function will return EGL_FALSE. The eglGetFrameTimestampsANDROID function takes an array of timestamps to query and returns timestamps in the corresponding indices of the values array. The possible timestamps that can be queried are: - EGL_QUEUE_TIME_ANDROID - The time this frame was queued by the application. - EGL_RENDERING_COMPLETE_TIME_ANDROID - The time when all of the application's rendering to the surface was completed. - EGL_COMPOSITION_START_TIME_ANDROID - The time at which the compositor began preparing composition for this frame. - EGL_COMPOSITION_FINISHED_TIME_ANDROID - The time at which the compositor's rendering work for this frame finished. This will be zero if composition was handled by the display and the compositor didn't do any rendering. - EGL_DISPLAY_RETIRE_TIME_ANDROID - The time at which this frame was replaced by the next frame on-screen. - EGL_READS_DONE_TIME_ANDROID - The time at which all reads for the purpose of display/composition were completed for this frame. Not all implementations may support all off the above timestamp queries. The function EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp); allows querying which timestamps are supported on the implementation." Issues None Revision History #1 (Pablo Ceballos, May 31, 2016) - Initial draft.