Merge "flatland: add a GPU hardware benchmark"
diff --git a/include/media/drm/DrmClientAPI.h b/include/media/drm/DrmClientAPI.h
new file mode 100644
index 0000000..6a08933
--- /dev/null
+++ b/include/media/drm/DrmClientAPI.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DRM_CLIENT_API_H_
+#define DRM_CLIENT_API_H_
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/List.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+ // A DrmMessageStatus object aggregates a sessionId, which uniquely
+ // identifies a playback context with a status code and opaque message
+ // data.
+ struct DrmMessageStatus {
+ Vector<uint8_t> mSessionId;
+ status_t mStatus;
+ Vector<uint8_t> mData;
+ };
+
+ class DrmClientPlugin {
+ public:
+
+ // A license can be for downloaded, offline content or for online streaming
+ // Offline licenses are persisted on the device and may be used when the device
+ // is disconnected from the network.
+ enum LicenseType {
+ kLicenseType_Offline,
+ kLicenseType_Streaming
+ };
+
+ DrmClientPlugin() {}
+ virtual ~DrmClientPlugin() {}
+
+ // A license request/response exchange occurs between the app and a License
+ // Server to obtain the keys required to decrypt the content. getLicenseRequest()
+ // is used to obtain an opaque license request blob that is delivered to the
+ // license server.
+ //
+ // The init data passed to getLicenseRequest is container-specific and its
+ // meaning is interpreted based on the mime type provided in the mimeType
+ // parameter to getLicenseRequest. It could contain, for example, the content
+ // ID, key ID or other data obtained from the content metadata that is required
+ // in generating the license request.
+ //
+ // The DrmMessageStatus returned from getLicenseRequest contains a sessionId for
+ // the new session, a status code indicating whether the operation was successful
+ // and if so, the request blob is placed into the mData field.
+ virtual DrmMessageStatus getLicenseRequest(Vector<uint8_t> const &initData,
+ String8 const &mimeType, LicenseType licenseType) = 0;
+
+ // After a license response is received by the app, it is provided to the
+ // DrmClient plugin using provideLicenseResponse. The response data is provided
+ // in the mData field of the response parameter.
+ virtual status_t provideLicenseResponse(DrmMessageStatus const &response) = 0;
+
+ // Remove the keys associated with a license and release the session
+ virtual status_t clearLicense(Vector<uint8_t> const &sessionId) = 0;
+
+ // A provision request/response exchange occurs between the app and a
+ // provisioning server to retrieve a device certificate. getProvisionRequest
+ // is used to obtain an opaque license request blob that is delivered to the
+ // provisioning server.
+ //
+ // The DrmMessageStatus returned from getLicenseRequest contains a status code
+ // indicating whether the operation was successful and if so, the request blob
+ // is placed into the mData field.
+ virtual DrmMessageStatus getProvisionRequest() = 0;
+
+ // After a provision response is received by the app, it is provided to the
+ // DrmClient plugin using provideProvisionResponse. The response data is
+ // provided in the mData field of the response parameter.
+ virtual status_t provideProvisionResponse(DrmMessageStatus const &response) = 0;
+
+ // A means of enforcing the contractual requirement for a concurrent stream
+ // limit per subscriber across devices is provided via SecureStop. SecureStop
+ // is a means of securely monitoring the lifetime of sessions. Since playback
+ // on a device can be interrupted due to reboot, power failure, etc. a means
+ // of persisting the lifetime information on the device is needed.
+ //
+ // A signed version of the sessionID is written to persistent storage on the
+ // device when each MediaCrypto object is created. The sessionID is signed by
+ // the device private key to prevent tampering.
+ //
+ // In the normal case, playback will be completed, the session destroyed and
+ // the Secure Stops will be queried. The App queries secure stops and forwards
+ // the secure stop message to the server which verifies the signature and
+ // notifies the server side database that the session destruction has been
+ // confirmed. The persisted record on the client is only removed after positive
+ // confirmation that the server received the message using releaseSecureStops().
+ virtual List<DrmMessageStatus> getSecureStops() = 0;
+ virtual status_t releaseSecureStops(DrmMessageStatus const &ssRelease) = 0;
+
+ // Retrieve the device unique identifier for this device. The device unique
+ // identifier is established during device provisioning.
+ virtual Vector<uint8_t> getDeviceUniqueId() const = 0;
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(DrmClientPlugin);
+ };
+
+} // namespace android
+
+#endif // DRM_CLIENT_API_H_
diff --git a/include/media/drm/DrmEngineAPI.h b/include/media/drm/DrmEngineAPI.h
new file mode 100644
index 0000000..25bd34a
--- /dev/null
+++ b/include/media/drm/DrmEngineAPI.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DRM_ENGINE_API_H_
+#define DRM_ENGINE_API_H_
+
+#include <utils/Errors.h>
+#include <media/stagefright/foundation/ABase.h>
+
+
+namespace android {
+
+ class CryptoPlugin;
+ class DrmClientPlugin;
+
+ // DRMs are implemented in DrmEngine plugins, which are dynamically
+ // loadable shared libraries that implement the entry point
+ // createDrmPluginFactory. createDrmPluginFactory constructs and returns
+ // an instance of a DrmPluginFactory object. When a MediaCrypto or
+ // DrmClient object needs to be constructed, all available
+ // DrmEngines present in the plugins directory on the device are scanned
+ // for a matching DrmEngine that can support the crypto scheme. When a
+ // match is found, the DrmEngine’s createCryptoPlugin or
+ // createDrmClientPlugin methods are used to create CryptoPlugin or
+ // DrmClientPlugin instances to support that DRM scheme.
+
+ class DrmPluginFactory {
+ public:
+ DrmPluginFactory() {}
+ virtual ~DrmPluginFactory() {}
+
+ // DrmPluginFactory::isCryptoSchemeSupported can be called to determine
+ // if the plugin factory is able to construct plugins that support a
+ // given crypto scheme, which is specified by a UUID.
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const = 0;
+
+ // Construct a CryptoPlugin for the crypto scheme specified by UUID.
+ // {data, size} provide scheme-specific initialization data.
+ virtual status_t createCryptoPlugin(
+ const uint8_t uuid[16], const void *data, size_t size,
+ CryptoPlugin **plugin) = 0;
+
+ // Construct a DrmClientPlugin for the crypto scheme specified by UUID.
+ // {data, size} provide scheme-specific initialization data.
+ virtual status_t createDrmClientPlugin(
+ const uint8_t uuid[16], const void *data, size_t size,
+ DrmClientPlugin **plugin) = 0;
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(DrmPluginFactory);
+ };
+
+} // namespace android
+
+ // Loadable DrmEngine shared libraries should define the entry point
+ // createDrmPluginFactory as shown below:
+ //
+ // extern "C" {
+ // extern android::DrmPluginFactory *createDrmPluginFactory();
+ // }
+
+#endif // DRM_ENGINE_API_H_
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index d46f83b..bf2477a 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -84,13 +84,20 @@
static bool sEGLSystraceEnabled;
static bool sEGLGetErrorEnabled;
-int gEGLDebugLevel;
-static int sEGLApplicationDebugLevel;
+static volatile int sEGLDebugLevel;
extern gl_hooks_t gHooksTrace;
extern gl_hooks_t gHooksSystrace;
extern gl_hooks_t gHooksErrorTrace;
+int getEGLDebugLevel() {
+ return sEGLDebugLevel;
+}
+
+void setEGLDebugLevel(int level) {
+ sEGLDebugLevel = level;
+}
+
static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
pthread_setspecific(gGLTraceKey, value);
}
@@ -122,36 +129,36 @@
}
void initEglDebugLevel() {
- int propertyLevel = 0;
- char value[PROPERTY_VALUE_MAX];
+ if (getEGLDebugLevel() == 0) {
+ char value[PROPERTY_VALUE_MAX];
- // check system property only on userdebug or eng builds
- property_get("ro.debuggable", value, "0");
- if (value[0] == '0')
- return;
+ // check system property only on userdebug or eng builds
+ property_get("ro.debuggable", value, "0");
+ if (value[0] == '0')
+ return;
- property_get("debug.egl.debug_proc", value, "");
- if (strlen(value) > 0) {
- long pid = getpid();
- char procPath[128] = {};
- sprintf(procPath, "/proc/%ld/cmdline", pid);
- FILE * file = fopen(procPath, "r");
- if (file) {
- char cmdline[256] = {};
- if (fgets(cmdline, sizeof(cmdline) - 1, file)) {
- if (!strncmp(value, cmdline, strlen(value))) {
- // set EGL debug if the "debug.egl.debug_proc" property
- // matches the prefix of this application's command line
- propertyLevel = 1;
+ property_get("debug.egl.debug_proc", value, "");
+ if (strlen(value) > 0) {
+ FILE * file = fopen("/proc/self/cmdline", "r");
+ if (file) {
+ char cmdline[256];
+ if (fgets(cmdline, sizeof(cmdline), file)) {
+ if (!strncmp(value, cmdline, strlen(value))) {
+ // set EGL debug if the "debug.egl.debug_proc" property
+ // matches the prefix of this application's command line
+ setEGLDebugLevel(1);
+ }
}
+ fclose(file);
}
- fclose(file);
}
}
- gEGLDebugLevel = propertyLevel || sEGLApplicationDebugLevel;
- if (gEGLDebugLevel > 0) {
- GLTrace_start();
+ if (getEGLDebugLevel() > 0) {
+ if (GLTrace_start() < 0) {
+ ALOGE("Error starting Tracer for OpenGL ES. Disabling..");
+ setEGLDebugLevel(0);
+ }
}
}
@@ -165,10 +172,11 @@
} else if (sEGLTraceLevel > 0) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksTrace);
- } else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
+ } else if (getEGLDebugLevel() > 0 && value != &gHooksNoContext) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(GLTrace_getGLHooks());
} else {
+ setGlTraceThreadSpecific(NULL);
setGlThreadSpecific(value);
}
}
@@ -186,9 +194,12 @@
* Global entry point to allow applications to modify their own debug level.
* Debugging is enabled if either the application requested it, or if the system property
* matches the application's name.
+ * Note that this only sets the debug level. The value is read and used either in
+ * initEglDebugLevel() if the application hasn't initialized its display yet, or when
+ * eglSwapBuffers() is called next.
*/
void EGLAPI setGLDebugLevel(int level) {
- sEGLApplicationDebugLevel = level;
+ setEGLDebugLevel(level);
}
#else
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 4e44941..d1f25e0 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -97,7 +97,8 @@
extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
extern EGLBoolean egl_init_drivers();
extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
-extern int gEGLDebugLevel;
+extern int getEGLDebugLevel();
+extern void setEGLDebugLevel(int level);
extern gl_hooks_t gHooksTrace;
} // namespace android;
@@ -465,7 +466,7 @@
egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
version);
#if EGL_TRACE
- if (gEGLDebugLevel > 0)
+ if (getEGLDebugLevel() > 0)
GLTrace_eglCreateContext(version, c);
#endif
return c;
@@ -578,7 +579,7 @@
setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
egl_tls_t::setContext(ctx);
#if EGL_TRACE
- if (gEGLDebugLevel > 0)
+ if (getEGLDebugLevel() > 0)
GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx);
#endif
_c.acquire();
@@ -858,8 +859,31 @@
return setError(EGL_BAD_SURFACE, EGL_FALSE);
#if EGL_TRACE
- if (gEGLDebugLevel > 0)
+ gl_hooks_t const *trace_hooks = getGLTraceThreadSpecific();
+ if (getEGLDebugLevel() > 0) {
+ if (trace_hooks == NULL) {
+ if (GLTrace_start() < 0) {
+ ALOGE("Disabling Tracer for OpenGL ES");
+ setEGLDebugLevel(0);
+ } else {
+ // switch over to the trace version of hooks
+ EGLContext ctx = egl_tls_t::getContext();
+ egl_context_t * const c = get_context(ctx);
+ if (c) {
+ setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
+ GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx);
+ }
+ }
+ }
+
GLTrace_eglSwapBuffers(dpy, draw);
+ } else if (trace_hooks != NULL) {
+ // tracing is now disabled, so switch back to the non trace version
+ EGLContext ctx = egl_tls_t::getContext();
+ egl_context_t * const c = get_context(ctx);
+ if (c) setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
+ GLTrace_stop();
+ }
#endif
egl_surface_t const * const s = get_surface(draw);
@@ -1078,7 +1102,7 @@
egl_tls_t::clearTLS();
#if EGL_TRACE
- if (gEGLDebugLevel > 0)
+ if (getEGLDebugLevel() > 0)
GLTrace_eglReleaseThread();
#endif
return EGL_TRUE;
diff --git a/opengl/libs/GLES_trace/DESIGN.txt b/opengl/libs/GLES_trace/DESIGN.txt
index a189e1d..72a2e15 100644
--- a/opengl/libs/GLES_trace/DESIGN.txt
+++ b/opengl/libs/GLES_trace/DESIGN.txt
@@ -9,9 +9,6 @@
control whether tracing should be enabled for a certain process. If tracing is enabled, this
calls GLTrace_start() to start the trace server.
- Note that initEglTraceLevel() is also called from early_egl_init(), but that happens in the
- context of the zygote, so that invocation has no effect.
-
egl_display_t::initialize() then calls setGLHooksThreadSpecific() where we set the thread
specific gl_hooks structure to point to the trace implementation. From this point on, every
GLES call is redirected to the trace implementation.
@@ -30,6 +27,37 @@
to explore if a more graceful method of stopping the application, or detaching tracing from the
application is required.
+
+Enabling tracing while the application is running:
+
+ In order to allow tracing of an already running application, we allow DdmServer to enable
+ OpenGL tracing. In such a case, the application already has its GL hooks set up to point to the
+ real GL implementation, and we need to switch them to point to the trace implementation.
+
+ This is achieved by checking whether tracing should be enabled at every eglSwap call.
+ (Note: We were already checking for tracing at every eglSwap, the only change now is that
+ the tracing could actually be ON/OFF at runtime - earlier it was set once and never changed).
+
+ If eglSwap detects that tracing should be enabled now, then it performs the following steps:
+ - switch the gl hooks to point to the trace implementation.
+ - call trace eglMakeCurrent to indicate that there is now a new context that is current.
+ - continue on with tracing the eglSwap call.
+ This switches the hooks to point to the trace implementation only for the current context.
+ But the other contexts have their gl hooks updated when they perform eglMakeCurrent.
+
+ The GLTrace version of eglMakeCurrent now has to be updated to allow switching to a context
+ it may not know of. In such a case, it creates a context matching the version that it is now
+ switching to.
+
+Disabling tracing:
+
+ We disable tracing under two conditions:
+ - stop tracing request from DdmServer
+ - gltrace transport gets disconnected from the host.
+ In either case, both actions simply disable the tracing flag. The current context gets its
+ gl hooks restored in the next eglSwap, and the other traced contexts get their gl hooks
+ restored when they perform a eglMakeCurrent.
+
Code Structure:
glestrace.h declares all the hooks exposed by libglestrace. These are used by EGL/egl.cpp and
diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
index 9698bf9..512d562 100644
--- a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
@@ -33,6 +33,9 @@
using gltrace::GLTraceContext;
using gltrace::TCPStream;
+static pthread_mutex_t sGlTraceStateLock = PTHREAD_MUTEX_INITIALIZER;
+
+static int sGlTraceInProgress;
static GLTraceState *sGLTraceState;
static pthread_t sReceiveThreadId;
@@ -105,33 +108,66 @@
return NULL;
}
-void GLTrace_start() {
- char udsName[PROPERTY_VALUE_MAX];
+/**
+ * Starts Trace Server and waits for connection from the host.
+ * Returns -1 in case of connection error, 0 otherwise.
+ */
+int GLTrace_start() {
+ int status = 0;
+ int clientSocket = -1;
+ TCPStream *stream = NULL;
- property_get("debug.egl.debug_portname", udsName, "gltrace");
- int clientSocket = gltrace::acceptClientConnection(udsName);
- if (clientSocket < 0) {
- ALOGE("Error creating GLTrace server socket. Quitting application.");
- exit(-1);
+ pthread_mutex_lock(&sGlTraceStateLock);
+
+ if (sGlTraceInProgress) {
+ goto done;
}
+ char udsName[PROPERTY_VALUE_MAX];
+ property_get("debug.egl.debug_portname", udsName, "gltrace");
+ clientSocket = gltrace::acceptClientConnection(udsName);
+ if (clientSocket < 0) {
+ ALOGE("Error creating GLTrace server socket. Tracing disabled.");
+ status = -1;
+ goto done;
+ }
+
+ sGlTraceInProgress = 1;
+
// create communication channel to the host
- TCPStream *stream = new TCPStream(clientSocket);
+ stream = new TCPStream(clientSocket);
// initialize tracing state
sGLTraceState = new GLTraceState(stream);
pthread_create(&sReceiveThreadId, NULL, commandReceiveTask, sGLTraceState);
+
+done:
+ pthread_mutex_unlock(&sGlTraceStateLock);
+ return status;
}
void GLTrace_stop() {
- delete sGLTraceState;
- sGLTraceState = NULL;
+ pthread_mutex_lock(&sGlTraceStateLock);
+
+ if (sGlTraceInProgress) {
+ sGlTraceInProgress = 0;
+ delete sGLTraceState;
+ sGLTraceState = NULL;
+ }
+
+ pthread_mutex_unlock(&sGlTraceStateLock);
}
void GLTrace_eglCreateContext(int version, EGLContext c) {
+ pthread_mutex_lock(&sGlTraceStateLock);
+ GLTraceState *state = sGLTraceState;
+ pthread_mutex_unlock(&sGlTraceStateLock);
+
+ if (state == NULL) return;
+
// update trace state for new EGL context
- GLTraceContext *traceContext = sGLTraceState->createTraceContext(version, c);
+ GLTraceContext *traceContext = state->createTraceContext(version, c);
gltrace::setupTraceContextThreadSpecific(traceContext);
// trace command through to the host
@@ -139,8 +175,19 @@
}
void GLTrace_eglMakeCurrent(const unsigned version, gl_hooks_t *hooks, EGLContext c) {
+ pthread_mutex_lock(&sGlTraceStateLock);
+ GLTraceState *state = sGLTraceState;
+ pthread_mutex_unlock(&sGlTraceStateLock);
+
+ if (state == NULL) return;
+
// setup per context state
- GLTraceContext *traceContext = sGLTraceState->getTraceContext(c);
+ GLTraceContext *traceContext = state->getTraceContext(c);
+ if (traceContext == NULL) {
+ GLTrace_eglCreateContext(version, c);
+ traceContext = state->getTraceContext(c);
+ }
+
traceContext->hooks = hooks;
gltrace::setupTraceContextThreadSpecific(traceContext);
diff --git a/opengl/libs/glestrace.h b/opengl/libs/glestrace.h
index a08f97b..868b18d 100644
--- a/opengl/libs/glestrace.h
+++ b/opengl/libs/glestrace.h
@@ -30,7 +30,7 @@
void GLTrace_eglSwapBuffers(void*, void*);
/* Start and stop GL Tracing. */
-void GLTrace_start();
+int GLTrace_start();
void GLTrace_stop();
/* Obtain the gl_hooks structure filled with the trace implementation for all GL functions. */
diff --git a/opengl/specs/EGL_ANDROID_blob_cache.txt b/opengl/specs/EGL_ANDROID_blob_cache.txt
index 98da00d..e984694 100644
--- a/opengl/specs/EGL_ANDROID_blob_cache.txt
+++ b/opengl/specs/EGL_ANDROID_blob_cache.txt
@@ -20,11 +20,11 @@
Version
- Version 2, April 25, 2011
+ Version 3, December 13, 2012
Number
- EGL Extension #XXX
+ EGL Extension #48
Dependencies
@@ -88,8 +88,8 @@
New Procedures and Functions
void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
- EGLSetBlobFunc set,
- EGLGetBlobFunc get);
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get);
New Tokens
@@ -200,6 +200,9 @@
Revision History
+#3 (Jon Leech, December 13, 2012)
+ - Fix typo in New Functions section & assign extension #.
+
#2 (Jamie Gennis, April 25, 2011)
- Swapped the order of the size and pointer arguments to the get and set
functions.
diff --git a/opengl/specs/EGL_ANDROID_framebuffer_target.txt b/opengl/specs/EGL_ANDROID_framebuffer_target.txt
index 5a301aa..a15dfa8 100644
--- a/opengl/specs/EGL_ANDROID_framebuffer_target.txt
+++ b/opengl/specs/EGL_ANDROID_framebuffer_target.txt
@@ -24,7 +24,7 @@
Number
- EGL Extension #XXX
+ EGL Extension #47
Dependencies
diff --git a/opengl/specs/EGL_ANDROID_image_native_buffer.txt b/opengl/specs/EGL_ANDROID_image_native_buffer.txt
index 146615f..7392d4f 100644
--- a/opengl/specs/EGL_ANDROID_image_native_buffer.txt
+++ b/opengl/specs/EGL_ANDROID_image_native_buffer.txt
@@ -26,7 +26,7 @@
Number
- EGL Extension #XXX
+ EGL Extension #49
Dependencies
diff --git a/opengl/specs/EGL_ANDROID_native_fence_sync.txt b/opengl/specs/EGL_ANDROID_native_fence_sync.txt
index 976207e..d72edd7 100644
--- a/opengl/specs/EGL_ANDROID_native_fence_sync.txt
+++ b/opengl/specs/EGL_ANDROID_native_fence_sync.txt
@@ -24,7 +24,7 @@
Number
- EGL Extension #XXX
+ EGL Extension #50
Dependencies
diff --git a/opengl/specs/EGL_ANDROID_recordable.txt b/opengl/specs/EGL_ANDROID_recordable.txt
index e4aaa4b..d21094e 100644
--- a/opengl/specs/EGL_ANDROID_recordable.txt
+++ b/opengl/specs/EGL_ANDROID_recordable.txt
@@ -24,7 +24,7 @@
Number
- EGL Extension #XXX
+ EGL Extension #51
Dependencies