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 @@ ...@@ -84,17 +84,17 @@
"Vulkan mandatory format support table:src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json": "Vulkan mandatory format support table:src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json":
"fa2bd54c1bb0ab2cf1d386061a4bc5c5", "fa2bd54c1bb0ab2cf1d386061a4bc5c5",
"Vulkan mandatory format support table:third_party/vulkan-headers/src/registry/vk.xml": "Vulkan mandatory format support table:third_party/vulkan-headers/src/registry/vk.xml":
"36d0ec2733888108d2acb56134df6b22", "cd73387d7cdaa5d403eab411194342b3",
"packed enum:src/common/gen_packed_gl_enums.py": "packed enum:src/common/gen_packed_gl_enums.py":
"a9b1c38b4e4d8a1038e743be323f1a51", "a9b1c38b4e4d8a1038e743be323f1a51",
"packed enum:src/common/packed_egl_enums.json": "packed enum:src/common/packed_egl_enums.json":
"0389a8a565ccee99163bd0cf3ca146d3", "5f591d220ee53b6e54a27d1523a3ab79",
"packed enum:src/common/packed_gl_enums.json": "packed enum:src/common/packed_gl_enums.json":
"7338a2a11c679aeb8efe2b415dbd4810", "7338a2a11c679aeb8efe2b415dbd4810",
"proc table:src/libGLESv2/gen_proc_table.py": "proc table:src/libGLESv2/gen_proc_table.py":
"027bfd5a8a8dffe91f492bf199029cde", "027bfd5a8a8dffe91f492bf199029cde",
"proc table:src/libGLESv2/proc_table_data.json": "proc table:src/libGLESv2/proc_table_data.json":
"9bc7a48223f99e16f11b14ccaeedb09d", "78d7d15862b563adf3fe957672ca1845",
"uniform type:src/common/gen_uniform_type_table.py": "uniform type:src/common/gen_uniform_type_table.py":
"59cb4ffd0f584c4bd37f2f4ff59a2b93" "59cb4ffd0f584c4bd37f2f4ff59a2b93"
} }
\ No newline at end of file
...@@ -16,6 +16,38 @@ namespace egl ...@@ -16,6 +16,38 @@ namespace egl
{ {
template <> 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) MessageType FromEGLenum<MessageType>(EGLenum from)
{ {
switch (from) switch (from)
...@@ -131,4 +163,60 @@ EGLenum ToEGLenum(TextureFormat 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 } // namespace egl
...@@ -24,6 +24,20 @@ namespace egl ...@@ -24,6 +24,20 @@ namespace egl
template <typename Enum> template <typename Enum>
Enum FromEGLenum(EGLenum from); 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 enum class MessageType : uint8_t
{ {
Critical = 0, Critical = 0,
...@@ -71,6 +85,26 @@ template <> ...@@ -71,6 +85,26 @@ template <>
TextureFormat FromEGLenum<TextureFormat>(EGLenum from); TextureFormat FromEGLenum<TextureFormat>(EGLenum from);
EGLenum ToEGLenum(TextureFormat 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 } // namespace egl
#endif // COMMON_PACKEDEGLENUMS_AUTOGEN_H_ #endif // COMMON_PACKEDEGLENUMS_AUTOGEN_H_
...@@ -21,5 +21,23 @@ ...@@ -21,5 +21,23 @@
"Error": "EGL_DEBUG_MSG_ERROR_KHR", "Error": "EGL_DEBUG_MSG_ERROR_KHR",
"Warn": "EGL_DEBUG_MSG_WARN_KHR", "Warn": "EGL_DEBUG_MSG_WARN_KHR",
"Info": "EGL_DEBUG_MSG_INFO_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() ...@@ -1362,7 +1362,8 @@ DisplayExtensions::DisplayExtensions()
createContextExtensionsEnabled(false), createContextExtensionsEnabled(false),
presentationTime(false), presentationTime(false),
blobCache(false), blobCache(false),
imageNativeBuffer(false) imageNativeBuffer(false),
getFrameTimestamps(false)
{ {
} }
...@@ -1413,6 +1414,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1413,6 +1414,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings); InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings);
InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings); InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings);
InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings); InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings);
InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings);
// TODO(jmadill): Enable this when complete. // TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on // clang-format on
......
...@@ -813,6 +813,9 @@ struct DisplayExtensions ...@@ -813,6 +813,9 @@ struct DisplayExtensions
// EGL_ANDROID_image_native_buffer // EGL_ANDROID_image_native_buffer
bool imageNativeBuffer; bool imageNativeBuffer;
// EGL_ANDROID_get_frame_timestamps
bool getFrameTimestamps;
}; };
struct DeviceExtensions struct DeviceExtensions
......
...@@ -26,7 +26,7 @@ namespace egl ...@@ -26,7 +26,7 @@ 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) : label(nullptr), config(configIn), attributes(attributesIn), timestampsEnabled(false)
{ {
} }
...@@ -169,6 +169,12 @@ Error Surface::initialize(const Display *display) ...@@ -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(); return NoError();
} }
...@@ -481,6 +487,47 @@ void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState ...@@ -481,6 +487,47 @@ void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState
mInitState = 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, WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
const egl::Config *config, const egl::Config *config,
EGLNativeWindowType window, EGLNativeWindowType window,
......
...@@ -40,6 +40,9 @@ namespace egl ...@@ -40,6 +40,9 @@ namespace egl
class Display; class Display;
struct Config; struct Config;
using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>;
using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>;
struct SurfaceState final : private angle::NonCopyable struct SurfaceState final : private angle::NonCopyable
{ {
SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn); SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
...@@ -47,6 +50,10 @@ struct SurfaceState final : private angle::NonCopyable ...@@ -47,6 +50,10 @@ struct SurfaceState final : private angle::NonCopyable
EGLLabelKHR label; EGLLabelKHR label;
const egl::Config *config; const egl::Config *config;
AttributeMap attributes; AttributeMap attributes;
bool timestampsEnabled;
SupportedCompositorTiming supportedCompositorTimings;
SupportedTimestamps supportedTimestamps;
}; };
class Surface : public LabeledObject, public gl::FramebufferAttachmentObject class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
...@@ -140,6 +147,22 @@ 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; } 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: protected:
Surface(EGLint surfaceType, Surface(EGLint surfaceType,
const egl::Config *config, const egl::Config *config,
......
...@@ -2988,6 +2988,9 @@ void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value) ...@@ -2988,6 +2988,9 @@ void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value)
case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
*value = surface->isRobustResourceInitEnabled(); *value = surface->isRobustResourceInitEnabled();
break; break;
case EGL_TIMESTAMPS_ANDROID:
*value = surface->isTimestampsEnabled();
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -3013,6 +3016,9 @@ void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value) ...@@ -3013,6 +3016,9 @@ void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
case EGL_HEIGHT: case EGL_HEIGHT:
surface->setFixedHeight(value); surface->setFixedHeight(value);
break; break;
case EGL_TIMESTAMPS_ANDROID:
surface->setTimestampsEnabled(value != EGL_FALSE);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -34,6 +34,9 @@ class Display; ...@@ -34,6 +34,9 @@ class Display;
struct Config; struct Config;
struct SurfaceState; struct SurfaceState;
class Thread; class Thread;
using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>;
using SupportedCompositorTimings = angle::PackedEnumBitSet<CompositorTiming>;
} }
namespace rx namespace rx
...@@ -58,22 +61,22 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl ...@@ -58,22 +61,22 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl
EGLint width, EGLint width,
EGLint height) = 0; EGLint height) = 0;
virtual egl::Error setPresentationTime(EGLnsecsANDROID time); 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, virtual egl::Error bindTexImage(const gl::Context *context,
gl::Texture *texture, gl::Texture *texture,
EGLint buffer) = 0; EGLint buffer) = 0;
virtual egl::Error releaseTexImage(const gl::Context *context, 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 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 setFixedWidth(EGLint width);
virtual void setFixedHeight(EGLint height); virtual void setFixedHeight(EGLint height);
// width and height can change with client window resizing // 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 getHeight() const = 0;
virtual EGLint isPostSubBufferSupported() 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. // Used to query color format from pbuffers created from D3D textures.
virtual const angle::Format *getD3DTextureColorFormat() const virtual const angle::Format *getD3DTextureColorFormat() const
...@@ -82,11 +85,44 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl ...@@ -82,11 +85,44 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl
return nullptr; 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: protected:
const egl::SurfaceState &mState; 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 ...@@ -112,8 +112,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->createContextRobustness = outExtensions->createContextRobustness =
mEGL->hasExtension("EGL_EXT_create_context_robustness"); mEGL->hasExtension("EGL_EXT_create_context_robustness");
outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented
outExtensions->presentationTime = mEGL->hasExtension("EGL_ANDROID_presentation_time"); outExtensions->presentationTime = mEGL->hasExtension("EGL_ANDROID_presentation_time");
// Contexts are virtualized so textures can be shared globally // Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true; outExtensions->displayTextureShareGroup = true;
...@@ -133,6 +133,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -133,6 +133,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->imageNativeBuffer = mEGL->hasExtension("EGL_ANDROID_image_native_buffer"); outExtensions->imageNativeBuffer = mEGL->hasExtension("EGL_ANDROID_image_native_buffer");
outExtensions->getFrameTimestamps = mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps");
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#include <algorithm> #include <algorithm>
#include "common/string_utils.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h" #include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
#include "common/string_utils.h"
namespace namespace
{ {
...@@ -54,6 +54,7 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -54,6 +54,7 @@ struct FunctionsEGL::EGLDispatchTable
bindTexImagePtr(nullptr), bindTexImagePtr(nullptr),
releaseTexImagePtr(nullptr), releaseTexImagePtr(nullptr),
surfaceAttribPtr(nullptr),
swapIntervalPtr(nullptr), swapIntervalPtr(nullptr),
createImageKHRPtr(nullptr), createImageKHRPtr(nullptr),
...@@ -68,7 +69,13 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -68,7 +69,13 @@ struct FunctionsEGL::EGLDispatchTable
presentationTimeANDROIDPtr(nullptr), presentationTimeANDROIDPtr(nullptr),
setBlobCacheFuncsANDROIDPtr(nullptr) setBlobCacheFuncsANDROIDPtr(nullptr),
getCompositorTimingSupportedANDROIDPtr(nullptr),
getCompositorTimingANDROIDPtr(nullptr),
getNextFrameIdANDROIDPtr(nullptr),
getFrameTimestampSupportedANDROIDPtr(nullptr),
getFrameTimestampsANDROIDPtr(nullptr)
{ {
} }
...@@ -93,6 +100,7 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -93,6 +100,7 @@ struct FunctionsEGL::EGLDispatchTable
// 1.1 // 1.1
PFNEGLBINDTEXIMAGEPROC bindTexImagePtr; PFNEGLBINDTEXIMAGEPROC bindTexImagePtr;
PFNEGLRELEASETEXIMAGEPROC releaseTexImagePtr; PFNEGLRELEASETEXIMAGEPROC releaseTexImagePtr;
PFNEGLSURFACEATTRIBPROC surfaceAttribPtr;
PFNEGLSWAPINTERVALPROC swapIntervalPtr; PFNEGLSWAPINTERVALPROC swapIntervalPtr;
// EGL_KHR_image // EGL_KHR_image
...@@ -113,6 +121,13 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -113,6 +121,13 @@ struct FunctionsEGL::EGLDispatchTable
// EGL_ANDROID_blob_cache // EGL_ANDROID_blob_cache
PFNEGLSETBLOBCACHEFUNCSANDROIDPROC setBlobCacheFuncsANDROIDPtr; PFNEGLSETBLOBCACHEFUNCSANDROIDPROC setBlobCacheFuncsANDROIDPtr;
// EGL_ANDROID_get_frame_timestamps
PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC getCompositorTimingSupportedANDROIDPtr;
PFNEGLGETCOMPOSITORTIMINGANDROIDPROC getCompositorTimingANDROIDPtr;
PFNEGLGETNEXTFRAMEIDANDROIDPROC getNextFrameIdANDROIDPtr;
PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC getFrameTimestampSupportedANDROIDPtr;
PFNEGLGETFRAMETIMESTAMPSANDROIDPROC getFrameTimestampsANDROIDPtr;
}; };
FunctionsEGL::FunctionsEGL() FunctionsEGL::FunctionsEGL()
...@@ -152,6 +167,7 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay) ...@@ -152,6 +167,7 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindTexImagePtr, eglBindTexImage); ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindTexImagePtr, eglBindTexImage);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->releaseTexImagePtr, eglReleaseTexImage); ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->releaseTexImagePtr, eglReleaseTexImage);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->surfaceAttribPtr, eglSurfaceAttrib);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalPtr, eglSwapInterval); ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalPtr, eglSwapInterval);
mEGLDisplay = mFnPtrs->getDisplayPtr(nativeDisplay); mEGLDisplay = mFnPtrs->getDisplayPtr(nativeDisplay);
...@@ -207,6 +223,19 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay) ...@@ -207,6 +223,19 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->setBlobCacheFuncsANDROIDPtr, eglSetBlobCacheFuncsANDROID); 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 #undef ANGLE_GET_PROC_OR_ERROR
return egl::NoError(); return egl::NoError();
...@@ -330,6 +359,11 @@ EGLBoolean FunctionsEGL::releaseTexImage(EGLSurface surface, EGLint buffer) cons ...@@ -330,6 +359,11 @@ EGLBoolean FunctionsEGL::releaseTexImage(EGLSurface surface, EGLint buffer) cons
return mFnPtrs->releaseTexImagePtr(mEGLDisplay, surface, buffer); 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 EGLBoolean FunctionsEGL::swapInterval(EGLint interval) const
{ {
return mFnPtrs->swapIntervalPtr(mEGLDisplay, interval); return mFnPtrs->swapIntervalPtr(mEGLDisplay, interval);
...@@ -385,4 +419,40 @@ void FunctionsEGL::setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set, ...@@ -385,4 +419,40 @@ void FunctionsEGL::setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set,
{ {
return mFnPtrs->setBlobCacheFuncsANDROIDPtr(mEGLDisplay, set, get); 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 } // namespace rx
...@@ -62,6 +62,7 @@ class FunctionsEGL ...@@ -62,6 +62,7 @@ class FunctionsEGL
EGLBoolean bindTexImage(EGLSurface surface, EGLint buffer) const; EGLBoolean bindTexImage(EGLSurface surface, EGLint buffer) const;
EGLBoolean releaseTexImage(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; EGLBoolean swapInterval(EGLint interval) const;
EGLImageKHR createImageKHR(EGLContext context, EGLImageKHR createImageKHR(EGLContext context,
...@@ -81,6 +82,19 @@ class FunctionsEGL ...@@ -81,6 +82,19 @@ class FunctionsEGL
void setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) const; 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: private:
// So as to isolate from angle we do not include angleutils.h and cannot // So as to isolate 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.
......
...@@ -156,4 +156,84 @@ EGLSurface SurfaceEGL::getSurface() const ...@@ -156,4 +156,84 @@ EGLSurface SurfaceEGL::getSurface() const
return mSurface; 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 } // namespace rx
...@@ -43,6 +43,18 @@ class SurfaceEGL : public SurfaceGL ...@@ -43,6 +43,18 @@ class SurfaceEGL : public SurfaceGL
EGLint isPostSubBufferSupported() const override; EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() 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; EGLSurface getSurface() const;
protected: protected:
......
...@@ -625,7 +625,41 @@ Error ValidateDisplayPointer(const Display *display) ...@@ -625,7 +625,41 @@ Error ValidateDisplayPointer(const Display *display)
return NoError(); 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) Error ValidateDisplay(const Display *display)
{ {
...@@ -3024,6 +3058,23 @@ Error ValidateSurfaceAttrib(const Display *display, ...@@ -3024,6 +3058,23 @@ Error ValidateSurfaceAttrib(const Display *display,
} }
break; 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: default:
return EglBadAttribute() << "Invalid surface attribute."; return EglBadAttribute() << "Invalid surface attribute.";
} }
...@@ -3117,6 +3168,14 @@ Error ValidateQuerySurface(const Display *display, ...@@ -3117,6 +3168,14 @@ Error ValidateQuerySurface(const Display *display,
} }
break; 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: default:
return EglBadAttribute() << "Invalid surface attribute."; return EglBadAttribute() << "Invalid surface attribute.";
} }
...@@ -3225,4 +3284,169 @@ Error ValidateLabelObjectKHR(Thread *thread, ...@@ -3225,4 +3284,169 @@ Error ValidateLabelObjectKHR(Thread *thread,
return NoError(); 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 } // namespace egl
...@@ -248,6 +248,32 @@ Error ValidateLabelObjectKHR(Thread *thread, ...@@ -248,6 +248,32 @@ Error ValidateLabelObjectKHR(Thread *thread,
EGLObjectKHR object, EGLObjectKHR object,
EGLLabelKHR label); 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 } // namespace egl
#define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \ #define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \
......
...@@ -518,4 +518,44 @@ void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, ...@@ -518,4 +518,44 @@ void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
return egl::SetBlobCacheFuncsANDROID(dpy, set, get); 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" } // extern "C"
...@@ -1135,7 +1135,7 @@ EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay dpy, ...@@ -1135,7 +1135,7 @@ EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay dpy,
{ {
ANGLE_SCOPED_GLOBAL_LOCK(); ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR 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 ")", "EGLLabelKHR label = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, objectType, (uintptr_t)object, (uintptr_t)label); (uintptr_t)dpy, objectType, (uintptr_t)object, (uintptr_t)label);
...@@ -1161,4 +1161,125 @@ EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay dpy, ...@@ -1161,4 +1161,125 @@ EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay dpy,
return EGL_SUCCESS; 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 } // namespace egl
...@@ -151,6 +151,32 @@ ANGLE_EXPORT EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay display, ...@@ -151,6 +151,32 @@ ANGLE_EXPORT EGLint EGLAPIENTRY LabelObjectKHR(EGLDisplay display,
EGLObjectKHR object, EGLObjectKHR object,
EGLLabelKHR label); 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 } // namespace egl
#endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_ #endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_
...@@ -54,6 +54,8 @@ ProcEntry g_procTable[] = { ...@@ -54,6 +54,8 @@ ProcEntry g_procTable[] = {
{"eglDestroyStreamKHR", P(egl::DestroyStreamKHR)}, {"eglDestroyStreamKHR", P(egl::DestroyStreamKHR)},
{"eglDestroySurface", P(egl::DestroySurface)}, {"eglDestroySurface", P(egl::DestroySurface)},
{"eglDestroySync", P(egl::DestroySync)}, {"eglDestroySync", P(egl::DestroySync)},
{"eglGetCompositorTimingANDROID", P(egl::GetCompositorTimingANDROID)},
{"eglGetCompositorTimingSupportedANDROID", P(egl::GetCompositorTimingSupportedANDROID)},
{"eglGetConfigAttrib", P(egl::GetConfigAttrib)}, {"eglGetConfigAttrib", P(egl::GetConfigAttrib)},
{"eglGetConfigs", P(egl::GetConfigs)}, {"eglGetConfigs", P(egl::GetConfigs)},
{"eglGetCurrentContext", P(egl::GetCurrentContext)}, {"eglGetCurrentContext", P(egl::GetCurrentContext)},
...@@ -61,6 +63,9 @@ ProcEntry g_procTable[] = { ...@@ -61,6 +63,9 @@ ProcEntry g_procTable[] = {
{"eglGetCurrentSurface", P(egl::GetCurrentSurface)}, {"eglGetCurrentSurface", P(egl::GetCurrentSurface)},
{"eglGetDisplay", P(egl::GetDisplay)}, {"eglGetDisplay", P(egl::GetDisplay)},
{"eglGetError", P(egl::GetError)}, {"eglGetError", P(egl::GetError)},
{"eglGetFrameTimestampSupportedANDROID", P(egl::GetFrameTimestampSupportedANDROID)},
{"eglGetFrameTimestampsANDROID", P(egl::GetFrameTimestampsANDROID)},
{"eglGetNextFrameIdANDROID", P(egl::GetNextFrameIdANDROID)},
{"eglGetPlatformDisplay", P(egl::GetPlatformDisplay)}, {"eglGetPlatformDisplay", P(egl::GetPlatformDisplay)},
{"eglGetPlatformDisplayEXT", P(egl::GetPlatformDisplayEXT)}, {"eglGetPlatformDisplayEXT", P(egl::GetPlatformDisplayEXT)},
{"eglGetProcAddress", P(egl::GetProcAddress)}, {"eglGetProcAddress", P(egl::GetProcAddress)},
...@@ -1268,5 +1273,5 @@ ProcEntry g_procTable[] = { ...@@ -1268,5 +1273,5 @@ ProcEntry g_procTable[] = {
{"glWeightPointerOES", P(gl::WeightPointerOES)}, {"glWeightPointerOES", P(gl::WeightPointerOES)},
{"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}}; {"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}};
size_t g_numProcs = 1200; size_t g_numProcs = 1205;
} // namespace egl } // namespace egl
...@@ -879,6 +879,14 @@ ...@@ -879,6 +879,14 @@
"eglLabelObjectKHR" "eglLabelObjectKHR"
], ],
"EGL_ANDROID_get_frame_timestamps": [
"eglGetCompositorTimingSupportedANDROID",
"eglGetCompositorTimingANDROID",
"eglGetNextFrameIdANDROID",
"eglGetFrameTimestampSupportedANDROID",
"eglGetFrameTimestampsANDROID"
],
"angle::Platform related entry points": [ "angle::Platform related entry points": [
"ANGLEGetDisplayPlatform", "ANGLEGetDisplayPlatform",
"ANGLEResetDisplayPlatform" "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